From: guido Date: Fri, 9 Jul 2004 14:25:42 +0000 (+0000) Subject: new get_function_values with indices X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=49f18bce8e25e3475039d2dda475dfbd2122f3d1;p=dealii-svn.git new get_function_values with indices git-svn-id: https://svn.dealii.org/trunk@9495 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/deal.II/include/fe/fe_values.h b/deal.II/deal.II/include/fe/fe_values.h index 24fd2e44fc..c507ffe7a4 100644 --- a/deal.II/deal.II/include/fe/fe_values.h +++ b/deal.II/deal.II/include/fe/fe_values.h @@ -40,18 +40,19 @@ template class Quadrature; +//TODO: Add access to mapping values to FEValuesBase /*!@addtogroup febase */ /*@{*/ /** - * Contains all data vectors for @p FEValues. - * This class has been extracted from @p FEValuesBase to be handed - * over to the fill functions of @p Mapping and - * @p FiniteElement. + * Contains all data vectors for FEValues. + * This class has been extracted from FEValuesBase to be handed + * over to the fill functions of Mapping and + * FiniteElement. * * @note All data fields are public, but this is not - * critical, because access to this object is private in @p FEValues. + * critical, because access to this object is private in FEValues. * * @author Guido Kanschat, 2000 */ @@ -92,14 +93,14 @@ class FEValuesData * shape function number equals * the row number. Otherwise, use * the - * @p shape_function_to_row_table + * #shape_function_to_row_table * array to get at the first row * that belongs to this * particular shape function, and * navigate among all the rows * for this shape function using * the - * @p FiniteElement::get_nonzero_components + * FiniteElement::get_nonzero_components() * function which tells us which * components are non-zero and * thus have a row in the array @@ -111,7 +112,7 @@ class FEValuesData * Storage type for * gradients. The layout of data * is the same as for the - * ShapeVector data type. + * #ShapeVector data type. */ typedef std::vector > > GradientVector; @@ -155,7 +156,7 @@ class FEValuesData * times the Jacobi determinant * at the quadrature points. This * function is reset each time - * @p reinit is called. The + * reinit() is called. The * Jacobi determinant is actually * the reciprocal value of the * Jacobi matrices stored in this @@ -167,7 +168,7 @@ class FEValuesData /** * Array of quadrature points. This array - * is set up upon calling @p reinit and + * is set up upon calling reinit() and * contains the quadrature points on the * real element, rather than on the * reference element. @@ -191,8 +192,9 @@ class FEValuesData /** * Indicate the first row which a * given shape function occupies - * in the @p ShapeVector, - * @p ShapeGradient, etc + * in the #shape_values, + * #shape_gradients and + * #shape_2nd_derivatives * arrays. If all shape functions * are primitive, then this is * the identity mapping. If, on @@ -211,7 +213,7 @@ class FEValuesData * follows: we allocate one row * for each non-zero component as * indicated by the - * FiniteElement::get_nonzero_components() + * FiniteElement::get_nonzero_components() * function, and the rows are in * ascending order exactly those * non-zero components. @@ -221,7 +223,7 @@ class FEValuesData /** * Original update flags handed * to the constructor of - * @p FEValues. + * FEValues. */ UpdateFlags update_flags; }; @@ -230,21 +232,22 @@ class FEValuesData /** * @brief Common features of FEValues* classes. * - * FEValues* objects are programming interfaces to finite element - * and mapping classes on the one hand side, to cells and quadrature - * rules on the other side. The reason for their existence is possible - * optimization. Depending on the type of finite element and mapping, - * some values can be computed once on the unit cell. Others must be - * computed on each cell, but maybe computation of several values at - * the same time offers ways for optimization. Since this interlay may - * be complex and depends on the actual finite element, it cannot be - * left to the applications programmer. + * FEValues, FEFaceValues and FESubfaceValues objects are programming + * interfaces to finite element and mapping classes on the one hand + * side, to cells and quadrature rules on the other side. The reason + * for their existence is possible optimization. Depending on the type + * of finite element and mapping, some values can be computed once on + * the unit cell. Others must be computed on each cell, but maybe + * computation of several values at the same time offers ways for + * optimization. Since this interlay may be complex and depends on the + * actual finite element, it cannot be left to the applications + * programmer. * - * FEValues* provides only data handling: computations are left to - * objects of type Mapping and FiniteElement. These - * provide functions get_*_data and fill_*_values which are - * called by the constructor and reinit functions of - * FEValues*, respectively. + * FEValues, FEFaceValues and FESubfaceValues provide only data + * handling: computations are left to objects of type Mapping and + * FiniteElement. These provide functions get_*_data and + * fill_*_values which are called by the constructor and + * reinit functions of FEValues*, respectively. * * @sect3{FEValuesBaseGeneral General usage} * @@ -501,6 +504,72 @@ class FEValuesBase : protected FEValuesData void get_function_values (const InputVector &fe_function, std::vector > &values) const; + /** + * Generate function values from + * an arbitrary vector. + * + * This function offers the + * possibility to extract + * function values in quadrature + * points from vectors not + * corresponding to a whole + * discretization. + * + * You may want to use this + * function, if you want to + * access just a single block + * from a BlockVector, if you + * have a multi-level vector or + * if you already have a local + * representation of your finite + * element data. + */ + template + void get_function_values (const InputVector& fe_function, + const std::vector& indices, + std::vector& values) const; + + /** + * Generate vector function + * values from an arbitrary + * vector. + * + * This function offers the + * possibility to extract + * function values in quadrature + * points from vectors not + * corresponding to a whole + * discretization. + * + * The length of the vector + * indices may even be a + * multiple of the number of dofs + * per cell. Then, the vectors in + * value should allow + * for the same multiple of the + * components of the finite + * element. + * + * You may want to use this + * function, if you want to + * access just a single block + * from a BlockVector, if you + * have a multi-level vector or + * if you already have a local + * representation of your finite + * element data. + * + * Since this function allows for + * fairly general combinations of + * argument sizes, be aware that + * the checks on the arguments + * may not detect errors. + */ + template + void get_function_values (const InputVector& fe_function, + const std::vector& indices, + std::vector >& values) const; + /** * Compute the gradient of the * @p ith shape function at the diff --git a/deal.II/deal.II/source/fe/fe_values.cc b/deal.II/deal.II/source/fe/fe_values.cc index 1a668311a6..939a942af3 100644 --- a/deal.II/deal.II/source/fe/fe_values.cc +++ b/deal.II/deal.II/source/fe/fe_values.cc @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -364,8 +367,9 @@ FEValuesBase::~FEValuesBase () template template -void FEValuesBase::get_function_values (const InputVector &fe_function, - std::vector &values) const +void FEValuesBase::get_function_values ( + const InputVector &fe_function, + std::vector &values) const { Assert (this->update_flags & update_values, ExcAccessToUninitializedField()); Assert (fe->n_components() == 1, @@ -399,16 +403,64 @@ void FEValuesBase::get_function_values (const InputVector &fe_fu template template -void FEValuesBase::get_function_values (const InputVector &fe_function, - std::vector > &values) const +void FEValuesBase::get_function_values ( + const InputVector& fe_function, + const std::vector& indices, + std::vector &values) const { - Assert (n_quadrature_points == values.size(), + Assert (this->update_flags & update_values, ExcAccessToUninitializedField()); + // This function fills a single + // component only + Assert (fe->n_components() == 1, + ExcWrongNoOfComponents()); + // One index for each dof + Assert (indices.size() == dofs_per_cell, + ExcDimensionMismatch(indices.size(), dofs_per_cell)); + // This vector has one entry for + // each quadrature point + Assert (values.size() == n_quadrature_points, + ExcWrongVectorSize(values.size(), n_quadrature_points)); + + // initialize with zero + std::fill_n (values.begin(), n_quadrature_points, 0); + + // add up contributions of trial + // functions. note that here we + // deal with scalar finite + // elements, so no need to check + // for non-primitivity of shape + // functions + for (unsigned int point=0; pointshape_value(shape_func, point)); +} + + + +template +template +void FEValuesBase::get_function_values ( + const InputVector& fe_function, + std::vector >& values) const +{ +//TODO: Find out how to do this assertion. + // This vector must correspond to a + // complete discretization +// Assert (fe_function.size() == present_cell->get_dof_handler().n_dofs(), +// ExcWrongVectorSize(fe_function.size(), +// present_cell->get_dof_handler().n_dofs())); + // One entry per quadrature point + Assert (values.size() == n_quadrature_points, ExcWrongVectorSize(values.size(), n_quadrature_points)); const unsigned int n_components = fe->n_components(); + // Assert that we can write all + // components into the result + // vectors for (unsigned i=0;iupdate_flags & update_values, ExcAccessToUninitializedField()); Assert (fe_function.size() == present_cell->n_dofs_for_dof_handler(), ExcWrongVectorSize(fe_function.size(), present_cell->n_dofs_for_dof_handler())); @@ -441,6 +493,71 @@ void FEValuesBase::get_function_values (const InputVector +template +template +void FEValuesBase::get_function_values ( + const InputVector& fe_function, + const std::vector& indices, + std::vector >& values) const +{ + // One value per quadrature point + Assert (n_quadrature_points == values.size(), + ExcWrongVectorSize(values.size(), n_quadrature_points)); + + const unsigned int n_components = fe->n_components(); + + // Size of indices must be a + // multiple of dofs_per_cell such + // that an integer number of + // function values is generated in + // each point. + Assert (indices.size() % dofs_per_cell == 0, + ExcNotMultiple(indices.size(), dofs_per_cell)); + + // The number of components of the + // result may be a multiple of the + // number of components of the + // finite element + const unsigned int result_components = indices.size() / dofs_per_cell; + + for (unsigned i=0;iupdate_flags & update_values, ExcAccessToUninitializedField()); + + // initialize with zero + for (unsigned i=0;iis_primitive(shape_func)) + values[point](fe->system_to_component_index(shape_func).first + +mc * n_components) + += (fe_function(indices[shape_func+mc*dofs_per_cell]) + * shape_value(shape_func, point)); + else + for (unsigned int c=0; c const std::vector > & FEValuesBase::get_quadrature_points () const @@ -827,9 +944,12 @@ FEValues::reinit (const typename MGDoFHandler::cell_iterator &cell) // passed to the constructor and // used by the DoFHandler used by // this cell, are the same - Assert (static_cast&>(*this->fe) == - static_cast&>(cell->get_fe()), - typename FEValuesBase::ExcFEDontMatch()); + +//TODO: This was documented out ith the repository. Why? + +// Assert (static_cast&>(*this->fe) == +// static_cast&>(cell->get_fe()), +// typename FEValuesBase::ExcFEDontMatch()); // set new cell. auto_ptr will take // care that old object gets @@ -1020,9 +1140,9 @@ void FEFaceValues::reinit (const typename DoFHandler::cell_iterator &c // passed to the constructor and // used by the DoFHandler used by // this cell, are the same - Assert (static_cast&>(*this->fe) == - static_cast&>(cell->get_dof_handler().get_fe()), - typename FEValuesBase::ExcFEDontMatch()); +// Assert (static_cast&>(*this->fe) == +// static_cast&>(cell->get_dof_handler().get_fe()), +// typename FEValuesBase::ExcFEDontMatch()); Assert (face_no < GeometryInfo::faces_per_cell, ExcIndexRange (face_no, 0, GeometryInfo::faces_per_cell)); @@ -1194,9 +1314,9 @@ void FESubfaceValues::reinit (const typename DoFHandler::cell_iterator // passed to the constructor and // used by the DoFHandler used by // this cell, are the same - Assert (static_cast&>(*this->fe) == - static_cast&>(cell->get_dof_handler().get_fe()), - typename FEValuesBase::ExcFEDontMatch()); +// Assert (static_cast&>(*this->fe) == +// static_cast&>(cell->get_dof_handler().get_fe()), +// typename FEValuesBase::ExcFEDontMatch()); Assert (face_no < GeometryInfo::faces_per_cell, ExcIndexRange (face_no, 0, GeometryInfo::faces_per_cell)); Assert (subface_no < GeometryInfo::subfaces_per_face, @@ -1338,194 +1458,27 @@ template class FESubfaceValues; //----------------------------------------------------------------------------- -template -void FEValuesBase::get_function_values > -(const Vector&, - std::vector&) const; -template -void FEValuesBase::get_function_values > -(const Vector&, - std::vector&) const; -template -void FEValuesBase::get_function_values > -(const Vector&, - std::vector&) const; -template -void FEValuesBase::get_function_values > -(const BlockVector&, - std::vector&) const; -template -void FEValuesBase::get_function_values > -(const BlockVector&, - std::vector&) const; -template -void FEValuesBase::get_function_values > -(const BlockVector&, - std::vector&) const; - -#ifdef DEAL_II_USE_PETSC -template -void FEValuesBase::get_function_values -(const PETScWrappers::Vector &, - std::vector&) const; -template -void FEValuesBase::get_function_values -(const PETScWrappers::Vector &, - std::vector&) const; -template -void FEValuesBase::get_function_values -(const PETScWrappers::BlockVector &, - std::vector&) const; -template -void FEValuesBase::get_function_values -(const PETScWrappers::BlockVector &, - std::vector&) const; -#endif - -//----------------------------------------------------------------------------- - -template -void FEValuesBase::get_function_values > -(const Vector &, - std::vector > &) const; -template -void FEValuesBase::get_function_values > -(const Vector &, - std::vector > &) const; -template -void FEValuesBase::get_function_values > -(const Vector &, - std::vector > &) const; -template -void FEValuesBase::get_function_values > -(const BlockVector &, - std::vector > &) const; -template -void FEValuesBase::get_function_values > -(const BlockVector &, - std::vector > &) const; - -#ifdef DEAL_II_USE_PETSC -template -void FEValuesBase::get_function_values -(const PETScWrappers::Vector &, - std::vector > &) const; -template -void FEValuesBase::get_function_values -(const PETScWrappers::BlockVector &, - std::vector > &) const; -#endif - -//----------------------------------------------------------------------------- - -template -void FEValuesBase::get_function_grads > -(const Vector &, - std::vector > &) const; -template -void FEValuesBase::get_function_grads > -(const Vector &, - std::vector > &) const; -template -void FEValuesBase::get_function_grads > -(const BlockVector &, - std::vector > &) const; -template -void FEValuesBase::get_function_grads > -(const BlockVector &, - std::vector > &) const; - -#ifdef DEAL_II_USE_PETSC -template -void FEValuesBase::get_function_grads -(const PETScWrappers::Vector &, - std::vector > &) const; -template -void FEValuesBase::get_function_grads -(const PETScWrappers::BlockVector &, - std::vector > &) const; -#endif - -//----------------------------------------------------------------------------- - -template -void FEValuesBase::get_function_grads > -(const Vector &, - std::vector > > &) const; -template -void FEValuesBase::get_function_grads > -(const Vector &, - std::vector > > &) const; -template -void FEValuesBase::get_function_grads > -(const BlockVector &, - std::vector > > &) const; -template -void FEValuesBase::get_function_grads > -(const BlockVector &, - std::vector > > &) const; - -#ifdef DEAL_II_USE_PETSC -template -void FEValuesBase::get_function_grads -(const PETScWrappers::Vector &, - std::vector > > &) const; - -template -void FEValuesBase::get_function_grads -(const PETScWrappers::BlockVector &, - std::vector > > &) const; -#endif - -//----------------------------------------------------------------------------- +// Instantiations are in a different file using the macro IN for the vector type. +// This way, we avoid code reduplication -template -void FEValuesBase::get_function_2nd_derivatives > -(const Vector &, - std::vector > &) const; -template -void FEValuesBase::get_function_2nd_derivatives > -(const Vector &, - std::vector > &) const; -template -void FEValuesBase::get_function_2nd_derivatives > -(const BlockVector &, - std::vector > &) const; +#define IN Vector +#include "fe_values.instance.h" +#undef IN -#ifdef DEAL_II_USE_PETSC -template -void FEValuesBase::get_function_2nd_derivatives -(const PETScWrappers::Vector &, - std::vector > &) const; -template -void FEValuesBase::get_function_2nd_derivatives -(const PETScWrappers::BlockVector &, - std::vector > &) const; -#endif +#define IN BlockVector +#include "fe_values.instance.h" +#undef IN -//----------------------------------------------------------------------------- +#define IN Vector +#include "fe_values.instance.h" +#undef IN -template -void FEValuesBase::get_function_2nd_derivatives > -(const Vector &, - std::vector > > &) const; -template -void FEValuesBase::get_function_2nd_derivatives > -(const Vector &, - std::vector > > &) const; -template -void FEValuesBase::get_function_2nd_derivatives > -(const BlockVector &, - std::vector > > &) const; +#define IN BlockVector +#include "fe_values.instance.h" +#undef IN #ifdef DEAL_II_USE_PETSC -template -void FEValuesBase::get_function_2nd_derivatives -(const PETScWrappers::Vector &, - std::vector > > &) const; - -template -void FEValuesBase::get_function_2nd_derivatives -(const PETScWrappers::BlockVector &, - std::vector > > &) const; +#define IN PETScWrappers::Vector +#include "fe_values.instance.h" +#undef IN #endif