Reference documentation for deal.II version 9.4.1
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
mapping_cartesian.cc
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2001 - 2022 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
21#include <deal.II/base/tensor.h>
22
24
27
28#include <deal.II/grid/tria.h>
30
32
33#include <algorithm>
34#include <cmath>
35#include <memory>
36
37
39
42 "You are using MappingCartesian, but the incoming cell is not Cartesian.");
43
44
45
51template <class CellType>
52bool
53is_cartesian(const CellType &cell)
54{
55 if (!cell->reference_cell().is_hyper_cube())
56 return false;
57
58 const double tolerance = 1e-14;
59 const auto bounding_box = cell->bounding_box();
60 const auto & bounding_vertices = bounding_box.get_boundary_points();
61 const auto cell_measure =
62 bounding_vertices.first.distance_square(bounding_vertices.second);
63
64 for (const unsigned int v : cell->vertex_indices())
65 {
66 const double vertex_tolerance =
67 tolerance * std::max(cell->vertex(v).norm_square(), cell_measure);
68
69 if (cell->vertex(v).distance_square(bounding_box.vertex(v)) >
70 vertex_tolerance)
71 return false;
72 }
73
74 return true;
75}
76
77
78
79template <int dim, int spacedim>
81 const Quadrature<dim> &q)
82 : cell_extents(numbers::signaling_nan<Tensor<1, dim>>())
83 , volume_element(numbers::signaling_nan<double>())
84 , quadrature_points(q.get_points())
85{}
86
87
88
89template <int dim, int spacedim>
90std::size_t
92{
96 MemoryConsumption::memory_consumption(quadrature_points));
97}
98
99
100
101template <int dim, int spacedim>
102bool
104{
105 return true;
106}
107
108
109
110template <int dim, int spacedim>
111bool
113 const ReferenceCell &reference_cell) const
114{
115 Assert(dim == reference_cell.get_dimension(),
116 ExcMessage("The dimension of your mapping (" +
118 ") and the reference cell cell_type (" +
119 Utilities::to_string(reference_cell.get_dimension()) +
120 " ) do not agree."));
121
122 return reference_cell.is_hyper_cube();
123}
124
125
126
127template <int dim, int spacedim>
130 const UpdateFlags in) const
131{
132 // this mapping is pretty simple in that it can basically compute
133 // every piece of information wanted by FEValues without requiring
134 // computing any other quantities. boundary forms are one exception
135 // since they can be computed from the normal vectors without much
136 // further ado
137 UpdateFlags out = in;
138 if (out & update_boundary_forms)
140
141 return out;
142}
143
144
145
146template <int dim, int spacedim>
147std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
149 const Quadrature<dim> &q) const
150{
151 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase> data_ptr =
152 std::make_unique<InternalData>(q);
153 auto &data = dynamic_cast<InternalData &>(*data_ptr);
154
155 // store the flags in the internal data object so we can access them
156 // in fill_fe_*_values(). use the transitive hull of the required
157 // flags
158 data.update_each = requires_update_flags(update_flags);
159
160 return data_ptr;
161}
162
163
164
165template <int dim, int spacedim>
166std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
168 const UpdateFlags update_flags,
169 const hp::QCollection<dim - 1> &quadrature) const
170{
171 AssertDimension(quadrature.size(), 1);
172
173 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase> data_ptr =
174 std::make_unique<InternalData>(QProjector<dim>::project_to_all_faces(
175 ReferenceCells::get_hypercube<dim>(), quadrature[0]));
176 auto &data = dynamic_cast<InternalData &>(*data_ptr);
177
178 // verify that we have computed the transitive hull of the required
179 // flags and that FEValues has faithfully passed them on to us
180 Assert(update_flags == requires_update_flags(update_flags),
182
183 // store the flags in the internal data object so we can access them
184 // in fill_fe_*_values()
185 data.update_each = update_flags;
186
187 return data_ptr;
188}
189
190
191
192template <int dim, int spacedim>
193std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
195 const UpdateFlags update_flags,
196 const Quadrature<dim - 1> &quadrature) const
197{
198 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase> data_ptr =
199 std::make_unique<InternalData>(QProjector<dim>::project_to_all_subfaces(
200 ReferenceCells::get_hypercube<dim>(), quadrature));
201 auto &data = dynamic_cast<InternalData &>(*data_ptr);
202
203 // verify that we have computed the transitive hull of the required
204 // flags and that FEValues has faithfully passed them on to us
205 Assert(update_flags == requires_update_flags(update_flags),
207
208 // store the flags in the internal data object so we can access them
209 // in fill_fe_*_values()
210 data.update_each = update_flags;
211
212 return data_ptr;
213}
214
215
216
217template <int dim, int spacedim>
218void
221 const CellSimilarity::Similarity cell_similarity,
222 const InternalData & data) const
223{
224 // Compute start point and sizes
225 // along axes. Strange vertex
226 // numbering makes this complicated
227 // again.
228 if (cell_similarity != CellSimilarity::translation)
229 {
230 const Point<dim> &start = cell->vertex(0);
231 switch (dim)
232 {
233 case 1:
234 data.cell_extents[0] = cell->vertex(1)(0) - start(0);
235 break;
236 case 2:
237 data.cell_extents[0] = cell->vertex(1)(0) - start(0);
238 data.cell_extents[1] = cell->vertex(2)(1) - start(1);
239 break;
240 case 3:
241 data.cell_extents[0] = cell->vertex(1)(0) - start(0);
242 data.cell_extents[1] = cell->vertex(2)(1) - start(1);
243 data.cell_extents[2] = cell->vertex(4)(2) - start(2);
244 break;
245 default:
246 Assert(false, ExcNotImplemented());
247 }
248 }
249}
250
251
252
253template <int dim, int spacedim>
254void
257 const InternalData & data,
258 std::vector<Point<dim>> &quadrature_points) const
259{
260 if (data.update_each & update_quadrature_points)
261 {
262 const auto offset = QProjector<dim>::DataSetDescriptor::cell();
263
264 transform_quadrature_points(cell, data, offset, quadrature_points);
265 }
266}
267
268
269
270template <int dim, int spacedim>
271void
274 const unsigned int face_no,
275 const InternalData & data,
276 std::vector<Point<dim>> &quadrature_points) const
277{
279
280 if (data.update_each & update_quadrature_points)
281 {
283 ReferenceCells::get_hypercube<dim>(),
284 face_no,
285 cell->face_orientation(face_no),
286 cell->face_flip(face_no),
287 cell->face_rotation(face_no),
288 quadrature_points.size());
289
290
291 transform_quadrature_points(cell, data, offset, quadrature_points);
292 }
293}
294
295
296
297template <int dim, int spacedim>
298void
301 const unsigned int face_no,
302 const unsigned int sub_no,
303 const InternalData & data,
304 std::vector<Point<dim>> &quadrature_points) const
305{
308 if (cell->face(face_no)->has_children())
309 {
310 AssertIndexRange(sub_no, cell->face(face_no)->n_children());
311 }
312
313 if (data.update_each & update_quadrature_points)
314 {
316 ReferenceCells::get_hypercube<dim>(),
317 face_no,
318 sub_no,
319 cell->face_orientation(face_no),
320 cell->face_flip(face_no),
321 cell->face_rotation(face_no),
322 quadrature_points.size(),
323 cell->subface_case(face_no));
324
325 transform_quadrature_points(cell, data, offset, quadrature_points);
326 }
327}
328
329
330
331template <int dim, int spacedim>
332void
335 const InternalData & data,
336 const typename QProjector<dim>::DataSetDescriptor & offset,
337 std::vector<Point<dim>> &quadrature_points) const
338{
339 // let @p{start} be the origin of a local coordinate system. it is chosen
340 // as the (lower) left vertex
341 const Point<dim> &start = cell->vertex(0);
342
343 for (unsigned int i = 0; i < quadrature_points.size(); ++i)
344 {
345 quadrature_points[i] = start;
346 for (unsigned int d = 0; d < dim; ++d)
347 quadrature_points[i](d) +=
348 data.cell_extents[d] * data.quadrature_points[i + offset](d);
349 }
350}
351
352
353
354template <int dim, int spacedim>
355void
357 const unsigned int face_no,
358 const InternalData & data,
359 std::vector<Tensor<1, dim>> &normal_vectors) const
360{
361 // compute normal vectors. All normals on a face have the same value.
362 if (data.update_each & update_normal_vectors)
363 {
365 std::fill(normal_vectors.begin(),
366 normal_vectors.end(),
368 }
369}
370
371
372
373template <int dim, int spacedim>
374void
376 const InternalData & data,
377 const CellSimilarity::Similarity cell_similarity,
379 &output_data) const
380{
381 if (cell_similarity != CellSimilarity::translation)
382 {
383 if (data.update_each & update_jacobian_grads)
384 for (unsigned int i = 0; i < output_data.jacobian_grads.size(); ++i)
386
387 if (data.update_each & update_jacobian_pushed_forward_grads)
388 for (unsigned int i = 0;
389 i < output_data.jacobian_pushed_forward_grads.size();
390 ++i)
392
393 if (data.update_each & update_jacobian_2nd_derivatives)
394 for (unsigned int i = 0;
395 i < output_data.jacobian_2nd_derivatives.size();
396 ++i)
397 output_data.jacobian_2nd_derivatives[i] =
399
401 for (unsigned int i = 0;
402 i < output_data.jacobian_pushed_forward_2nd_derivatives.size();
403 ++i)
406
407 if (data.update_each & update_jacobian_3rd_derivatives)
408 for (unsigned int i = 0;
409 i < output_data.jacobian_3rd_derivatives.size();
410 ++i)
411 output_data.jacobian_3rd_derivatives[i] =
413
415 for (unsigned int i = 0;
416 i < output_data.jacobian_pushed_forward_3rd_derivatives.size();
417 ++i)
420 }
421}
422
423
424
425template <int dim, int spacedim>
426void
428 const InternalData &data) const
429{
430 if (data.update_each & update_volume_elements)
431 {
432 double volume = data.cell_extents[0];
433 for (unsigned int d = 1; d < dim; ++d)
434 volume *= data.cell_extents[d];
435 data.volume_element = volume;
436 }
437}
438
439
440
441template <int dim, int spacedim>
442void
444 const InternalData & data,
445 const CellSimilarity::Similarity cell_similarity,
447 &output_data) const
448{
449 // "compute" Jacobian at the quadrature points, which are all the
450 // same
451 if (data.update_each & update_jacobians)
452 if (cell_similarity != CellSimilarity::translation)
453 for (unsigned int i = 0; i < output_data.jacobians.size(); ++i)
454 {
456 for (unsigned int j = 0; j < dim; ++j)
457 output_data.jacobians[i][j][j] = data.cell_extents[j];
458 }
459}
460
461
462
463template <int dim, int spacedim>
464void
466 const InternalData & data,
467 const CellSimilarity::Similarity cell_similarity,
469 &output_data) const
470{
471 // "compute" inverse Jacobian at the quadrature points, which are
472 // all the same
473 if (data.update_each & update_inverse_jacobians)
474 if (cell_similarity != CellSimilarity::translation)
475 for (unsigned int i = 0; i < output_data.inverse_jacobians.size(); ++i)
476 {
477 output_data.inverse_jacobians[i] = Tensor<2, dim>();
478 for (unsigned int j = 0; j < dim; ++j)
479 output_data.inverse_jacobians[i][j][j] = 1. / data.cell_extents[j];
480 }
481}
482
483
484
485template <int dim, int spacedim>
489 const CellSimilarity::Similarity cell_similarity,
490 const Quadrature<dim> & quadrature,
491 const typename Mapping<dim, spacedim>::InternalDataBase & internal_data,
493 &output_data) const
494{
496
497 // convert data object to internal data for this class. fails with
498 // an exception if that is not possible
499 Assert(dynamic_cast<const InternalData *>(&internal_data) != nullptr,
501 const InternalData &data = static_cast<const InternalData &>(internal_data);
502
503
504 update_cell_extents(cell, cell_similarity, data);
505
507 data,
508 output_data.quadrature_points);
509
510 // compute Jacobian determinant. all values are equal and are the
511 // product of the local lengths in each coordinate direction
512 if (data.update_each & (update_JxW_values | update_volume_elements))
513 if (cell_similarity != CellSimilarity::translation)
514 {
515 double J = data.cell_extents[0];
516 for (unsigned int d = 1; d < dim; ++d)
517 J *= data.cell_extents[d];
518 data.volume_element = J;
519 if (data.update_each & update_JxW_values)
520 for (unsigned int i = 0; i < output_data.JxW_values.size(); ++i)
521 output_data.JxW_values[i] = J * quadrature.weight(i);
522 }
523
524
525 maybe_update_jacobians(data, cell_similarity, output_data);
526 maybe_update_jacobian_derivatives(data, cell_similarity, output_data);
527 maybe_update_inverse_jacobians(data, cell_similarity, output_data);
528
529 return cell_similarity;
530}
531
532
533
534template <int dim, int spacedim>
535void
538 const ArrayView<const Point<dim>> & unit_points,
539 const UpdateFlags update_flags,
541 &output_data) const
542{
543 if (update_flags == update_default)
544 return;
545
547
548 Assert(update_flags & update_inverse_jacobians ||
549 update_flags & update_jacobians ||
550 update_flags & update_quadrature_points,
552
553 output_data.initialize(unit_points.size(), update_flags);
554
555 InternalData data;
556 data.update_each = update_flags;
557 data.quadrature_points =
558 std::vector<Point<dim>>(unit_points.begin(), unit_points.end());
559
561
563 data,
564 output_data.quadrature_points);
565
568}
569
570
571
572template <int dim, int spacedim>
573void
576 const unsigned int face_no,
577 const hp::QCollection<dim - 1> & quadrature,
578 const typename Mapping<dim, spacedim>::InternalDataBase & internal_data,
580 &output_data) const
581{
583 AssertDimension(quadrature.size(), 1);
584
585 // convert data object to internal
586 // data for this class. fails with
587 // an exception if that is not
588 // possible
589 Assert(dynamic_cast<const InternalData *>(&internal_data) != nullptr,
591 const InternalData &data = static_cast<const InternalData &>(internal_data);
592
594
596 face_no,
597 data,
598 output_data.quadrature_points);
599
600 maybe_update_normal_vectors(face_no, data, output_data.normal_vectors);
601
602 // first compute Jacobian determinant, which is simply the product
603 // of the local lengths since the jacobian is diagonal
604 double J = 1.;
605 for (unsigned int d = 0; d < dim; ++d)
607 J *= data.cell_extents[d];
608
609 if (data.update_each & update_JxW_values)
610 for (unsigned int i = 0; i < output_data.JxW_values.size(); ++i)
611 output_data.JxW_values[i] = J * quadrature[0].weight(i);
612
613 if (data.update_each & update_boundary_forms)
614 for (unsigned int i = 0; i < output_data.boundary_forms.size(); ++i)
615 output_data.boundary_forms[i] = J * output_data.normal_vectors[i];
616
621}
622
623
624
625template <int dim, int spacedim>
626void
629 const unsigned int face_no,
630 const unsigned int subface_no,
631 const Quadrature<dim - 1> & quadrature,
632 const typename Mapping<dim, spacedim>::InternalDataBase & internal_data,
634 &output_data) const
635{
637
638 // convert data object to internal data for this class. fails with
639 // an exception if that is not possible
640 Assert(dynamic_cast<const InternalData *>(&internal_data) != nullptr,
642 const InternalData &data = static_cast<const InternalData &>(internal_data);
643
645
647 cell, face_no, subface_no, data, output_data.quadrature_points);
648
649 maybe_update_normal_vectors(face_no, data, output_data.normal_vectors);
650
651 // first compute Jacobian determinant, which is simply the product
652 // of the local lengths since the jacobian is diagonal
653 double J = 1.;
654 for (unsigned int d = 0; d < dim; ++d)
656 J *= data.cell_extents[d];
657
658 if (data.update_each & update_JxW_values)
659 {
660 // Here, cell->face(face_no)->n_children() would be the right
661 // choice, but unfortunately the current function is also called
662 // for faces without children (see tests/fe/mapping.cc). Add
663 // following switch to avoid diffs in tests/fe/mapping.OK
664 const unsigned int n_subfaces =
665 cell->face(face_no)->has_children() ?
666 cell->face(face_no)->n_children() :
668 for (unsigned int i = 0; i < output_data.JxW_values.size(); ++i)
669 output_data.JxW_values[i] = J * quadrature.weight(i) / n_subfaces;
670 }
671
672 if (data.update_each & update_boundary_forms)
673 for (unsigned int i = 0; i < output_data.boundary_forms.size(); ++i)
674 output_data.boundary_forms[i] = J * output_data.normal_vectors[i];
675
680}
681
682
683
684template <int dim, int spacedim>
685void
689 const typename Mapping<dim, spacedim>::InternalDataBase & internal_data,
691 &output_data) const
692{
693 AssertDimension(dim, spacedim);
695
696 // Convert data object to internal data for this class. Fails with an
697 // exception if that is not possible.
698 Assert(dynamic_cast<const InternalData *>(&internal_data) != nullptr,
700 const InternalData &data = static_cast<const InternalData &>(internal_data);
701
702
704
706 data,
707 output_data.quadrature_points);
708
709 if (data.update_each & update_normal_vectors)
710 for (unsigned int i = 0; i < output_data.normal_vectors.size(); ++i)
711 {
712 // The normals are n = J^{-T} * \hat{n} before normalizing.
713 Tensor<1, dim> normal;
714 const Tensor<1, dim> &ref_space_normal = quadrature.normal_vector(i);
715 for (unsigned int d = 0; d < dim; ++d)
716 {
717 normal[d] = ref_space_normal[d] / data.cell_extents[d];
718 }
719 normal /= normal.norm();
720 output_data.normal_vectors[i] = normal;
721 }
722
723 if (data.update_each & update_JxW_values)
724 for (unsigned int i = 0; i < output_data.JxW_values.size(); ++i)
725 {
726 const Tensor<1, dim> &ref_space_normal = quadrature.normal_vector(i);
727
728 // J^{-T} \times \hat{n}
729 Tensor<1, dim> invJTxNormal;
730 double det_jacobian = 1.;
731 for (unsigned int d = 0; d < dim; ++d)
732 {
733 det_jacobian *= data.cell_extents[d];
734 invJTxNormal[d] = ref_space_normal[d] / data.cell_extents[d];
735 }
736 output_data.JxW_values[i] =
737 det_jacobian * invJTxNormal.norm() * quadrature.weight(i);
738 }
739
744}
745
746
747
748template <int dim, int spacedim>
749void
751 const ArrayView<const Tensor<1, dim>> & input,
752 const MappingKind mapping_kind,
753 const typename Mapping<dim, spacedim>::InternalDataBase &mapping_data,
754 const ArrayView<Tensor<1, spacedim>> & output) const
755{
756 AssertDimension(input.size(), output.size());
757 Assert(dynamic_cast<const InternalData *>(&mapping_data) != nullptr,
759 const InternalData &data = static_cast<const InternalData &>(mapping_data);
760
761 switch (mapping_kind)
762 {
764 {
765 Assert(data.update_each & update_covariant_transformation,
767 "update_covariant_transformation"));
768
769 for (unsigned int i = 0; i < output.size(); ++i)
770 for (unsigned int d = 0; d < dim; ++d)
771 output[i][d] = input[i][d] / data.cell_extents[d];
772 return;
773 }
774
776 {
779 "update_contravariant_transformation"));
780
781 for (unsigned int i = 0; i < output.size(); ++i)
782 for (unsigned int d = 0; d < dim; ++d)
783 output[i][d] = input[i][d] * data.cell_extents[d];
784 return;
785 }
786 case mapping_piola:
787 {
790 "update_contravariant_transformation"));
791 Assert(data.update_each & update_volume_elements,
793 "update_volume_elements"));
794
795 for (unsigned int i = 0; i < output.size(); ++i)
796 for (unsigned int d = 0; d < dim; ++d)
797 output[i][d] =
798 input[i][d] * data.cell_extents[d] / data.volume_element;
799 return;
800 }
801 default:
802 Assert(false, ExcNotImplemented());
803 }
804}
805
806
807
808template <int dim, int spacedim>
809void
812 const MappingKind mapping_kind,
813 const typename Mapping<dim, spacedim>::InternalDataBase &mapping_data,
814 const ArrayView<Tensor<2, spacedim>> & output) const
815{
816 AssertDimension(input.size(), output.size());
817 Assert(dynamic_cast<const InternalData *>(&mapping_data) != nullptr,
819 const InternalData &data = static_cast<const InternalData &>(mapping_data);
820
821 switch (mapping_kind)
822 {
824 {
825 Assert(data.update_each & update_covariant_transformation,
827 "update_covariant_transformation"));
828
829 for (unsigned int i = 0; i < output.size(); ++i)
830 for (unsigned int d1 = 0; d1 < dim; ++d1)
831 for (unsigned int d2 = 0; d2 < dim; ++d2)
832 output[i][d1][d2] = input[i][d1][d2] / data.cell_extents[d2];
833 return;
834 }
835
837 {
840 "update_contravariant_transformation"));
841
842 for (unsigned int i = 0; i < output.size(); ++i)
843 for (unsigned int d1 = 0; d1 < dim; ++d1)
844 for (unsigned int d2 = 0; d2 < dim; ++d2)
845 output[i][d1][d2] = input[i][d1][d2] * data.cell_extents[d2];
846 return;
847 }
848
850 {
851 Assert(data.update_each & update_covariant_transformation,
853 "update_covariant_transformation"));
854
855 for (unsigned int i = 0; i < output.size(); ++i)
856 for (unsigned int d1 = 0; d1 < dim; ++d1)
857 for (unsigned int d2 = 0; d2 < dim; ++d2)
858 output[i][d1][d2] = input[i][d1][d2] / data.cell_extents[d2] /
859 data.cell_extents[d1];
860 return;
861 }
862
864 {
867 "update_contravariant_transformation"));
868
869 for (unsigned int i = 0; i < output.size(); ++i)
870 for (unsigned int d1 = 0; d1 < dim; ++d1)
871 for (unsigned int d2 = 0; d2 < dim; ++d2)
872 output[i][d1][d2] = input[i][d1][d2] * data.cell_extents[d2] /
873 data.cell_extents[d1];
874 return;
875 }
876
877 case mapping_piola:
878 {
881 "update_contravariant_transformation"));
882 Assert(data.update_each & update_volume_elements,
884 "update_volume_elements"));
885
886 for (unsigned int i = 0; i < output.size(); ++i)
887 for (unsigned int d1 = 0; d1 < dim; ++d1)
888 for (unsigned int d2 = 0; d2 < dim; ++d2)
889 output[i][d1][d2] = input[i][d1][d2] * data.cell_extents[d2] /
890 data.volume_element;
891 return;
892 }
893
895 {
898 "update_contravariant_transformation"));
899 Assert(data.update_each & update_volume_elements,
901 "update_volume_elements"));
902
903 for (unsigned int i = 0; i < output.size(); ++i)
904 for (unsigned int d1 = 0; d1 < dim; ++d1)
905 for (unsigned int d2 = 0; d2 < dim; ++d2)
906 output[i][d1][d2] = input[i][d1][d2] * data.cell_extents[d2] /
907 data.cell_extents[d1] / data.volume_element;
908 return;
909 }
910
911 default:
912 Assert(false, ExcNotImplemented());
913 }
914}
915
916
917
918template <int dim, int spacedim>
919void
921 const ArrayView<const Tensor<2, dim>> & input,
922 const MappingKind mapping_kind,
923 const typename Mapping<dim, spacedim>::InternalDataBase &mapping_data,
924 const ArrayView<Tensor<2, spacedim>> & output) const
925{
926 AssertDimension(input.size(), output.size());
927 Assert(dynamic_cast<const InternalData *>(&mapping_data) != nullptr,
929 const InternalData &data = static_cast<const InternalData &>(mapping_data);
930
931 switch (mapping_kind)
932 {
934 {
935 Assert(data.update_each & update_covariant_transformation,
937 "update_covariant_transformation"));
938
939 for (unsigned int i = 0; i < output.size(); ++i)
940 for (unsigned int d1 = 0; d1 < dim; ++d1)
941 for (unsigned int d2 = 0; d2 < dim; ++d2)
942 output[i][d1][d2] = input[i][d1][d2] / data.cell_extents[d2];
943 return;
944 }
945
947 {
950 "update_contravariant_transformation"));
951
952 for (unsigned int i = 0; i < output.size(); ++i)
953 for (unsigned int d1 = 0; d1 < dim; ++d1)
954 for (unsigned int d2 = 0; d2 < dim; ++d2)
955 output[i][d1][d2] = input[i][d1][d2] * data.cell_extents[d2];
956 return;
957 }
958
960 {
961 Assert(data.update_each & update_covariant_transformation,
963 "update_covariant_transformation"));
964
965 for (unsigned int i = 0; i < output.size(); ++i)
966 for (unsigned int d1 = 0; d1 < dim; ++d1)
967 for (unsigned int d2 = 0; d2 < dim; ++d2)
968 output[i][d1][d2] = input[i][d1][d2] / data.cell_extents[d2] /
969 data.cell_extents[d1];
970 return;
971 }
972
974 {
977 "update_contravariant_transformation"));
978
979 for (unsigned int i = 0; i < output.size(); ++i)
980 for (unsigned int d1 = 0; d1 < dim; ++d1)
981 for (unsigned int d2 = 0; d2 < dim; ++d2)
982 output[i][d1][d2] = input[i][d1][d2] * data.cell_extents[d2] /
983 data.cell_extents[d1];
984 return;
985 }
986
987 case mapping_piola:
988 {
991 "update_contravariant_transformation"));
992 Assert(data.update_each & update_volume_elements,
994 "update_volume_elements"));
995
996 for (unsigned int i = 0; i < output.size(); ++i)
997 for (unsigned int d1 = 0; d1 < dim; ++d1)
998 for (unsigned int d2 = 0; d2 < dim; ++d2)
999 output[i][d1][d2] = input[i][d1][d2] * data.cell_extents[d2] /
1000 data.volume_element;
1001 return;
1002 }
1003
1005 {
1008 "update_contravariant_transformation"));
1009 Assert(data.update_each & update_volume_elements,
1011 "update_volume_elements"));
1012
1013 for (unsigned int i = 0; i < output.size(); ++i)
1014 for (unsigned int d1 = 0; d1 < dim; ++d1)
1015 for (unsigned int d2 = 0; d2 < dim; ++d2)
1016 output[i][d1][d2] = input[i][d1][d2] * data.cell_extents[d2] /
1017 data.cell_extents[d1] / data.volume_element;
1018 return;
1019 }
1020
1021 default:
1022 Assert(false, ExcNotImplemented());
1023 }
1024}
1025
1026
1027
1028template <int dim, int spacedim>
1029void
1031 const ArrayView<const DerivativeForm<2, dim, spacedim>> &input,
1032 const MappingKind mapping_kind,
1033 const typename Mapping<dim, spacedim>::InternalDataBase &mapping_data,
1034 const ArrayView<Tensor<3, spacedim>> & output) const
1035{
1036 AssertDimension(input.size(), output.size());
1037 Assert(dynamic_cast<const InternalData *>(&mapping_data) != nullptr,
1039 const InternalData &data = static_cast<const InternalData &>(mapping_data);
1040
1041 switch (mapping_kind)
1042 {
1044 {
1047 "update_covariant_transformation"));
1048
1049 for (unsigned int q = 0; q < output.size(); ++q)
1050 for (unsigned int i = 0; i < spacedim; ++i)
1051 for (unsigned int j = 0; j < spacedim; ++j)
1052 for (unsigned int k = 0; k < spacedim; ++k)
1053 {
1054 output[q][i][j][k] = input[q][i][j][k] /
1055 data.cell_extents[j] /
1056 data.cell_extents[k];
1057 }
1058 return;
1059 }
1060 default:
1061 Assert(false, ExcNotImplemented());
1062 }
1063}
1064
1065
1066
1067template <int dim, int spacedim>
1068void
1070 const ArrayView<const Tensor<3, dim>> & input,
1071 const MappingKind mapping_kind,
1072 const typename Mapping<dim, spacedim>::InternalDataBase &mapping_data,
1073 const ArrayView<Tensor<3, spacedim>> & output) const
1074{
1075 AssertDimension(input.size(), output.size());
1076 Assert(dynamic_cast<const InternalData *>(&mapping_data) != nullptr,
1078 const InternalData &data = static_cast<const InternalData &>(mapping_data);
1079
1080 switch (mapping_kind)
1081 {
1083 {
1084 Assert(data.update_each & update_covariant_transformation,
1086 "update_covariant_transformation"));
1089 "update_contravariant_transformation"));
1090
1091 for (unsigned int q = 0; q < output.size(); ++q)
1092 for (unsigned int i = 0; i < spacedim; ++i)
1093 for (unsigned int j = 0; j < spacedim; ++j)
1094 for (unsigned int k = 0; k < spacedim; ++k)
1095 {
1096 output[q][i][j][k] =
1097 input[q][i][j][k] * data.cell_extents[i] /
1098 data.cell_extents[j] / data.cell_extents[k];
1099 }
1100 return;
1101 }
1102
1104 {
1105 Assert(data.update_each & update_covariant_transformation,
1107 "update_covariant_transformation"));
1108
1109 for (unsigned int q = 0; q < output.size(); ++q)
1110 for (unsigned int i = 0; i < spacedim; ++i)
1111 for (unsigned int j = 0; j < spacedim; ++j)
1112 for (unsigned int k = 0; k < spacedim; ++k)
1113 {
1114 output[q][i][j][k] =
1115 input[q][i][j][k] / data.cell_extents[i] /
1116 data.cell_extents[j] / data.cell_extents[k];
1117 }
1118
1119 return;
1120 }
1121
1123 {
1124 Assert(data.update_each & update_covariant_transformation,
1126 "update_covariant_transformation"));
1129 "update_contravariant_transformation"));
1130 Assert(data.update_each & update_volume_elements,
1132 "update_volume_elements"));
1133
1134 for (unsigned int q = 0; q < output.size(); ++q)
1135 for (unsigned int i = 0; i < spacedim; ++i)
1136 for (unsigned int j = 0; j < spacedim; ++j)
1137 for (unsigned int k = 0; k < spacedim; ++k)
1138 {
1139 output[q][i][j][k] =
1140 input[q][i][j][k] * data.cell_extents[i] /
1141 data.volume_element / data.cell_extents[j] /
1142 data.cell_extents[k];
1143 }
1144
1145 return;
1146 }
1147
1148 default:
1149 Assert(false, ExcNotImplemented());
1150 }
1151}
1152
1153
1154
1155template <int dim, int spacedim>
1159 const Point<dim> & p) const
1160{
1162
1163 Tensor<1, dim> length;
1164 const Point<dim> start = cell->vertex(0);
1165 switch (dim)
1166 {
1167 case 1:
1168 length[0] = cell->vertex(1)(0) - start(0);
1169 break;
1170 case 2:
1171 length[0] = cell->vertex(1)(0) - start(0);
1172 length[1] = cell->vertex(2)(1) - start(1);
1173 break;
1174 case 3:
1175 length[0] = cell->vertex(1)(0) - start(0);
1176 length[1] = cell->vertex(2)(1) - start(1);
1177 length[2] = cell->vertex(4)(2) - start(2);
1178 break;
1179 default:
1180 Assert(false, ExcNotImplemented());
1181 }
1182
1183 Point<dim> p_real = cell->vertex(0);
1184 for (unsigned int d = 0; d < dim; ++d)
1185 p_real(d) += length[d] * p(d);
1186
1187 return p_real;
1188}
1189
1190
1191
1192template <int dim, int spacedim>
1196 const Point<spacedim> & p) const
1197{
1199
1200 if (dim != spacedim)
1201 Assert(false, ExcNotImplemented());
1202 const Point<dim> &start = cell->vertex(0);
1203 Point<dim> real = p;
1204 real -= start;
1205
1206 switch (dim)
1207 {
1208 case 1:
1209 real(0) /= cell->vertex(1)(0) - start(0);
1210 break;
1211 case 2:
1212 real(0) /= cell->vertex(1)(0) - start(0);
1213 real(1) /= cell->vertex(2)(1) - start(1);
1214 break;
1215 case 3:
1216 real(0) /= cell->vertex(1)(0) - start(0);
1217 real(1) /= cell->vertex(2)(1) - start(1);
1218 real(2) /= cell->vertex(4)(2) - start(2);
1219 break;
1220 default:
1221 Assert(false, ExcNotImplemented());
1222 }
1223 return real;
1224}
1225
1226
1227
1228template <int dim, int spacedim>
1229std::unique_ptr<Mapping<dim, spacedim>>
1231{
1232 return std::make_unique<MappingCartesian<dim, spacedim>>(*this);
1233}
1234
1235
1236//---------------------------------------------------------------------------
1237// explicit instantiations
1238#include "mapping_cartesian.inst"
1239
1240
std::vector< Point< dim > > quadrature_points
virtual std::size_t memory_consumption() const override
void fill_mapping_data_for_generic_points(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const ArrayView< const Point< dim > > &unit_points, const UpdateFlags update_flags, ::internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const
virtual void fill_fe_face_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const hp::QCollection< dim - 1 > &quadrature, const typename Mapping< dim, spacedim >::InternalDataBase &internal_data, internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const override
void maybe_update_volume_elements(const InternalData &data) const
virtual std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > get_face_data(const UpdateFlags flags, const hp::QCollection< dim - 1 > &quadrature) const override
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const override
virtual std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > get_subface_data(const UpdateFlags flags, const Quadrature< dim - 1 > &quadrature) const override
void update_cell_extents(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const CellSimilarity::Similarity cell_similarity, const InternalData &data) const
void maybe_update_jacobians(const InternalData &data, const CellSimilarity::Similarity cell_similarity, internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const
void maybe_update_subface_quadrature_points(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const unsigned int sub_no, const InternalData &data, std::vector< Point< dim > > &quadrature_points) const
virtual CellSimilarity::Similarity fill_fe_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const CellSimilarity::Similarity cell_similarity, const Quadrature< dim > &quadrature, const typename Mapping< dim, spacedim >::InternalDataBase &internal_data, internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const override
virtual void fill_fe_immersed_surface_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const NonMatching::ImmersedSurfaceQuadrature< dim > &quadrature, const typename Mapping< dim, spacedim >::InternalDataBase &internal_data, ::internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const override
void maybe_update_face_quadrature_points(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const InternalData &data, std::vector< Point< dim > > &quadrature_points) const
virtual bool is_compatible_with(const ReferenceCell &reference_cell) const override
void maybe_update_cell_quadrature_points(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const InternalData &data, std::vector< Point< dim > > &quadrature_points) const
virtual bool preserves_vertex_locations() const override
virtual Point< spacedim > transform_unit_to_real_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< dim > &p) const override
virtual std::unique_ptr< Mapping< dim, spacedim > > clone() const override
virtual Point< dim > transform_real_to_unit_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< spacedim > &p) const override
void transform_quadrature_points(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const InternalData &data, const typename QProjector< dim >::DataSetDescriptor &offset, std::vector< Point< dim > > &quadrature_points) const
void maybe_update_jacobian_derivatives(const InternalData &data, const CellSimilarity::Similarity cell_similarity, internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const
virtual void transform(const ArrayView< const Tensor< 1, dim > > &input, const MappingKind kind, const typename Mapping< dim, spacedim >::InternalDataBase &internal, const ArrayView< Tensor< 1, spacedim > > &output) const override
void maybe_update_normal_vectors(const unsigned int face_no, const InternalData &data, std::vector< Tensor< 1, dim > > &normal_vectors) const
virtual std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > get_data(const UpdateFlags, const Quadrature< dim > &quadrature) const override
void maybe_update_inverse_jacobians(const InternalData &data, const CellSimilarity::Similarity cell_similarity, internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const
virtual void fill_fe_subface_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const unsigned int subface_no, const Quadrature< dim - 1 > &quadrature, const typename Mapping< dim, spacedim >::InternalDataBase &internal_data, internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const override
Abstract base class for mapping classes.
Definition: mapping.h:311
const Tensor< 1, spacedim > & normal_vector(const unsigned int i) const
Definition: point.h:111
static DataSetDescriptor cell()
Definition: qprojector.h:563
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)
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: qprojector.cc:1365
double weight(const unsigned int i) const
Definition: tensor.h:503
numbers::NumberTraits< Number >::real_type norm() const
unsigned int size() const
Definition: collection.h:264
std::vector< DerivativeForm< 1, spacedim, dim > > inverse_jacobians
void initialize(const unsigned int n_quadrature_points, const UpdateFlags flags)
Definition: fe_values.cc:2704
std::vector< Tensor< 1, spacedim > > normal_vectors
std::vector< Tensor< 5, spacedim > > jacobian_pushed_forward_3rd_derivatives
std::vector< DerivativeForm< 4, dim, spacedim > > jacobian_3rd_derivatives
std::vector< DerivativeForm< 3, dim, spacedim > > jacobian_2nd_derivatives
std::vector< Point< spacedim > > quadrature_points
std::vector< Tensor< 4, spacedim > > jacobian_pushed_forward_2nd_derivatives
std::vector< Tensor< 3, spacedim > > jacobian_pushed_forward_grads
std::vector< DerivativeForm< 2, dim, spacedim > > jacobian_grads
std::vector< Tensor< 1, spacedim > > boundary_forms
std::vector< DerivativeForm< 1, dim, spacedim > > jacobians
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:442
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:443
UpdateFlags
@ update_jacobian_pushed_forward_2nd_derivatives
@ update_volume_elements
Determinant of the Jacobian.
@ update_contravariant_transformation
Contravariant transformation.
@ update_jacobian_pushed_forward_grads
@ update_jacobian_3rd_derivatives
@ update_jacobian_grads
Gradient of volume element.
@ update_normal_vectors
Normal vectors.
@ update_JxW_values
Transformed quadrature weights.
@ update_covariant_transformation
Covariant transformation.
@ update_jacobians
Volume element.
@ update_inverse_jacobians
Volume element.
@ update_quadrature_points
Transformed quadrature points.
@ update_default
No update.
@ update_jacobian_pushed_forward_3rd_derivatives
@ update_boundary_forms
Outer normal vector, not normalized.
@ update_jacobian_2nd_derivatives
static ::ExceptionBase & ExcCellNotCartesian()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
Definition: exceptions.h:1473
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1667
#define AssertIndexRange(index, range)
Definition: exceptions.h:1732
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:487
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
MappingKind
Definition: mapping.h:72
@ mapping_piola
Definition: mapping.h:107
@ mapping_covariant_gradient
Definition: mapping.h:93
@ mapping_covariant
Definition: mapping.h:82
@ mapping_contravariant
Definition: mapping.h:87
@ mapping_contravariant_hessian
Definition: mapping.h:149
@ mapping_covariant_hessian
Definition: mapping.h:143
@ mapping_contravariant_gradient
Definition: mapping.h:99
@ mapping_piola_gradient
Definition: mapping.h:113
@ mapping_piola_hessian
Definition: mapping.h:155
bool is_cartesian(const CellType &cell)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:482
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)