deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\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_info.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2022 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13
14#ifndef dealii_non_matching_mapping_info_h
15#define dealii_non_matching_mapping_info_h
16
17
18#include <deal.II/base/config.h>
19
24
25#include <deal.II/fe/fe_dgq.h>
27#include <deal.II/fe/mapping.h>
31
33
34#include <memory>
35
36
38
39namespace NonMatching
40{
41 namespace internal
42 {
43 template <int dim, int spacedim = dim>
45 {
48 spacedim>;
49
50 public:
51 static UpdateFlags
53 const ObserverPointer<const Mapping<dim, spacedim>> &mapping,
54 const UpdateFlags &update_flags)
55 {
56 return mapping->requires_update_flags(update_flags);
57 }
58
59 static void
61 const ObserverPointer<const Mapping<dim, spacedim>> &mapping,
62 const UpdateFlags &update_flags_mapping,
64 const Quadrature<dim> &quadrature,
65 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
66 &internal_mapping_data,
67 MappingData &mapping_data)
68 {
69 mapping_data.initialize(quadrature.size(), update_flags_mapping);
70 internal_mapping_data->reinit(update_flags_mapping, quadrature);
71
72 // Since the points passed to the function will in general vary from
73 // one call to the next, do not detect any cell similarity that aims
74 // to avoid some computations of metric terms.
75 mapping->fill_fe_values(cell,
77 quadrature,
78 *internal_mapping_data,
79 mapping_data);
80 }
81
82
83
84 static void
86 const ObserverPointer<const Mapping<dim, spacedim>> &mapping,
87 const UpdateFlags &update_flags_mapping,
89 const ImmersedSurfaceQuadrature<dim> &quadrature,
90 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
91 &internal_mapping_data,
92 MappingData &mapping_data)
93 {
94 mapping_data.initialize(quadrature.size(), update_flags_mapping);
95
96 internal_mapping_data->reinit(update_flags_mapping, quadrature);
97
98 mapping->fill_fe_immersed_surface_values(cell,
99 quadrature,
100 *internal_mapping_data,
101 mapping_data);
102 }
103
104
105
106 static void
108 const ObserverPointer<const Mapping<dim, spacedim>> &mapping,
109 const UpdateFlags &update_flags_mapping,
111 const unsigned int face_no,
112 const Quadrature<dim - 1> &quadrature,
113 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
114 &internal_mapping_data,
115 MappingData &mapping_data)
116 {
117 mapping_data.initialize(quadrature.size(), update_flags_mapping);
118
119 // reuse internal_mapping_data for MappingQ to avoid memory allocations
120 if (const MappingQ<dim, spacedim> *mapping_q =
121 dynamic_cast<const MappingQ<dim, spacedim> *>(&(*mapping)))
122 {
123 auto &data =
124 dynamic_cast<typename MappingQ<dim, spacedim>::InternalData &>(
125 *internal_mapping_data);
126 data.initialize_face(update_flags_mapping,
128 cell->reference_cell(),
129 quadrature,
130 face_no,
131 cell->combined_face_orientation(face_no)),
132 quadrature.size());
133
134 mapping_q->fill_mapping_data_for_face_quadrature(
135 cell, face_no, quadrature, *internal_mapping_data, mapping_data);
136 }
137 else
138 {
139 auto internal_mapping_data =
140 mapping->get_face_data(update_flags_mapping,
141 hp::QCollection<dim - 1>(quadrature));
142
143 mapping->fill_fe_face_values(cell,
144 face_no,
145 hp::QCollection<dim - 1>(quadrature),
146 *internal_mapping_data,
147 mapping_data);
148 }
149 }
150 };
151
152 template <int dim, int spacedim = dim>
155 const double diameter,
157 &inverse_jacobians)
158 {
159 const auto jac_0 = inverse_jacobians[0];
160 const double zero_tolerance_double =
161 1e4 / diameter * std::numeric_limits<double>::epsilon() * 1024.;
162 bool jacobian_constant = true;
163 for (unsigned int q = 1; q < inverse_jacobians.size(); ++q)
164 {
165 const DerivativeForm<1, spacedim, dim> &jac = inverse_jacobians[q];
166 for (unsigned int d = 0; d < dim; ++d)
167 for (unsigned int e = 0; e < spacedim; ++e)
168 if (std::fabs(jac_0[d][e] - jac[d][e]) > zero_tolerance_double)
169 jacobian_constant = false;
170 if (!jacobian_constant)
171 break;
172 }
173
174 // check whether the Jacobian is diagonal to machine
175 // accuracy
176 bool cell_cartesian = jacobian_constant && dim == spacedim;
177 for (unsigned int d = 0; d < dim; ++d)
178 for (unsigned int e = 0; e < dim; ++e)
179 if (d != e)
180 if (std::fabs(jac_0[d][e]) > zero_tolerance_double)
181 {
182 cell_cartesian = false;
183 break;
184 }
185
186 // return cell type
187 if (cell_cartesian)
188 return ::internal::MatrixFreeFunctions::GeometryType::cartesian;
189 else if (jacobian_constant)
190 return ::internal::MatrixFreeFunctions::GeometryType::affine;
191 else
192 return ::internal::MatrixFreeFunctions::GeometryType::general;
193 }
194 } // namespace internal
195
218 template <int dim, int spacedim = dim, typename Number = double>
220 {
221 public:
225 using VectorizedArrayType = typename ::internal::VectorizedArrayTrait<
226 Number>::vectorized_value_type;
227
233 {
238 const bool store_cells = false)
241 {}
242
249
258 };
259
274 const AdditionalData additional_data = AdditionalData());
275
279 MappingInfo(const MappingInfo &) = delete;
280
285 operator=(const MappingInfo &) = delete;
286
291 void
293 const std::vector<Point<dim>> &unit_points);
294
299 void
301 const ArrayView<const Point<dim>> &unit_points);
302
308 void
311
322 template <typename ContainerType>
323 void
325 const ContainerType &cell_iterator_range,
326 const std::vector<std::vector<Point<dim>>> &unit_points_vector,
327 const unsigned int n_unfiltered_cells = numbers::invalid_unsigned_int);
328
335 template <typename ContainerType>
336 void
338 const ContainerType &cell_iterator_range,
339 const std::vector<Quadrature<dim>> &quadrature_vector,
340 const unsigned int n_unfiltered_cells = numbers::invalid_unsigned_int);
341
346 template <typename ContainerType>
347 void
349 const ContainerType &cell_iterator_range,
350 const std::vector<ImmersedSurfaceQuadrature<dim>> &quadrature_vector,
351 const unsigned int n_unfiltered_cells = numbers::invalid_unsigned_int);
352
357 template <typename ContainerType>
358 void
360 const ContainerType &cell_iterator_range,
361 const std::vector<std::vector<Quadrature<dim - 1>>> &quadrature_vector,
362 const unsigned int n_unfiltered_cells = numbers::invalid_unsigned_int);
363
368 template <typename CellIteratorType>
369 void
370 reinit_faces(const std::vector<std::pair<CellIteratorType, unsigned int>>
371 &face_iterator_range_interior,
372 const std::vector<Quadrature<dim - 1>> &quadrature_vector);
373
378 bool
380
384 unsigned int
385 get_face_number(const unsigned int offset, const bool is_interior) const;
386
392 get_unit_point(const unsigned int offset) const;
393
398 const Point<dim - 1, VectorizedArrayType> *
399 get_unit_point_faces(const unsigned int offset) const;
400
406 get_jacobian(const unsigned int offset,
407 const bool is_interior = true) const;
408
414 get_inverse_jacobian(const unsigned int offset,
415 const bool is_interior = true) const;
416
422 get_normal_vector(const unsigned int offset) const;
423
428 const Number *
429 get_JxW(const unsigned int offset) const;
430
436 get_real_point(const unsigned int offset) const;
437
442 get_mapping() const;
443
449
455
459 template <bool is_face>
460 unsigned int
462 const unsigned int face_number) const;
463
467 unsigned int
468 compute_unit_point_index_offset(const unsigned int geometry_index) const;
469
473 unsigned int
474 compute_data_index_offset(const unsigned int geometry_index) const;
475
479 unsigned int
481 const unsigned int geometry_index) const;
482
486 unsigned int
487 get_n_q_points_unvectorized(const unsigned int geometry_index) const;
488
493 get_cell_type(const unsigned int geometry_index) const;
494
501 get_cell_iterator(const unsigned int cell_index) const;
502
506 std::size_t
508
509 private:
512 spacedim>;
513
517 template <typename NumberType>
518 unsigned int
520
524 void
526
530 void
531 resize_unit_points(const unsigned int n_unit_point_batches);
532
536 void
537 resize_unit_points_faces(const unsigned int n_unit_point_batches);
538
542 void
543 resize_data_fields(const unsigned int n_data_point_batches,
544 const bool is_face_centric = false);
545
549 void
550 store_unit_points(const unsigned int unit_points_index_offset,
551 const unsigned int n_q_points,
552 const unsigned int n_q_points_unvectorized,
553 const std::vector<Point<dim>> &points);
554
558 void
559 store_unit_points_faces(const unsigned int unit_points_index_offset,
560 const unsigned int n_q_points,
561 const unsigned int n_q_points_unvectorized,
562 const std::vector<Point<dim - 1>> &points);
563
567 void
568 store_mapping_data(const unsigned int unit_points_index_offset,
569 const unsigned int n_q_points,
570 const unsigned int n_q_points_unvectorized,
572 const std::vector<double> &weights,
573 const unsigned int compressed_unit_point_index_offset,
574 const bool affine_cell,
575 const bool is_interior = true);
576
580 unsigned int
581 compute_compressed_cell_index(const unsigned int cell_index) const;
582
586 template <typename ContainerType, typename QuadratureType>
587 void
589 const ContainerType &cell_iterator_range,
590 const std::vector<QuadratureType> &quadrature_vector,
591 const unsigned int n_unfiltered_cells,
592 const std::function<
593 void(const typename Triangulation<dim, spacedim>::cell_iterator &cell,
594 const QuadratureType &quadrature,
595 MappingData &mapping_data)> &compute_mapping_data);
596
600 enum class State
601 {
602 invalid,
607 };
608
614
621
628
632 std::vector<unsigned int> unit_points_index;
633
637 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
639
644
651
656
661
666
671
678 std::vector<::internal::MatrixFreeFunctions::GeometryType> cell_type;
679
683 std::vector<unsigned int> data_index_offsets;
684
688 std::vector<unsigned int> compressed_data_index_offsets;
689
697
704
711 std::array<AlignedVector<DerivativeForm<1, dim, spacedim, Number>>, 2>
713
721 std::array<AlignedVector<DerivativeForm<1, spacedim, dim, Number>>, 2>
723
730
734 std::vector<unsigned int> n_q_points_unvectorized;
735
740 std::vector<unsigned int> cell_index_offset;
741
746 std::vector<unsigned int> cell_index_to_compressed_cell_index;
747
752
759
764 std::vector<std::pair<int, int>> cell_level_and_indices;
765
770 std::vector<std::pair<unsigned char, unsigned char>> face_number;
771 };
772
773 template <int dim, int spacedim, typename Number>
774 inline unsigned int
776 const unsigned int offset,
777 const bool is_interior) const
778 {
779 const auto &face_pair = face_number[offset];
780 return is_interior ? face_pair.first : face_pair.second;
781 }
782
783 // ----------------------- template functions ----------------------
784
785
786 template <int dim, int spacedim, typename Number>
788 const Mapping<dim, spacedim> &mapping,
789 const UpdateFlags update_flags,
790 const AdditionalData additional_data)
791 : mapping(&mapping)
792 , update_flags(update_flags)
793 , update_flags_mapping(update_default)
794 , additional_data(additional_data)
795 {
796 // translate update flags
806
807 // always save quadrature points for now
809
812 this->mapping, update_flags_mapping);
813
814 // construct internal_mapping_data for mappings for reuse in reinit()
815 // calls to avoid frequent memory allocations
817 }
818
819
820
821 template <int dim, int spacedim, typename Number>
822 void
824 {
825 n_q_points_unvectorized.clear();
826 unit_points_index.clear();
827 data_index_offsets.clear();
828 compressed_data_index_offsets.clear();
829 cell_type.clear();
830 }
831
832
833
834 template <int dim, int spacedim, typename Number>
835 void
838 const std::vector<Point<dim>> &unit_points_in)
839 {
840 reinit(cell, make_array_view(unit_points_in));
841 }
842
843
844
845 template <int dim, int spacedim, typename Number>
846 void
849 const ArrayView<const Point<dim>> &unit_points_in)
850 {
851 quadrature.initialize(unit_points_in);
852 reinit(cell, quadrature);
853 }
854
855
856
857 template <int dim, int spacedim, typename Number>
858 void
861 const Quadrature<dim> &quadrature)
862 {
863 n_q_points_unvectorized.resize(1);
864 n_q_points_unvectorized[0] = quadrature.size();
865
866 const unsigned int n_q_points =
867 compute_n_q_points<VectorizedArrayType>(n_q_points_unvectorized[0]);
868
869 const unsigned int n_q_points_data =
870 compute_n_q_points<Number>(n_q_points_unvectorized[0]);
871
872 // resize data vectors
873 resize_unit_points(n_q_points);
874 resize_data_fields(n_q_points_data);
875
876 // store unit points
877 store_unit_points(0,
878 n_q_points,
879 n_q_points_unvectorized[0],
880 quadrature.get_points());
881
882 // compute mapping data
885 update_flags_mapping,
886 cell,
887 quadrature,
888 internal_mapping_data,
889 mapping_data);
890
891 // Since with this reinit() function there is no storage of the mapping
892 // data beyond the present call, do not try to check for cell types (as
893 // that would be costly) but simply assume the cell to be of general type.
895
896 // store mapping data
897 store_mapping_data(
898 0,
899 n_q_points_data,
900 n_q_points_unvectorized[0],
901 mapping_data,
902 quadrature.get_weights(),
903 0,
904 cell_type.back() <=
906
907 unit_points_index = {0};
908 data_index_offsets = {0};
909 compressed_data_index_offsets = {0};
910
911 state = State::single_cell;
912 }
913
914
915
916 template <int dim, int spacedim, typename Number>
917 template <typename ContainerType>
918 void
920 const ContainerType &cell_iterator_range,
921 const std::vector<std::vector<Point<dim>>> &unit_points_vector,
922 const unsigned int n_unfiltered_cells)
923 {
924 const unsigned int n_cells = unit_points_vector.size();
925 AssertDimension(n_cells,
926 std::distance(cell_iterator_range.begin(),
927 cell_iterator_range.end()));
928
929 std::vector<Quadrature<dim>> quadrature_vector(n_cells);
930 for (unsigned int cell_index = 0; cell_index < n_cells; ++cell_index)
931 quadrature_vector[cell_index] =
932 Quadrature<dim>(unit_points_vector[cell_index]);
933
934 reinit_cells(cell_iterator_range, quadrature_vector, n_unfiltered_cells);
935 }
936
937
938
939 template <int dim, int spacedim, typename Number>
940 template <typename ContainerType, typename QuadratureType>
941 void
943 const ContainerType &cell_iterator_range,
944 const std::vector<QuadratureType> &quadrature_vector,
945 const unsigned int n_unfiltered_cells,
946 const std::function<
947 void(const typename Triangulation<dim, spacedim>::cell_iterator &cell,
948 const QuadratureType &quadrature,
949 MappingData &mapping_data)> &compute_mapping_data)
950 {
951 clear();
952
953 do_cell_index_compression =
954 n_unfiltered_cells != numbers::invalid_unsigned_int;
955
956 const unsigned int n_cells = quadrature_vector.size();
957 AssertDimension(n_cells,
958 std::distance(cell_iterator_range.begin(),
959 cell_iterator_range.end()));
960
961 n_q_points_unvectorized.reserve(n_cells);
962
963 cell_type.reserve(n_cells);
964
965 if (additional_data.store_cells)
966 cell_level_and_indices.resize(n_cells);
967
968 // fill unit points index offset vector
969 unit_points_index.reserve(n_cells + 1);
970 unit_points_index.push_back(0);
971 data_index_offsets.reserve(n_cells + 1);
972 data_index_offsets.push_back(0);
973 for (const auto &quadrature : quadrature_vector)
974 {
975 const unsigned int n_points = quadrature.size();
976 n_q_points_unvectorized.push_back(n_points);
977
978 const unsigned int n_q_points =
979 compute_n_q_points<VectorizedArrayType>(n_points);
980 unit_points_index.push_back(unit_points_index.back() + n_q_points);
981
982 const unsigned int n_q_points_data =
983 compute_n_q_points<Number>(n_points);
984 data_index_offsets.push_back(data_index_offsets.back() +
985 n_q_points_data);
986 }
987
988 const unsigned int n_unit_points = unit_points_index.back();
989 const unsigned int n_data_points = data_index_offsets.back();
990
991 // resize data vectors
992 resize_unit_points(n_unit_points);
993 resize_data_fields(n_data_points);
994
995 if (do_cell_index_compression)
996 cell_index_to_compressed_cell_index.resize(n_unfiltered_cells,
998
999 MappingData mapping_data_previous_cell;
1000 unsigned int size_compressed_data = 0;
1001 unsigned int cell_index = 0;
1002 for (const auto &cell : cell_iterator_range)
1003 {
1004 if (additional_data.store_cells)
1005 {
1006 this->triangulation = &cell->get_triangulation();
1007 cell_level_and_indices[cell_index] = {cell->level(), cell->index()};
1008 }
1009
1010 const auto &quadrature = quadrature_vector[cell_index];
1011 const bool empty = quadrature.empty();
1012
1013 // store unit points
1014 const unsigned int n_q_points = compute_n_q_points<VectorizedArrayType>(
1015 n_q_points_unvectorized[cell_index]);
1016 store_unit_points(unit_points_index[cell_index],
1017 n_q_points,
1018 n_q_points_unvectorized[cell_index],
1019 quadrature.get_points());
1020
1021 // compute mapping data
1022 compute_mapping_data(cell, quadrature, mapping_data);
1023
1024 // store mapping data
1025 const unsigned int n_q_points_data =
1026 compute_n_q_points<Number>(n_q_points_unvectorized[cell_index]);
1027
1028 // check for cartesian/affine cell
1029 if (!empty &&
1030 update_flags_mapping & UpdateFlags::update_inverse_jacobians)
1031 {
1032 cell_type.push_back(
1033 internal::compute_geometry_type(cell->diameter(),
1034 mapping_data.inverse_jacobians));
1035 }
1036 else
1037 cell_type.push_back(
1039
1040 if (cell_index > 0)
1041 {
1042 // check if current and previous cell are affine
1043 const bool affine_cells =
1044 cell_type[cell_index] <=
1046 cell_type[cell_index - 1] <=
1048
1049 // create a comparator to compare inverse Jacobian of current
1050 // and previous cell
1052 1e4 / cell->diameter() * std::numeric_limits<double>::epsilon() *
1053 1024.);
1054
1055 // we can only compare if current and previous cell have at least
1056 // one quadrature point and both cells are at least affine
1057 const auto comparison_result =
1058 (!affine_cells || mapping_data.inverse_jacobians.empty() ||
1059 mapping_data_previous_cell.inverse_jacobians.empty()) ?
1061 comparator.compare(
1062 mapping_data.inverse_jacobians[0],
1063 mapping_data_previous_cell.inverse_jacobians[0]);
1064
1065 // we can compress the Jacobians and inverse Jacobians if
1066 // inverse Jacobians are equal and cells are affine
1067 if (affine_cells &&
1068 comparison_result ==
1070 {
1071 compressed_data_index_offsets.push_back(
1072 compressed_data_index_offsets.back());
1073 }
1074 else
1075 {
1076 const unsigned int n_compressed_data_last_cell =
1077 cell_type[cell_index - 1] <=
1079 1 :
1080 compute_n_q_points<Number>(
1081 n_q_points_unvectorized[cell_index - 1]);
1082
1083 compressed_data_index_offsets.push_back(
1084 compressed_data_index_offsets.back() +
1085 n_compressed_data_last_cell);
1086 }
1087 }
1088 else
1089 compressed_data_index_offsets.push_back(0);
1090
1091 // cache mapping_data from previous cell
1092 mapping_data_previous_cell = mapping_data;
1093
1094 store_mapping_data(data_index_offsets[cell_index],
1095 n_q_points_data,
1096 n_q_points_unvectorized[cell_index],
1097 mapping_data,
1098 quadrature.get_weights(),
1099 compressed_data_index_offsets[cell_index],
1100 cell_type[cell_index] <=
1102
1103 // update size of compressed data depending on cell type and handle
1104 // empty quadratures
1105 if (cell_type[cell_index] <=
1107 size_compressed_data = compressed_data_index_offsets.back() + 1;
1108 else
1109 size_compressed_data =
1110 std::max(size_compressed_data,
1111 compressed_data_index_offsets.back() + n_q_points_data);
1112
1113 if (do_cell_index_compression)
1114 cell_index_to_compressed_cell_index[cell->active_cell_index()] =
1115 cell_index;
1116
1117 ++cell_index;
1118 }
1119
1120 if (update_flags_mapping & UpdateFlags::update_jacobians)
1121 {
1122 jacobians[0].resize(size_compressed_data);
1123 jacobians[0].shrink_to_fit();
1124 }
1125 if (update_flags_mapping & UpdateFlags::update_inverse_jacobians)
1126 {
1127 inverse_jacobians[0].resize(size_compressed_data);
1128 inverse_jacobians[0].shrink_to_fit();
1129 }
1130
1131 state = State::cell_vector;
1132 }
1133
1134
1135
1136 template <int dim, int spacedim, typename Number>
1137 template <typename ContainerType>
1138 void
1140 const ContainerType &cell_iterator_range,
1141 const std::vector<Quadrature<dim>> &quadrature_vector,
1142 const unsigned int n_unfiltered_cells)
1143 {
1144 auto compute_mapping_data_for_cells =
1145 [&](const typename Triangulation<dim, spacedim>::cell_iterator &cell,
1146 const Quadrature<dim> &quadrature,
1147 MappingData &mapping_data) {
1150 update_flags_mapping,
1151 cell,
1152 quadrature,
1153 internal_mapping_data,
1154 mapping_data);
1155 };
1156
1157 do_reinit_cells<ContainerType, Quadrature<dim>>(
1158 cell_iterator_range,
1159 quadrature_vector,
1160 n_unfiltered_cells,
1161 compute_mapping_data_for_cells);
1162 }
1163
1164
1165
1166 template <int dim, int spacedim, typename Number>
1167 template <typename ContainerType>
1168 void
1170 const ContainerType &cell_iterator_range,
1171 const std::vector<ImmersedSurfaceQuadrature<dim>> &quadrature_vector,
1172 const unsigned int n_unfiltered_cells)
1173 {
1174 Assert(
1175 additional_data.use_global_weights == false,
1176 ExcMessage(
1177 "There is no known use-case for AdditionalData::use_global_weights=true and reinit_surface()"));
1178
1179 Assert(additional_data.store_cells == false, ExcNotImplemented());
1180
1181 if (update_flags_mapping & (update_JxW_values | update_normal_vectors))
1182 update_flags_mapping |= update_covariant_transformation;
1183
1184 auto compute_mapping_data_for_surface =
1185 [&](const typename Triangulation<dim, spacedim>::cell_iterator &cell,
1186 const ImmersedSurfaceQuadrature<dim> &quadrature,
1187 MappingData &mapping_data) {
1190 mapping,
1191 update_flags_mapping,
1192 cell,
1193 quadrature,
1194 internal_mapping_data,
1195 mapping_data);
1196 };
1197
1198 do_reinit_cells<ContainerType, ImmersedSurfaceQuadrature<dim>>(
1199 cell_iterator_range,
1200 quadrature_vector,
1201 n_unfiltered_cells,
1202 compute_mapping_data_for_surface);
1203 }
1204
1205
1206
1207 template <int dim, int spacedim, typename Number>
1208 template <typename ContainerType>
1209 void
1211 const ContainerType &cell_iterator_range,
1212 const std::vector<std::vector<Quadrature<dim - 1>>> &quadrature_vector,
1213 const unsigned int n_unfiltered_cells)
1214 {
1215 clear();
1216
1217 Assert(additional_data.store_cells == false, ExcNotImplemented());
1218
1219 do_cell_index_compression =
1220 n_unfiltered_cells != numbers::invalid_unsigned_int;
1221
1222 const unsigned int n_cells = quadrature_vector.size();
1223 AssertDimension(n_cells,
1224 std::distance(cell_iterator_range.begin(),
1225 cell_iterator_range.end()));
1226
1227 // fill cell index offset vector
1228 cell_index_offset.resize(n_cells);
1229 unsigned int n_faces = 0;
1230 unsigned int cell_index = 0;
1231 for (const auto &cell : cell_iterator_range)
1232 {
1233 cell_index_offset[cell_index] = n_faces;
1234 n_faces += cell->n_faces();
1235 ++cell_index;
1236 }
1237
1238 n_q_points_unvectorized.reserve(n_faces);
1239
1240 cell_type.reserve(n_faces);
1241
1242 // fill unit points index offset vector
1243 unit_points_index.resize(n_faces + 1);
1244 data_index_offsets.resize(n_faces + 1);
1245 cell_index = 0;
1246 unsigned int n_unit_points = 0;
1247 unsigned int n_data_points = 0;
1248 for (const auto &cell : cell_iterator_range)
1249 {
1250 for (const auto &f : cell->face_indices())
1251 {
1252 const unsigned int current_face_index =
1253 cell_index_offset[cell_index] + f;
1254
1255 unit_points_index[current_face_index] = n_unit_points;
1256 data_index_offsets[current_face_index] = n_data_points;
1257
1258 const unsigned int n_points =
1259 quadrature_vector[cell_index][f].size();
1260 n_q_points_unvectorized.push_back(n_points);
1261
1262 const unsigned int n_q_points =
1263 compute_n_q_points<VectorizedArrayType>(n_points);
1264 n_unit_points += n_q_points;
1265
1266 const unsigned int n_q_points_data =
1267 compute_n_q_points<Number>(n_points);
1268 n_data_points += n_q_points_data;
1269 }
1270
1271 ++cell_index;
1272 }
1273 unit_points_index[n_faces] = n_unit_points;
1274 data_index_offsets[n_faces] = n_data_points;
1275
1276 // compress indices
1277 if (do_cell_index_compression)
1278 cell_index_to_compressed_cell_index.resize(n_unfiltered_cells,
1280
1281 // fill unit points and mapping data for every face of all cells
1282 // resize data vectors
1283 resize_unit_points_faces(n_unit_points);
1284 resize_data_fields(n_data_points);
1285
1286 MappingData mapping_data_previous_cell;
1287 MappingData mapping_data_first;
1288 bool first_set = false;
1289 unsigned int size_compressed_data = 0;
1290 cell_index = 0;
1291 for (const auto &cell : cell_iterator_range)
1292 {
1293 const auto &quadratures_on_faces = quadrature_vector[cell_index];
1294
1295 Assert(quadratures_on_faces.size() == cell->n_faces(),
1296 ExcDimensionMismatch(quadratures_on_faces.size(),
1297 cell->n_faces()));
1298
1299 for (const auto &f : cell->face_indices())
1300 {
1301 const auto &quadrature_on_face = quadratures_on_faces[f];
1302 const bool empty = quadrature_on_face.empty();
1303
1304 const unsigned int current_face_index =
1305 cell_index_offset[cell_index] + f;
1306
1307 // store unit points
1308 const unsigned int n_q_points =
1309 compute_n_q_points<VectorizedArrayType>(
1310 n_q_points_unvectorized[current_face_index]);
1311 store_unit_points_faces(unit_points_index[current_face_index],
1312 n_q_points,
1313 n_q_points_unvectorized[current_face_index],
1314 quadrature_on_face.get_points());
1315
1318 update_flags_mapping,
1319 cell,
1320 f,
1321 quadrature_on_face,
1322 internal_mapping_data,
1323 mapping_data);
1324
1325 // check for cartesian/affine cell
1326 if (!empty &&
1327 update_flags_mapping & UpdateFlags::update_inverse_jacobians)
1328 {
1329 cell_type.push_back(internal::compute_geometry_type(
1330 cell->diameter(), mapping_data.inverse_jacobians));
1331
1332 if (!first_set)
1333 {
1334 mapping_data_first = mapping_data;
1335 first_set = true;
1336 }
1337 }
1338 else
1339 cell_type.push_back(
1341
1342 if (current_face_index > 0)
1343 {
1344 // check if current and previous cell are affine
1345 const bool affine_cells =
1346 cell_type[current_face_index] <=
1348 cell_type[current_face_index - 1] <=
1350
1351 // create a comparator to compare inverse Jacobian of current
1352 // and previous cell
1354 1e4 / cell->diameter() *
1355 std::numeric_limits<double>::epsilon() * 1024.);
1356
1357 // we can only compare if current and previous cell have at
1358 // least one quadrature point and both cells are at least affine
1359 const auto comparison_result =
1360 (!affine_cells || mapping_data.inverse_jacobians.empty() ||
1361 mapping_data_previous_cell.inverse_jacobians.empty()) ?
1363 comparator.compare(
1364 mapping_data.inverse_jacobians[0],
1365 mapping_data_previous_cell.inverse_jacobians[0]);
1366
1367 // we can compress the Jacobians and inverse Jacobians if
1368 // inverse Jacobians are equal and cells are affine
1369 if (affine_cells &&
1370 comparison_result ==
1372 {
1373 compressed_data_index_offsets.push_back(
1374 compressed_data_index_offsets.back());
1375 }
1376 else if (first_set &&
1377 (cell_type[current_face_index] <=
1379 (comparator.compare(
1380 mapping_data.inverse_jacobians[0],
1381 mapping_data_first.inverse_jacobians[0]) ==
1383 double>::ComparisonResult::equal))
1384 {
1385 compressed_data_index_offsets.push_back(0);
1386 }
1387 else
1388 {
1389 const unsigned int n_compressed_data_last_cell =
1390 cell_type[current_face_index - 1] <=
1392 1 :
1393 compute_n_q_points<Number>(
1394 n_q_points_unvectorized[current_face_index - 1]);
1395
1396 compressed_data_index_offsets.push_back(
1397 compressed_data_index_offsets.back() +
1398 n_compressed_data_last_cell);
1399 }
1400 }
1401 else
1402 compressed_data_index_offsets.push_back(0);
1403
1404 // cache mapping_data from previous cell
1405 mapping_data_previous_cell = mapping_data;
1406
1407 const unsigned int n_q_points_data = compute_n_q_points<Number>(
1408 n_q_points_unvectorized[current_face_index]);
1409 store_mapping_data(data_index_offsets[current_face_index],
1410 n_q_points_data,
1411 n_q_points_unvectorized[current_face_index],
1412 mapping_data,
1413 quadrature_on_face.get_weights(),
1414 data_index_offsets[current_face_index],
1415 cell_type[current_face_index] <=
1417
1418 // update size of compressed data depending on cell type and handle
1419 // empty quadratures
1420 if (cell_type[current_face_index] <=
1422 size_compressed_data = compressed_data_index_offsets.back() + 1;
1423 else
1424 size_compressed_data =
1425 std::max(size_compressed_data,
1426 compressed_data_index_offsets.back() +
1427 n_q_points_data);
1428 }
1429 if (do_cell_index_compression)
1430 cell_index_to_compressed_cell_index[cell->active_cell_index()] =
1431 cell_index;
1432
1433 ++cell_index;
1434 }
1435
1436 if (update_flags_mapping & UpdateFlags::update_jacobians)
1437 {
1438 jacobians[0].resize(size_compressed_data);
1439 jacobians[0].shrink_to_fit();
1440 }
1441 if (update_flags_mapping & UpdateFlags::update_inverse_jacobians)
1442 {
1443 inverse_jacobians[0].resize(size_compressed_data);
1444 inverse_jacobians[0].shrink_to_fit();
1445 }
1446
1447 state = State::faces_on_cells_in_vector;
1448 }
1449
1450
1451
1452 template <int dim, int spacedim, typename Number>
1453 template <typename CellIteratorType>
1454 void
1456 const std::vector<std::pair<CellIteratorType, unsigned int>>
1457 &face_iterator_range_interior,
1458 const std::vector<Quadrature<dim - 1>> &quadrature_vector)
1459 {
1460 clear();
1461
1462 do_cell_index_compression = false;
1463
1464 Assert(additional_data.store_cells == false, ExcNotImplemented());
1465
1466
1467 const unsigned int n_faces = quadrature_vector.size();
1468 AssertDimension(n_faces,
1469 std::distance(face_iterator_range_interior.begin(),
1470 face_iterator_range_interior.end()));
1471
1472 n_q_points_unvectorized.reserve(n_faces);
1473
1474 cell_type.reserve(n_faces);
1475 face_number.reserve(n_faces);
1476
1477 // fill unit points index offset vector
1478 unit_points_index.reserve(n_faces + 1);
1479 unit_points_index.push_back(0);
1480 data_index_offsets.reserve(n_faces + 1);
1481 data_index_offsets.push_back(0);
1482 for (const auto &quadrature : quadrature_vector)
1483 {
1484 const unsigned int n_points = quadrature.size();
1485 n_q_points_unvectorized.push_back(n_points);
1486
1487 const unsigned int n_q_points =
1488 compute_n_q_points<VectorizedArrayType>(n_points);
1489 unit_points_index.push_back(unit_points_index.back() + n_q_points);
1490
1491 const unsigned int n_q_points_data =
1492 compute_n_q_points<Number>(n_points);
1493 data_index_offsets.push_back(data_index_offsets.back() +
1494 n_q_points_data);
1495 }
1496
1497 const unsigned int n_unit_points = unit_points_index.back();
1498 const unsigned int n_data_points = data_index_offsets.back();
1499
1500 // resize data vectors
1501 resize_unit_points_faces(n_unit_points);
1502 resize_data_fields(n_data_points, true);
1503
1504 std::array<MappingData, 2> mapping_data;
1505 std::array<MappingData, 2> mapping_data_previous_cell;
1506 std::array<MappingData, 2> mapping_data_first;
1507 bool first_set = false;
1508 unsigned int size_compressed_data = 0;
1509 unsigned int face_index = 0;
1510 for (const auto &cell_and_f : face_iterator_range_interior)
1511 {
1512 const auto &quadrature_on_face = quadrature_vector[face_index];
1513 const bool empty = quadrature_on_face.empty();
1514
1515 // get interior cell and face number
1516 const auto &cell_m = cell_and_f.first;
1517 const auto f_m = cell_and_f.second;
1518
1519 // get exterior cell and face number
1520 const auto &cell_p =
1521 cell_m->at_boundary(f_m) ? cell_m : cell_m->neighbor(f_m);
1522 const auto f_p =
1523 cell_m->at_boundary(f_m) ? f_m : cell_m->neighbor_face_no(f_m);
1524
1525 Assert(
1526 empty || (cell_m->level() == cell_p->level()),
1527 ExcMessage(
1528 "Intersected faces with quadrature points need to have the same "
1529 "refinement level!"));
1530
1531 face_number.emplace_back(f_m, f_p);
1532
1533 Assert(
1534 cell_m->combined_face_orientation(f_m) ==
1536 cell_p->combined_face_orientation(f_p) ==
1538 ExcMessage(
1539 "Non standard face orientation is currently not implemented."));
1540
1541 // store unit points
1542 const unsigned int n_q_points = compute_n_q_points<VectorizedArrayType>(
1543 n_q_points_unvectorized[face_index]);
1544 store_unit_points_faces(unit_points_index[face_index],
1545 n_q_points,
1546 n_q_points_unvectorized[face_index],
1547 quadrature_on_face.get_points());
1548
1549 // compute mapping for interior face
1552 update_flags_mapping,
1553 cell_m,
1554 f_m,
1555 quadrature_on_face,
1556 internal_mapping_data,
1557 mapping_data[0]);
1558
1559 // compute mapping for exterior face
1562 update_flags_mapping,
1563 cell_p,
1564 f_p,
1565 quadrature_on_face,
1566 internal_mapping_data,
1567 mapping_data[1]);
1568
1569 // check for cartesian/affine cell
1570 if (!empty &&
1571 update_flags_mapping & UpdateFlags::update_inverse_jacobians)
1572 {
1573 // select more general type of interior and exterior cell
1574 cell_type.push_back(std::max(
1576 cell_m->diameter(), mapping_data[0].inverse_jacobians),
1578 cell_m->diameter(), mapping_data[1].inverse_jacobians)));
1579
1580 // cache mapping data of first cell pair with non-empty quadrature
1581 // on the face
1582 if (!first_set)
1583 {
1584 mapping_data_first = mapping_data;
1585 first_set = true;
1586 }
1587 }
1588 else
1589 cell_type.push_back(
1591
1592 if (face_index > 0)
1593 {
1594 // check if current and previous cell pairs are affine
1595 const bool affine_cells =
1596 cell_type[face_index] <=
1598 cell_type[face_index - 1] <=
1600
1601 // create a comparator to compare inverse Jacobian of current
1602 // and previous cell pair
1604 1e4 / cell_m->diameter() *
1605 std::numeric_limits<double>::epsilon() * 1024.);
1606
1607 // we can only compare if current and previous cell have at
1608 // least one quadrature point and both cells are at least affine
1609 const auto comparison_result_m =
1610 (!affine_cells || mapping_data[0].inverse_jacobians.empty() ||
1611 mapping_data_previous_cell[0].inverse_jacobians.empty()) ?
1613 comparator.compare(
1614 mapping_data[0].inverse_jacobians[0],
1615 mapping_data_previous_cell[0].inverse_jacobians[0]);
1616
1617 const auto comparison_result_p =
1618 (!affine_cells || mapping_data[1].inverse_jacobians.empty() ||
1619 mapping_data_previous_cell[1].inverse_jacobians.empty()) ?
1621 comparator.compare(
1622 mapping_data[1].inverse_jacobians[0],
1623 mapping_data_previous_cell[1].inverse_jacobians[0]);
1624
1625 // we can compress the Jacobians and inverse Jacobians if
1626 // inverse Jacobians are equal and cells are affine
1627 if (affine_cells &&
1628 comparison_result_m ==
1630 comparison_result_p ==
1632 {
1633 compressed_data_index_offsets.push_back(
1634 compressed_data_index_offsets.back());
1635 }
1636 else if (first_set &&
1637 (cell_type[face_index] <=
1639 (comparator.compare(
1640 mapping_data[0].inverse_jacobians[0],
1641 mapping_data_first[0].inverse_jacobians[0]) ==
1643 double>::ComparisonResult::equal) &&
1644 (comparator.compare(
1645 mapping_data[1].inverse_jacobians[0],
1646 mapping_data_first[1].inverse_jacobians[0]) ==
1648 {
1649 compressed_data_index_offsets.push_back(0);
1650 }
1651 else
1652 {
1653 const unsigned int n_compressed_data_last_cell =
1654 cell_type[face_index - 1] <=
1656 1 :
1657 compute_n_q_points<Number>(
1658 n_q_points_unvectorized[face_index - 1]);
1659
1660 compressed_data_index_offsets.push_back(
1661 compressed_data_index_offsets.back() +
1662 n_compressed_data_last_cell);
1663 }
1664 }
1665 else
1666 compressed_data_index_offsets.push_back(0);
1667
1668 // cache mapping_data from previous cell pair
1669 mapping_data_previous_cell = mapping_data;
1670
1671 const unsigned int n_q_points_data =
1672 compute_n_q_points<Number>(n_q_points_unvectorized[face_index]);
1673
1674 // store mapping data of interior face
1675 store_mapping_data(data_index_offsets[face_index],
1676 n_q_points_data,
1677 n_q_points_unvectorized[face_index],
1678 mapping_data[0],
1679 quadrature_on_face.get_weights(),
1680 data_index_offsets[face_index],
1681 cell_type[face_index] <=
1683 true);
1684
1685 // store only necessary mapping data for exterior face (Jacobians and
1686 // inverse Jacobians)
1687 store_mapping_data(data_index_offsets[face_index],
1688 n_q_points_data,
1689 n_q_points_unvectorized[face_index],
1690 mapping_data[1],
1691 quadrature_on_face.get_weights(),
1692 data_index_offsets[face_index],
1693 cell_type[face_index] <=
1695 false);
1696
1697 // update size of compressed data depending on cell type and handle
1698 // empty quadratures
1699 if (cell_type[face_index] <=
1701 size_compressed_data = compressed_data_index_offsets.back() + 1;
1702 else
1703 size_compressed_data =
1704 std::max(size_compressed_data,
1705 compressed_data_index_offsets.back() + n_q_points_data);
1706
1707 ++face_index;
1708 }
1709
1710 if (update_flags_mapping & UpdateFlags::update_jacobians)
1711 {
1712 jacobians[0].resize(size_compressed_data);
1713 jacobians[0].shrink_to_fit();
1714 jacobians[1].resize(size_compressed_data);
1715 jacobians[1].shrink_to_fit();
1716 }
1717 if (update_flags_mapping & UpdateFlags::update_inverse_jacobians)
1718 {
1719 inverse_jacobians[0].resize(size_compressed_data);
1720 inverse_jacobians[0].shrink_to_fit();
1721 inverse_jacobians[1].resize(size_compressed_data);
1722 inverse_jacobians[1].shrink_to_fit();
1723 }
1724
1725 state = State::face_vector;
1726 }
1727
1728
1729
1730 template <int dim, int spacedim, typename Number>
1731 bool
1733 {
1734 return state == State::faces_on_cells_in_vector;
1735 }
1736
1737
1738
1739 template <int dim, int spacedim, typename Number>
1740 unsigned int
1742 const unsigned int geometry_index) const
1743 {
1744 return n_q_points_unvectorized[geometry_index];
1745 }
1746
1747
1748 template <int dim, int spacedim, typename Number>
1751 const unsigned int geometry_index) const
1752 {
1753 AssertIndexRange(geometry_index, cell_type.size());
1754 return cell_type[geometry_index];
1755 }
1756
1757
1758
1759 template <int dim, int spacedim, typename Number>
1762 const unsigned int cell_index) const
1763 {
1764 Assert(
1765 additional_data.store_cells,
1766 ExcMessage(
1767 "Cells have been not stored. You can enable this by Additional::store_cells."));
1768 return {triangulation.get(),
1769 cell_level_and_indices[cell_index].first,
1770 cell_level_and_indices[cell_index].second};
1771 }
1772
1773
1774
1775 template <int dim, int spacedim, typename Number>
1776 template <typename NumberType>
1777 unsigned int
1779 const unsigned int n_q_points_unvectorized)
1780 {
1781 const unsigned int n_lanes =
1783 const unsigned int n_filled_lanes_last_batch =
1784 n_q_points_unvectorized % n_lanes;
1785 unsigned int n_q_points = n_q_points_unvectorized / n_lanes;
1786 if (n_filled_lanes_last_batch > 0)
1787 ++n_q_points;
1788 return n_q_points;
1789 }
1790
1791
1792
1793 template <int dim, int spacedim, typename Number>
1794 template <bool is_face>
1795 unsigned int
1797 const unsigned int cell_index,
1798 const unsigned int face_number) const
1799 {
1801 return 0;
1802
1803 const unsigned int compressed_cell_index =
1804 compute_compressed_cell_index(cell_index);
1805 if (!is_face)
1806 {
1807 Assert(state == State::cell_vector,
1808 ExcMessage(
1809 "This mapping info is not reinitialized for a cell vector!"));
1810 return compressed_cell_index;
1811 }
1812 else
1813 {
1815 ExcMessage(
1816 "cell_index has to be set if face_number is specified!"));
1817 Assert(state == State::faces_on_cells_in_vector ||
1818 state == State::face_vector,
1819 ExcMessage("This mapping info is not reinitialized for faces"
1820 " on cells in a vector!"));
1821 if (state == State::faces_on_cells_in_vector)
1822 return cell_index_offset[compressed_cell_index] + face_number;
1823 else if (state == State::face_vector)
1824 return cell_index;
1825 }
1826 }
1827
1828
1829
1830 template <int dim, int spacedim, typename Number>
1831 unsigned int
1833 const unsigned int cell_index) const
1834 {
1835 if (do_cell_index_compression)
1836 {
1837 Assert(cell_index_to_compressed_cell_index[cell_index] !=
1839 ExcMessage("Mapping info object was not initialized for this"
1840 " active cell index!"));
1841 return cell_index_to_compressed_cell_index[cell_index];
1842 }
1843 else
1844 return cell_index;
1845 }
1846
1847
1848 template <int dim, int spacedim, typename Number>
1849 void
1851 const unsigned int unit_points_index_offset,
1852 const unsigned int n_q_points,
1853 const unsigned int n_q_points_unvectorized,
1854 const std::vector<Point<dim>> &points)
1855 {
1856 const unsigned int n_lanes =
1858
1859 for (unsigned int q = 0; q < n_q_points; ++q)
1860 {
1861 const unsigned int offset = unit_points_index_offset + q;
1862 for (unsigned int v = 0;
1863 v < n_lanes && q * n_lanes + v < n_q_points_unvectorized;
1864 ++v)
1865 for (unsigned int d = 0; d < dim; ++d)
1867 unit_points[offset][d], v) = points[q * n_lanes + v][d];
1868 }
1869 }
1870
1871
1872
1873 template <int dim, int spacedim, typename Number>
1874 void
1876 const unsigned int unit_points_index_offset,
1877 const unsigned int n_q_points,
1878 const unsigned int n_q_points_unvectorized,
1879 const std::vector<Point<dim - 1>> &points)
1880 {
1881 const unsigned int n_lanes =
1883
1884 for (unsigned int q = 0; q < n_q_points; ++q)
1885 {
1886 const unsigned int offset = unit_points_index_offset + q;
1887 for (unsigned int v = 0;
1888 v < n_lanes && q * n_lanes + v < n_q_points_unvectorized;
1889 ++v)
1890 for (unsigned int d = 0; d < dim - 1; ++d)
1892 unit_points_faces[offset][d], v) = points[q * n_lanes + v][d];
1893 }
1894 }
1895
1896
1897
1898 template <int dim, int spacedim, typename Number>
1899 void
1901 const unsigned int unit_points_index_offset,
1902 const unsigned int n_q_points,
1903 const unsigned int n_q_points_unvectorized,
1904 const MappingInfo::MappingData &mapping_data,
1905 const std::vector<double> &weights,
1906 const unsigned int compressed_unit_point_index_offset,
1907 const bool affine_cell,
1908 const bool is_interior)
1909 {
1910 const unsigned int n_lanes =
1912
1913 for (unsigned int q = 0; q < n_q_points; ++q)
1914 {
1915 const unsigned int offset = unit_points_index_offset + q;
1916 const unsigned int compressed_offset =
1917 compressed_unit_point_index_offset + q;
1918 for (unsigned int v = 0;
1919 v < n_lanes && q * n_lanes + v < n_q_points_unvectorized;
1920 ++v)
1921 {
1922 if (q == 0 || !affine_cell)
1923 {
1924 if (update_flags_mapping & UpdateFlags::update_jacobians)
1925 for (unsigned int d = 0; d < dim; ++d)
1926 for (unsigned int s = 0; s < spacedim; ++s)
1928 jacobians[is_interior ? 0 : 1][compressed_offset][d][s],
1929 v) = mapping_data.jacobians[q * n_lanes + v][d][s];
1930 if (update_flags_mapping &
1932 for (unsigned int d = 0; d < dim; ++d)
1933 for (unsigned int s = 0; s < spacedim; ++s)
1935 inverse_jacobians[is_interior ? 0 : 1]
1936 [compressed_offset][d][s],
1937 v) =
1938 mapping_data.inverse_jacobians[q * n_lanes + v][d][s];
1939 }
1940
1941 if (is_interior)
1942 {
1943 if (update_flags_mapping & UpdateFlags::update_JxW_values)
1944 {
1945 if (additional_data.use_global_weights)
1946 {
1948 JxW_values[offset], v) = weights[q * n_lanes + v];
1949 }
1950 else
1951 {
1953 JxW_values[offset], v) =
1954 mapping_data.JxW_values[q * n_lanes + v];
1955 }
1956 }
1957 if (update_flags_mapping & UpdateFlags::update_normal_vectors)
1958 for (unsigned int s = 0; s < spacedim; ++s)
1960 normal_vectors[offset][s], v) =
1961 mapping_data.normal_vectors[q * n_lanes + v][s];
1962 if (update_flags_mapping &
1964 for (unsigned int s = 0; s < spacedim; ++s)
1966 real_points[offset][s], v) =
1967 mapping_data.quadrature_points[q * n_lanes + v][s];
1968 }
1969 }
1970 }
1971 }
1972
1973
1974
1975 template <int dim, int spacedim, typename Number>
1976 void
1978 const unsigned int n_unit_point_batches)
1979 {
1980 unit_points.resize(n_unit_point_batches);
1981 }
1982
1983
1984
1985 template <int dim, int spacedim, typename Number>
1986 void
1988 const unsigned int n_unit_point_batches)
1989 {
1990 unit_points_faces.resize(n_unit_point_batches);
1991 }
1992
1993
1994
1995 template <int dim, int spacedim, typename Number>
1996 void
1998 const unsigned int n_data_point_batches,
1999 const bool is_face_centric)
2000 {
2001 if (update_flags_mapping & UpdateFlags::update_jacobians)
2002 {
2003 jacobians[0].resize(n_data_point_batches);
2004 if (is_face_centric)
2005 jacobians[1].resize(n_data_point_batches);
2006 }
2007 if (update_flags_mapping & UpdateFlags::update_inverse_jacobians)
2008 {
2009 inverse_jacobians[0].resize(n_data_point_batches);
2010 if (is_face_centric)
2011 inverse_jacobians[1].resize(n_data_point_batches);
2012 }
2013 if (update_flags_mapping & UpdateFlags::update_JxW_values)
2014 JxW_values.resize(n_data_point_batches);
2015 if (update_flags_mapping & UpdateFlags::update_normal_vectors)
2016 normal_vectors.resize(n_data_point_batches);
2017 if (update_flags_mapping & UpdateFlags::update_quadrature_points)
2018 real_points.resize(n_data_point_batches);
2019 }
2020
2021
2022
2023 template <int dim, int spacedim, typename Number>
2024 inline const Point<
2025 dim,
2028 const unsigned int offset) const
2029 {
2030 return unit_points.data() + offset;
2031 }
2032
2033
2034
2035 template <int dim, int spacedim, typename Number>
2036 inline const Point<
2037 dim - 1,
2040 const unsigned int offset) const
2041 {
2042 return unit_points_faces.data() + offset;
2043 }
2044
2045
2046
2047 template <int dim, int spacedim, typename Number>
2048 inline const Point<spacedim, Number> *
2050 const unsigned int offset) const
2051 {
2052 return real_points.data() + offset;
2053 }
2054
2055
2056
2057 template <int dim, int spacedim, typename Number>
2058 unsigned int
2060 const unsigned int geometry_index) const
2061 {
2062 return unit_points_index[geometry_index];
2063 }
2064
2065
2066
2067 template <int dim, int spacedim, typename Number>
2068 unsigned int
2070 const unsigned int geometry_index) const
2071 {
2072 return data_index_offsets[geometry_index];
2073 }
2074
2075
2076 template <int dim, int spacedim, typename Number>
2077 unsigned int
2079 const unsigned int geometry_index) const
2080 {
2081 return compressed_data_index_offsets[geometry_index];
2082 }
2083
2084
2085
2086 template <int dim, int spacedim, typename Number>
2089 const bool is_interior) const
2090 {
2091 return jacobians[is_interior ? 0 : 1].data() + offset;
2092 }
2093
2094
2095
2096 template <int dim, int spacedim, typename Number>
2099 const unsigned int offset,
2100 const bool is_interior) const
2101 {
2102 return inverse_jacobians[is_interior ? 0 : 1].data() + offset;
2103 }
2104
2105
2106
2107 template <int dim, int spacedim, typename Number>
2108 inline const Tensor<1, spacedim, Number> *
2110 const unsigned int offset) const
2111 {
2112 return normal_vectors.data() + offset;
2113 }
2114
2115
2116
2117 template <int dim, int spacedim, typename Number>
2118 inline const Number *
2119 MappingInfo<dim, spacedim, Number>::get_JxW(const unsigned int offset) const
2120 {
2121 return JxW_values.data() + offset;
2122 }
2123
2124
2125
2126 template <int dim, int spacedim, typename Number>
2129 {
2130 return *mapping;
2131 }
2132
2133
2134
2135 template <int dim, int spacedim, typename Number>
2138 {
2139 return update_flags;
2140 }
2141
2142
2143
2144 template <int dim, int spacedim, typename Number>
2147 {
2148 return update_flags_mapping;
2149 }
2150
2151
2152
2153 template <int dim, int spacedim, typename Number>
2154 std::size_t
2156 {
2157 std::size_t memory = MemoryConsumption::memory_consumption(unit_points);
2158 memory += MemoryConsumption::memory_consumption(unit_points_faces);
2159 memory += MemoryConsumption::memory_consumption(unit_points_index);
2160 memory += cell_type.capacity() *
2162 memory += MemoryConsumption::memory_consumption(data_index_offsets);
2163 memory +=
2164 MemoryConsumption::memory_consumption(compressed_data_index_offsets);
2165 memory += MemoryConsumption::memory_consumption(JxW_values);
2166 memory += MemoryConsumption::memory_consumption(normal_vectors);
2167 memory += MemoryConsumption::memory_consumption(jacobians);
2168 memory += MemoryConsumption::memory_consumption(inverse_jacobians);
2169 memory += MemoryConsumption::memory_consumption(real_points);
2170 memory += MemoryConsumption::memory_consumption(n_q_points_unvectorized);
2171 memory += MemoryConsumption::memory_consumption(cell_index_offset);
2173 cell_index_to_compressed_cell_index);
2174 memory += MemoryConsumption::memory_consumption(cell_level_and_indices);
2175 memory += sizeof(*this);
2176 return memory;
2177 }
2178} // namespace NonMatching
2179
2181
2182#endif
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
void initialize_face(const UpdateFlags update_flags, const Quadrature< dim > &quadrature, const unsigned int n_original_q_points)
Definition mapping_q.cc:168
Abstract base class for mapping classes.
Definition mapping.h:318
const UpdateFlags update_flags
unsigned int compute_compressed_data_index_offset(const unsigned int geometry_index) const
const DerivativeForm< 1, spacedim, dim, Number > * get_inverse_jacobian(const unsigned int offset, const bool is_interior=true) const
AlignedVector< Point< dim, VectorizedArrayType > > unit_points
std::array< AlignedVector< DerivativeForm< 1, dim, spacedim, Number > >, 2 > jacobians
AlignedVector< Number > JxW_values
::internal::MatrixFreeFunctions::GeometryType get_cell_type(const unsigned int geometry_index) const
unsigned int get_face_number(const unsigned int offset, const bool is_interior) const
const Mapping< dim, spacedim > & get_mapping() const
void reinit_faces(const ContainerType &cell_iterator_range, const std::vector< std::vector< Quadrature< dim - 1 > > > &quadrature_vector, const unsigned int n_unfiltered_cells=numbers::invalid_unsigned_int)
std::array< AlignedVector< DerivativeForm< 1, spacedim, dim, Number > >, 2 > inverse_jacobians
const Point< dim, VectorizedArrayType > * get_unit_point(const unsigned int offset) const
unsigned int get_n_q_points_unvectorized(const unsigned int geometry_index) const
const ObserverPointer< const Mapping< dim, spacedim > > mapping
unsigned int compute_compressed_cell_index(const unsigned int cell_index) const
const Point< dim - 1, VectorizedArrayType > * get_unit_point_faces(const unsigned int offset) const
Quadrature< dim > quadrature
std::vector< unsigned int > cell_index_offset
void reinit(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Quadrature< dim > &quadrature)
void store_mapping_data(const unsigned int unit_points_index_offset, const unsigned int n_q_points, const unsigned int n_q_points_unvectorized, const MappingData &mapping_data, const std::vector< double > &weights, const unsigned int compressed_unit_point_index_offset, const bool affine_cell, const bool is_interior=true)
AlignedVector< Tensor< 1, spacedim, Number > > normal_vectors
unsigned int compute_geometry_index_offset(const unsigned int cell_index, const unsigned int face_number) const
std::vector<::internal::MatrixFreeFunctions::GeometryType > cell_type
void reinit(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const ArrayView< const Point< dim > > &unit_points)
void reinit_cells(const ContainerType &cell_iterator_range, const std::vector< Quadrature< dim > > &quadrature_vector, const unsigned int n_unfiltered_cells=numbers::invalid_unsigned_int)
MappingInfo & operator=(const MappingInfo &)=delete
ObserverPointer< const Triangulation< dim, spacedim > > triangulation
std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > internal_mapping_data
void reinit_surface(const ContainerType &cell_iterator_range, const std::vector< ImmersedSurfaceQuadrature< dim > > &quadrature_vector, const unsigned int n_unfiltered_cells=numbers::invalid_unsigned_int)
void resize_unit_points_faces(const unsigned int n_unit_point_batches)
const Tensor< 1, spacedim, Number > * get_normal_vector(const unsigned int offset) const
void reinit(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const std::vector< Point< dim > > &unit_points)
const DerivativeForm< 1, dim, spacedim, Number > * get_jacobian(const unsigned int offset, const bool is_interior=true) const
typename ::internal::VectorizedArrayTrait< Number >::vectorized_value_type VectorizedArrayType
void reinit_cells(const ContainerType &cell_iterator_range, const std::vector< std::vector< Point< dim > > > &unit_points_vector, const unsigned int n_unfiltered_cells=numbers::invalid_unsigned_int)
void resize_data_fields(const unsigned int n_data_point_batches, const bool is_face_centric=false)
void resize_unit_points(const unsigned int n_unit_point_batches)
std::size_t memory_consumption() const
UpdateFlags get_update_flags() const
void store_unit_points_faces(const unsigned int unit_points_index_offset, const unsigned int n_q_points, const unsigned int n_q_points_unvectorized, const std::vector< Point< dim - 1 > > &points)
unsigned int compute_unit_point_index_offset(const unsigned int geometry_index) const
std::vector< unsigned int > cell_index_to_compressed_cell_index
AlignedVector< Point< spacedim, Number > > real_points
unsigned int compute_data_index_offset(const unsigned int geometry_index) const
std::vector< std::pair< unsigned char, unsigned char > > face_number
MappingInfo(const Mapping< dim, spacedim > &mapping, const UpdateFlags update_flags, const AdditionalData additional_data=AdditionalData())
std::vector< unsigned int > unit_points_index
std::vector< std::pair< int, int > > cell_level_and_indices
std::vector< unsigned int > compressed_data_index_offsets
std::vector< unsigned int > data_index_offsets
std::vector< unsigned int > n_q_points_unvectorized
const Number * get_JxW(const unsigned int offset) const
const Point< spacedim, Number > * get_real_point(const unsigned int offset) const
void store_unit_points(const unsigned int unit_points_index_offset, const unsigned int n_q_points, const unsigned int n_q_points_unvectorized, const std::vector< Point< dim > > &points)
const AdditionalData additional_data
AlignedVector< Point< dim - 1, VectorizedArrayType > > unit_points_faces
unsigned int compute_n_q_points(const unsigned int n_q_points_unvectorized)
MappingInfo(const MappingInfo &)=delete
void reinit_faces(const std::vector< std::pair< CellIteratorType, unsigned int > > &face_iterator_range_interior, const std::vector< Quadrature< dim - 1 > > &quadrature_vector)
UpdateFlags update_flags_mapping
void do_reinit_cells(const ContainerType &cell_iterator_range, const std::vector< QuadratureType > &quadrature_vector, const unsigned int n_unfiltered_cells, const std::function< void(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const QuadratureType &quadrature, MappingData &mapping_data)> &compute_mapping_data)
UpdateFlags get_update_flags_mapping() const
Triangulation< dim, spacedim >::cell_iterator get_cell_iterator(const unsigned int cell_index) const
static void compute_mapping_data_for_immersed_surface_quadrature(const ObserverPointer< const Mapping< dim, spacedim > > &mapping, const UpdateFlags &update_flags_mapping, const typename Triangulation< dim, spacedim >::cell_iterator &cell, const ImmersedSurfaceQuadrature< dim > &quadrature, std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > &internal_mapping_data, MappingData &mapping_data)
static void compute_mapping_data_for_face_quadrature(const ObserverPointer< const Mapping< dim, spacedim > > &mapping, const UpdateFlags &update_flags_mapping, const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const Quadrature< dim - 1 > &quadrature, std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > &internal_mapping_data, MappingData &mapping_data)
static void compute_mapping_data_for_quadrature(const ObserverPointer< const Mapping< dim, spacedim > > &mapping, const UpdateFlags &update_flags_mapping, const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Quadrature< dim > &quadrature, std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > &internal_mapping_data, MappingData &mapping_data)
static UpdateFlags required_update_flags(const ObserverPointer< const Mapping< dim, spacedim > > &mapping, const UpdateFlags &update_flags)
Definition point.h:111
Class which transforms dim - 1-dimensional quadrature rules to dim-dimensional face quadratures.
Definition qprojector.h:68
const std::vector< double > & get_weights() const
const std::vector< Point< dim > > & get_points() const
unsigned int size() const
std::vector< DerivativeForm< 1, spacedim, dim > > inverse_jacobians
void initialize(const unsigned int n_quadrature_points, const UpdateFlags flags)
std::vector< DerivativeForm< 1, dim, spacedim > > jacobians
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
unsigned int cell_index
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
UpdateFlags
@ 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_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
@ update_default
No update.
std::vector< index_type > data
Definition mpi.cc:734
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
::internal::MatrixFreeFunctions::GeometryType compute_geometry_type(const double diameter, const std::vector< DerivativeForm< 1, spacedim, dim, double > > &inverse_jacobians)
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
constexpr types::geometric_orientation default_geometric_orientation
Definition types.h:342
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
ComparisonResult compare(const std::vector< T > &v1, const std::vector< T > &v2) const
AdditionalData(const bool use_global_weights=false, const bool store_cells=false)
static constexpr std::size_t width()
static value_type & get(value_type &value, unsigned int c)