17 #include <deal.II/base/array_view.h> 18 #include <deal.II/base/derivative_form.h> 19 #include <deal.II/base/quadrature.h> 20 #include <deal.II/base/qprojector.h> 21 #include <deal.II/base/quadrature_lib.h> 22 #include <deal.II/base/std_cxx14/memory.h> 23 #include <deal.II/base/tensor_product_polynomials.h> 24 #include <deal.II/base/memory_consumption.h> 25 #include <deal.II/lac/full_matrix.h> 26 #include <deal.II/grid/tria.h> 27 #include <deal.II/grid/tria_iterator.h> 28 #include <deal.II/grid/tria_boundary.h> 29 #include <deal.II/dofs/dof_accessor.h> 30 #include <deal.II/grid/manifold.h> 31 #include <deal.II/fe/fe_tools.h> 32 #include <deal.II/fe/fe.h> 33 #include <deal.II/fe/fe_values.h> 34 #include <deal.II/fe/mapping_manifold.h> 35 #include <deal.II/fe/mapping_q1.h> 44 DEAL_II_NAMESPACE_OPEN
46 template <
int dim,
int spacedim>
65 template <
int dim,
int spacedim>
70 const unsigned int n_original_q_points)
74 this->update_each = update_flags;
85 compute_manifold_quadrature_weights(q);
88 covariant.resize(n_original_q_points);
91 contravariant.resize(n_original_q_points);
94 volume_elements.resize(n_original_q_points);
98 template <
int dim,
int spacedim>
103 const unsigned int n_original_q_points)
105 initialize (update_flags, q, n_original_q_points);
114 for (
unsigned int i=0; i<unit_tangentials.size(); ++i)
115 unit_tangentials[i].resize (n_original_q_points);
122 static const int tangential_orientation[4]= {-1,1,1,-1};
123 for (
unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
126 tang[1-i/2]=tangential_orientation[i];
127 std::fill (unit_tangentials[i].begin(),
128 unit_tangentials[i].end(),
135 for (
unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
139 const unsigned int nd=
151 tang2[(nd+2)%dim]=1.;
156 std::fill (unit_tangentials[i].begin(),
157 unit_tangentials[i].end(), tang1);
173 template <
int dim,
int spacedim>
179 template <
int dim,
int spacedim>
180 std::unique_ptr<Mapping<dim,spacedim> >
183 return std_cxx14::make_unique<MappingManifold<dim,spacedim>>(*this);
188 template <
int dim,
int spacedim>
200 template <
int dim,
int spacedim>
207 std::array<double, GeometryInfo<dim>::vertices_per_cell> weights;
209 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
211 vertices[v] = cell->vertex(v);
214 return cell->get_manifold().get_new_point(make_array_view(vertices.begin(),
216 make_array_view(weights.begin(),
235 template <
int dim,
int spacedim>
246 for (
unsigned int i=0; i<5; ++i)
302 template <
int dim,
int spacedim>
303 std::unique_ptr<typename Mapping<dim,spacedim>::InternalDataBase>
307 auto data = std_cxx14::make_unique<InternalData>();
310 return std::move(data);
315 template <
int dim,
int spacedim>
316 std::unique_ptr<typename Mapping<dim,spacedim>::InternalDataBase>
320 auto data = std_cxx14::make_unique<InternalData>();
325 return std::move(data);
330 template <
int dim,
int spacedim>
331 std::unique_ptr<typename Mapping<dim,spacedim>::InternalDataBase>
335 auto data = std_cxx14::make_unique<InternalData>();
340 return std::move(data);
347 namespace MappingManifoldImplementation
357 template <
int dim,
int spacedim>
359 maybe_compute_q_points
361 const typename ::MappingManifold<dim,spacedim>::InternalData &data,
370 for (
unsigned int point=0; point<quadrature_points.size(); ++point)
372 quadrature_points[point] = data.manifold->get_new_point
373 (make_array_view(data.vertices),
374 make_array_view(data.cell_manifold_quadrature_weights[point+data_set]));
386 template <
int dim,
int spacedim>
388 maybe_update_Jacobians
389 (
const typename ::QProjector<dim>::DataSetDescriptor data_set,
390 const typename ::MappingManifold<dim,spacedim>::InternalData &data)
396 const unsigned int n_q_points = data.contravariant.size();
398 std::fill(data.contravariant.begin(), data.contravariant.end(),
402 data.vertices.size());
403 for (
unsigned int point=0;
point<n_q_points; ++
point)
407 const Point<dim> &p = data.quad.point(point+data_set);
411 (make_array_view(data.vertices),
412 make_array_view(data.cell_manifold_quadrature_weights[point+data_set]));
421 for (
unsigned int i=0; i<dim; ++i)
424 const double pi = p[i];
425 Assert(pi >=0 && pi <= 1.0,
427 "inside the unit reference element."));
431 const double L = pi > .5 ? -pi: 1-pi;
436 for (
unsigned int j=0; j<GeometryInfo<dim>::vertices_per_cell; ++j)
440 data.manifold->get_new_point(make_array_view(data.vertices),
441 make_array_view(data.vertex_weights));
445 for (
unsigned int d=0;
d<spacedim; ++
d)
446 data.contravariant[point][d][i] = T[d]/L;
452 const unsigned int n_q_points = data.contravariant.size();
453 for (
unsigned int point=0;
point<n_q_points; ++
point)
455 data.covariant[
point] = (data.contravariant[
point]).covariant_form();
461 const unsigned int n_q_points = data.contravariant.size();
462 for (
unsigned int point=0;
point<n_q_points; ++
point)
463 data.volume_elements[point] = data.contravariant[point].
determinant();
473 template <
int dim,
int spacedim>
483 Assert (dynamic_cast<const InternalData *>(&internal_data) !=
nullptr,
487 const unsigned int n_q_points=quadrature.
size();
490 data.
manifold = &(cell->get_manifold());
492 internal::MappingManifoldImplementation::maybe_compute_q_points<dim,spacedim>
497 internal::MappingManifoldImplementation::maybe_update_Jacobians<dim,spacedim>
502 const std::vector<double> &weights=quadrature.
get_weights();
517 for (
unsigned int point=0; point<n_q_points; ++point)
522 const double det = data.contravariant[point].determinant();
529 Assert (det > 1e-12*Utilities::fixed_power<dim>(cell->diameter()/
530 std::sqrt(
double(dim))),
533 output_data.
JxW_values[point] = weights[point] * det;
541 for (
unsigned int i=0; i<spacedim; ++i)
542 for (
unsigned int j=0; j<dim; ++j)
543 DX_t[j][i] = data.contravariant[point][i][j];
546 for (
unsigned int i=0; i<dim; ++i)
547 for (
unsigned int j=0; j<dim; ++j)
548 G[i][j] = DX_t[i] * DX_t[j];
564 ExcMessage(
"There is no (unique) cell normal for " 566 "-dimensional cells in " 568 "-dimensional space. This only works if the " 569 "space dimension is one greater than the " 570 "dimensionality of the mesh cells."));
574 cross_product_2d(-DX_t[0]);
577 cross_product_3d(DX_t[0], DX_t[1]);
581 if (cell->direction_flag() ==
false)
598 for (
unsigned int point=0; point<n_q_points; ++point)
599 output_data.
jacobians[point] = data.contravariant[point];
607 for (
unsigned int point=0; point<n_q_points; ++point)
611 return cell_similarity;
621 namespace MappingManifoldImplementation
634 template <
int dim,
int spacedim>
636 maybe_compute_face_data
637 (const ::MappingManifold<dim,spacedim> &mapping,
638 const typename ::Triangulation<dim,spacedim>::cell_iterator &cell,
639 const unsigned int face_no,
640 const unsigned int subface_no,
641 const unsigned int n_q_points,
642 const std::vector<double> &weights,
643 const typename ::MappingManifold<dim,spacedim>::InternalData &data,
659 for (
unsigned int d=0; d!=dim-1; ++d)
662 data.unit_tangentials.size(),
664 Assert (data.aux[d].size() <=
671 make_array_view(data.aux[d]));
678 for (
unsigned int i=0; i<n_q_points; ++i)
691 cross_product_2d(data.aux[0][i]);
695 cross_product_3d(data.aux[0][i], data.aux[1][i]);
711 for (
unsigned int point=0;
point<n_q_points; ++
point)
731 cross_product_3d(DX_t[0], DX_t[1]);
732 cell_normal /= cell_normal.
norm();
737 cross_product_3d(data.aux[0][point], cell_normal);
770 for (
unsigned int point=0;
point<n_q_points; ++
point)
771 output_data.
jacobians[point] = data.contravariant[point];
774 for (
unsigned int point=0;
point<n_q_points; ++
point)
786 template <
int dim,
int spacedim>
788 do_fill_fe_face_values
789 (const ::MappingManifold<dim,spacedim> &mapping,
790 const typename ::Triangulation<dim,spacedim>::cell_iterator &cell,
791 const unsigned int face_no,
792 const unsigned int subface_no,
795 const typename ::MappingManifold<dim,spacedim>::InternalData &data,
798 data.store_vertices(cell);
800 data.manifold = &cell->face(face_no)->get_manifold();
802 maybe_compute_q_points<dim,spacedim> (data_set,
805 maybe_update_Jacobians<dim,spacedim> (data_set,
808 maybe_compute_face_data (mapping,
809 cell, face_no, subface_no, quadrature.
size(),
814 template <
int dim,
int spacedim,
int rank>
822 Assert ((
dynamic_cast<const typename ::MappingManifold<dim,spacedim>::InternalData *
>(&mapping_data) !=
nullptr),
824 const typename ::MappingManifold<dim,spacedim>::InternalData
825 &data =
static_cast<const typename ::MappingManifold<dim,spacedim>::InternalData &
>(mapping_data);
827 switch (mapping_type)
834 for (
unsigned int i=0; i<output.size(); ++i)
835 output[i] = apply_transformation(data.contravariant[i], input[i]);
850 for (
unsigned int i=0; i<output.size(); ++i)
852 output[i] = apply_transformation(data.contravariant[i], input[i]);
853 output[i] /= data.volume_elements[i];
865 for (
unsigned int i=0; i<output.size(); ++i)
866 output[i] = apply_transformation(data.covariant[i], input[i]);
877 template <
int dim,
int spacedim,
int rank>
885 Assert ((
dynamic_cast<const typename ::MappingManifold<dim,spacedim>::InternalData *
>(&mapping_data) !=
nullptr),
887 const typename ::MappingManifold<dim,spacedim>::InternalData
888 &data =
static_cast<const typename ::MappingManifold<dim,spacedim>::InternalData &
>(mapping_data);
890 switch (mapping_type)
900 for (
unsigned int i=0; i<output.size(); ++i)
903 apply_transformation(data.contravariant[i],
transpose(input[i]) );
904 output[i] = apply_transformation(data.covariant[i], A.
transpose() );
916 for (
unsigned int i=0; i<output.size(); ++i)
919 apply_transformation(data.covariant[i],
transpose(input[i]) );
920 output[i] = apply_transformation(data.covariant[i], A.
transpose() );
936 for (
unsigned int i=0; i<output.size(); ++i)
939 apply_transformation(data.covariant[i], input[i] );
941 apply_transformation(data.contravariant[i], A.
transpose() );
944 output[i] /= data.volume_elements[i];
958 template <
int dim,
int spacedim>
966 Assert ((
dynamic_cast<const typename ::MappingManifold<dim,spacedim>::InternalData *
>(&mapping_data) !=
nullptr),
968 const typename ::MappingManifold<dim,spacedim>::InternalData
969 &data =
static_cast<const typename ::MappingManifold<dim,spacedim>::InternalData &
>(mapping_data);
971 switch (mapping_type)
980 for (
unsigned int q=0; q<output.size(); ++q)
981 for (
unsigned int i=0; i<spacedim; ++i)
983 double tmp1[dim][dim];
984 for (
unsigned int J=0; J<dim; ++J)
985 for (
unsigned int K=0; K<dim; ++K)
987 tmp1[J][K] = data.contravariant[q][i][0] * input[q][0][J][K];
988 for (
unsigned int I=1; I<dim; ++I)
989 tmp1[J][K] += data.contravariant[q][i][I] * input[q][I][J][K];
991 for (
unsigned int j=0; j<spacedim; ++j)
994 for (
unsigned int K=0; K<dim; ++K)
996 tmp2[K] = data.covariant[q][j][0] * tmp1[0][K];
997 for (
unsigned int J=1; J<dim; ++J)
998 tmp2[K] += data.covariant[q][j][J] * tmp1[J][K];
1000 for (
unsigned int k=0; k<spacedim; ++k)
1002 output[q][i][j][k] = data.covariant[q][k][0] * tmp2[0];
1003 for (
unsigned int K=1; K<dim; ++K)
1004 output[q][i][j][k] += data.covariant[q][k][K] * tmp2[K];
1016 for (
unsigned int q=0; q<output.size(); ++q)
1017 for (
unsigned int i=0; i<spacedim; ++i)
1019 double tmp1[dim][dim];
1020 for (
unsigned int J=0; J<dim; ++J)
1021 for (
unsigned int K=0; K<dim; ++K)
1023 tmp1[J][K] = data.covariant[q][i][0] * input[q][0][J][K];
1024 for (
unsigned int I=1; I<dim; ++I)
1025 tmp1[J][K] += data.covariant[q][i][I] * input[q][I][J][K];
1027 for (
unsigned int j=0; j<spacedim; ++j)
1030 for (
unsigned int K=0; K<dim; ++K)
1032 tmp2[K] = data.covariant[q][j][0] * tmp1[0][K];
1033 for (
unsigned int J=1; J<dim; ++J)
1034 tmp2[K] += data.covariant[q][j][J] * tmp1[J][K];
1036 for (
unsigned int k=0; k<spacedim; ++k)
1038 output[q][i][j][k] = data.covariant[q][k][0] * tmp2[0];
1039 for (
unsigned int K=1; K<dim; ++K)
1040 output[q][i][j][k] += data.covariant[q][k][K] * tmp2[K];
1057 for (
unsigned int q=0; q<output.size(); ++q)
1058 for (
unsigned int i=0; i<spacedim; ++i)
1061 for (
unsigned int I=0; I<dim; ++I)
1062 factor[I] = data.contravariant[q][i][I] / data.volume_elements[q];
1063 double tmp1[dim][dim];
1064 for (
unsigned int J=0; J<dim; ++J)
1065 for (
unsigned int K=0; K<dim; ++K)
1067 tmp1[J][K] = factor[0] * input[q][0][J][K];
1068 for (
unsigned int I=1; I<dim; ++I)
1069 tmp1[J][K] += factor[I] * input[q][I][J][K];
1071 for (
unsigned int j=0; j<spacedim; ++j)
1074 for (
unsigned int K=0; K<dim; ++K)
1076 tmp2[K] = data.covariant[q][j][0] * tmp1[0][K];
1077 for (
unsigned int J=1; J<dim; ++J)
1078 tmp2[K] += data.covariant[q][j][J] * tmp1[J][K];
1080 for (
unsigned int k=0; k<spacedim; ++k)
1082 output[q][i][j][k] = data.covariant[q][k][0] * tmp2[0];
1083 for (
unsigned int K=1; K<dim; ++K)
1084 output[q][i][j][k] += data.covariant[q][k][K] * tmp2[K];
1100 template <
int dim,
int spacedim,
int rank>
1108 Assert ((
dynamic_cast<const typename ::MappingManifold<dim,spacedim>::InternalData *
>(&mapping_data) !=
nullptr),
1110 const typename ::MappingManifold<dim,spacedim>::InternalData
1111 &data =
static_cast<const typename ::MappingManifold<dim,spacedim>::InternalData &
>(mapping_data);
1113 switch (mapping_type)
1120 for (
unsigned int i=0; i<output.size(); ++i)
1121 output[i] = apply_transformation(data.covariant[i], input[i]);
1135 template <
int dim,
int spacedim>
1139 const unsigned int face_no,
1145 Assert ((dynamic_cast<const InternalData *>(&internal_data) !=
nullptr),
1150 internal::MappingManifoldImplementation::do_fill_fe_face_values
1154 cell->face_orientation(face_no),
1155 cell->face_flip(face_no),
1156 cell->face_rotation(face_no),
1165 template <
int dim,
int spacedim>
1169 const unsigned int face_no,
1170 const unsigned int subface_no,
1176 Assert ((dynamic_cast<const InternalData *>(&internal_data) !=
nullptr),
1181 internal::MappingManifoldImplementation::do_fill_fe_face_values
1183 cell, face_no, subface_no,
1185 cell->face_orientation(face_no),
1186 cell->face_flip(face_no),
1187 cell->face_rotation(face_no),
1189 cell->subface_case(face_no)),
1197 template <
int dim,
int spacedim>
1205 internal::MappingManifoldImplementation::transform_fields(input, mapping_type, mapping_data, output);
1210 template <
int dim,
int spacedim>
1218 internal::MappingManifoldImplementation::transform_differential_forms(input, mapping_type, mapping_data, output);
1223 template <
int dim,
int spacedim>
1231 switch (mapping_type)
1234 internal::MappingManifoldImplementation::transform_fields(input, mapping_type, mapping_data, output);
1240 internal::MappingManifoldImplementation::transform_gradients(input, mapping_type, mapping_data, output);
1249 template <
int dim,
int spacedim>
1259 Assert (dynamic_cast<const InternalData *>(&mapping_data) !=
nullptr,
1263 switch (mapping_type)
1270 for (
unsigned int q=0; q<output.size(); ++q)
1271 for (
unsigned int i=0; i<spacedim; ++i)
1272 for (
unsigned int j=0; j<spacedim; ++j)
1275 for (
unsigned int K=0; K<dim; ++K)
1277 tmp[K] = data.
covariant[q][j][0] * input[q][i][0][K];
1278 for (
unsigned int J=1; J<dim; ++J)
1279 tmp[K] += data.
covariant[q][j][J] * input[q][i][J][K];
1281 for (
unsigned int k=0; k<spacedim; ++k)
1283 output[q][i][j][k] = data.
covariant[q][k][0] * tmp[0];
1284 for (
unsigned int K=1; K<dim; ++K)
1285 output[q][i][j][k] += data.
covariant[q][k][K] * tmp[K];
1298 template <
int dim,
int spacedim>
1306 switch (mapping_type)
1311 internal::MappingManifoldImplementation::transform_hessians(input, mapping_type, mapping_data, output);
1319 #include "mapping_manifold.inst" 1322 DEAL_II_NAMESPACE_CLOSE
Transformed quadrature weights.
static const unsigned int invalid_unsigned_int
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 std::unique_ptr< Mapping< dim, spacedim > > clone() const override
#define AssertDimension(dim1, dim2)
Number determinant(const SymmetricTensor< 2, dim, Number > &)
Contravariant transformation.
const std::vector< double > & get_weights() const
Point< spacedim > point(const gp_Pnt &p, const double &tolerance=1e-10)
std::array< std::vector< Tensor< 1, dim > >, GeometryInfo< dim >::faces_per_cell *(dim-1)> unit_tangentials
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
Outer normal vector, not normalized.
Determinant of the Jacobian.
Transformed quadrature points.
void store_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
Triangulation< dim, spacedim >::cell_iterator cell
virtual std::size_t memory_consumption() const override
numbers::NumberTraits< Number >::real_type norm() const
static DataSetDescriptor 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
static ::ExceptionBase & ExcMessage(std::string arg1)
std::vector< std::vector< Tensor< 1, spacedim > > > aux
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static Point< dim, Number > unit_vector(const unsigned int i)
Abstract base class for mapping classes.
void initialize(const UpdateFlags update_flags, const Quadrature< dim > &quadrature, const unsigned int n_original_q_points)
std::vector< DerivativeForm< 1, dim, spacedim > > covariant
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)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
std::vector< double > volume_elements
unsigned int size() const
std::vector< DerivativeForm< 1, dim, spacedim > > contravariant
std::vector< double > vertex_weights
SmartPointer< const Manifold< dim, spacedim > > manifold
Number determinant(const Tensor< 2, dim, Number > &t)
static double d_linear_shape_function(const Point< dim > &xi, const unsigned int i)
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 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
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::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
MappingManifold()=default
static ::ExceptionBase & ExcInternalError()