Reference documentation for deal.II version 8.4.2
mapping_fe_field.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2001 - 2015 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 #include <deal.II/base/utilities.h>
17 #include <deal.II/base/polynomial.h>
18 #include <deal.II/base/quadrature.h>
19 #include <deal.II/base/quadrature_lib.h>
20 #include <deal.II/base/qprojector.h>
21 #include <deal.II/base/memory_consumption.h>
22 #include <deal.II/base/tensor_product_polynomials.h>
23 #include <deal.II/base/std_cxx11/unique_ptr.h>
24 #include <deal.II/lac/full_matrix.h>
25 #include <deal.II/grid/tria_iterator.h>
26 #include <deal.II/grid/tria_boundary.h>
27 #include <deal.II/dofs/dof_accessor.h>
28 #include <deal.II/fe/fe_tools.h>
29 #include <deal.II/fe/fe_values.h>
30 #include <deal.II/fe/fe_system.h>
31 #include <deal.II/fe/mapping_fe_field.h>
32 #include <deal.II/fe/fe_q.h>
33 #include <deal.II/fe/mapping.h>
34 #include <deal.II/fe/mapping_q1.h>
35 #include <deal.II/base/qprojector.h>
36 #include <deal.II/base/thread_management.h>
37 #include <deal.II/numerics/vector_tools.h>
38 
39 #include <numeric>
40 #include <fstream>
41 
42 
43 
44 DEAL_II_NAMESPACE_OPEN
45 
46 
47 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
50  const ComponentMask mask)
51  :
52  n_shape_functions (fe.dofs_per_cell),
53  mask (mask),
54  local_dof_indices(fe.dofs_per_cell),
55  local_dof_values(fe.dofs_per_cell)
56 {}
57 
58 
59 
60 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
61 std::size_t
63 {
64  Assert (false, ExcNotImplemented());
65  return 0;
66 }
67 
68 
69 
70 template<int dim, int spacedim, typename DoFHandlerType, typename VectorType>
71 double &
73 (const unsigned int qpoint,
74  const unsigned int shape_nr)
75 {
76  Assert(qpoint*n_shape_functions + shape_nr < shape_values.size(),
77  ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
78  shape_values.size()));
79  return shape_values [qpoint*n_shape_functions + shape_nr];
80 }
81 
82 
83 template<int dim, int spacedim, typename DoFHandlerType, typename VectorType>
84 const Tensor<1,dim> &
86 (const unsigned int qpoint,
87  const unsigned int shape_nr) const
88 {
89  Assert(qpoint*n_shape_functions + shape_nr < shape_derivatives.size(),
90  ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
91  shape_derivatives.size()));
92  return shape_derivatives [qpoint*n_shape_functions + shape_nr];
93 }
94 
95 
96 
97 template<int dim, int spacedim, typename DoFHandlerType, typename VectorType>
100 (const unsigned int qpoint,
101  const unsigned int shape_nr)
102 {
103  Assert(qpoint*n_shape_functions + shape_nr < shape_derivatives.size(),
104  ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
105  shape_derivatives.size()));
106  return shape_derivatives [qpoint*n_shape_functions + shape_nr];
107 }
108 
109 
110 template <int dim, int spacedim, typename DoFHandlerType, typename VectorType>
111 const Tensor<2,dim> &
113 (const unsigned int qpoint,
114  const unsigned int shape_nr) const
115 {
116  Assert(qpoint*n_shape_functions + shape_nr < shape_second_derivatives.size(),
117  ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
118  shape_second_derivatives.size()));
119  return shape_second_derivatives [qpoint*n_shape_functions + shape_nr];
120 }
121 
122 
123 
124 template <int dim, int spacedim, typename DoFHandlerType, typename VectorType>
127 (const unsigned int qpoint,
128  const unsigned int shape_nr)
129 {
130  Assert(qpoint*n_shape_functions + shape_nr < shape_second_derivatives.size(),
131  ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
132  shape_second_derivatives.size()));
133  return shape_second_derivatives [qpoint*n_shape_functions + shape_nr];
134 }
135 
136 
137 template <int dim, int spacedim, typename DoFHandlerType, typename VectorType>
138 const Tensor<3,dim> &
140 (const unsigned int qpoint,
141  const unsigned int shape_nr) const
142 {
143  Assert(qpoint*n_shape_functions + shape_nr < shape_third_derivatives.size(),
144  ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
145  shape_third_derivatives.size()));
146  return shape_third_derivatives [qpoint*n_shape_functions + shape_nr];
147 }
148 
149 
150 
151 template <int dim, int spacedim, typename DoFHandlerType, typename VectorType>
154 (const unsigned int qpoint,
155  const unsigned int shape_nr)
156 {
157  Assert(qpoint*n_shape_functions + shape_nr < shape_third_derivatives.size(),
158  ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
159  shape_third_derivatives.size()));
160  return shape_third_derivatives [qpoint*n_shape_functions + shape_nr];
161 }
162 
163 
164 template <int dim, int spacedim, typename DoFHandlerType, typename VectorType>
165 const Tensor<4,dim> &
167 (const unsigned int qpoint,
168  const unsigned int shape_nr) const
169 {
170  Assert(qpoint*n_shape_functions + shape_nr < shape_fourth_derivatives.size(),
171  ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
172  shape_fourth_derivatives.size()));
173  return shape_fourth_derivatives [qpoint*n_shape_functions + shape_nr];
174 }
175 
176 
177 
178 template <int dim, int spacedim, typename DoFHandlerType, typename VectorType>
181 (const unsigned int qpoint,
182  const unsigned int shape_nr)
183 {
184  Assert(qpoint*n_shape_functions + shape_nr < shape_fourth_derivatives.size(),
185  ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
186  shape_fourth_derivatives.size()));
187  return shape_fourth_derivatives [qpoint*n_shape_functions + shape_nr];
188 }
189 
190 
191 
192 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
194 (const DoFHandlerType &euler_dof_handler,
195  const VectorType &euler_vector,
196  const ComponentMask mask)
197  :
198  euler_vector(&euler_vector),
199  fe(&euler_dof_handler.get_fe()),
200  euler_dof_handler(&euler_dof_handler),
201  fe_mask(mask.size() ? mask :
202  ComponentMask(fe->get_nonzero_components(0).size(), true)),
204 {
205  unsigned int size = 0;
206  for (unsigned int i=0; i<fe_mask.size(); ++i)
207  {
208  if (fe_mask[i])
209  fe_to_real[i] = size++;
210  }
211  AssertDimension(size,spacedim);
212 }
213 
214 
215 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
218  :
219  euler_vector(mapping.euler_vector),
220  fe(mapping.fe),
222  fe_mask(mapping.fe_mask),
223  fe_to_real(mapping.fe_to_real)
224 {}
225 
226 
227 
228 template<int dim, int spacedim, typename DoFHandlerType, typename VectorType>
229 inline
230 const double &
232 (const unsigned int qpoint,
233  const unsigned int shape_nr) const
234 {
235  Assert(qpoint*n_shape_functions + shape_nr < shape_values.size(),
236  ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
237  shape_values.size()));
238  return shape_values [qpoint*n_shape_functions + shape_nr];
239 }
240 
241 
242 
243 template <int dim, int spacedim, typename DoFHandlerType, typename VectorType>
244 bool
246 {
247  return false;
248 }
249 
250 
251 
252 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
253 void
255 compute_shapes_virtual (const std::vector<Point<dim> > &unit_points,
256  typename MappingFEField<dim, spacedim>::InternalData &data) const
257 {
258  const unsigned int n_points=unit_points.size();
259 
260  for (unsigned int point=0; point<n_points; ++point)
261  {
262  if (data.shape_values.size()!=0)
263  for (unsigned int i=0; i<data.n_shape_functions; ++i)
264  data.shape(point, i) = fe->shape_value(i, unit_points[point]);
265 
266  if (data.shape_derivatives.size()!=0)
267  for (unsigned int i=0; i<data.n_shape_functions; ++i)
268  data.derivative(point, i) = fe->shape_grad(i, unit_points[point]);
269 
270  if (data.shape_second_derivatives.size()!=0)
271  for (unsigned int i=0; i<data.n_shape_functions; ++i)
272  data.second_derivative(point, i) = fe->shape_grad_grad(i, unit_points[point]);
273 
274  if (data.shape_third_derivatives.size()!=0)
275  for (unsigned int i=0; i<data.n_shape_functions; ++i)
276  data.third_derivative(point, i) = fe->shape_3rd_derivative(i, unit_points[point]);
277 
278  if (data.shape_fourth_derivatives.size()!=0)
279  for (unsigned int i=0; i<data.n_shape_functions; ++i)
280  data.fourth_derivative(point, i) = fe->shape_4th_derivative(i, unit_points[point]);
281  }
282 }
283 
284 
285 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
288 {
289  // add flags if the respective quantities are necessary to compute
290  // what we need. note that some flags appear in both conditions and
291  // in subsequent set operations. this leads to some circular
292  // logic. the only way to treat this is to iterate. since there are
293  // 5 if-clauses in the loop, it will take at most 4 iterations to
294  // converge. do them:
295  UpdateFlags out = in;
296  for (unsigned int i=0; i<5; ++i)
297  {
298  // The following is a little incorrect:
299  // If not applied on a face,
300  // update_boundary_forms does not
301  // make sense. On the other hand,
302  // it is necessary on a
303  // face. Currently,
304  // update_boundary_forms is simply
305  // ignored for the interior of a
306  // cell.
307  if (out & (update_JxW_values
309  out |= update_boundary_forms;
310 
318 
319  if (out & (update_inverse_jacobians
324 
325  // The contravariant transformation
326  // is a Piola transformation, which
327  // requires the determinant of the
328  // Jacobi matrix of the transformation.
329  // Therefore these values have to be
330  // updated for each cell.
332  out |= update_JxW_values;
333 
334  if (out & update_normal_vectors)
335  out |= update_JxW_values;
336  }
337 
338  return out;
339 }
340 
341 
342 
343 
344 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
345 void
347 (const UpdateFlags update_flags,
348  const Quadrature<dim> &q,
349  const unsigned int n_original_q_points,
350  InternalData &data) const
351 {
352  // store the flags in the internal data object so we can access them
353  // in fill_fe_*_values(). use the transitive hull of the required
354  // flags
355  data.update_each = requires_update_flags(update_flags);
356 
357  const unsigned int n_q_points = q.size();
358 
359  // see if we need the (transformation) shape function values
360  // and/or gradients and resize the necessary arrays
362  data.shape_values.resize(data.n_shape_functions * n_q_points);
363 
372  data.shape_derivatives.resize(data.n_shape_functions * n_q_points);
373 
375  data.covariant.resize(n_original_q_points);
376 
378  data.contravariant.resize(n_original_q_points);
379 
381  data.volume_elements.resize(n_original_q_points);
382 
384  data.shape_second_derivatives.resize(data.n_shape_functions * n_q_points);
385 
387  data.shape_third_derivatives.resize(data.n_shape_functions * n_q_points);
388 
390  data.shape_fourth_derivatives.resize(data.n_shape_functions * n_q_points);
391 
393 }
394 
395 
396 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
397 void
399 (const UpdateFlags update_flags,
400  const Quadrature<dim> &q,
401  const unsigned int n_original_q_points,
402  InternalData &data) const
403 {
404  compute_data (update_flags, q, n_original_q_points, data);
405 
406  if (dim > 1)
407  {
409  {
410  data.aux.resize (dim-1, std::vector<Tensor<1,spacedim> > (n_original_q_points));
411 
412  // Compute tangentials to the
413  // unit cell.
414  const unsigned int nfaces = GeometryInfo<dim>::faces_per_cell;
415  data.unit_tangentials.resize (nfaces*(dim-1),
416  std::vector<Tensor<1,dim> > (n_original_q_points));
417  if (dim==2)
418  {
419  // ensure a counterclockwise
420  // orientation of tangentials
421  static const int tangential_orientation[4]= {-1,1,1,-1};
422  for (unsigned int i=0; i<nfaces; ++i)
423  {
424  Tensor<1,dim> tang;
425  tang[1-i/2]=tangential_orientation[i];
426  std::fill (data.unit_tangentials[i].begin(),
427  data.unit_tangentials[i].end(), tang);
428  }
429  }
430  else if (dim==3)
431  {
432  for (unsigned int i=0; i<nfaces; ++i)
433  {
434  Tensor<1,dim> tang1, tang2;
435 
436  const unsigned int nd=
438 
439  // first tangential
440  // vector in direction
441  // of the (nd+1)%3 axis
442  // and inverted in case
443  // of unit inward normal
444  tang1[(nd+1)%dim]=GeometryInfo<dim>::unit_normal_orientation[i];
445  // second tangential
446  // vector in direction
447  // of the (nd+2)%3 axis
448  tang2[(nd+2)%dim]=1.;
449 
450  // same unit tangents
451  // for all quadrature
452  // points on this face
453  std::fill (data.unit_tangentials[i].begin(),
454  data.unit_tangentials[i].end(), tang1);
455  std::fill (data.unit_tangentials[nfaces+i].begin(),
456  data.unit_tangentials[nfaces+i].end(), tang2);
457  }
458  }
459  }
460  }
461 }
462 
463 
464 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
465 typename
468  const Quadrature<dim> &quadrature) const
469 {
470  InternalData *data = new InternalData(*fe, fe_mask);
471  this->compute_data (update_flags, quadrature,
472  quadrature.size(), *data);
473  return data;
474 }
475 
476 
477 
478 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
481 (const UpdateFlags update_flags,
482  const Quadrature<dim-1> &quadrature) const
483 {
484  InternalData *data = new InternalData(*fe, fe_mask);
486  this->compute_face_data (update_flags, q,
487  quadrature.size(), *data);
488 
489  return data;
490 }
491 
492 
493 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
496 (const UpdateFlags update_flags,
497  const Quadrature<dim-1> &quadrature) const
498 {
499  InternalData *data = new InternalData(*fe, fe_mask);
501  this->compute_face_data (update_flags, q,
502  quadrature.size(), *data);
503 
504  return data;
505 }
506 
507 
508 
509 namespace internal
510 {
511  namespace
512  {
519  template <int dim, int spacedim>
520  void
521  maybe_compute_q_points (const typename ::QProjector<dim>::DataSetDescriptor data_set,
522  const typename ::MappingFEField<dim,spacedim>::InternalData &data,
524  const ComponentMask &fe_mask,
525  const std::vector<unsigned int> &fe_to_real,
526  std::vector<Point<spacedim> > &quadrature_points)
527  {
528  const UpdateFlags update_flags = data.update_each;
529 
530  if (update_flags & update_quadrature_points)
531  {
532  for (unsigned int point=0; point<quadrature_points.size(); ++point)
533  {
534  Point<spacedim> result;
535  const double *shape = &data.shape(point+data_set,0);
536 
537  for (unsigned int k=0; k<data.n_shape_functions; ++k)
538  {
539  unsigned int comp_k = fe.system_to_component_index(k).first;
540  if (fe_mask[comp_k])
541  result[fe_to_real[comp_k]] += data.local_dof_values[k] * shape[k];
542  }
543 
544  quadrature_points[point] = result;
545  }
546  }
547  }
548 
556  template <int dim, int spacedim>
557  void
558  maybe_update_Jacobians (const CellSimilarity::Similarity cell_similarity,
559  const typename ::QProjector<dim>::DataSetDescriptor data_set,
560  const typename ::MappingFEField<dim,spacedim>::InternalData &data,
562  const ComponentMask &fe_mask,
563  const std::vector<unsigned int> &fe_to_real)
564  {
565  const UpdateFlags update_flags = data.update_each;
566 
567  // then Jacobians
568  if (update_flags & update_contravariant_transformation)
569  {
570 
571  // if the current cell is just a translation of the previous one, no
572  // need to recompute jacobians...
573  if (cell_similarity != CellSimilarity::translation)
574  {
575  const unsigned int n_q_points = data.contravariant.size();
576 
577  Assert (data.n_shape_functions > 0, ExcInternalError());
578 
579  for (unsigned int point=0; point<n_q_points; ++point)
580  {
581  const Tensor<1,dim> *data_derv =
582  &data.derivative(point+data_set, 0);
583 
584  Tensor<1, dim> result[spacedim];
585 
586  for (unsigned int k=0; k<data.n_shape_functions; ++k)
587  {
588  unsigned int comp_k = fe.system_to_component_index(k).first;
589  if (fe_mask[comp_k])
590  result[fe_to_real[comp_k]] += data.local_dof_values[k] * data_derv[k];
591  }
592 
593  // write result into contravariant data
594  for (unsigned int i=0; i<spacedim; ++i)
595  {
596  data.contravariant[point][i] = result[i];
597  }
598  }
599  }
600  }
601 
602  if (update_flags & update_covariant_transformation)
603  {
604  AssertDimension(data.covariant.size(), data.contravariant.size());
605  if (cell_similarity != CellSimilarity::translation)
606  for (unsigned int point=0; point<data.contravariant.size(); ++point)
607  data.covariant[point] = (data.contravariant[point]).covariant_form();
608  }
609 
610  if (update_flags & update_volume_elements)
611  {
612  AssertDimension(data.covariant.size(), data.volume_elements.size());
613  if (cell_similarity != CellSimilarity::translation)
614  for (unsigned int point=0; point<data.contravariant.size(); ++point)
615  data.volume_elements[point] = data.contravariant[point].determinant();
616  }
617  }
618 
625  template <int dim, int spacedim>
626  void
627  maybe_update_jacobian_grads (const CellSimilarity::Similarity cell_similarity,
628  const typename ::QProjector<dim>::DataSetDescriptor data_set,
629  const typename ::MappingFEField<dim,spacedim>::InternalData &data,
631  const ComponentMask &fe_mask,
632  const std::vector<unsigned int> &fe_to_real,
633  std::vector<DerivativeForm<2,dim,spacedim> > &jacobian_grads)
634  {
635  const UpdateFlags update_flags = data.update_each;
636  if (update_flags & update_jacobian_grads)
637  {
638  const unsigned int n_q_points = jacobian_grads.size();
639 
640  if (cell_similarity != CellSimilarity::translation)
641  {
642  for (unsigned int point=0; point<n_q_points; ++point)
643  {
644  const Tensor<2,dim> *second =
645  &data.second_derivative(point+data_set, 0);
646 
648 
649  for (unsigned int k=0; k<data.n_shape_functions; ++k)
650  {
651  unsigned int comp_k = fe.system_to_component_index(k).first;
652  if (fe_mask[comp_k])
653  for (unsigned int j=0; j<dim; ++j)
654  for (unsigned int l=0; l<dim; ++l)
655  result[fe_to_real[comp_k]][j][l] += (second[k][j][l]
656  * data.local_dof_values[k]);
657  }
658 
659  // never touch any data for j=dim in case dim<spacedim, so
660  // it will always be zero as it was initialized
661  for (unsigned int i=0; i<spacedim; ++i)
662  for (unsigned int j=0; j<dim; ++j)
663  for (unsigned int l=0; l<dim; ++l)
664  jacobian_grads[point][i][j][l] = result[i][j][l];
665  }
666  }
667  }
668  }
669 
676  template <int dim, int spacedim>
677  void
678  maybe_update_jacobian_pushed_forward_grads (
679  const CellSimilarity::Similarity cell_similarity,
680  const typename ::QProjector<dim>::DataSetDescriptor data_set,
681  const typename ::MappingFEField<dim,spacedim>::InternalData &data,
683  const ComponentMask &fe_mask,
684  const std::vector<unsigned int> &fe_to_real,
685  std::vector<Tensor<3,spacedim> > &jacobian_pushed_forward_grads )
686  {
687  const UpdateFlags update_flags = data.update_each;
688  if (update_flags & update_jacobian_pushed_forward_grads)
689  {
690  const unsigned int n_q_points = jacobian_pushed_forward_grads.size();
691 
692  if (cell_similarity != CellSimilarity::translation)
693  {
694  double tmp[spacedim][spacedim][spacedim];
695  for (unsigned int point=0; point<n_q_points; ++point)
696  {
697  const Tensor<2,dim> *second =
698  &data.second_derivative(point+data_set, 0);
699 
701 
702  for (unsigned int k=0; k<data.n_shape_functions; ++k)
703  {
704  unsigned int comp_k = fe.system_to_component_index(k).first;
705  if (fe_mask[comp_k])
706  for (unsigned int j=0; j<dim; ++j)
707  for (unsigned int l=0; l<dim; ++l)
708  result[fe_to_real[comp_k]][j][l] += (second[k][j][l]
709  * data.local_dof_values[k]);
710  }
711 
712  // first push forward the j-components
713  for (unsigned int i=0; i<spacedim; ++i)
714  for (unsigned int j=0; j<spacedim; ++j)
715  for (unsigned int l=0; l<dim; ++l)
716  {
717  tmp[i][j][l] = result[i][0][l] *
718  data.covariant[point][j][0];
719  for (unsigned int jr=1; jr<dim; ++jr)
720  {
721  tmp[i][j][l] += result[i][jr][l] *
722  data.covariant[point][j][jr];
723  }
724  }
725 
726  // now, pushing forward the l-components
727  for (unsigned int i=0; i<spacedim; ++i)
728  for (unsigned int j=0; j<spacedim; ++j)
729  for (unsigned int l=0; l<spacedim; ++l)
730  {
731  jacobian_pushed_forward_grads[point][i][j][l] = tmp[i][j][0] *
732  data.covariant[point][l][0];
733  for (unsigned int lr=1; lr<dim; ++lr)
734  {
735  jacobian_pushed_forward_grads[point][i][j][l] += tmp[i][j][lr] *
736  data.covariant[point][l][lr];
737  }
738 
739  }
740  }
741  }
742  }
743  }
744 
751  template <int dim, int spacedim>
752  void
753  maybe_update_jacobian_2nd_derivatives (const CellSimilarity::Similarity cell_similarity,
754  const typename ::QProjector<dim>::DataSetDescriptor data_set,
755  const typename ::MappingFEField<dim,spacedim>::InternalData &data,
757  const ComponentMask &fe_mask,
758  const std::vector<unsigned int> &fe_to_real,
759  std::vector<DerivativeForm<3,dim,spacedim> > &jacobian_2nd_derivatives)
760  {
761  const UpdateFlags update_flags = data.update_each;
762  if (update_flags & update_jacobian_2nd_derivatives)
763  {
764  const unsigned int n_q_points = jacobian_2nd_derivatives.size();
765 
766  if (cell_similarity != CellSimilarity::translation)
767  {
768  for (unsigned int point=0; point<n_q_points; ++point)
769  {
770  const Tensor<3,dim> *third =
771  &data.third_derivative(point+data_set, 0);
772 
774 
775  for (unsigned int k=0; k<data.n_shape_functions; ++k)
776  {
777  unsigned int comp_k = fe.system_to_component_index(k).first;
778  if (fe_mask[comp_k])
779  for (unsigned int j=0; j<dim; ++j)
780  for (unsigned int l=0; l<dim; ++l)
781  for (unsigned int m=0; m<dim; ++m)
782  result[fe_to_real[comp_k]][j][l][m] += (third[k][j][l][m]
783  * data.local_dof_values[k]);
784  }
785 
786  // never touch any data for j=dim in case dim<spacedim, so
787  // it will always be zero as it was initialized
788  for (unsigned int i=0; i<spacedim; ++i)
789  for (unsigned int j=0; j<dim; ++j)
790  for (unsigned int l=0; l<dim; ++l)
791  for (unsigned int m=0; m<dim; ++m)
792  jacobian_2nd_derivatives[point][i][j][l][m] = result[i][j][l][m];
793  }
794  }
795  }
796  }
797 
804  template <int dim, int spacedim>
805  void
806  maybe_update_jacobian_pushed_forward_2nd_derivatives (
807  const CellSimilarity::Similarity cell_similarity,
808  const typename ::QProjector<dim>::DataSetDescriptor data_set,
809  const typename ::MappingFEField<dim,spacedim>::InternalData &data,
811  const ComponentMask &fe_mask,
812  const std::vector<unsigned int> &fe_to_real,
813  std::vector<Tensor<4,spacedim> > &jacobian_pushed_forward_2nd_derivatives )
814  {
815  const UpdateFlags update_flags = data.update_each;
817  {
818  const unsigned int n_q_points = jacobian_pushed_forward_2nd_derivatives.size();
819 
820  if (cell_similarity != CellSimilarity::translation)
821  {
822  double tmp[spacedim][spacedim][spacedim][spacedim];
823  for (unsigned int point=0; point<n_q_points; ++point)
824  {
825  const Tensor<3,dim> *third =
826  &data.third_derivative(point+data_set, 0);
827 
829 
830  for (unsigned int k=0; k<data.n_shape_functions; ++k)
831  {
832  unsigned int comp_k = fe.system_to_component_index(k).first;
833  if (fe_mask[comp_k])
834  for (unsigned int j=0; j<dim; ++j)
835  for (unsigned int l=0; l<dim; ++l)
836  for (unsigned int m=0; m<dim; ++m)
837  result[fe_to_real[comp_k]][j][l][m] += (third[k][j][l][m]
838  * data.local_dof_values[k]);
839  }
840 
841  // push forward the j-coordinate
842  for (unsigned int i=0; i<spacedim; ++i)
843  for (unsigned int j=0; j<spacedim; ++j)
844  for (unsigned int l=0; l<dim; ++l)
845  for (unsigned int m=0; m<dim; ++m)
846  {
847  jacobian_pushed_forward_2nd_derivatives[point][i][j][l][m]
848  = result[i][0][l][m]*
849  data.covariant[point][j][0];
850  for (unsigned int jr=1; jr<dim; ++jr)
851  jacobian_pushed_forward_2nd_derivatives[point][i][j][l][m]
852  += result[i][jr][l][m]*
853  data.covariant[point][j][jr];
854  }
855 
856  // push forward the l-coordinate
857  for (unsigned int i=0; i<spacedim; ++i)
858  for (unsigned int j=0; j<spacedim; ++j)
859  for (unsigned int l=0; l<spacedim; ++l)
860  for (unsigned int m=0; m<dim; ++m)
861  {
862  tmp[i][j][l][m]
863  = jacobian_pushed_forward_2nd_derivatives[point][i][j][0][m]*
864  data.covariant[point][l][0];
865  for (unsigned int lr=1; lr<dim; ++lr)
866  tmp[i][j][l][m]
867  += jacobian_pushed_forward_2nd_derivatives[point][i][j][lr][m]*
868  data.covariant[point][l][lr];
869  }
870 
871  // push forward the m-coordinate
872  for (unsigned int i=0; i<spacedim; ++i)
873  for (unsigned int j=0; j<spacedim; ++j)
874  for (unsigned int l=0; l<spacedim; ++l)
875  for (unsigned int m=0; m<spacedim; ++m)
876  {
877  jacobian_pushed_forward_2nd_derivatives[point][i][j][l][m]
878  = tmp[i][j][l][0]*
879  data.covariant[point][m][0];
880  for (unsigned int mr=1; mr<dim; ++mr)
881  jacobian_pushed_forward_2nd_derivatives[point][i][j][l][m]
882  += tmp[i][j][l][mr]*
883  data.covariant[point][m][mr];
884  }
885  }
886  }
887  }
888  }
889  }
890 
897  template <int dim, int spacedim>
898  void
899  maybe_update_jacobian_3rd_derivatives (const CellSimilarity::Similarity cell_similarity,
900  const typename ::QProjector<dim>::DataSetDescriptor data_set,
901  const typename ::MappingFEField<dim,spacedim>::InternalData &data,
903  const ComponentMask &fe_mask,
904  const std::vector<unsigned int> &fe_to_real,
905  std::vector<DerivativeForm<4,dim,spacedim> > &jacobian_3rd_derivatives)
906  {
907  const UpdateFlags update_flags = data.update_each;
908  if (update_flags & update_jacobian_3rd_derivatives)
909  {
910  const unsigned int n_q_points = jacobian_3rd_derivatives.size();
911 
912  if (cell_similarity != CellSimilarity::translation)
913  {
914  for (unsigned int point=0; point<n_q_points; ++point)
915  {
916  const Tensor<4,dim> *fourth =
917  &data.fourth_derivative(point+data_set, 0);
918 
920 
921  for (unsigned int k=0; k<data.n_shape_functions; ++k)
922  {
923  unsigned int comp_k = fe.system_to_component_index(k).first;
924  if (fe_mask[comp_k])
925  for (unsigned int j=0; j<dim; ++j)
926  for (unsigned int l=0; l<dim; ++l)
927  for (unsigned int m=0; m<dim; ++m)
928  for (unsigned int n=0; n<dim; ++n)
929  result[fe_to_real[comp_k]][j][l][m][n] += (fourth[k][j][l][m][n]
930  * data.local_dof_values[k]);
931  }
932 
933  // never touch any data for j,l,m,n=dim in case dim<spacedim, so
934  // it will always be zero as it was initialized
935  for (unsigned int i=0; i<spacedim; ++i)
936  for (unsigned int j=0; j<dim; ++j)
937  for (unsigned int l=0; l<dim; ++l)
938  for (unsigned int m=0; m<dim; ++m)
939  for (unsigned int n=0; n<dim; ++n)
940  jacobian_3rd_derivatives[point][i][j][l][m][n] = result[i][j][l][m][n];
941  }
942  }
943  }
944  }
945 
953  template <int dim, int spacedim>
954  void
956  const CellSimilarity::Similarity cell_similarity,
957  const typename ::QProjector<dim>::DataSetDescriptor data_set,
958  const typename ::MappingFEField<dim,spacedim>::InternalData &data,
960  const ComponentMask &fe_mask,
961  const std::vector<unsigned int> &fe_to_real,
962  std::vector<Tensor<5,spacedim> > &jacobian_pushed_forward_3rd_derivatives )
963  {
964  const UpdateFlags update_flags = data.update_each;
966  {
967  const unsigned int n_q_points = jacobian_pushed_forward_3rd_derivatives.size();
968 
969  if (cell_similarity != CellSimilarity::translation)
970  {
971  double tmp[spacedim][spacedim][spacedim][spacedim][spacedim];
972  for (unsigned int point=0; point<n_q_points; ++point)
973  {
974  const Tensor<4,dim> *fourth =
975  &data.fourth_derivative(point+data_set, 0);
976 
978 
979  for (unsigned int k=0; k<data.n_shape_functions; ++k)
980  {
981  unsigned int comp_k = fe.system_to_component_index(k).first;
982  if (fe_mask[comp_k])
983  for (unsigned int j=0; j<dim; ++j)
984  for (unsigned int l=0; l<dim; ++l)
985  for (unsigned int m=0; m<dim; ++m)
986  for (unsigned int n=0; n<dim; ++n)
987  result[fe_to_real[comp_k]][j][l][m][n]
988  += (fourth[k][j][l][m][n]
989  * data.local_dof_values[k]);
990  }
991 
992  // push-forward the j-coordinate
993  for (unsigned int i=0; i<spacedim; ++i)
994  for (unsigned int j=0; j<spacedim; ++j)
995  for (unsigned int l=0; l<dim; ++l)
996  for (unsigned int m=0; m<dim; ++m)
997  for (unsigned int n=0; n<dim; ++n)
998  {
999  tmp[i][j][l][m][n] = result[i][0][l][m][n] *
1000  data.covariant[point][j][0];
1001  for (unsigned int jr=1; jr<dim; ++jr)
1002  tmp[i][j][l][m][n] += result[i][jr][l][m][n] *
1003  data.covariant[point][j][jr];
1004  }
1005 
1006  // push-forward the l-coordinate
1007  for (unsigned int i=0; i<spacedim; ++i)
1008  for (unsigned int j=0; j<spacedim; ++j)
1009  for (unsigned int l=0; l<spacedim; ++l)
1010  for (unsigned int m=0; m<dim; ++m)
1011  for (unsigned int n=0; n<dim; ++n)
1012  {
1013  jacobian_pushed_forward_3rd_derivatives[point][i][j][l][m][n]
1014  = tmp[i][j][0][m][n] *
1015  data.covariant[point][l][0];
1016  for (unsigned int lr=1; lr<dim; ++lr)
1017  jacobian_pushed_forward_3rd_derivatives[point][i][j][l][m][n]
1018  += tmp[i][j][lr][m][n] *
1019  data.covariant[point][l][lr];
1020  }
1021 
1022  // push-forward the m-coordinate
1023  for (unsigned int i=0; i<spacedim; ++i)
1024  for (unsigned int j=0; j<spacedim; ++j)
1025  for (unsigned int l=0; l<spacedim; ++l)
1026  for (unsigned int m=0; m<spacedim; ++m)
1027  for (unsigned int n=0; n<dim; ++n)
1028  {
1029  tmp[i][j][l][m][n]
1030  = jacobian_pushed_forward_3rd_derivatives[point][i][j][l][0][n] *
1031  data.covariant[point][m][0];
1032  for (unsigned int mr=1; mr<dim; ++mr)
1033  tmp[i][j][l][m][n]
1034  += jacobian_pushed_forward_3rd_derivatives[point][i][j][l][mr][n] *
1035  data.covariant[point][m][mr];
1036  }
1037 
1038  // push-forward the n-coordinate
1039  for (unsigned int i=0; i<spacedim; ++i)
1040  for (unsigned int j=0; j<spacedim; ++j)
1041  for (unsigned int l=0; l<spacedim; ++l)
1042  for (unsigned int m=0; m<spacedim; ++m)
1043  for (unsigned int n=0; n<spacedim; ++n)
1044  {
1045  jacobian_pushed_forward_3rd_derivatives[point][i][j][l][m][n]
1046  = tmp[i][j][l][m][0] *
1047  data.covariant[point][n][0];
1048  for (unsigned int nr=1; nr<dim; ++nr)
1049  jacobian_pushed_forward_3rd_derivatives[point][i][j][l][m][n]
1050  += tmp[i][j][l][m][nr] *
1051  data.covariant[point][n][nr];
1052  }
1053  }
1054  }
1055  }
1056  }
1057 
1058 
1068  template <int dim, int spacedim>
1069  void
1070  maybe_compute_face_data (const ::MappingFEField<dim,spacedim> &mapping,
1071  const typename ::Triangulation<dim,spacedim>::cell_iterator &cell,
1072  const unsigned int face_no,
1073  const unsigned int subface_no,
1074  const std::vector<double> &weights,
1075  const typename ::MappingFEField<dim,spacedim>::InternalData &data,
1077  {
1078  const UpdateFlags update_flags = data.update_each;
1079 
1080  if (update_flags & update_boundary_forms)
1081  {
1082  const unsigned int n_q_points = output_data.boundary_forms.size();
1083  if (update_flags & update_normal_vectors)
1084  AssertDimension (output_data.normal_vectors.size(), n_q_points);
1085  if (update_flags & update_JxW_values)
1086  AssertDimension (output_data.JxW_values.size(), n_q_points);
1087 
1088  // map the unit tangentials to the real cell. checking for d!=dim-1
1089  // eliminates compiler warnings regarding unsigned int expressions <
1090  // 0.
1091  for (unsigned int d=0; d!=dim-1; ++d)
1092  {
1094  data.unit_tangentials.size(),
1095  ExcInternalError());
1096  Assert (data.aux[d].size() <=
1097  data.unit_tangentials[face_no+GeometryInfo<dim>::faces_per_cell*d].size(),
1098  ExcInternalError());
1099 
1100  mapping.transform (make_array_view(data.unit_tangentials[face_no+GeometryInfo<dim>::faces_per_cell*d]),
1102  data,
1103  make_array_view(data.aux[d]));
1104  }
1105 
1106  // if dim==spacedim, we can use the unit tangentials to compute the
1107  // boundary form by simply taking the cross product
1108  if (dim == spacedim)
1109  {
1110  for (unsigned int i=0; i<n_q_points; ++i)
1111  switch (dim)
1112  {
1113  case 1:
1114  // in 1d, we don't have access to any of the data.aux
1115  // fields (because it has only dim-1 components), but we
1116  // can still compute the boundary form by simply looking
1117  // at the number of the face
1118  output_data.boundary_forms[i][0] = (face_no == 0 ?
1119  -1 : +1);
1120  break;
1121  case 2:
1122  output_data.boundary_forms[i] = cross_product_2d(data.aux[0][i]);
1123  break;
1124  case 3:
1125  output_data.boundary_forms[i] =
1126  cross_product_3d(data.aux[0][i], data.aux[1][i]);
1127  break;
1128  default:
1129  Assert(false, ExcNotImplemented());
1130  }
1131  }
1132  else //(dim < spacedim)
1133  {
1134  // in the codim-one case, the boundary form results from the
1135  // cross product of all the face tangential vectors and the cell
1136  // normal vector
1137  //
1138  // to compute the cell normal, use the same method used in
1139  // fill_fe_values for cells above
1140  AssertDimension (data.contravariant.size(), n_q_points);
1141 
1142  for (unsigned int point=0; point<n_q_points; ++point)
1143  {
1144  if (dim==1)
1145  {
1146  // J is a tangent vector
1147  output_data.boundary_forms[point] = data.contravariant[point].transpose()[0];
1148  output_data.boundary_forms[point] /=
1149  (face_no == 0 ? -1. : +1.) * output_data.boundary_forms[point].norm();
1150 
1151  }
1152 
1153  if (dim==2)
1154  {
1155  const DerivativeForm<1,spacedim,dim> DX_t =
1156  data.contravariant[point].transpose();
1157 
1158  Tensor<1, spacedim> cell_normal =
1159  cross_product_3d(DX_t[0], DX_t[1]);
1160  cell_normal /= cell_normal.norm();
1161 
1162  // then compute the face normal from the face tangent
1163  // and the cell normal:
1164  output_data.boundary_forms[point] =
1165  cross_product_3d(data.aux[0][point], cell_normal);
1166  }
1167 
1168  }
1169  }
1170 
1171  if (update_flags & (update_normal_vectors | update_JxW_values))
1172  for (unsigned int i=0; i<output_data.boundary_forms.size(); ++i)
1173  {
1174  if (update_flags & update_JxW_values)
1175  {
1176  output_data.JxW_values[i] = output_data.boundary_forms[i].norm() * weights[i];
1177 
1178  if (subface_no != numbers::invalid_unsigned_int)
1179  {
1180  const double area_ratio=GeometryInfo<dim>::subface_ratio(
1181  cell->subface_case(face_no), subface_no);
1182  output_data.JxW_values[i] *= area_ratio;
1183  }
1184  }
1185 
1186  if (update_flags & update_normal_vectors)
1187  output_data.normal_vectors[i] = Point<spacedim>(output_data.boundary_forms[i] / output_data.boundary_forms[i].norm());
1188  }
1189 
1190  if (update_flags & update_jacobians)
1191  for (unsigned int point=0; point<n_q_points; ++point)
1192  output_data.jacobians[point] = data.contravariant[point];
1193 
1194  if (update_flags & update_inverse_jacobians)
1195  for (unsigned int point=0; point<n_q_points; ++point)
1196  output_data.inverse_jacobians[point] = data.covariant[point].transpose();
1197  }
1198  }
1199 
1206  template<int dim, int spacedim>
1207  void
1208  do_fill_fe_face_values (const ::MappingFEField<dim,spacedim> &mapping,
1209  const typename ::Triangulation<dim,spacedim>::cell_iterator &cell,
1210  const unsigned int face_no,
1211  const unsigned int subface_no,
1212  const typename ::QProjector<dim>::DataSetDescriptor data_set,
1213  const Quadrature<dim-1> &quadrature,
1214  const typename ::MappingFEField<dim,spacedim>::InternalData &data,
1215  const FiniteElement<dim, spacedim> &fe,
1216  const ComponentMask &fe_mask,
1217  const std::vector<unsigned int> &fe_to_real,
1219  {
1220  maybe_compute_q_points<dim,spacedim> (data_set,
1221  data,
1222  fe, fe_mask, fe_to_real,
1223  output_data.quadrature_points);
1224 
1225  maybe_update_Jacobians<dim,spacedim> (CellSimilarity::none,
1226  data_set,
1227  data,
1228  fe, fe_mask, fe_to_real);
1229 
1230  maybe_update_jacobian_grads<dim,spacedim> (CellSimilarity::none,
1231  data_set,
1232  data,
1233  fe, fe_mask, fe_to_real,
1234  output_data.jacobian_grads);
1235 
1236  maybe_update_jacobian_pushed_forward_grads<dim,spacedim> (CellSimilarity::none,
1237  data_set,
1238  data,
1239  fe, fe_mask, fe_to_real,
1240  output_data.jacobian_pushed_forward_grads);
1241 
1242  maybe_update_jacobian_2nd_derivatives<dim,spacedim> (CellSimilarity::none,
1243  data_set,
1244  data,
1245  fe, fe_mask, fe_to_real,
1246  output_data.jacobian_2nd_derivatives);
1247 
1248  maybe_update_jacobian_pushed_forward_2nd_derivatives<dim,spacedim> (CellSimilarity::none,
1249  data_set,
1250  data,
1251  fe, fe_mask, fe_to_real,
1253 
1254  maybe_update_jacobian_3rd_derivatives<dim,spacedim> (CellSimilarity::none,
1255  data_set,
1256  data,
1257  fe, fe_mask, fe_to_real,
1258  output_data.jacobian_3rd_derivatives);
1259 
1260  maybe_update_jacobian_pushed_forward_3rd_derivatives<dim,spacedim> (CellSimilarity::none,
1261  data_set,
1262  data,
1263  fe, fe_mask, fe_to_real,
1265 
1266  maybe_compute_face_data (mapping,
1267  cell, face_no, subface_no,
1268  quadrature.get_weights(), data,
1269  output_data);
1270  }
1271 }
1272 
1273 
1274 // Note that the CellSimilarity flag is modifiable, since MappingFEField can need to
1275 // recalculate data even when cells are similar.
1276 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1277 CellSimilarity::Similarity
1280  const CellSimilarity::Similarity cell_similarity,
1281  const Quadrature<dim> &quadrature,
1282  const typename Mapping<dim,spacedim>::InternalDataBase &internal_data,
1284 {
1285  // convert data object to internal data for this class. fails with an
1286  // exception if that is not possible
1287  Assert (dynamic_cast<const InternalData *> (&internal_data) != 0, ExcInternalError());
1288  const InternalData &data = static_cast<const InternalData &> (internal_data);
1289 
1290  const unsigned int n_q_points=quadrature.size();
1291  const CellSimilarity::Similarity updated_cell_similarity
1292  = (get_degree() == 1
1293  ?
1294  cell_similarity
1295  :
1296  CellSimilarity::invalid_next_cell);
1297 
1298  update_internal_dofs(cell, data);
1299 
1300  internal::maybe_compute_q_points(QProjector<dim>::DataSetDescriptor::cell (),
1301  data, *fe, fe_mask, fe_to_real,
1302  output_data.quadrature_points);
1303 
1304  internal::maybe_update_Jacobians(cell_similarity,
1306  data, *fe, fe_mask, fe_to_real);
1307 
1308  const UpdateFlags update_flags = data.update_each;
1309  const std::vector<double> &weights=quadrature.get_weights();
1310 
1311  // Multiply quadrature weights by absolute value of Jacobian determinants or
1312  // the area element g=sqrt(DX^t DX) in case of codim > 0
1313 
1314  if (update_flags & (update_normal_vectors | update_JxW_values))
1315  {
1316  AssertDimension (output_data.JxW_values.size(), n_q_points);
1317 
1318  Assert( !(update_flags & update_normal_vectors ) ||
1319  (output_data.normal_vectors.size() == n_q_points),
1320  ExcDimensionMismatch(output_data.normal_vectors.size(), n_q_points));
1321 
1322 
1323  if (cell_similarity != CellSimilarity::translation)
1324  for (unsigned int point=0; point<n_q_points; ++point)
1325  {
1326  if (dim == spacedim)
1327  {
1328  const double det = data.contravariant[point].determinant();
1329 
1330  // check for distorted cells.
1331 
1332  // TODO: this allows for anisotropies of up to 1e6 in 3D and
1333  // 1e12 in 2D. might want to find a finer
1334  // (dimension-independent) criterion
1335  Assert (det > 1e-12*Utilities::fixed_power<dim>(cell->diameter()/
1336  std::sqrt(double(dim))),
1337  (typename Mapping<dim,spacedim>::ExcDistortedMappedCell(cell->center(), det, point)));
1338  output_data.JxW_values[point] = weights[point] * det;
1339  }
1340  // if dim==spacedim, then there is no cell normal to
1341  // compute. since this is for FEValues (and not FEFaceValues),
1342  // there are also no face normals to compute
1343  else //codim>0 case
1344  {
1345  Tensor<1, spacedim> DX_t [dim];
1346  for (unsigned int i=0; i<spacedim; ++i)
1347  for (unsigned int j=0; j<dim; ++j)
1348  DX_t[j][i] = data.contravariant[point][i][j];
1349 
1350  Tensor<2, dim> G; //First fundamental form
1351  for (unsigned int i=0; i<dim; ++i)
1352  for (unsigned int j=0; j<dim; ++j)
1353  G[i][j] = DX_t[i] * DX_t[j];
1354 
1355  output_data.JxW_values[point] = sqrt(determinant(G)) * weights[point];
1356 
1357  if (cell_similarity == CellSimilarity::inverted_translation)
1358  {
1359  // we only need to flip the normal
1360  if (update_flags & update_normal_vectors)
1361  output_data.normal_vectors[point] *= -1.;
1362  }
1363  else
1364  {
1365  if (update_flags & update_normal_vectors)
1366  {
1367  Assert (spacedim - dim == 1,
1368  ExcMessage("There is no cell normal in codim 2."));
1369 
1370  if (dim==1)
1371  output_data.normal_vectors[point] =
1372  cross_product_2d(-DX_t[0]);
1373  else //dim == 2
1374  output_data.normal_vectors[point] =
1375  cross_product_3d(DX_t[0], DX_t[1]);
1376 
1377  output_data.normal_vectors[point] /= output_data.normal_vectors[point].norm();
1378 
1379  if (cell->direction_flag() == false)
1380  output_data.normal_vectors[point] *= -1.;
1381  }
1382 
1383  }
1384  } //codim>0 case
1385  }
1386  }
1387 
1388  // copy values from InternalData to vector given by reference
1389  if (update_flags & update_jacobians)
1390  {
1391  AssertDimension (output_data.jacobians.size(), n_q_points);
1392  if (cell_similarity != CellSimilarity::translation)
1393  for (unsigned int point=0; point<n_q_points; ++point)
1394  output_data.jacobians[point] = data.contravariant[point];
1395  }
1396 
1397  // copy values from InternalData to vector given by reference
1398  if (update_flags & update_inverse_jacobians)
1399  {
1400  AssertDimension (output_data.inverse_jacobians.size(), n_q_points);
1401  if (cell_similarity != CellSimilarity::translation)
1402  for (unsigned int point=0; point<n_q_points; ++point)
1403  output_data.inverse_jacobians[point] = data.covariant[point].transpose();
1404  }
1405 
1406  // calculate derivatives of the Jacobians
1407  internal::maybe_update_jacobian_grads(cell_similarity,
1409  data, *fe, fe_mask, fe_to_real,
1410  output_data.jacobian_grads);
1411 
1412  // calculate derivatives of the Jacobians pushed forward to real cell coordinates
1413  internal::maybe_update_jacobian_pushed_forward_grads(cell_similarity,
1415  data, *fe, fe_mask, fe_to_real,
1416  output_data.jacobian_pushed_forward_grads);
1417 
1418  // calculate hessians of the Jacobians
1419  internal::maybe_update_jacobian_2nd_derivatives(cell_similarity,
1421  data, *fe, fe_mask, fe_to_real,
1422  output_data.jacobian_2nd_derivatives);
1423 
1424  // calculate hessians of the Jacobians pushed forward to real cell coordinates
1425  internal::maybe_update_jacobian_pushed_forward_2nd_derivatives(cell_similarity,
1427  data, *fe, fe_mask, fe_to_real,
1429 
1430  // calculate gradients of the hessians of the Jacobians
1433  data, *fe, fe_mask, fe_to_real,
1434  output_data.jacobian_3rd_derivatives);
1435 
1436  // calculate gradients of the hessians of the Jacobians pushed forward to real
1437  // cell coordinates
1440  data, *fe, fe_mask, fe_to_real,
1442 
1443  return updated_cell_similarity;
1444 }
1445 
1446 
1447 
1448 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1449 void
1452  const unsigned int face_no,
1453  const Quadrature<dim-1> &quadrature,
1454  const typename Mapping<dim,spacedim>::InternalDataBase &internal_data,
1456 {
1457  // convert data object to internal data for this class. fails with an
1458  // exception if that is not possible
1459  Assert (dynamic_cast<const InternalData *> (&internal_data) != 0,
1460  ExcInternalError());
1461  const InternalData &data = static_cast<const InternalData &> (internal_data);
1462 
1463  update_internal_dofs(cell, data);
1464 
1466  cell, face_no, numbers::invalid_unsigned_int,
1468  face (face_no,
1469  cell->face_orientation(face_no),
1470  cell->face_flip(face_no),
1471  cell->face_rotation(face_no),
1472  quadrature.size()),
1473  quadrature,
1474  data,
1475  *fe, fe_mask, fe_to_real,
1476  output_data);
1477 }
1478 
1479 
1480 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1481 void
1484  const unsigned int face_no,
1485  const unsigned int subface_no,
1486  const Quadrature<dim-1> &quadrature,
1487  const typename Mapping<dim,spacedim>::InternalDataBase &internal_data,
1489 {
1490  // convert data object to internal data for this class. fails with an
1491  // exception if that is not possible
1492  Assert (dynamic_cast<const InternalData *> (&internal_data) != 0,
1493  ExcInternalError());
1494  const InternalData &data = static_cast<const InternalData &> (internal_data);
1495 
1496  update_internal_dofs(cell, data);
1497 
1499  cell, face_no, numbers::invalid_unsigned_int,
1501  subface (face_no, subface_no,
1502  cell->face_orientation(face_no),
1503  cell->face_flip(face_no),
1504  cell->face_rotation(face_no),
1505  quadrature.size(),
1506  cell->subface_case(face_no)),
1507  quadrature,
1508  data,
1509  *fe, fe_mask, fe_to_real,
1510  output_data);
1511 }
1512 
1513 
1514 namespace
1515 {
1516  template<int dim, int spacedim, int rank, typename VectorType, typename DoFHandlerType>
1517  void
1518  transform_fields(const ArrayView<const Tensor<rank,dim> > &input,
1519  const MappingType mapping_type,
1520  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
1521  const ArrayView<Tensor<rank,spacedim> > &output)
1522  {
1523  AssertDimension (input.size(), output.size());
1524  Assert ((dynamic_cast<const typename MappingFEField<dim,spacedim,VectorType,DoFHandlerType>::InternalData *>(&mapping_data) != 0),
1525  ExcInternalError());
1527  &data = static_cast<const typename MappingFEField<dim,spacedim,VectorType,DoFHandlerType>::InternalData &>(mapping_data);
1528 
1529  switch (mapping_type)
1530  {
1531  case mapping_contravariant:
1532  {
1534  typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
1535 
1536  for (unsigned int i=0; i<output.size(); ++i)
1537  output[i] = apply_transformation(data.contravariant[i], input[i]);
1538 
1539  return;
1540  }
1541 
1542  case mapping_piola:
1543  {
1545  typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
1547  typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_volume_elements"));
1548  Assert (rank==1, ExcMessage("Only for rank 1"));
1549  for (unsigned int i=0; i<output.size(); ++i)
1550  {
1551  output[i] = apply_transformation(data.contravariant[i], input[i]);
1552  output[i] /= data.volume_elements[i];
1553  }
1554  return;
1555  }
1556 
1557 
1558  //We still allow this operation as in the
1559  //reference cell Derivatives are Tensor
1560  //rather than DerivativeForm
1561  case mapping_covariant:
1562  {
1564  typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
1565 
1566  for (unsigned int i=0; i<output.size(); ++i)
1567  output[i] = apply_transformation(data.covariant[i], input[i]);
1568 
1569  return;
1570  }
1571 
1572  default:
1573  Assert(false, ExcNotImplemented());
1574  }
1575  }
1576 
1577 
1578  template<int dim, int spacedim, int rank, typename VectorType, typename DoFHandlerType>
1579  void
1580  transform_differential_forms
1581  (const ArrayView<const DerivativeForm<rank, dim,spacedim> > &input,
1582  const MappingType mapping_type,
1583  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
1584  const ArrayView<Tensor<rank+1, spacedim> > &output)
1585  {
1586 
1587  AssertDimension (input.size(), output.size());
1588  Assert ((dynamic_cast<const typename MappingFEField<dim,spacedim,VectorType,DoFHandlerType>::InternalData *>(&mapping_data) != 0),
1589  ExcInternalError());
1591  &data = static_cast<const typename MappingFEField<dim,spacedim,VectorType,DoFHandlerType>::InternalData &>(mapping_data);
1592 
1593  switch (mapping_type)
1594  {
1595  case mapping_covariant:
1596  {
1598  typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_contravariant_transformation"));
1599 
1600  for (unsigned int i=0; i<output.size(); ++i)
1601  output[i] = apply_transformation(data.covariant[i], input[i]);
1602 
1603  return;
1604  }
1605  default:
1606  Assert(false, ExcNotImplemented());
1607  }
1608 
1609  }
1610 }
1611 
1612 
1613 
1614 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1615 void
1617 transform (const ArrayView<const Tensor<1,dim> > &input,
1618  const MappingType mapping_type,
1619  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
1620  const ArrayView<Tensor<1,spacedim> > &output) const
1621 {
1622  AssertDimension (input.size(), output.size());
1623 
1624  transform_fields<dim,spacedim,1,VectorType,DoFHandlerType>(input, mapping_type, mapping_data, output);
1625 }
1626 
1627 
1628 
1629 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1630 void
1633  const MappingType mapping_type,
1634  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
1635  const ArrayView<Tensor<2,spacedim> > &output) const
1636 {
1637  AssertDimension (input.size(), output.size());
1638 
1639  transform_differential_forms<dim,spacedim,1,VectorType,DoFHandlerType>(input, mapping_type, mapping_data, output);
1640 }
1641 
1642 
1643 
1644 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1645 void
1647 transform (const ArrayView<const Tensor<2, dim> > &input,
1648  const MappingType ,
1649  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
1650  const ArrayView<Tensor<2,spacedim> > &output) const
1651 {
1652  (void)input;
1653  (void)output;
1654  (void)mapping_data;
1655  AssertDimension (input.size(), output.size());
1656 
1657  AssertThrow(false, ExcNotImplemented());
1658 }
1659 
1660 
1661 
1662 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1663 void
1666  const MappingType mapping_type,
1667  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
1668  const ArrayView<Tensor<3,spacedim> > &output) const
1669 {
1670  AssertDimension (input.size(), output.size());
1671  Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
1672  ExcInternalError());
1673  const InternalData &data = static_cast<const InternalData &>(mapping_data);
1674 
1675  switch (mapping_type)
1676  {
1678  {
1680  typename FEValuesBase<dim>::ExcAccessToUninitializedField("update_covariant_transformation"));
1681 
1682  for (unsigned int q=0; q<output.size(); ++q)
1683  for (unsigned int i=0; i<spacedim; ++i)
1684  for (unsigned int j=0; j<spacedim; ++j)
1685  for (unsigned int k=0; k<spacedim; ++k)
1686  {
1687  output[q][i][j][k] = data.covariant[q][j][0]
1688  * data.covariant[q][k][0]
1689  * input[q][i][0][0];
1690  for (unsigned int J=0; J<dim; ++J)
1691  {
1692  const unsigned int K0 = (0==J)? 1 : 0;
1693  for (unsigned int K=K0; K<dim; ++K)
1694  output[q][i][j][k] += data.covariant[q][j][J]
1695  * data.covariant[q][k][K]
1696  * input[q][i][J][K];
1697  }
1698 
1699  }
1700  return;
1701  }
1702 
1703  default:
1704  Assert(false, ExcNotImplemented());
1705  }
1706 
1707 }
1708 
1709 
1710 
1711 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1712 void
1714 transform (const ArrayView<const Tensor<3,dim> > &input,
1715  const MappingType /*mapping_type*/,
1716  const typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
1717  const ArrayView<Tensor<3,spacedim> > &output) const
1718 {
1719 
1720  (void)input;
1721  (void)output;
1722  (void)mapping_data;
1723  AssertDimension (input.size(), output.size());
1724 
1725  AssertThrow(false, ExcNotImplemented());
1726 
1727 }
1728 
1729 
1730 
1731 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1735  const Point<dim> &p) const
1736 {
1737 // Use the get_data function to create an InternalData with data vectors of
1738 // the right size and transformation shape values already computed at point
1739 // p.
1740  const Quadrature<dim> point_quadrature(p);
1741  std_cxx11::unique_ptr<InternalData> mdata (get_data(update_quadrature_points | update_jacobians,
1742  point_quadrature));
1743 
1744  update_internal_dofs(cell, *mdata);
1745 
1746  return do_transform_unit_to_real_cell(*mdata);
1747 }
1748 
1749 
1750 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1754 {
1755  Point<spacedim> p_real;
1756 
1757  for (unsigned int i=0; i<data.n_shape_functions; ++i)
1758  {
1759  unsigned int comp_i = fe->system_to_component_index(i).first;
1760  if (fe_mask[comp_i])
1761  p_real[fe_to_real[comp_i]] += data.local_dof_values[i] * data.shape(0,i);
1762  }
1763 
1764  return p_real;
1765 }
1766 
1767 
1768 
1769 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1770 Point<dim>
1773  const Point<spacedim> &p) const
1774 {
1775  // first a Newton iteration based on the real mapping. It uses the center
1776  // point of the cell as a starting point
1777  Point<dim> initial_p_unit;
1778  try
1779  {
1780  initial_p_unit
1781  = StaticMappingQ1<dim,spacedim>::mapping.transform_real_to_unit_cell(cell, p);
1782  }
1783  catch (const typename Mapping<dim,spacedim>::ExcTransformationFailed &)
1784  {
1785  // mirror the conditions of the code below to determine if we need to
1786  // use an arbitrary starting point or if we just need to rethrow the
1787  // exception
1788  for (unsigned int d=0; d<dim; ++d)
1789  initial_p_unit[d] = 0.5;
1790  }
1791 
1792  initial_p_unit = GeometryInfo<dim>::project_to_unit_cell(initial_p_unit);
1793 
1794  // for (unsigned int d=0; d<dim; ++d)
1795  // initial_p_unit[d] = 0.;
1796 
1797  const Quadrature<dim> point_quadrature(initial_p_unit);
1798 
1800  if (spacedim>dim)
1801  update_flags |= update_jacobian_grads;
1802  std_cxx11::unique_ptr<InternalData>
1803  mdata (get_data(update_flags,point_quadrature));
1804 
1805  update_internal_dofs(cell, *mdata);
1806 
1807  return do_transform_real_to_unit_cell(cell, p, initial_p_unit, *mdata);
1808 
1809 }
1810 
1811 
1812 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1813 Point<dim>
1817  const Point<spacedim> &p,
1818  const Point<dim> &initial_p_unit,
1819  InternalData &mdata) const
1820 {
1821  const unsigned int n_shapes=mdata.shape_values.size();
1822  (void)n_shapes;
1823  Assert(n_shapes!=0, ExcInternalError());
1824  AssertDimension (mdata.shape_derivatives.size(), n_shapes);
1825 
1826 
1827  // Newton iteration to solve
1828  // f(x)=p(x)-p=0
1829  // x_{n+1}=x_n-[f'(x)]^{-1}f(x)
1830  // The start value was set to be the
1831  // linear approximation to the cell
1832  // The shape values and derivatives
1833  // of the mapping at this point are
1834  // previously computed.
1835  // f(x)
1836  Point<dim> p_unit = initial_p_unit;
1837  Point<dim> f;
1838  compute_shapes_virtual(std::vector<Point<dim> > (1, p_unit), mdata);
1840  Tensor<1,spacedim> p_minus_F = p - p_real;
1841  const double eps = 1.e-12*cell->diameter();
1842  const unsigned int newton_iteration_limit = 20;
1843  unsigned int newton_iteration=0;
1844  while (p_minus_F.norm_square() > eps*eps)
1845  {
1846  // f'(x)
1847  Point<spacedim> DF[dim];
1848  Tensor<2,dim> df;
1849  for (unsigned int k=0; k<mdata.n_shape_functions; ++k)
1850  {
1851  const Tensor<1,dim> &grad_k = mdata.derivative(0,k);
1852  unsigned int comp_k = fe->system_to_component_index(k).first;
1853  if (fe_mask[comp_k])
1854  for (unsigned int j=0; j<dim; ++j)
1855  DF[j][fe_to_real[comp_k]] += mdata.local_dof_values[k] * grad_k[j];
1856  }
1857  for (unsigned int j=0; j<dim; ++j)
1858  {
1859  f[j] = DF[j] * p_minus_F;
1860  for (unsigned int l=0; l<dim; ++l)
1861  df[j][l] = -DF[j] * DF[l];
1862  }
1863  // Solve [f'(x)]d=f(x)
1864  const Tensor<1, dim> delta =
1865  invert(df) * static_cast<const Tensor<1, dim> &>(f);
1866  // do a line search
1867  double step_length = 1;
1868  do
1869  {
1870  // update of p_unit. The
1871  // spacedimth component of
1872  // transformed point is simply
1873  // ignored in codimension one
1874  // case. When this component is
1875  // not zero, then we are
1876  // projecting the point to the
1877  // surface or curve identified
1878  // by the cell.
1879  Point<dim> p_unit_trial = p_unit;
1880  for (unsigned int i=0; i<dim; ++i)
1881  p_unit_trial[i] -= step_length * delta[i];
1882  // shape values and derivatives
1883  // at new p_unit point
1884  compute_shapes_virtual(std::vector<Point<dim> > (1, p_unit_trial), mdata);
1885  // f(x)
1886  Point<spacedim> p_real_trial = do_transform_unit_to_real_cell(mdata);
1887  const Tensor<1,spacedim> f_trial = p - p_real_trial;
1888  // see if we are making progress with the current step length
1889  // and if not, reduce it by a factor of two and try again
1890  if (f_trial.norm() < p_minus_F.norm())
1891  {
1892  p_real = p_real_trial;
1893  p_unit = p_unit_trial;
1894  p_minus_F = f_trial;
1895  break;
1896  }
1897  else if (step_length > 0.05)
1898  step_length /= 2;
1899  else
1900  goto failure;
1901  }
1902  while (true);
1903  ++newton_iteration;
1904  if (newton_iteration > newton_iteration_limit)
1905  goto failure;
1906  }
1907  return p_unit;
1908  // if we get to the following label, then we have either run out
1909  // of Newton iterations, or the line search has not converged.
1910  // in either case, we need to give up, so throw an exception that
1911  // can then be caught
1912 failure:
1914  // ...the compiler wants us to return something, though we can
1915  // of course never get here...
1916  return Point<dim>();
1917 }
1918 
1919 
1920 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1921 unsigned int
1923 {
1924  return fe->degree;
1925 }
1926 
1927 
1928 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1931 {
1932  return this->fe_mask;
1933 }
1934 
1935 
1936 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1939 {
1941 }
1942 
1943 
1944 template<int dim, int spacedim, typename VectorType, typename DoFHandlerType>
1945 void
1948  const typename MappingFEField<dim, spacedim>::InternalData &data) const
1949 {
1950  Assert(euler_dof_handler != 0, ExcMessage("euler_dof_handler is empty"));
1951 
1952  typename DoFHandlerType::cell_iterator dof_cell(*cell, euler_dof_handler);
1953  Assert (dof_cell->active() == true, ExcInactiveCell());
1954 
1955  dof_cell->get_dof_indices(data.local_dof_indices);
1956 
1957  for (unsigned int i=0; i<data.local_dof_values.size(); ++i)
1958  data.local_dof_values[i] = (*euler_vector)(data.local_dof_indices[i]);
1959 }
1960 
1961 // explicit instantiations
1962 #include "mapping_fe_field.inst"
1963 
1964 
1965 DEAL_II_NAMESPACE_CLOSE
Transformed quadrature weights.
static const unsigned int invalid_unsigned_int
Definition: types.h:164
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1052
virtual Mapping< dim, spacedim >::InternalDataBase * get_subface_data(const UpdateFlags flags, const Quadrature< dim-1 > &quadrature) const
Contravariant transformation.
virtual Tensor< 3, dim > shape_3rd_derivative(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:233
const std::vector< Point< dim > > & get_points() const
const std::vector< double > & get_weights() const
virtual std::size_t memory_consumption() const
MappingType
Definition: mapping.h:50
virtual Tensor< 1, dim > shape_grad(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:187
Volume element.
::ExceptionBase & ExcMessage(std::string arg1)
const unsigned int degree
Definition: fe_base.h:299
Outer normal vector, not normalized.
std::vector< unsigned int > fe_to_real
Determinant of the Jacobian.
Transformed quadrature points.
SmartPointer< const FiniteElement< dim, spacedim >, MappingFEField< dim, spacedim, VectorType, DoFHandlerType > > fe
#define AssertThrow(cond, exc)
Definition: exceptions.h:358
numbers::NumberTraits< Number >::real_type norm() const
Definition: tensor.h:1047
Point< spacedim > do_transform_unit_to_real_cell(const InternalData &mdata) const
std::vector< Tensor< 1, spacedim > > boundary_forms
std::vector< Tensor< 4, spacedim > > jacobian_pushed_forward_2nd_derivatives
unsigned int get_degree() const
std::vector< DerivativeForm< 2, dim, spacedim > > jacobian_grads
virtual Mapping< dim, spacedim > * clone() const
std::vector< DerivativeForm< 1, dim, spacedim > > covariant
std::vector< std::vector< Tensor< 1, dim > > > unit_tangentials
virtual Point< dim > transform_real_to_unit_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< spacedim > &p) const
InternalData(const FiniteElement< dim, spacedim > &fe, const ComponentMask mask)
std::vector< Tensor< 3, spacedim > > jacobian_pushed_forward_grads
void maybe_update_jacobian_pushed_forward_3rd_derivatives(const CellSimilarity::Similarity cell_similarity, const typename ::QProjector< dim >::DataSetDescriptor data_set, const typename ::MappingFEField< dim, spacedim >::InternalData &data, const FiniteElement< dim, spacedim > &fe, const ComponentMask &fe_mask, const std::vector< unsigned int > &fe_to_real, std::vector< Tensor< 5, spacedim > > &jacobian_pushed_forward_3rd_derivatives)
std::vector< Tensor< 3, dim > > shape_third_derivatives
#define Assert(cond, exc)
Definition: exceptions.h:294
UpdateFlags
Abstract base class for mapping classes.
Definition: dof_tools.h:52
std::vector< DerivativeForm< 1, dim, spacedim > > jacobians
std::vector< Tensor< 1, spacedim > > normal_vectors
const ComponentMask & get_nonzero_components(const unsigned int i) const
Definition: fe.h:2915
virtual Point< spacedim > transform_unit_to_real_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< dim > &p) const
std::vector< double > volume_elements
numbers::NumberTraits< Number >::real_type norm_square() const
Definition: tensor.h:1056
unsigned int size() const
const double & shape(const unsigned int qpoint, const unsigned int shape_nr) const
virtual InternalData * get_data(const UpdateFlags, const Quadrature< dim > &quadrature) const
DerivativeForm< 1, spacedim, dim, Number > transpose() const
virtual void compute_shapes_virtual(const std::vector< Point< dim > > &unit_points, typename MappingFEField< dim, spacedim >::InternalData &data) const
void update_internal_dofs(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const typename MappingFEField< dim, spacedim >::InternalData &data) const
virtual Mapping< dim, spacedim >::InternalDataBase * get_face_data(const UpdateFlags flags, const Quadrature< dim-1 > &quadrature) const
SmartPointer< const DoFHandlerType, MappingFEField< dim, spacedim, VectorType, DoFHandlerType > > euler_dof_handler
virtual bool preserves_vertex_locations() const
Gradient of volume element.
std::vector< double > local_dof_values
const Tensor< 3, dim > & third_derivative(const unsigned int qpoint, const unsigned int shape_nr) const
unsigned int size() const
const unsigned int dofs_per_cell
Definition: fe_base.h:283
std::vector< double > shape_values
std::vector< Tensor< 4, dim > > shape_fourth_derivatives
std::vector< Tensor< 5, spacedim > > jacobian_pushed_forward_3rd_derivatives
friend class MappingFEField
std::vector< types::global_dof_index > local_dof_indices
void maybe_compute_face_data(const ::MappingFEField< dim, spacedim > &mapping, const typename ::Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const unsigned int subface_no, const std::vector< double > &weights, const typename ::MappingFEField< dim, spacedim >::InternalData &data, internal::FEValues::MappingRelatedData< dim, spacedim > &output_data)
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
Definition: fe.h:2742
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:164
const Tensor< 2, dim > & second_derivative(const unsigned int qpoint, const unsigned int shape_nr) const
std::vector< DerivativeForm< 4, dim, spacedim > > jacobian_3rd_derivatives
SmartPointer< const VectorType, MappingFEField< dim, spacedim, VectorType, DoFHandlerType > > euler_vector
std::vector< Point< spacedim > > quadrature_points
Normal vectors.
void do_fill_fe_face_values(const ::MappingFEField< dim, spacedim > &mapping, const typename ::Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const unsigned int subface_no, const typename ::QProjector< dim >::DataSetDescriptor data_set, const Quadrature< dim-1 > &quadrature, const typename ::MappingFEField< dim, spacedim >::InternalData &data, const FiniteElement< dim, spacedim > &fe, const ComponentMask &fe_mask, const std::vector< unsigned int > &fe_to_real, internal::FEValues::MappingRelatedData< dim, spacedim > &output_data)
const Tensor< 4, dim > & fourth_derivative(const unsigned int qpoint, const unsigned int shape_nr) const
void maybe_update_jacobian_3rd_derivatives(const CellSimilarity::Similarity cell_similarity, const typename ::QProjector< dim >::DataSetDescriptor data_set, const typename ::MappingFEField< dim, spacedim >::InternalData &data, const FiniteElement< dim, spacedim > &fe, const ComponentMask &fe_mask, const std::vector< unsigned int > &fe_to_real, std::vector< DerivativeForm< 4, dim, spacedim > > &jacobian_3rd_derivatives)
virtual Tensor< 2, dim > shape_grad_grad(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:210
static Point< dim > project_to_unit_cell(const Point< dim > &p)
const Tensor< 1, dim > & derivative(const unsigned int qpoint, const unsigned int shape_nr) const
std::vector< DerivativeForm< 1, dim, spacedim > > contravariant
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const
ComponentMask get_component_mask() const
std::vector< Tensor< 2, dim > > shape_second_derivatives
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
virtual Tensor< 4, dim > shape_4th_derivative(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:256
std::vector< DerivativeForm< 1, spacedim, dim > > inverse_jacobians
std::vector< DerivativeForm< 3, dim, spacedim > > jacobian_2nd_derivatives
std::vector< Tensor< 1, dim > > shape_derivatives
Point< dim > do_transform_real_to_unit_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< spacedim > &p, const Point< dim > &initial_p_unit, InternalData &mdata) const
static double subface_ratio(const internal::SubfaceCase< dim > &subface_case, const unsigned int subface_no)
Covariant transformation.
UpdateFlags update_each
Definition: mapping.h:560
std::vector< std::vector< Tensor< 1, spacedim > > > aux