From 9f1b72177ee0c3dd2a0383eaa88350e5b3c18def Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Tue, 10 Nov 2015 15:31:21 -0600 Subject: [PATCH] Add an output data object to FE::get_*_data(). This allows finite elements to already fill certain output data elements at the time the get_data() function is called, rather than having to later figure out whether this is the first time (or not) they get into fill_fe_*_values(). In its current form, the patch only adds that possibility to passing the same output object to FiniteElement::get_*_data() that will later be used when FiniteElement::fill_fe_*_values() will be called. The patch does not actually implement any of the elements using this -- I will leave this to a later patch addressing #1824. --- include/deal.II/fe/fe.h | 30 ++++++---- include/deal.II/fe/fe_dgp_nonparametric.h | 7 ++- include/deal.II/fe/fe_face.h | 19 ++++--- include/deal.II/fe/fe_nothing.h | 7 ++- include/deal.II/fe/fe_poly.h | 7 ++- include/deal.II/fe/fe_poly_face.h | 24 ++++---- include/deal.II/fe/fe_poly_tensor.h | 7 ++- include/deal.II/fe/fe_system.h | 28 +++++---- source/fe/fe.cc | 12 ++-- source/fe/fe_dgp_nonparametric.cc | 9 +-- source/fe/fe_nothing.cc | 7 ++- source/fe/fe_system.cc | 69 ++++++++++++++++------- source/fe/fe_values.cc | 33 ++++++----- 13 files changed, 159 insertions(+), 100 deletions(-) diff --git a/include/deal.II/fe/fe.h b/include/deal.II/fe/fe.h index 1afbc4bfec..4fd17ef699 100644 --- a/include/deal.II/fe/fe.h +++ b/include/deal.II/fe/fe.h @@ -2202,10 +2202,12 @@ protected: * FEValues can be found in the @ref FE_vs_Mapping_vs_FEValues documentation * module. */ - virtual InternalDataBase * - get_data (const UpdateFlags flags, - const Mapping &mapping, - const Quadrature &quadrature) const = 0; + virtual + InternalDataBase * + get_data (const UpdateFlags update_flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &output_data) const = 0; /** * Prepare internal data structure for transformation of faces and fill in @@ -2222,10 +2224,12 @@ protected: * FEValues can be found in the @ref FE_vs_Mapping_vs_FEValues documentation * module. */ - virtual InternalDataBase * - get_face_data (const UpdateFlags flags, - const Mapping &mapping, - const Quadrature &quadrature) const; + virtual + InternalDataBase * + get_face_data (const UpdateFlags update_flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &output_data) const; /** * Prepare internal data structure for transformation of children of faces @@ -2242,10 +2246,12 @@ protected: * FEValues can be found in the @ref FE_vs_Mapping_vs_FEValues documentation * module. */ - virtual InternalDataBase * - get_subface_data (const UpdateFlags flags, - const Mapping &mapping, - const Quadrature &quadrature) const; + virtual + InternalDataBase * + get_subface_data (const UpdateFlags update_flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &output_data) const; /** * Compute information about the shape functions on the cell denoted diff --git a/include/deal.II/fe/fe_dgp_nonparametric.h b/include/deal.II/fe/fe_dgp_nonparametric.h index 33d2b64724..b695616e82 100644 --- a/include/deal.II/fe/fe_dgp_nonparametric.h +++ b/include/deal.II/fe/fe_dgp_nonparametric.h @@ -530,9 +530,10 @@ protected: */ virtual typename FiniteElement::InternalDataBase * - get_data (const UpdateFlags, - const Mapping &mapping, - const Quadrature &quadrature) const; + get_data (const UpdateFlags update_flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &output_data) const; virtual void diff --git a/include/deal.II/fe/fe_face.h b/include/deal.II/fe/fe_face.h index 973af22f08..f9fe8fcaba 100644 --- a/include/deal.II/fe/fe_face.h +++ b/include/deal.II/fe/fe_face.h @@ -240,9 +240,10 @@ protected: virtual typename FiniteElement<1,spacedim>::InternalDataBase * - get_data (const UpdateFlags, - const Mapping<1,spacedim> &/*mapping*/, - const Quadrature<1> &/*quadrature*/) const + get_data (const UpdateFlags /*update_flags*/, + const Mapping<1,spacedim> &/*mapping*/, + const Quadrature<1> &/*quadrature*/, + dealii::internal::FEValues::FiniteElementRelatedData<1, spacedim> &/*output_data*/) const { return new typename FiniteElement<1, spacedim>::InternalDataBase; } @@ -250,7 +251,8 @@ protected: typename FiniteElement<1,spacedim>::InternalDataBase * get_face_data(const UpdateFlags update_flags, const Mapping<1,spacedim> &/*mapping*/, - const Quadrature<0> &quadrature) const + const Quadrature<0> &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData<1, spacedim> &/*output_data*/) const { // generate a new data object and initialize some fields typename FiniteElement<1,spacedim>::InternalDataBase *data = @@ -271,11 +273,12 @@ protected: } typename FiniteElement<1,spacedim>::InternalDataBase * - get_subface_data(const UpdateFlags update_flags, - const Mapping<1,spacedim> &mapping, - const Quadrature<0> &quadrature) const + get_subface_data(const UpdateFlags update_flags, + const Mapping<1,spacedim> &mapping, + const Quadrature<0> &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData<1, spacedim> &output_data) const { - return get_face_data(update_flags, mapping, quadrature); + return get_face_data(update_flags, mapping, quadrature, output_data); } virtual diff --git a/include/deal.II/fe/fe_nothing.h b/include/deal.II/fe/fe_nothing.h index 90e3ce9567..765a705ef0 100644 --- a/include/deal.II/fe/fe_nothing.h +++ b/include/deal.II/fe/fe_nothing.h @@ -174,9 +174,10 @@ public: */ virtual typename FiniteElement::InternalDataBase * - get_data (const UpdateFlags update_flags, - const Mapping &mapping, - const Quadrature &quadrature) const; + get_data (const UpdateFlags update_flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &output_data) const; /** * Return whether this element dominates the one given as argument when they diff --git a/include/deal.II/fe/fe_poly.h b/include/deal.II/fe/fe_poly.h index 43ba79eb3e..b74c75cb62 100644 --- a/include/deal.II/fe/fe_poly.h +++ b/include/deal.II/fe/fe_poly.h @@ -220,9 +220,10 @@ protected: virtual typename FiniteElement::InternalDataBase * - get_data(const UpdateFlags update_flags, - const Mapping &/*mapping*/, - const Quadrature &quadrature) const + get_data(const UpdateFlags update_flags, + const Mapping &/*mapping*/, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &/*output_data*/) const { // generate a new data object and // initialize some fields diff --git a/include/deal.II/fe/fe_poly_face.h b/include/deal.II/fe/fe_poly_face.h index 9454af99fd..4e53f7408b 100644 --- a/include/deal.II/fe/fe_poly_face.h +++ b/include/deal.II/fe/fe_poly_face.h @@ -88,18 +88,20 @@ protected: virtual typename FiniteElement::InternalDataBase * - get_data (const UpdateFlags /*update_flags*/, - const Mapping &/*mapping*/, - const Quadrature &/*quadrature*/) const + get_data (const UpdateFlags /*update_flags*/, + const Mapping &/*mapping*/, + const Quadrature &/*quadrature*/, + dealii::internal::FEValues::FiniteElementRelatedData &/*output_data*/) const { InternalData *data = new InternalData; return data; } typename FiniteElement::InternalDataBase * - get_face_data(const UpdateFlags update_flags, - const Mapping &/*mapping*/, - const Quadrature& quadrature) const + get_face_data(const UpdateFlags update_flags, + const Mapping &/*mapping*/, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &/*output_data*/) const { // generate a new data object and // initialize some fields @@ -145,12 +147,14 @@ protected: } typename FiniteElement::InternalDataBase * - get_subface_data(const UpdateFlags update_flags, - const Mapping &mapping, - const Quadrature& quadrature) const + get_subface_data(const UpdateFlags update_flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &output_data) const { return get_face_data(update_flags, mapping, - QProjector::project_to_all_children(quadrature)); + QProjector::project_to_all_children(quadrature), + output_data); } virtual diff --git a/include/deal.II/fe/fe_poly_tensor.h b/include/deal.II/fe/fe_poly_tensor.h index 33ec7876ac..2fb7e5c703 100644 --- a/include/deal.II/fe/fe_poly_tensor.h +++ b/include/deal.II/fe/fe_poly_tensor.h @@ -187,9 +187,10 @@ protected: because we otherwise run into a compiler error with MS Visual Studio. */ virtual typename FiniteElement::InternalDataBase * - get_data(const UpdateFlags update_flags, - const Mapping &, - const Quadrature &quadrature) const + get_data(const UpdateFlags update_flags, + const Mapping &/*mapping*/, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &/*output_data*/) const { // generate a new data object and // initialize some fields diff --git a/include/deal.II/fe/fe_system.h b/include/deal.II/fe/fe_system.h index 4b64df4fbf..869809e0f1 100644 --- a/include/deal.II/fe/fe_system.h +++ b/include/deal.II/fe/fe_system.h @@ -861,20 +861,26 @@ protected: */ virtual FiniteElement *clone() const; - virtual typename FiniteElement::InternalDataBase * - get_data (const UpdateFlags update_flags, - const Mapping &mapping, - const Quadrature &quadrature) const; virtual typename FiniteElement::InternalDataBase * - get_face_data (const UpdateFlags update_flags, - const Mapping &mapping, - const Quadrature &quadrature) const; + get_data (const UpdateFlags update_flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &output_data) const; - virtual typename FiniteElement::InternalDataBase * - get_subface_data (const UpdateFlags update_flags, - const Mapping &mapping, - const Quadrature &quadrature) const; + virtual + typename FiniteElement::InternalDataBase * + get_face_data (const UpdateFlags update_flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &output_data) const; + + virtual + typename FiniteElement::InternalDataBase * + get_subface_data (const UpdateFlags update_flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &output_data) const; virtual void diff --git a/source/fe/fe.cc b/source/fe/fe.cc index 8107ac7e5f..a1f110493d 100644 --- a/source/fe/fe.cc +++ b/source/fe/fe.cc @@ -1207,10 +1207,12 @@ template typename FiniteElement::InternalDataBase * FiniteElement::get_face_data (const UpdateFlags flags, const Mapping &mapping, - const Quadrature &quadrature) const + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &output_data) const { return get_data (flags, mapping, - QProjector::project_to_all_faces(quadrature)); + QProjector::project_to_all_faces(quadrature), + output_data); } @@ -1219,10 +1221,12 @@ template typename FiniteElement::InternalDataBase * FiniteElement::get_subface_data (const UpdateFlags flags, const Mapping &mapping, - const Quadrature &quadrature) const + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &output_data) const { return get_data (flags, mapping, - QProjector::project_to_all_subfaces(quadrature)); + QProjector::project_to_all_subfaces(quadrature), + output_data); } diff --git a/source/fe/fe_dgp_nonparametric.cc b/source/fe/fe_dgp_nonparametric.cc index f66cfb0b6b..b12b7dd6bd 100644 --- a/source/fe/fe_dgp_nonparametric.cc +++ b/source/fe/fe_dgp_nonparametric.cc @@ -258,10 +258,11 @@ FE_DGPNonparametric::update_each (const UpdateFlags flags) const template typename FiniteElement::InternalDataBase * -FE_DGPNonparametric::get_data ( - const UpdateFlags update_flags, - const Mapping &, - const Quadrature &) const +FE_DGPNonparametric:: +get_data (const UpdateFlags update_flags, + const Mapping &, + const Quadrature &, + dealii::internal::FEValues::FiniteElementRelatedData &/*output_data*/) const { // generate a new data object typename FiniteElement::InternalDataBase *data = new typename FiniteElement::InternalDataBase; diff --git a/source/fe/fe_nothing.cc b/source/fe/fe_nothing.cc index f4a7f96db5..3ed5782264 100644 --- a/source/fe/fe_nothing.cc +++ b/source/fe/fe_nothing.cc @@ -93,9 +93,10 @@ FE_Nothing::shape_value (const unsigned int /*i*/, template typename FiniteElement::InternalDataBase * -FE_Nothing::get_data (const UpdateFlags /*flags*/, - const Mapping & /*mapping*/, - const Quadrature & /*quadrature*/) const +FE_Nothing::get_data (const UpdateFlags /*update_flags*/, + const Mapping &/*mapping*/, + const Quadrature &/*quadrature*/, + dealii::internal::FEValues::FiniteElementRelatedData &/*output_data*/) const { // Create a default data object. Normally we would then // need to resize things to hold the appropriate numbers diff --git a/source/fe/fe_system.cc b/source/fe/fe_system.cc index 34b97c49d3..f50d3a2f62 100644 --- a/source/fe/fe_system.cc +++ b/source/fe/fe_system.cc @@ -858,9 +858,11 @@ FESystem::requires_update_flags (const UpdateFlags flags) const template typename FiniteElement::InternalDataBase * -FESystem::get_data (const UpdateFlags flags, - const Mapping &mapping, - const Quadrature &quadrature) const +FESystem:: +get_data (const UpdateFlags flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &/*output_data*/) 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, @@ -886,13 +888,20 @@ FESystem::get_data (const UpdateFlags flags, // function is called for (unsigned int base_no=0; base_non_base_elements(); ++base_no) { - typename FiniteElement::InternalDataBase *base_fe_data = - base_element(base_no).get_data (flags, mapping, quadrature); - internal::FEValues::FiniteElementRelatedData &base_fe_output_object = data->get_fe_output_object(base_no); base_fe_output_object.initialize (quadrature.size(), base_element(base_no), - flags | base_fe_data->update_each); + flags | base_element(base_no).requires_update_flags(flags)); + + // let base objects produce their scratch objects. they may + // also at this time write into the output objects we provide + // for them; it would be nice if we could already copy something + // out of the base output object into the system output object, + // but we can't because we can't know what the elements already + // copied and/or will want to update on every cell + typename FiniteElement::InternalDataBase *base_fe_data = + base_element(base_no).get_data (flags, mapping, quadrature, + base_fe_output_object); data->set_fe_data(base_no, base_fe_data); } @@ -905,9 +914,11 @@ FESystem::get_data (const UpdateFlags flags, template typename FiniteElement::InternalDataBase * -FESystem::get_face_data (const UpdateFlags flags, - const Mapping &mapping, - const Quadrature &quadrature) const +FESystem:: +get_face_data (const UpdateFlags flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &/*output_data*/) 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, @@ -933,13 +944,20 @@ FESystem::get_face_data (const UpdateFlags flags, // function is called for (unsigned int base_no=0; base_non_base_elements(); ++base_no) { - typename FiniteElement::InternalDataBase *base_fe_data = - base_element(base_no).get_face_data (flags, mapping, quadrature); - internal::FEValues::FiniteElementRelatedData &base_fe_output_object = data->get_fe_output_object(base_no); base_fe_output_object.initialize (quadrature.size(), base_element(base_no), - flags | base_fe_data->update_each); + flags | base_element(base_no).requires_update_flags(flags)); + + // let base objects produce their scratch objects. they may + // also at this time write into the output objects we provide + // for them; it would be nice if we could already copy something + // out of the base output object into the system output object, + // but we can't because we can't know what the elements already + // copied and/or will want to update on every cell + typename FiniteElement::InternalDataBase *base_fe_data = + base_element(base_no).get_face_data (flags, mapping, quadrature, + base_fe_output_object); data->set_fe_data(base_no, base_fe_data); } @@ -954,9 +972,11 @@ FESystem::get_face_data (const UpdateFlags flags, template typename FiniteElement::InternalDataBase * -FESystem::get_subface_data (const UpdateFlags flags, - const Mapping &mapping, - const Quadrature &quadrature) const +FESystem:: +get_subface_data (const UpdateFlags flags, + const Mapping &mapping, + const Quadrature &quadrature, + dealii::internal::FEValues::FiniteElementRelatedData &/*output_data*/) 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, @@ -982,13 +1002,20 @@ FESystem::get_subface_data (const UpdateFlags flags, // function is called for (unsigned int base_no=0; base_non_base_elements(); ++base_no) { - typename FiniteElement::InternalDataBase *base_fe_data = - base_element(base_no).get_subface_data (flags, mapping, quadrature); - internal::FEValues::FiniteElementRelatedData &base_fe_output_object = data->get_fe_output_object(base_no); base_fe_output_object.initialize (quadrature.size(), base_element(base_no), - flags | base_fe_data->update_each); + flags | base_element(base_no).requires_update_flags(flags)); + + // let base objects produce their scratch objects. they may + // also at this time write into the output objects we provide + // for them; it would be nice if we could already copy something + // out of the base output object into the system output object, + // but we can't because we can't know what the elements already + // copied and/or will want to update on every cell + typename FiniteElement::InternalDataBase *base_fe_data = + base_element(base_no).get_subface_data (flags, mapping, quadrature, + base_fe_output_object); data->set_fe_data(base_no, base_fe_data); } diff --git a/source/fe/fe_values.cc b/source/fe/fe_values.cc index 7cf2f8bfd8..e800b2cdbf 100644 --- a/source/fe/fe_values.cc +++ b/source/fe/fe_values.cc @@ -3631,6 +3631,10 @@ FEValues::initialize (const UpdateFlags update_flags) const UpdateFlags flags = this->compute_update_flags (update_flags); + // initialize the base classes + this->mapping_output.initialize(this->n_quadrature_points, flags); + this->finite_element_output.initialize(this->n_quadrature_points, *this->fe, flags); + // then get objects into which the FE and the Mapping can store // intermediate data used across calls to reinit. we can do this in parallel Threads::Task::InternalDataBase *> @@ -3638,17 +3642,14 @@ FEValues::initialize (const UpdateFlags update_flags) *this->fe, flags, *this->mapping, - quadrature); + quadrature, + this->finite_element_output); Threads::Task::InternalDataBase *> mapping_get_data = Threads::new_task (&Mapping::get_data, *this->mapping, flags, quadrature); - // initialize the base classes - this->mapping_output.initialize(this->n_quadrature_points, flags); - this->finite_element_output.initialize(this->n_quadrature_points, *this->fe, flags); - this->update_flags = flags; // then collect answers from the two task above @@ -3869,6 +3870,10 @@ FEFaceValues::initialize (const UpdateFlags update_flags) { const UpdateFlags flags = this->compute_update_flags (update_flags); + // initialize the base classes + this->mapping_output.initialize(this->n_quadrature_points, flags); + this->finite_element_output.initialize(this->n_quadrature_points, *this->fe, flags); + // then get objects into which the FE and the Mapping can store // intermediate data used across calls to reinit. this can be done in parallel Threads::Task::InternalDataBase *> @@ -3876,17 +3881,14 @@ FEFaceValues::initialize (const UpdateFlags update_flags) *this->fe, flags, *this->mapping, - this->quadrature); + this->quadrature, + this->finite_element_output); Threads::Task::InternalDataBase *> mapping_get_data = Threads::new_task (&Mapping::get_face_data, *this->mapping, flags, this->quadrature); - // initialize the base classes - this->mapping_output.initialize(this->n_quadrature_points, flags); - this->finite_element_output.initialize(this->n_quadrature_points, *this->fe, flags); - this->update_flags = flags; // then collect answers from the two task above @@ -4024,6 +4026,10 @@ FESubfaceValues::initialize (const UpdateFlags update_flags) { const UpdateFlags flags = this->compute_update_flags (update_flags); + // initialize the base classes + this->mapping_output.initialize(this->n_quadrature_points, flags); + this->finite_element_output.initialize(this->n_quadrature_points, *this->fe, flags); + // then get objects into which the FE and the Mapping can store // intermediate data used across calls to reinit. this can be done // in parallel @@ -4032,17 +4038,14 @@ FESubfaceValues::initialize (const UpdateFlags update_flags) *this->fe, flags, *this->mapping, - this->quadrature); + this->quadrature, + this->finite_element_output); Threads::Task::InternalDataBase *> mapping_get_data = Threads::new_task (&Mapping::get_subface_data, *this->mapping, flags, this->quadrature); - // initialize the base classes - this->mapping_output.initialize(this->n_quadrature_points, flags); - this->finite_element_output.initialize(this->n_quadrature_points, *this->fe, flags); - this->update_flags = flags; // then collect answers from the two task above -- 2.39.5