Reference documentation for deal.II version 9.0.0
fe_poly.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2004 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_fe_poly_h
17 #define dealii_fe_poly_h
18 
19 
20 #include <deal.II/fe/fe.h>
21 #include <deal.II/base/quadrature.h>
22 #include <deal.II/base/std_cxx14/memory.h>
23 
24 DEAL_II_NAMESPACE_OPEN
25 
28 
68 template <class PolynomialType, int dim=PolynomialType::dimension, int spacedim=dim>
69 class FE_Poly : public FiniteElement<dim,spacedim>
70 {
71 public:
75  FE_Poly (const PolynomialType &poly_space,
76  const FiniteElementData<dim> &fe_data,
77  const std::vector<bool> &restriction_is_additive_flags,
78  const std::vector<ComponentMask> &nonzero_components);
79 
84  unsigned int get_degree () const;
85 
86  // for documentation, see the FiniteElement base class
87  virtual
89  requires_update_flags (const UpdateFlags update_flags) const;
90 
96  std::vector<unsigned int> get_poly_space_numbering() const;
97 
102  std::vector<unsigned int> get_poly_space_numbering_inverse() const;
103 
109  virtual double shape_value (const unsigned int i,
110  const Point<dim> &p) const;
111 
122  virtual double shape_value_component (const unsigned int i,
123  const Point<dim> &p,
124  const unsigned int component) const;
125 
131  virtual Tensor<1,dim> shape_grad (const unsigned int i,
132  const Point<dim> &p) const;
133 
144  virtual Tensor<1,dim> shape_grad_component (const unsigned int i,
145  const Point<dim> &p,
146  const unsigned int component) const;
147 
153  virtual Tensor<2,dim> shape_grad_grad (const unsigned int i,
154  const Point<dim> &p) const;
155 
166  virtual Tensor<2,dim> shape_grad_grad_component (const unsigned int i,
167  const Point<dim> &p,
168  const unsigned int component) const;
169 
175  virtual Tensor<3,dim> shape_3rd_derivative (const unsigned int i,
176  const Point<dim> &p) const;
177 
188  virtual Tensor<3,dim> shape_3rd_derivative_component (const unsigned int i,
189  const Point<dim> &p,
190  const unsigned int component) const;
191 
197  virtual Tensor<4,dim> shape_4th_derivative (const unsigned int i,
198  const Point<dim> &p) const;
199 
210  virtual Tensor<4,dim> shape_4th_derivative_component (const unsigned int i,
211  const Point<dim> &p,
212  const unsigned int component) const;
213 
214 protected:
215  /*
216  * NOTE: The following function has its definition inlined into the class declaration
217  * because we otherwise run into a compiler error with MS Visual Studio.
218  */
219 
220 
221  virtual
222  std::unique_ptr<typename FiniteElement<dim,spacedim>::InternalDataBase>
223  get_data(const UpdateFlags update_flags,
224  const Mapping<dim,spacedim> &/*mapping*/,
225  const Quadrature<dim> &quadrature,
227  {
228  // generate a new data object and
229  // initialize some fields
230  auto data = std_cxx14::make_unique<InternalData>();
231  data->update_each = requires_update_flags(update_flags);
232 
233  const unsigned int n_q_points = quadrature.size();
234 
235  // initialize some scratch arrays. we need them for the underlying
236  // polynomial to put the values and derivatives of shape functions
237  // to put there, depending on what the user requested
238  std::vector<double> values(update_flags & update_values ?
239  this->dofs_per_cell : 0);
240  std::vector<Tensor<1,dim> > grads(update_flags & update_gradients ?
241  this->dofs_per_cell : 0);
242  std::vector<Tensor<2,dim> > grad_grads(update_flags & update_hessians ?
243  this->dofs_per_cell : 0);
244  std::vector<Tensor<3,dim> > third_derivatives(update_flags & update_3rd_derivatives ?
245  this->dofs_per_cell : 0);
246  std::vector<Tensor<4,dim> > fourth_derivatives; // won't be needed, so leave empty
247 
248  // now also initialize fields the fields of this class's own
249  // temporary storage, depending on what we need for the given
250  // update flags.
251  //
252  // there is one exception from the rule: if we are dealing with
253  // cells (i.e., if this function is not called via
254  // get_(sub)face_data()), then we can already store things in the
255  // final location where FEValues::reinit() later wants to see
256  // things. we then don't need the intermediate space. we determine
257  // whether we are on a cell by asking whether the number of
258  // elements in the output array equals the number of quadrature
259  // points (yes, it's a cell) or not (because in that case the
260  // number of quadrature points we use here equals the number of
261  // quadrature points summed over *all* faces or subfaces, whereas
262  // the number of output slots equals the number of quadrature
263  // points on only *one* face)
264  if ((update_flags & update_values)
265  &&
266  !((output_data.shape_values.n_rows() > 0)
267  &&
268  (output_data.shape_values.n_cols() == n_q_points)))
269  data->shape_values.reinit (this->dofs_per_cell, n_q_points);
270 
271  if (update_flags & update_gradients)
272  data->shape_gradients.reinit (this->dofs_per_cell, n_q_points);
273 
274  if (update_flags & update_hessians)
275  data->shape_hessians.reinit (this->dofs_per_cell, n_q_points);
276 
277  if (update_flags & update_3rd_derivatives)
278  data->shape_3rd_derivatives.reinit (this->dofs_per_cell, n_q_points);
279 
280  // next already fill those fields of which we have information by
281  // now. note that the shape gradients are only those on the unit
282  // cell, and need to be transformed when visiting an actual cell
283  if (update_flags & (update_values | update_gradients
285  for (unsigned int i=0; i<n_q_points; ++i)
286  {
287  poly_space.compute(quadrature.point(i),
288  values, grads, grad_grads,
289  third_derivatives,
290  fourth_derivatives);
291 
292  // the values of shape functions at quadrature points don't change.
293  // consequently, write these values right into the output array if
294  // we can, i.e., if the output array has the correct size. this is
295  // the case on cells. on faces, we already precompute data on *all*
296  // faces and subfaces, but we later on copy only a portion of it
297  // into the output object; in that case, copy the data from all
298  // faces into the scratch object
299  if (update_flags & update_values)
300  if (output_data.shape_values.n_rows() > 0)
301  {
302  if (output_data.shape_values.n_cols() == n_q_points)
303  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
304  output_data.shape_values[k][i] = values[k];
305  else
306  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
307  data->shape_values[k][i] = values[k];
308  }
309 
310  // for everything else, derivatives need to be transformed,
311  // so we write them into our scratch space and only later
312  // copy stuff into where FEValues wants it
313  if (update_flags & update_gradients)
314  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
315  data->shape_gradients[k][i] = grads[k];
316 
317  if (update_flags & update_hessians)
318  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
319  data->shape_hessians[k][i] = grad_grads[k];
320 
321  if (update_flags & update_3rd_derivatives)
322  for (unsigned int k=0; k<this->dofs_per_cell; ++k)
323  data->shape_3rd_derivatives[k][i] = third_derivatives[k];
324  }
325  return std::move(data);
326  }
327 
328  virtual
329  void
330  fill_fe_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
331  const CellSimilarity::Similarity cell_similarity,
332  const Quadrature<dim> &quadrature,
333  const Mapping<dim,spacedim> &mapping,
334  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_internal,
335  const ::internal::FEValuesImplementation::MappingRelatedData<dim, spacedim> &mapping_data,
336  const typename FiniteElement<dim,spacedim>::InternalDataBase &fe_internal,
338 
339  virtual
340  void
341  fill_fe_face_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
342  const unsigned int face_no,
343  const Quadrature<dim-1> &quadrature,
344  const Mapping<dim,spacedim> &mapping,
345  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_internal,
346  const ::internal::FEValuesImplementation::MappingRelatedData<dim, spacedim> &mapping_data,
347  const typename FiniteElement<dim,spacedim>::InternalDataBase &fe_internal,
349 
350  virtual
351  void
352  fill_fe_subface_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
353  const unsigned int face_no,
354  const unsigned int sub_no,
355  const Quadrature<dim-1> &quadrature,
356  const Mapping<dim,spacedim> &mapping,
357  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_internal,
358  const ::internal::FEValuesImplementation::MappingRelatedData<dim, spacedim> &mapping_data,
359  const typename FiniteElement<dim,spacedim>::InternalDataBase &fe_internal,
361 
368  class InternalData : public FiniteElement<dim,spacedim>::InternalDataBase
369  {
370  public:
381 
392 
403 
414  };
415 
435  void
438  const unsigned int n_q_points,
439  const unsigned int dof) const;
440 
445  PolynomialType poly_space;
446 };
447 
450 DEAL_II_NAMESPACE_CLOSE
451 
452 #endif
Shape function values.
virtual Tensor< 3, dim > shape_3rd_derivative(const unsigned int i, const Point< dim > &p) const
virtual Tensor< 1, dim > shape_grad_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
const Point< dim > & point(const unsigned int i) const
Table< 2, Tensor< 2, dim > > shape_hessians
Definition: fe_poly.h:402
virtual Tensor< 1, dim > shape_grad(const unsigned int i, const Point< dim > &p) const
virtual double shape_value_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
FE_Poly(const PolynomialType &poly_space, const FiniteElementData< dim > &fe_data, const std::vector< bool > &restriction_is_additive_flags, const std::vector< ComponentMask > &nonzero_components)
Table< 2, double > shape_values
Definition: fe_poly.h:380
Third derivatives of shape functions.
UpdateFlags
virtual Tensor< 2, dim > shape_grad_grad_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
Abstract base class for mapping classes.
Definition: dof_tools.h:46
Table< 2, Tensor< 1, dim > > shape_gradients
Definition: fe_poly.h:391
virtual Tensor< 3, dim > shape_3rd_derivative_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
Second derivatives of shape functions.
unsigned int size() const
const unsigned int dofs_per_cell
Definition: fe_base.h:295
unsigned int get_degree() const
virtual Tensor< 2, dim > shape_grad_grad(const unsigned int i, const Point< dim > &p) const
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
void correct_third_derivatives(internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data, const internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &mapping_data, const unsigned int n_q_points, const unsigned int dof) const
Shape function gradients.
virtual Tensor< 4, dim > shape_4th_derivative(const unsigned int i, const Point< dim > &p) const
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const
const std::vector< ComponentMask > nonzero_components
Definition: fe.h:2550
Table< 2, Tensor< 3, dim > > shape_3rd_derivatives
Definition: fe_poly.h:413
virtual Tensor< 4, dim > shape_4th_derivative_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
virtual std::unique_ptr< typename FiniteElement< dim, spacedim >::InternalDataBase > get_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &, const Quadrature< dim > &quadrature, ::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const
Definition: fe_poly.h:223
PolynomialType poly_space
Definition: fe_poly.h:445
std::vector< unsigned int > get_poly_space_numbering_inverse() const
std::vector< unsigned int > get_poly_space_numbering() const
const std::vector< bool > restriction_is_additive_flags
Definition: fe.h:2541