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