The purpose of this patch is to align the finite element classes with the way the
mapping classes have already been converted. Specifically, there is no need for
any of the users of finite element classes to actually know whether a FE implementation
wants to treat a particular flags as update_once or update_each. This is an internal
decision. Rather, all we need to know is what flags they need overall. This is now
communicated by the new FiniteElement::requires_update_flags() function.
The update_once() and update_each() functions have been retained -- for now -- as
internal functions individual elements can implement, but they are no longer virtual.
compute_n_nonzero_components (const std::vector<ComponentMask> &nonzero_components);
/**
- * Determine the values a finite element should compute on initialization of
- * data for FEValues.
+ * Given a set of update flags, compute which other quantities <i>also</i>
+ * need to be computed in order to satisfy the request by the given flags.
+ * Then return the combination of the original set of flags and those
+ * just computed.
+ *
+ * As an example, if @p update_flags contains update_gradients
+ * a finite element class will typically
+ * require the computation of the inverse of the Jacobian matrix in order to
+ * rotate the gradient of shape functions on the reference cell to the
+ * real cell. It would then return not just
+ * update_gradients, but also update_covariant_transformation, the flag that
+ * makes the mapping class produce the inverse of the Jacobian matrix.
*
- * Given a set of flags indicating what quantities are requested from a
- * FEValues object, update_once() and update_each() compute which values
- * must really be computed. Then, the <tt>fill_*_values</tt> functions are
- * called with the result of these.
- *
- * Furthermore, values must be computed either on the unit cell or on the
- * physical cell. For instance, the function values of FE_Q do only depend
- * on the quadrature points on the unit cell. Therefore, this flags will be
- * returned by update_once(). The gradients require computation of the
- * covariant transformation matrix. Therefore, @p
- * update_covariant_transformation and @p update_gradients will be returned
- * by update_each().
- *
- * For an example see the same function in the derived class FE_Q.
- */
- virtual UpdateFlags update_once (const UpdateFlags flags) const = 0;
-
- /**
- * Complementary function for update_once().
- *
- * While update_once() returns the values to be computed on the unit cell
- * for yielding the required data, this function determines the values that
- * must be recomputed on each cell.
+ * An extensive discussion of the interaction between this function and
+ * FEValues can be found in the @ref FE_vs_Mapping_vs_FEValues documentation
+ * module.
*
- * Refer to update_once() for more details.
+ * @see UpdateFlags
*/
- virtual UpdateFlags update_each (const UpdateFlags flags) const = 0;
+ virtual
+ UpdateFlags
+ requires_update_flags (const UpdateFlags update_flags) const = 0;
/**
* Prepare internal data structures and fill in values independent of the
*/
virtual std::string get_name () const;
+ // for documentation, see the FiniteElement base class
+ virtual
+ UpdateFlags
+ requires_update_flags (const UpdateFlags update_flags) const;
+
/**
* Return the value of the @p ith shape function at the point @p p. See the
* FiniteElement base class for more information about the semantics of this
*
* For the present kind of finite element, this is exactly the case.
*/
- virtual UpdateFlags update_once (const UpdateFlags flags) const;
+ UpdateFlags update_once (const UpdateFlags flags) const;
/**
* This is the opposite to the above function: given a set of flags
* (for example, we often need the covariant transformation when gradients
* need to be computed), include this in the result as well.
*/
- virtual UpdateFlags update_each (const UpdateFlags flags) const;
+ UpdateFlags update_each (const UpdateFlags flags) const;
/**
* Degree of the polynomials.
*/
virtual std::string get_name () const;
+ // for documentation, see the FiniteElement base class
+ virtual
+ UpdateFlags
+ requires_update_flags (const UpdateFlags update_flags) const;
+
/**
* Return the matrix interpolating from a face of of one element to the face
* of the neighboring element. The size of the matrix is then
* All other flags of the result are cleared, since everything else must be
* computed for each cell.
*/
- virtual UpdateFlags update_once (const UpdateFlags flags) const;
+ UpdateFlags update_once (const UpdateFlags flags) const;
/**
* Determine the values that need to be computed on every cell to be able to
*
* </ul>
*/
- virtual UpdateFlags update_each (const UpdateFlags flags) const;
+ UpdateFlags update_each (const UpdateFlags flags) const;
private:
/**
std::string
get_name() const;
- /**
- * Determine the values a finite element should compute on initialization of
- * data for FEValues.
- *
- * Given a set of flags indicating what quantities are requested from a
- * FEValues object, update_once() and update_each() compute which values
- * must really be computed. Then, the <tt>fill_*_values</tt> functions are
- * called with the result of these.
- *
- * In this case, since the element has zero degrees of freedom and no
- * information can be computed on it, this function simply returns the
- * default (empty) set of update flags.
- */
-
- virtual
- UpdateFlags
- update_once (const UpdateFlags flags) const;
-
- /**
- * Complementary function for update_once().
- *
- * While update_once() returns the values to be computed on the unit cell
- * for yielding the required data, this function determines the values that
- * must be recomputed on each cell.
- *
- * Refer to update_once() for more details.
- */
+ // for documentation, see the FiniteElement base class
virtual
UpdateFlags
- update_each (const UpdateFlags flags) const;
+ requires_update_flags (const UpdateFlags update_flags) const;
/**
* Return the value of the @p ith shape function at the point @p p. @p p is
bool is_dominating() const;
private:
+
/**
* If true, this element will dominate any other apart from itself in compare_for_face_domination();
*/
const bool dominate;
-
};
*/
unsigned int get_degree () const;
+ // for documentation, see the FiniteElement base class
+ virtual
+ UpdateFlags
+ requires_update_flags (const UpdateFlags update_flags) const;
+
/**
* Return the numbering of the underlying polynomial space compared to
* lexicographic ordering of the basis functions. Returns
* All other flags of the result are cleared, since everything else must be
* computed for each cell.
*/
- virtual UpdateFlags update_once (const UpdateFlags flags) const;
+ UpdateFlags update_once (const UpdateFlags flags) const;
/**
* Determine the values that need to be computed on every cell to be able to
*
* </ul>
*/
- virtual UpdateFlags update_each (const UpdateFlags flags) const;
+ UpdateFlags update_each (const UpdateFlags flags) const;
/**
* Fields of cell-independent data.
//---------------------------------------------------------------------------
+template <class POLY, int dim, int spacedim>
+UpdateFlags
+FE_Poly<POLY,dim,spacedim>::requires_update_flags (const UpdateFlags flags) const
+{
+ return update_once(flags) | update_each(flags);
+}
+
template <class POLY, int dim, int spacedim>
*/
unsigned int get_degree () const;
+ // for documentation, see the FiniteElement base class
+ virtual
+ UpdateFlags
+ requires_update_flags (const UpdateFlags update_flags) const;
+
protected:
/*
* NOTE: The following functions have their definitions inlined into the class declaration
* All other flags of the result are cleared, since everything else must be
* computed for each cell.
*/
- virtual UpdateFlags update_once (const UpdateFlags flags) const;
+ UpdateFlags update_once (const UpdateFlags flags) const;
/**
* Determine the values that need to be computed on every cell to be able to
*
* </ul>
*/
- virtual UpdateFlags update_each (const UpdateFlags flags) const;
+ UpdateFlags update_each (const UpdateFlags flags) const;
/**
//---------------------------------------------------------------------------
+template <class POLY, int dim, int spacedim>
+UpdateFlags
+FE_PolyFace<POLY,dim,spacedim>::requires_update_flags (const UpdateFlags flags) const
+{
+ return update_once(flags) | update_each(flags);
+}
template <class POLY, int dim, int spacedim>
UpdateFlags
FE_PolyFace<POLY,dim,spacedim>::update_once (const UpdateFlags) const
{
- // for this kind of elements, only the values can be precomputed once and
- // for all. set this flag if the values are requested at all
return update_default;
}
const std::vector<bool> &restriction_is_additive_flags,
const std::vector<ComponentMask> &nonzero_components);
+ // for documentation, see the FiniteElement base class
+ virtual
+ UpdateFlags
+ requires_update_flags (const UpdateFlags update_flags) const;
+
/**
* Since these elements are vector valued, an exception is thrown.
*/
const Point<dim> &p,
const unsigned int component) const;
+protected:
+ /**
+ * The mapping type to be used to map shape functions from the reference
+ * cell to the mesh cell.
+ */
+ MappingType mapping_type;
+
+
/**
* Given <tt>flags</tt>, determines the values which must be computed only
* for the reference cell. Make sure, that #mapping_type is set by the
* derived class, such that this function can operate correctly.
*/
- virtual UpdateFlags update_once (const UpdateFlags flags) const;
+ UpdateFlags update_once (const UpdateFlags flags) const;
+
/**
* Given <tt>flags</tt>, determines the values which must be computed in
* each cell cell. Make sure, that #mapping_type is set by the derived
* class, such that this function can operate correctly.
*/
- virtual UpdateFlags update_each (const UpdateFlags flags) const;
+ UpdateFlags update_each (const UpdateFlags flags) const;
-protected:
- /**
- * The mapping type to be used to map shape functions from the reference
- * cell to the mesh cell.
- */
- MappingType mapping_type;
- /**
- NOTE: The following function has its definition inlined into the class declaration
- * because we otherwise run into a compiler error with MS Visual Studio.
- */
+ /* NOTE: The following function has its definition inlined into the class declaration
+ because we otherwise run into a compiler error with MS Visual Studio. */
virtual
typename FiniteElement<dim,spacedim>::InternalDataBase *
get_data(const UpdateFlags update_flags,
*/
virtual std::string get_name () const;
+ // for documentation, see the FiniteElement base class
+ virtual
+ UpdateFlags
+ requires_update_flags (const UpdateFlags update_flags) const;
+
/**
* Return the value of the @p ith shape function at the point @p p. @p p is
* a point on the reference element. Since this finite element is always
/**
* Compute flags for initial update only.
*/
- virtual UpdateFlags update_once (const UpdateFlags flags) const;
+ UpdateFlags update_once (const UpdateFlags flags) const;
/**
* Compute flags for update on each cell.
*/
- virtual UpdateFlags update_each (const UpdateFlags flags) const;
+ UpdateFlags update_each (const UpdateFlags flags) const;
/**
* @p clone function instead of a copy constructor.
}
+
+template <int dim, int spacedim>
+UpdateFlags
+FE_DGPNonparametric<dim,spacedim>::requires_update_flags (const UpdateFlags flags) const
+{
+ return update_once(flags) | update_each(flags);
+}
+
+
+
template <int dim, int spacedim>
UpdateFlags
FE_DGPNonparametric<dim,spacedim>::update_once (const UpdateFlags) const
+template <int spacedim>
+UpdateFlags
+FE_FaceQ<1,spacedim>::requires_update_flags (const UpdateFlags flags) const
+{
+ return update_once(flags) | update_each(flags);
+}
+
+
+
template <int spacedim>
UpdateFlags
FE_FaceQ<1,spacedim>::update_each (const UpdateFlags flags) const
template <int dim, int spacedim>
UpdateFlags
-FE_Nothing<dim,spacedim>::update_once (const UpdateFlags /*flags*/) const
+FE_Nothing<dim,spacedim>::requires_update_flags (const UpdateFlags flags) const
{
- return update_default;
-}
-
-
-
-template <int dim, int spacedim>
-UpdateFlags
-FE_Nothing<dim,spacedim>::update_each (const UpdateFlags /*flags*/) const
-{
- return update_default;
+ return flags;
}
}
+
+template <class POLY, int dim, int spacedim>
+UpdateFlags
+FE_PolyTensor<POLY,dim,spacedim>::requires_update_flags(const UpdateFlags flags) const
+{
+ return update_once(flags) | update_each(flags);
+}
+
+
template <class POLY, int dim, int spacedim>
UpdateFlags
FE_PolyTensor<POLY,dim,spacedim>::update_once (const UpdateFlags flags) const
template <int dim, int spacedim>
UpdateFlags
-FESystem<dim,spacedim>::update_once (const UpdateFlags flags) const
+FESystem<dim,spacedim>::requires_update_flags (const UpdateFlags flags) const
{
UpdateFlags out = update_default;
// generate maximal set of flags
// that are necessary
for (unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
- out |= base_element(base_no).update_once(flags);
- return out;
-}
-
-
-
-template <int dim, int spacedim>
-UpdateFlags
-FESystem<dim,spacedim>::update_each (const UpdateFlags flags) const
-{
- UpdateFlags out = update_default;
- // generate maximal set of flags
- // that are necessary
- for (unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
- out |= base_element(base_no).update_each(flags);
-
+ out |= base_element(base_no).requires_update_flags (flags);
return out;
}
template <int dim, int spacedim>
typename FiniteElement<dim,spacedim>::InternalDataBase *
-FESystem<dim,spacedim>::get_data (const UpdateFlags flags_,
+FESystem<dim,spacedim>::get_data (const UpdateFlags flags,
const Mapping<dim,spacedim> &mapping,
const Quadrature<dim> &quadrature) const
{
- UpdateFlags flags = flags_;
+ // create an internal data object and set the update flags we will need
+ // to deal with. the current object does not make use of these flags,
+ // but we need to nevertheless set them correctly since we look
+ // into the update_each flag of base elements in fill_fe_values,
+ // and so the current object's update_each flag needs to be
+ // correct in case the current FESystem is a base element for another,
+ // higher-level FESystem itself.
InternalData *data = new InternalData(this->n_base_elements());
- data->update_each = update_each(flags) | update_once(flags);
+ data->update_each = requires_update_flags(flags);
// get data objects from each of the base elements and store
// them. do the creation of these objects in parallel as their
template <int dim, int spacedim>
typename FiniteElement<dim,spacedim>::InternalDataBase *
-FESystem<dim,spacedim>::get_face_data (
- const UpdateFlags flags_,
- const Mapping<dim,spacedim> &mapping,
- const Quadrature<dim-1> &quadrature) const
-{
- UpdateFlags flags = flags_;
+FESystem<dim,spacedim>::get_face_data (const UpdateFlags flags,
+ const Mapping<dim,spacedim> &mapping,
+ const Quadrature<dim-1> &quadrature) const
+{
+ // create an internal data object and set the update flags we will need
+ // to deal with. the current object does not make use of these flags,
+ // but we need to nevertheless set them correctly since we look
+ // into the update_each flag of base elements in fill_fe_values,
+ // and so the current object's update_each flag needs to be
+ // correct in case the current FESystem is a base element for another,
+ // higher-level FESystem itself.
InternalData *data = new InternalData(this->n_base_elements());
- data->update_each = update_each(flags) | update_once(flags);
+ data->update_each = requires_update_flags(flags);
// get data objects from each of the base elements and store
// them. do the creation of these objects in parallel as their
template <int dim, int spacedim>
typename FiniteElement<dim,spacedim>::InternalDataBase *
-FESystem<dim,spacedim>::get_subface_data (
- const UpdateFlags flags_,
- const Mapping<dim,spacedim> &mapping,
- const Quadrature<dim-1> &quadrature) const
-{
- UpdateFlags flags = flags_;
+FESystem<dim,spacedim>::get_subface_data (const UpdateFlags flags,
+ const Mapping<dim,spacedim> &mapping,
+ const Quadrature<dim-1> &quadrature) const
+{
+ // create an internal data object and set the update flags we will need
+ // to deal with. the current object does not make use of these flags,
+ // but we need to nevertheless set them correctly since we look
+ // into the update_each flag of base elements in fill_fe_values,
+ // and so the current object's update_each flag needs to be
+ // correct in case the current FESystem is a base element for another,
+ // higher-level FESystem itself.
InternalData *data = new InternalData(this->n_base_elements());
- data->update_each = update_each(flags) | update_once(flags);
+ data->update_each = requires_update_flags(flags);
// get data objects from each of the base elements and store
// them. do the creation of these objects in parallel as their
UpdateFlags
FEValuesBase<dim,spacedim>::compute_update_flags (const UpdateFlags update_flags) const
{
-
- // first find out which objects
- // need to be recomputed on each
- // cell we visit. this we have to
- // ask the finite element and mapping.
- // elements are first since they
- // might require update in mapping
+ // first find out which objects need to be recomputed on each
+ // cell we visit. this we have to ask the finite element and mapping.
+ // elements are first since they might require update in mapping
+ //
+ // there is no need to iterate since mappings will never require
+ // the finite element to compute something for them
UpdateFlags flags = update_flags
- | fe->update_once (update_flags)
- | fe->update_each (update_flags);
+ | fe->requires_update_flags (update_flags);
flags |= mapping->requires_update_flags (flags);
return flags;