17 #include <deal.II/base/array_view.h> 18 #include <deal.II/base/derivative_form.h> 19 #include <deal.II/base/memory_consumption.h> 20 #include <deal.II/base/qprojector.h> 21 #include <deal.II/base/quadrature.h> 22 #include <deal.II/base/quadrature_lib.h> 23 #include <deal.II/base/std_cxx14/memory.h> 24 #include <deal.II/base/tensor_product_polynomials.h> 26 #include <deal.II/dofs/dof_accessor.h> 28 #include <deal.II/fe/fe.h> 29 #include <deal.II/fe/fe_tools.h> 30 #include <deal.II/fe/fe_values.h> 31 #include <deal.II/fe/mapping_manifold.h> 32 #include <deal.II/fe/mapping_q1.h> 34 #include <deal.II/grid/manifold.h> 35 #include <deal.II/grid/tria.h> 36 #include <deal.II/grid/tria_iterator.h> 38 #include <deal.II/lac/full_matrix.h> 47 DEAL_II_NAMESPACE_OPEN
49 template <
int dim,
int spacedim>
69 template <
int dim,
int spacedim>
74 const unsigned int n_original_q_points)
103 template <
int dim,
int spacedim>
108 const unsigned int n_original_q_points)
110 initialize(update_flags, q, n_original_q_points);
128 static const int tangential_orientation[4] = {-1, 1, 1, -1};
129 for (
unsigned int i = 0;
130 i < GeometryInfo<dim>::faces_per_cell;
134 tang[1 - i / 2] = tangential_orientation[i];
143 for (
unsigned int i = 0;
144 i < GeometryInfo<dim>::faces_per_cell;
149 const unsigned int nd =
157 tang1[(nd + 1) % dim] =
162 tang2[(nd + 2) % dim] = 1.;
188 template <
int dim,
int spacedim>
195 template <
int dim,
int spacedim>
196 std::unique_ptr<Mapping<dim, spacedim>>
199 return std_cxx14::make_unique<MappingManifold<dim, spacedim>>(*this);
204 template <
int dim,
int spacedim>
216 template <
int dim,
int spacedim>
223 std::array<double, GeometryInfo<dim>::vertices_per_cell> weights;
225 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; ++v)
227 vertices[v] = cell->vertex(v);
230 return cell->get_manifold().get_new_point(
231 make_array_view(vertices.begin(), vertices.end()),
232 make_array_view(weights.begin(), weights.end()));
250 template <
int dim,
int spacedim>
262 for (
unsigned int i = 0; i < 5; ++i)
312 template <
int dim,
int spacedim>
313 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
317 auto data = std_cxx14::make_unique<InternalData>();
320 return std::move(data);
325 template <
int dim,
int spacedim>
326 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
331 auto data = std_cxx14::make_unique<InternalData>();
336 return std::move(data);
341 template <
int dim,
int spacedim>
342 std::unique_ptr<typename Mapping<dim, spacedim>::InternalDataBase>
347 auto data = std_cxx14::make_unique<InternalData>();
352 return std::move(data);
359 namespace MappingManifoldImplementation
369 template <
int dim,
int spacedim>
371 maybe_compute_q_points(
373 const typename ::MappingManifold<dim, spacedim>::InternalData
384 for (
unsigned int point = 0; point < quadrature_points.size();
387 quadrature_points[point] = data.manifold->get_new_point(
388 make_array_view(data.vertices),
390 data.cell_manifold_quadrature_weights[point + data_set]));
403 template <
int dim,
int spacedim>
405 maybe_update_Jacobians(
406 const typename ::QProjector<dim>::DataSetDescriptor data_set,
407 const typename ::MappingManifold<dim, spacedim>::InternalData
414 const unsigned int n_q_points = data.contravariant.size();
416 std::fill(data.contravariant.begin(),
417 data.contravariant.end(),
421 data.vertices.size());
422 for (
unsigned int point = 0; point < n_q_points; ++point)
426 const Point<dim> &p = data.quad.point(point + data_set);
430 make_array_view(data.vertices),
432 data.cell_manifold_quadrature_weights[point + data_set]));
441 for (
unsigned int i = 0; i < dim; ++i)
444 const double pi = p[i];
445 Assert(pi >= 0 && pi <= 1.0,
447 "Was expecting a quadrature point " 448 "inside the unit reference element."));
452 const double L = pi > .5 ? -pi : 1 - pi;
457 for (
unsigned int j = 0;
458 j < GeometryInfo<dim>::vertices_per_cell;
460 data.vertex_weights[j] =
464 make_array_view(data.vertices),
465 make_array_view(data.vertex_weights));
468 data.manifold->get_tangent_vector(P, NP);
470 for (
unsigned int d = 0; d < spacedim; ++d)
471 data.contravariant[point][d][i] = T[d] / L;
477 const unsigned int n_q_points = data.contravariant.size();
478 for (
unsigned int point = 0; point < n_q_points; ++point)
480 data.covariant[point] =
481 (data.contravariant[point]).covariant_form();
487 const unsigned int n_q_points = data.contravariant.size();
488 for (
unsigned int point = 0; point < n_q_points; ++point)
489 data.volume_elements[point] =
490 data.contravariant[point].determinant();
500 template <
int dim,
int spacedim>
511 Assert(dynamic_cast<const InternalData *>(&internal_data) !=
nullptr,
515 const unsigned int n_q_points = quadrature.
size();
518 data.
manifold = &(cell->get_manifold());
520 internal::MappingManifoldImplementation::maybe_compute_q_points<dim,
526 internal::MappingManifoldImplementation::maybe_update_Jacobians<dim,
531 const std::vector<double> &weights = quadrature.
get_weights();
546 for (
unsigned int point = 0; point < n_q_points; ++point)
550 const double det = data.contravariant[point].determinant();
557 Assert(det > 1e-12 * Utilities::fixed_power<dim>(
558 cell->diameter() / std::sqrt(
double(dim))),
560 cell->center(), det, point)));
562 output_data.
JxW_values[point] = weights[point] * det;
570 for (
unsigned int i = 0; i < spacedim; ++i)
571 for (
unsigned int j = 0; j < dim; ++j)
572 DX_t[j][i] = data.contravariant[point][i][j];
575 for (
unsigned int i = 0; i < dim; ++i)
576 for (
unsigned int j = 0; j < dim; ++j)
577 G[i][j] = DX_t[i] * DX_t[j];
585 if (update_flags & update_normal_vectors)
590 if (update_flags & update_normal_vectors)
592 Assert(spacedim == dim + 1,
594 "There is no (unique) cell normal for " +
596 "-dimensional cells in " +
598 "-dimensional space. This only works if the " 599 "space dimension is one greater than the " 600 "dimensionality of the mesh cells."));
604 cross_product_2d(-DX_t[0]);
607 cross_product_3d(DX_t[0], DX_t[1]);
612 if (cell->direction_flag() ==
false)
627 for (
unsigned int point = 0; point < n_q_points; ++point)
628 output_data.
jacobians[point] = data.contravariant[point];
636 for (
unsigned int point = 0; point < n_q_points; ++point)
638 data.covariant[point].transpose();
641 return cell_similarity;
648 namespace MappingManifoldImplementation
661 template <
int dim,
int spacedim>
663 maybe_compute_face_data(
664 const ::MappingManifold<dim, spacedim> &mapping,
665 const typename ::Triangulation<dim, spacedim>::cell_iterator
667 const unsigned int face_no,
668 const unsigned int subface_no,
669 const unsigned int n_q_points,
670 const std::vector<double> &weights,
671 const typename ::MappingManifold<dim, spacedim>::InternalData
689 for (
unsigned int d = 0; d != dim - 1; ++d)
692 data.unit_tangentials.size(),
695 data.aux[d].size() <=
697 .unit_tangentials[face_no +
709 make_array_view(data.aux[d]));
716 for (
unsigned int i = 0; i < n_q_points; ++i)
725 (face_no == 0 ? -1 : +1);
729 cross_product_2d(data.aux[0][i]);
733 cross_product_3d(data.aux[0][i], data.aux[1][i]);
749 for (
unsigned int point = 0; point < n_q_points; ++point)
757 data.contravariant[point].transpose()[0];
759 (face_no == 0 ? -1. : +1.) *
771 cross_product_3d(DX_t[0], DX_t[1]);
772 cell_normal /= cell_normal.
norm();
777 cross_product_3d(data.aux[0][point], cell_normal);
788 if (update_flags & (update_normal_vectors | update_JxW_values))
792 if (update_flags & update_JxW_values)
799 const double area_ratio =
801 cell->subface_case(face_no), subface_no);
806 if (update_flags & update_normal_vectors)
813 for (
unsigned int point = 0; point < n_q_points; ++point)
814 output_data.
jacobians[point] = data.contravariant[point];
817 for (
unsigned int point = 0; point < n_q_points; ++point)
819 data.covariant[point].transpose();
830 template <
int dim,
int spacedim>
832 do_fill_fe_face_values(
833 const ::MappingManifold<dim, spacedim> &mapping,
834 const typename ::Triangulation<dim, spacedim>::cell_iterator
836 const unsigned int face_no,
837 const unsigned int subface_no,
840 const typename ::MappingManifold<dim, spacedim>::InternalData
845 data.store_vertices(cell);
847 data.manifold = &cell->face(face_no)->get_manifold();
849 maybe_compute_q_points<dim, spacedim>(data_set,
852 maybe_update_Jacobians<dim, spacedim>(data_set, data);
854 maybe_compute_face_data(mapping,
864 template <
int dim,
int spacedim,
int rank>
873 Assert((
dynamic_cast<const typename ::
874 MappingManifold<dim, spacedim>::InternalData *
>(
875 &mapping_data) !=
nullptr),
877 const typename ::MappingManifold<dim, spacedim>::InternalData
879 static_cast<const typename ::MappingManifold<dim, spacedim>::
882 switch (mapping_type)
889 "update_contravariant_transformation"));
891 for (
unsigned int i = 0; i < output.size(); ++i)
893 apply_transformation(data.contravariant[i], input[i]);
903 "update_contravariant_transformation"));
907 "update_volume_elements"));
912 for (
unsigned int i = 0; i < output.size(); ++i)
915 apply_transformation(data.contravariant[i], input[i]);
916 output[i] /= data.volume_elements[i];
928 "update_covariant_transformation"));
930 for (
unsigned int i = 0; i < output.size(); ++i)
931 output[i] = apply_transformation(data.covariant[i], input[i]);
942 template <
int dim,
int spacedim,
int rank>
951 Assert((
dynamic_cast<const typename ::
952 MappingManifold<dim, spacedim>::InternalData *
>(
953 &mapping_data) !=
nullptr),
955 const typename ::MappingManifold<dim, spacedim>::InternalData
957 static_cast<const typename ::MappingManifold<dim, spacedim>::
960 switch (mapping_type)
967 "update_covariant_transformation"));
971 "update_contravariant_transformation"));
974 for (
unsigned int i = 0; i < output.size(); ++i)
977 apply_transformation(data.contravariant[i],
980 apply_transformation(data.covariant[i], A.
transpose());
991 "update_covariant_transformation"));
994 for (
unsigned int i = 0; i < output.size(); ++i)
997 apply_transformation(data.covariant[i],
1000 apply_transformation(data.covariant[i], A.
transpose());
1011 "update_covariant_transformation"));
1015 "update_contravariant_transformation"));
1019 "update_volume_elements"));
1022 for (
unsigned int i = 0; i < output.size(); ++i)
1025 apply_transformation(data.covariant[i], input[i]);
1027 apply_transformation(data.contravariant[i],
1031 output[i] /= data.volume_elements[i];
1044 template <
int dim,
int spacedim>
1053 Assert((
dynamic_cast<const typename ::
1054 MappingManifold<dim, spacedim>::InternalData *
>(
1055 &mapping_data) !=
nullptr),
1057 const typename ::MappingManifold<dim, spacedim>::InternalData
1059 static_cast<const typename ::MappingManifold<dim, spacedim>::
1062 switch (mapping_type)
1069 "update_covariant_transformation"));
1073 "update_contravariant_transformation"));
1075 for (
unsigned int q = 0; q < output.size(); ++q)
1076 for (
unsigned int i = 0; i < spacedim; ++i)
1078 double tmp1[dim][dim];
1079 for (
unsigned int J = 0; J < dim; ++J)
1080 for (
unsigned int K = 0; K < dim; ++K)
1083 data.contravariant[q][i][0] * input[q][0][J][K];
1084 for (
unsigned int I = 1; I < dim; ++I)
1086 data.contravariant[q][i][I] * input[q][I][J][K];
1088 for (
unsigned int j = 0; j < spacedim; ++j)
1091 for (
unsigned int K = 0; K < dim; ++K)
1093 tmp2[K] = data.covariant[q][j][0] * tmp1[0][K];
1094 for (
unsigned int J = 1; J < dim; ++J)
1095 tmp2[K] += data.covariant[q][j][J] * tmp1[J][K];
1097 for (
unsigned int k = 0; k < spacedim; ++k)
1099 output[q][i][j][k] =
1100 data.covariant[q][k][0] * tmp2[0];
1101 for (
unsigned int K = 1; K < dim; ++K)
1102 output[q][i][j][k] +=
1103 data.covariant[q][k][K] * tmp2[K];
1115 "update_covariant_transformation"));
1117 for (
unsigned int q = 0; q < output.size(); ++q)
1118 for (
unsigned int i = 0; i < spacedim; ++i)
1120 double tmp1[dim][dim];
1121 for (
unsigned int J = 0; J < dim; ++J)
1122 for (
unsigned int K = 0; K < dim; ++K)
1125 data.covariant[q][i][0] * input[q][0][J][K];
1126 for (
unsigned int I = 1; I < dim; ++I)
1128 data.covariant[q][i][I] * input[q][I][J][K];
1130 for (
unsigned int j = 0; j < spacedim; ++j)
1133 for (
unsigned int K = 0; K < dim; ++K)
1135 tmp2[K] = data.covariant[q][j][0] * tmp1[0][K];
1136 for (
unsigned int J = 1; J < dim; ++J)
1137 tmp2[K] += data.covariant[q][j][J] * tmp1[J][K];
1139 for (
unsigned int k = 0; k < spacedim; ++k)
1141 output[q][i][j][k] =
1142 data.covariant[q][k][0] * tmp2[0];
1143 for (
unsigned int K = 1; K < dim; ++K)
1144 output[q][i][j][k] +=
1145 data.covariant[q][k][K] * tmp2[K];
1158 "update_covariant_transformation"));
1162 "update_contravariant_transformation"));
1166 "update_volume_elements"));
1168 for (
unsigned int q = 0; q < output.size(); ++q)
1169 for (
unsigned int i = 0; i < spacedim; ++i)
1172 for (
unsigned int I = 0; I < dim; ++I)
1174 data.contravariant[q][i][I] / data.volume_elements[q];
1175 double tmp1[dim][dim];
1176 for (
unsigned int J = 0; J < dim; ++J)
1177 for (
unsigned int K = 0; K < dim; ++K)
1179 tmp1[J][K] = factor[0] * input[q][0][J][K];
1180 for (
unsigned int I = 1; I < dim; ++I)
1181 tmp1[J][K] += factor[I] * input[q][I][J][K];
1183 for (
unsigned int j = 0; j < spacedim; ++j)
1186 for (
unsigned int K = 0; K < dim; ++K)
1188 tmp2[K] = data.covariant[q][j][0] * tmp1[0][K];
1189 for (
unsigned int J = 1; J < dim; ++J)
1190 tmp2[K] += data.covariant[q][j][J] * tmp1[J][K];
1192 for (
unsigned int k = 0; k < spacedim; ++k)
1194 output[q][i][j][k] =
1195 data.covariant[q][k][0] * tmp2[0];
1196 for (
unsigned int K = 1; K < dim; ++K)
1197 output[q][i][j][k] +=
1198 data.covariant[q][k][K] * tmp2[K];
1213 template <
int dim,
int spacedim,
int rank>
1215 transform_differential_forms(
1222 Assert((
dynamic_cast<const typename ::
1223 MappingManifold<dim, spacedim>::InternalData *
>(
1224 &mapping_data) !=
nullptr),
1226 const typename ::MappingManifold<dim, spacedim>::InternalData
1228 static_cast<const typename ::MappingManifold<dim, spacedim>::
1231 switch (mapping_type)
1238 "update_covariant_transformation"));
1240 for (
unsigned int i = 0; i < output.size(); ++i)
1241 output[i] = apply_transformation(data.covariant[i], input[i]);
1255 template <
int dim,
int spacedim>
1259 const unsigned int face_no,
1266 Assert((dynamic_cast<const InternalData *>(&internal_data) !=
nullptr),
1270 internal::MappingManifoldImplementation::do_fill_fe_face_values(
1276 cell->face_orientation(face_no),
1277 cell->face_flip(face_no),
1278 cell->face_rotation(face_no),
1287 template <
int dim,
int spacedim>
1291 const unsigned int face_no,
1292 const unsigned int subface_no,
1299 Assert((dynamic_cast<const InternalData *>(&internal_data) !=
nullptr),
1303 internal::MappingManifoldImplementation::do_fill_fe_face_values(
1310 cell->face_orientation(face_no),
1311 cell->face_flip(face_no),
1312 cell->face_rotation(face_no),
1314 cell->subface_case(face_no)),
1322 template <
int dim,
int spacedim>
1330 internal::MappingManifoldImplementation::transform_fields(input,
1338 template <
int dim,
int spacedim>
1346 internal::MappingManifoldImplementation::transform_differential_forms(
1347 input, mapping_type, mapping_data, output);
1352 template <
int dim,
int spacedim>
1360 switch (mapping_type)
1363 internal::MappingManifoldImplementation::transform_fields(input,
1372 internal::MappingManifoldImplementation::transform_gradients(
1373 input, mapping_type, mapping_data, output);
1382 template <
int dim,
int spacedim>
1391 Assert(dynamic_cast<const InternalData *>(&mapping_data) !=
nullptr,
1395 switch (mapping_type)
1401 "update_covariant_transformation"));
1403 for (
unsigned int q = 0; q < output.size(); ++q)
1404 for (
unsigned int i = 0; i < spacedim; ++i)
1405 for (
unsigned int j = 0; j < spacedim; ++j)
1408 for (
unsigned int K = 0; K < dim; ++K)
1410 tmp[K] = data.
covariant[q][j][0] * input[q][i][0][K];
1411 for (
unsigned int J = 1; J < dim; ++J)
1412 tmp[K] += data.
covariant[q][j][J] * input[q][i][J][K];
1414 for (
unsigned int k = 0; k < spacedim; ++k)
1416 output[q][i][j][k] = data.
covariant[q][k][0] * tmp[0];
1417 for (
unsigned int K = 1; K < dim; ++K)
1418 output[q][i][j][k] += data.
covariant[q][k][K] * tmp[K];
1431 template <
int dim,
int spacedim>
1439 switch (mapping_type)
1444 internal::MappingManifoldImplementation::transform_hessians(
1445 input, mapping_type, mapping_data, output);
1453 #include "mapping_manifold.inst" 1456 DEAL_II_NAMESPACE_CLOSE
Transformed quadrature weights.
std::vector< DerivativeForm< 1, dim, spacedim > > covariant
static const unsigned int invalid_unsigned_int
virtual void transform(const ArrayView< const Tensor< 1, dim >> &input, const MappingType type, const typename Mapping< dim, spacedim >::InternalDataBase &internal, const ArrayView< Tensor< 1, spacedim >> &output) const override
virtual std::unique_ptr< Mapping< dim, spacedim > > clone() const override
#define AssertDimension(dim1, dim2)
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
SmartPointer< const Manifold< dim, spacedim > > manifold
Number determinant(const SymmetricTensor< 2, dim, Number > &)
Contravariant transformation.
virtual void fill_fe_face_values(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const unsigned int face_no, const Quadrature< dim-1 > &quadrature, const typename Mapping< dim, spacedim >::InternalDataBase &internal_data,::internal::FEValuesImplementation::MappingRelatedData< dim, spacedim > &output_data) const override
std::vector< DerivativeForm< 1, dim, spacedim > > contravariant
std::array< std::vector< Tensor< 1, dim > >, GeometryInfo< dim >::faces_per_cell *(dim-1)> unit_tangentials
static Point< dim, Number > unit_vector(const unsigned int i)
Outer normal vector, not normalized.
Determinant of the Jacobian.
Transformed quadrature points.
virtual std::size_t memory_consumption() const override
numbers::NumberTraits< Number >::real_type norm() const
static DataSetDescriptor cell()
Triangulation< dim, spacedim >::cell_iterator cell
std::vector< Point< spacedim > > vertices
virtual std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > get_subface_data(const UpdateFlags flags, const Quadrature< dim-1 > &quadrature) const override
virtual UpdateFlags requires_update_flags(const UpdateFlags update_flags) const override
void store_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) 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
std::vector< std::vector< Tensor< 1, spacedim > > > aux
unsigned int size() const
static::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
Abstract base class for mapping classes.
void initialize(const UpdateFlags update_flags, const Quadrature< dim > &quadrature, const unsigned int n_original_q_points)
SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
Gradient of volume element.
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
std::vector< double > volume_elements
const std::vector< double > & get_weights() const
std::vector< double > vertex_weights
void compute_manifold_quadrature_weights(const Quadrature< dim > &quadrature)
static double d_linear_shape_function(const Point< dim > &xi, const unsigned int i)
virtual Point< spacedim > transform_unit_to_real_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< dim > &p) const override
static::ExceptionBase & ExcNotImplemented()
virtual Point< dim > transform_real_to_unit_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< spacedim > &p) const override
virtual std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > get_data(const UpdateFlags, const Quadrature< dim > &quadrature) const override
void initialize_face(const UpdateFlags update_flags, const Quadrature< dim > &quadrature, const unsigned int n_original_q_points)
virtual std::unique_ptr< typename Mapping< dim, spacedim >::InternalDataBase > get_face_data(const UpdateFlags flags, const Quadrature< dim-1 > &quadrature) const override
static double subface_ratio(const internal::SubfaceCase< dim > &subface_case, const unsigned int subface_no)
Covariant transformation.
std::vector< std::vector< double > > cell_manifold_quadrature_weights
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
MappingManifold()=default
static::ExceptionBase & ExcInternalError()