Reference documentation for deal.II version 9.1.0-pre
fe_poly.cc
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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/polynomials_p.h>
18 #include <deal.II/base/polynomials_piecewise.h>
19 #include <deal.II/base/polynomials_rannacher_turek.h>
20 #include <deal.II/base/qprojector.h>
21 #include <deal.II/base/tensor_product_polynomials.h>
22 #include <deal.II/base/tensor_product_polynomials_bubbles.h>
23 #include <deal.II/base/tensor_product_polynomials_const.h>
24 
25 #include <deal.II/fe/fe_poly.h>
26 #include <deal.II/fe/fe_poly.templates.h>
27 #include <deal.II/fe/fe_values.h>
28 
29 DEAL_II_NAMESPACE_OPEN
30 
31 
32 template <>
33 void
34 FE_Poly<TensorProductPolynomials<1>, 1, 2>::fill_fe_values(
36  const CellSimilarity::Similarity cell_similarity,
37  const Quadrature<1> & quadrature,
38  const Mapping<1, 2> & mapping,
39  const Mapping<1, 2>::InternalDataBase &mapping_internal,
40  const ::internal::FEValuesImplementation::MappingRelatedData<1, 2>
41  & mapping_data,
42  const FiniteElement<1, 2>::InternalDataBase &fe_internal,
44  &output_data) const
45 {
46  // convert data object to internal
47  // data for this class. fails with
48  // an exception if that is not
49  // possible
50  Assert(dynamic_cast<const InternalData *>(&fe_internal) != nullptr,
52  const InternalData &fe_data = static_cast<const InternalData &>(fe_internal);
53 
54  // transform gradients and higher derivatives. there is nothing to do
55  // for values since we already emplaced them into output_data when
56  // we were in get_data()
57  if (fe_data.update_each & update_gradients &&
58  cell_similarity != CellSimilarity::translation)
59  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
60  mapping.transform(make_array_view(fe_data.shape_gradients, k),
62  mapping_internal,
63  make_array_view(output_data.shape_gradients, k));
64 
65  if (fe_data.update_each & update_hessians &&
66  cell_similarity != CellSimilarity::translation)
67  {
68  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
69  mapping.transform(make_array_view(fe_data.shape_hessians, k),
71  mapping_internal,
72  make_array_view(output_data.shape_hessians, k));
73 
74  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
75  for (unsigned int i = 0; i < quadrature.size(); ++i)
76  for (unsigned int j = 0; j < 2; ++j)
77  output_data.shape_hessians[k][i] -=
78  mapping_data.jacobian_pushed_forward_grads[i][j] *
79  output_data.shape_gradients[k][i][j];
80  }
81 
82  if (fe_data.update_each & update_3rd_derivatives &&
83  cell_similarity != CellSimilarity::translation)
84  {
85  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
86  mapping.transform(make_array_view(fe_data.shape_3rd_derivatives, k),
88  mapping_internal,
90  k));
91 
92  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
93  correct_third_derivatives(output_data,
94  mapping_data,
95  quadrature.size(),
96  k);
97  }
98 }
99 
100 
101 
102 template <>
103 void
104 FE_Poly<TensorProductPolynomials<2>, 2, 3>::fill_fe_values(
106  const CellSimilarity::Similarity cell_similarity,
107  const Quadrature<2> & quadrature,
108  const Mapping<2, 3> & mapping,
109  const Mapping<2, 3>::InternalDataBase &mapping_internal,
110  const ::internal::FEValuesImplementation::MappingRelatedData<2, 3>
111  & mapping_data,
112  const FiniteElement<2, 3>::InternalDataBase &fe_internal,
114  &output_data) const
115 {
116  // assert that the following dynamics
117  // cast is really well-defined.
118  Assert(dynamic_cast<const InternalData *>(&fe_internal) != nullptr,
119  ExcInternalError());
120  const InternalData &fe_data = static_cast<const InternalData &>(fe_internal);
121 
122  // transform gradients and higher derivatives. there is nothing to do
123  // for values since we already emplaced them into output_data when
124  // we were in get_data()
125  if (fe_data.update_each & update_gradients &&
126  cell_similarity != CellSimilarity::translation)
127  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
128  mapping.transform(make_array_view(fe_data.shape_gradients, k),
130  mapping_internal,
131  make_array_view(output_data.shape_gradients, k));
132 
133  if (fe_data.update_each & update_hessians &&
134  cell_similarity != CellSimilarity::translation)
135  {
136  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
137  mapping.transform(make_array_view(fe_data.shape_hessians, k),
139  mapping_internal,
140  make_array_view(output_data.shape_hessians, k));
141 
142  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
143  for (unsigned int i = 0; i < quadrature.size(); ++i)
144  for (unsigned int j = 0; j < 3; ++j)
145  output_data.shape_hessians[k][i] -=
146  mapping_data.jacobian_pushed_forward_grads[i][j] *
147  output_data.shape_gradients[k][i][j];
148  }
149 
150  if (fe_data.update_each & update_3rd_derivatives &&
151  cell_similarity != CellSimilarity::translation)
152  {
153  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
154  mapping.transform(make_array_view(fe_data.shape_3rd_derivatives, k),
156  mapping_internal,
158  k));
159 
160  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
161  correct_third_derivatives(output_data,
162  mapping_data,
163  quadrature.size(),
164  k);
165  }
166 }
167 
168 
169 template <>
170 void
171 FE_Poly<PolynomialSpace<1>, 1, 2>::fill_fe_values(
173  const CellSimilarity::Similarity cell_similarity,
174  const Quadrature<1> & quadrature,
175  const Mapping<1, 2> & mapping,
176  const Mapping<1, 2>::InternalDataBase &mapping_internal,
177  const ::internal::FEValuesImplementation::MappingRelatedData<1, 2>
178  & mapping_data,
179  const FiniteElement<1, 2>::InternalDataBase &fe_internal,
181  &output_data) const
182 {
183  // convert data object to internal
184  // data for this class. fails with
185  // an exception if that is not
186  // possible
187 
188  Assert(dynamic_cast<const InternalData *>(&fe_internal) != nullptr,
189  ExcInternalError());
190  const InternalData &fe_data = static_cast<const InternalData &>(fe_internal);
191 
192  // transform gradients and higher derivatives. there is nothing to do
193  // for values since we already emplaced them into output_data when
194  // we were in get_data()
195  if (fe_data.update_each & update_gradients &&
196  cell_similarity != CellSimilarity::translation)
197  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
198  mapping.transform(make_array_view(fe_data.shape_gradients, k),
200  mapping_internal,
201  make_array_view(output_data.shape_gradients, k));
202 
203  if (fe_data.update_each & update_hessians &&
204  cell_similarity != CellSimilarity::translation)
205  {
206  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
207  mapping.transform(make_array_view(fe_data.shape_hessians, k),
209  mapping_internal,
210  make_array_view(output_data.shape_hessians, k));
211 
212  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
213  for (unsigned int i = 0; i < quadrature.size(); ++i)
214  for (unsigned int j = 0; j < 2; ++j)
215  output_data.shape_hessians[k][i] -=
216  mapping_data.jacobian_pushed_forward_grads[i][j] *
217  output_data.shape_gradients[k][i][j];
218  }
219 
220  if (fe_data.update_each & update_3rd_derivatives &&
221  cell_similarity != CellSimilarity::translation)
222  {
223  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
224  mapping.transform(make_array_view(fe_data.shape_3rd_derivatives, k),
226  mapping_internal,
228  k));
229 
230  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
231  correct_third_derivatives(output_data,
232  mapping_data,
233  quadrature.size(),
234  k);
235  }
236 }
237 
238 
239 template <>
240 void
241 FE_Poly<PolynomialSpace<2>, 2, 3>::fill_fe_values(
243  const CellSimilarity::Similarity cell_similarity,
244  const Quadrature<2> & quadrature,
245  const Mapping<2, 3> & mapping,
246  const Mapping<2, 3>::InternalDataBase &mapping_internal,
247  const ::internal::FEValuesImplementation::MappingRelatedData<2, 3>
248  & mapping_data,
249  const FiniteElement<2, 3>::InternalDataBase &fe_internal,
251  &output_data) const
252 {
253  Assert(dynamic_cast<const InternalData *>(&fe_internal) != nullptr,
254  ExcInternalError());
255  const InternalData &fe_data = static_cast<const InternalData &>(fe_internal);
256 
257  // transform gradients and higher derivatives. there is nothing to do
258  // for values since we already emplaced them into output_data when
259  // we were in get_data()
260  if (fe_data.update_each & update_gradients &&
261  cell_similarity != CellSimilarity::translation)
262  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
263  mapping.transform(make_array_view(fe_data.shape_gradients, k),
265  mapping_internal,
266  make_array_view(output_data.shape_gradients, k));
267 
268  if (fe_data.update_each & update_hessians &&
269  cell_similarity != CellSimilarity::translation)
270  {
271  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
272  mapping.transform(make_array_view(fe_data.shape_hessians, k),
274  mapping_internal,
275  make_array_view(output_data.shape_hessians, k));
276 
277  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
278  for (unsigned int i = 0; i < quadrature.size(); ++i)
279  for (unsigned int j = 0; j < 3; ++j)
280  output_data.shape_hessians[k][i] -=
281  mapping_data.jacobian_pushed_forward_grads[i][j] *
282  output_data.shape_gradients[k][i][j];
283  }
284 
285  if (fe_data.update_each & update_3rd_derivatives &&
286  cell_similarity != CellSimilarity::translation)
287  {
288  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
289  mapping.transform(make_array_view(fe_data.shape_3rd_derivatives, k),
291  mapping_internal,
293  k));
294 
295  for (unsigned int k = 0; k < this->dofs_per_cell; ++k)
296  correct_third_derivatives(output_data,
297  mapping_data,
298  quadrature.size(),
299  k);
300  }
301 }
302 
303 
304 #include "fe_poly.inst"
305 
306 DEAL_II_NAMESPACE_CLOSE
virtual void transform(const ArrayView< const Tensor< 1, dim >> &input, const MappingType type, const typename Mapping< dim, spacedim >::InternalDataBase &internal, const ArrayView< Tensor< 1, spacedim >> &output) const =0
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type > make_array_view(const Iterator begin, const Iterator end)
Definition: array_view.h:487
unsigned int size() const
Third derivatives of shape functions.
#define Assert(cond, exc)
Definition: exceptions.h:1227
Abstract base class for mapping classes.
Definition: dof_tools.h:57
Second derivatives of shape functions.
Shape function gradients.
static::ExceptionBase & ExcInternalError()