From ef05f597a1ebd6b477d1fcc5eb324d38dd7119ba Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Mon, 20 Jul 2015 12:32:32 -0500 Subject: [PATCH] Rewrite the FE_DGPNonparametric::fill_fe_*_values() functions. Specifically, make sure that the FiniteElement::InternalDataBase object they receive is really used specifically only for read-only purposes. This requires that we allocate some memory in the fill_fe_*_values() functions for scratch arrays, but on the upside, we can get rid of the FE_DGPNonparametric::InternalData class. --- include/deal.II/fe/fe_dgp_nonparametric.h | 28 ++++---- source/fe/fe_dgp_nonparametric.cc | 88 ++++++++--------------- 2 files changed, 43 insertions(+), 73 deletions(-) diff --git a/include/deal.II/fe/fe_dgp_nonparametric.h b/include/deal.II/fe/fe_dgp_nonparametric.h index d8fd5fcff7..2e4b3ffdaf 100644 --- a/include/deal.II/fe/fe_dgp_nonparametric.h +++ b/include/deal.II/fe/fe_dgp_nonparametric.h @@ -252,6 +252,19 @@ template class MappingQ; * * * + * + *

Implementation details

+ * + * This element does not have an InternalData class, unlike all other elements, + * because the InternalData classes are used to store things that can be computed once + * and reused multiple times (such as the values of shape functions + * at quadrature points on the reference cell). However, because the + * element is not mapped, this element has nothing that could be computed on the + * reference cell -- everything needs to be computed on the real cell -- and + * consequently there is nothing we'd like to store in such an object. We can thus + * simply use the members already provided by FiniteElement::InternalDataBase without + * adding anything in a derived class in this class. + * * @author Guido Kanschat, 2002 */ template @@ -595,21 +608,6 @@ private: */ const PolynomialSpace polynomial_space; - /** - * Fields of cell-independent data. - * - * For information about the general purpose of this class, see the - * documentation of the base class. - */ - class InternalData : public FiniteElement::InternalDataBase - { - public: - // have some scratch arrays - std::vector values; - std::vector > grads; - std::vector > grad_grads; - }; - /** * Allow access from other dimensions. */ diff --git a/source/fe/fe_dgp_nonparametric.cc b/source/fe/fe_dgp_nonparametric.cc index c0a44ea202..303e1ffc63 100644 --- a/source/fe/fe_dgp_nonparametric.cc +++ b/source/fe/fe_dgp_nonparametric.cc @@ -254,7 +254,7 @@ FE_DGPNonparametric::get_data ( const Quadrature &) const { // generate a new data object - InternalData *data = new InternalData; + typename FiniteElement::InternalDataBase *data = new typename FiniteElement::InternalDataBase; // check what needs to be // initialized only once and what // on every cell/face/subface we @@ -263,25 +263,9 @@ FE_DGPNonparametric::get_data ( data->update_each = update_each(update_flags); data->update_flags = data->update_once | data->update_each; - const UpdateFlags flags(data->update_flags); + // other than that, there is nothing we can add here as discussed + // in the general documentation of this class - // initialize fields only if really - // necessary. otherwise, don't - // allocate memory - if (flags & update_values) - { - data->values.resize (this->dofs_per_cell); - } - - if (flags & update_gradients) - { - data->grads.resize (this->dofs_per_cell); - } - - if (flags & update_hessians) - { - data->grad_grads.resize (this->dofs_per_cell); - } return data; } @@ -298,36 +282,32 @@ FE_DGPNonparametric::fill_fe_values ( const typename Triangulation::cell_iterator &, const Quadrature &, typename Mapping::InternalDataBase &, - typename Mapping::InternalDataBase &fedata, + typename Mapping::InternalDataBase &fe_data, FEValuesData &data, CellSimilarity::Similarity &/*cell_similarity*/) const { - // convert data object to internal - // data for this class. fails with - // an exception if that is not - // possible - Assert (dynamic_cast (&fedata) != 0, - ExcInternalError()); - InternalData &fe_data = static_cast (fedata); - const UpdateFlags flags(fe_data.current_update_flags()); Assert (flags & update_quadrature_points, ExcInternalError()); const unsigned int n_q_points = data.quadrature_points.size(); + std::vector values(flags & update_values ? this->dofs_per_cell : 0); + std::vector > grads(flags & update_gradients ? this->dofs_per_cell : 0); + std::vector > grad_grads(flags & update_hessians ? this->dofs_per_cell : 0); + if (flags & (update_values | update_gradients)) for (unsigned int i=0; idofs_per_cell; ++k) { if (flags & update_values) - data.shape_values[k][i] = fe_data.values[k]; + data.shape_values[k][i] = values[k]; if (flags & update_gradients) - data.shape_gradients[k][i] = fe_data.grads[k]; + data.shape_gradients[k][i] = grads[k]; if (flags & update_hessians) - data.shape_hessians[k][i] = fe_data.grad_grads[k]; + data.shape_hessians[k][i] = grad_grads[k]; } } } @@ -342,35 +322,31 @@ FE_DGPNonparametric::fill_fe_face_values ( const unsigned int, const Quadrature&, typename Mapping::InternalDataBase &, - typename Mapping::InternalDataBase &fedata, + typename Mapping::InternalDataBase &fe_data, FEValuesData &data) const { - // convert data object to internal - // data for this class. fails with - // an exception if that is not - // possible - Assert (dynamic_cast (&fedata) != 0, - ExcInternalError()); - InternalData &fe_data = static_cast (fedata); - const UpdateFlags flags(fe_data.update_once | fe_data.update_each); Assert (flags & update_quadrature_points, ExcInternalError()); const unsigned int n_q_points = data.quadrature_points.size(); + std::vector values(flags & update_values ? this->dofs_per_cell : 0); + std::vector > grads(flags & update_gradients ? this->dofs_per_cell : 0); + std::vector > grad_grads(flags & update_hessians ? this->dofs_per_cell : 0); + if (flags & (update_values | update_gradients)) for (unsigned int i=0; idofs_per_cell; ++k) { if (flags & update_values) - data.shape_values[k][i] = fe_data.values[k]; + data.shape_values[k][i] = values[k]; if (flags & update_gradients) - data.shape_gradients[k][i] = fe_data.grads[k]; + data.shape_gradients[k][i] = grads[k]; if (flags & update_hessians) - data.shape_hessians[k][i] = fe_data.grad_grads[k]; + data.shape_hessians[k][i] = grad_grads[k]; } } } @@ -386,35 +362,31 @@ FE_DGPNonparametric::fill_fe_subface_values ( const unsigned int, const Quadrature&, typename Mapping::InternalDataBase &, - typename Mapping::InternalDataBase &fedata, + typename Mapping::InternalDataBase &fe_data, FEValuesData &data) const { - // convert data object to internal - // data for this class. fails with - // an exception if that is not - // possible - Assert (dynamic_cast (&fedata) != 0, - ExcInternalError()); - InternalData &fe_data = static_cast (fedata); - const UpdateFlags flags(fe_data.update_once | fe_data.update_each); Assert (flags & update_quadrature_points, ExcInternalError()); const unsigned int n_q_points = data.quadrature_points.size(); + std::vector values(flags & update_values ? this->dofs_per_cell : 0); + std::vector > grads(flags & update_gradients ? this->dofs_per_cell : 0); + std::vector > grad_grads(flags & update_hessians ? this->dofs_per_cell : 0); + if (flags & (update_values | update_gradients)) for (unsigned int i=0; idofs_per_cell; ++k) { if (flags & update_values) - data.shape_values[k][i] = fe_data.values[k]; + data.shape_values[k][i] = values[k]; if (flags & update_gradients) - data.shape_gradients[k][i] = fe_data.grads[k]; + data.shape_gradients[k][i] = grads[k]; if (flags & update_hessians) - data.shape_hessians[k][i] = fe_data.grad_grads[k]; + data.shape_hessians[k][i] = grad_grads[k]; } } } -- 2.39.5