deal.II version GIT relicensing-6809-ge913b9bb34 2026-09-25 17: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
manifold.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) 2014 - 2024 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#ifndef dealii_tria_manifold_h
14#define dealii_tria_manifold_h
15
16
17/*---------------------------- manifold.h ---------------------------*/
18
19#include <deal.II/base/config.h>
20
24#include <deal.II/base/point.h>
26
27#include <deal.II/grid/tria.h>
28
30
31// forward declaration
32#ifndef DOXYGEN
33template <int, typename>
34class Table;
35#endif
36
41namespace Manifolds
42{
49 template <typename MeshIteratorType>
50 inline constexpr std::size_t
52 {
53 // Note that in C++11 a constexpr function can only have a return
54 // statement, so we cannot alias the structure dimension
56 vertices_per_cell +
58 lines_per_cell +
60 quads_per_cell +
62 hexes_per_cell -
63 1; // don't count the cell itself, just the bounding objects
64 }
65
108 template <typename MeshIteratorType>
109 std::pair<std::array<Point<MeshIteratorType::AccessorType::space_dimension>,
110 n_default_points_per_cell<MeshIteratorType>()>,
111 std::array<double, n_default_points_per_cell<MeshIteratorType>()>>
112 get_default_points_and_weights(const MeshIteratorType &iterator,
113 const bool with_interpolation = false);
114} // namespace Manifolds
115
116
117
282template <int dim, int spacedim = dim>
284{
285public:
286 // explicitly check for sensible template arguments
287 static_assert(dim <= spacedim,
288 "The dimension <dim> of a Manifold must be less than or "
289 "equal to the space dimension <spacedim> in which it lives.");
290
291
304 std::array<Tensor<1, spacedim>, GeometryInfo<dim>::vertices_per_face>;
305
306
311 virtual ~Manifold() override = default;
312
318 virtual std::unique_ptr<Manifold<dim, spacedim>>
319 clone() const = 0;
320
325
343 virtual Point<spacedim>
345 const Point<spacedim> &p2,
346 const double w) const;
347
364 virtual Point<spacedim>
365 get_new_point(const ArrayView<const Point<spacedim>> &surrounding_points,
366 const ArrayView<const double> &weights) const;
367
368
389 virtual void
390 get_new_points(const ArrayView<const Point<spacedim>> &surrounding_points,
391 const Table<2, double> &weights,
392 ArrayView<Point<spacedim>> new_points) const;
393
405 virtual Point<spacedim>
407 const ArrayView<const Point<spacedim>> &surrounding_points,
408 const Point<spacedim> &candidate) const;
409
423 virtual Point<spacedim>
425 const typename Triangulation<dim, spacedim>::line_iterator &line) const;
426
444 virtual Point<spacedim>
446 const typename Triangulation<dim, spacedim>::quad_iterator &quad) const;
447
466 virtual Point<spacedim>
468 const typename Triangulation<dim, spacedim>::hex_iterator &hex) const;
469
470
479 const typename Triangulation<dim, spacedim>::face_iterator &face) const;
480
481
490 const typename Triangulation<dim, spacedim>::cell_iterator &cell) const;
491
535 virtual Tensor<1, spacedim>
537 const Point<spacedim> &x2) const;
538
594 virtual Tensor<1, spacedim>
597 const Point<spacedim> &p) const;
598
613 virtual void
616 FaceVertexNormals &face_vertex_normals) const;
617
619};
620
621
631template <int dim, int spacedim = dim>
632class FlatManifold : public Manifold<dim, spacedim>
633{
634public:
663 const double tolerance = 1e-10);
664
668 virtual std::unique_ptr<Manifold<dim, spacedim>>
669 clone() const override;
670
692 virtual Point<spacedim>
693 get_new_point(const ArrayView<const Point<spacedim>> &surrounding_points,
694 const ArrayView<const double> &weights) const override;
695
696
707 virtual void
708 get_new_points(const ArrayView<const Point<spacedim>> &surrounding_points,
709 const Table<2, double> &weights,
710 ArrayView<Point<spacedim>> new_points) const override;
711
719 virtual Point<spacedim>
721 const Point<spacedim> &candidate) const override;
722
744 virtual Tensor<1, spacedim>
746 const Point<spacedim> &x2) const override;
747
755 virtual Tensor<1, spacedim>
758 const Point<spacedim> &p) const override;
759
768 virtual void
771 typename Manifold<dim, spacedim>::FaceVertexNormals &face_vertex_normals)
772 const override;
773
777 const Tensor<1, spacedim> &
779
783 double
785
786private:
801
803 int,
805 double,
806 << "The component number " << arg1 << " of the point [ "
807 << arg2 << " ] is not in the interval [ 0, " << arg3
808 << "), bailing out.");
809
814 const double tolerance;
815};
816
817
904template <int dim, int spacedim = dim, int chartdim = dim>
905class ChartManifold : public Manifold<dim, spacedim>
906{
907public:
908 // explicitly check for sensible template arguments
909 static_assert(dim <= spacedim,
910 "The dimension <dim> of a ChartManifold must be less than or "
911 "equal to the space dimension <spacedim> in which it lives.");
912
928
933 virtual ~ChartManifold() override = default;
934
939 virtual Point<spacedim>
941 const Point<spacedim> &p2,
942 const double w) const override;
943
948 virtual Point<spacedim>
949 get_new_point(const ArrayView<const Point<spacedim>> &surrounding_points,
950 const ArrayView<const double> &weights) const override;
951
973 virtual void
974 get_new_points(const ArrayView<const Point<spacedim>> &surrounding_points,
975 const Table<2, double> &weights,
976 ArrayView<Point<spacedim>> new_points) const override;
983 virtual Point<chartdim>
984 pull_back(const Point<spacedim> &space_point) const = 0;
985
992 virtual Point<spacedim>
993 push_forward(const Point<chartdim> &chart_point) const = 0;
994
1012 push_forward_gradient(const Point<chartdim> &chart_point) const;
1013
1069 virtual Tensor<1, spacedim>
1071 const Point<spacedim> &x2) const override;
1072
1076 const Tensor<1, chartdim> &
1077 get_periodicity() const;
1078
1079private:
1092};
1093
1094
1095/* -------------- declaration of explicit specializations ------------- */
1096
1097#ifndef DOXYGEN
1098
1099template <>
1103
1104template <>
1108
1109
1110template <>
1114
1115
1116template <>
1120
1121template <>
1125
1126
1127template <>
1131
1132
1133template <>
1136 const Triangulation<3, 3>::hex_iterator &) const;
1137
1138/*---Templated functions---*/
1139
1140template <int dim, int spacedim>
1141inline double
1143{
1144 return tolerance;
1145}
1146
1147
1148
1149namespace Manifolds
1150{
1151 template <typename MeshIteratorType>
1152 std::pair<std::array<Point<MeshIteratorType::AccessorType::space_dimension>,
1153 n_default_points_per_cell<MeshIteratorType>()>,
1154 std::array<double, n_default_points_per_cell<MeshIteratorType>()>>
1155 get_default_points_and_weights(const MeshIteratorType &iterator,
1156 const bool with_interpolation)
1157 {
1158 const int dim = MeshIteratorType::AccessorType::structure_dimension;
1159 const int spacedim = MeshIteratorType::AccessorType::space_dimension;
1160 constexpr std::size_t points_per_cell =
1161 n_default_points_per_cell<MeshIteratorType>();
1162
1163 std::pair<std::array<Point<spacedim>, points_per_cell>,
1164 std::array<double, points_per_cell>>
1165 points_weights;
1166
1167
1168 // note that the exact weights are chosen such as to minimize the
1169 // distortion of the four new quads from the optimal shape; their
1170 // derivation and values is copied over from the
1171 // interpolation function in the mapping
1172 switch (dim)
1173 {
1174 case 1:
1175 Assert(points_weights.first.size() == 2, ExcInternalError());
1176 Assert(points_weights.second.size() == 2, ExcInternalError());
1177 points_weights.first[0] = iterator->vertex(0);
1178 points_weights.second[0] = .5;
1179 points_weights.first[1] = iterator->vertex(1);
1180 points_weights.second[1] = .5;
1181 break;
1182 case 2:
1183 Assert(points_weights.first.size() == 8, ExcInternalError());
1184 Assert(points_weights.second.size() == 8, ExcInternalError());
1185
1186 for (unsigned int i = 0; i < 4; ++i)
1187 {
1188 points_weights.first[i] = iterator->vertex(i);
1189 points_weights.first[4 + i] =
1190 (iterator->line(i)->has_children() ?
1191 iterator->line(i)->child(0)->vertex(1) :
1192 iterator->line(i)->get_manifold().get_new_point_on_line(
1193 iterator->line(i)));
1194 }
1195
1196 if (with_interpolation)
1197 {
1198 std::fill(points_weights.second.begin(),
1199 points_weights.second.begin() + 4,
1200 -0.25);
1201 std::fill(points_weights.second.begin() + 4,
1202 points_weights.second.end(),
1203 0.5);
1204 }
1205 else
1206 std::fill(points_weights.second.begin(),
1207 points_weights.second.end(),
1208 1.0 / 8.0);
1209 break;
1210 case 3:
1211 {
1214 const unsigned int np = GeometryInfo<dim>::vertices_per_cell +
1217 Assert(points_weights.first.size() == np, ExcInternalError());
1218 Assert(points_weights.second.size() == np, ExcInternalError());
1219 auto *sp3 = reinterpret_cast<
1220 std::array<Point<3>, n_default_points_per_cell<decltype(hex)>()>
1221 *>(&points_weights.first);
1222
1223 unsigned int j = 0;
1224
1225 // note that the exact weights are chosen such as to minimize the
1226 // distortion of the eight new hexes from the optimal shape through
1227 // transfinite interpolation from the faces and vertices, see
1228 // TransfiniteInterpolationManifold for a deeper explanation of the
1229 // mechanisms
1230 if (with_interpolation)
1231 {
1232 for (unsigned int i = 0;
1233 i < GeometryInfo<dim>::vertices_per_cell;
1234 ++i, ++j)
1235 {
1236 (*sp3)[j] = hex->vertex(i);
1237 points_weights.second[j] = 1.0 / 8.0;
1238 }
1239 for (unsigned int i = 0; i < GeometryInfo<dim>::lines_per_cell;
1240 ++i, ++j)
1241 {
1242 (*sp3)[j] =
1243 (hex->line(i)->has_children() ?
1244 hex->line(i)->child(0)->vertex(1) :
1245 hex->line(i)->get_manifold().get_new_point_on_line(
1246 hex->line(i)));
1247 points_weights.second[j] = -1.0 / 4.0;
1248 }
1249 for (unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell;
1250 ++i, ++j)
1251 {
1252 (*sp3)[j] =
1253 (hex->quad(i)->has_children() ?
1254 hex->quad(i)->isotropic_child(0)->vertex(3) :
1255 hex->quad(i)->get_manifold().get_new_point_on_quad(
1256 hex->quad(i)));
1257 points_weights.second[j] = 1.0 / 2.0;
1258 }
1259 }
1260 else
1261 // Overwrite the weights with 1/np if we don't want to use
1262 // interpolation.
1263 std::fill(points_weights.second.begin(),
1264 points_weights.second.end(),
1265 1.0 / np);
1266 }
1267 break;
1268 default:
1270 break;
1271 }
1272 return points_weights;
1273 }
1274} // namespace Manifolds
1275
1276#endif // DOXYGEN
1277
1279
1280#endif
*  *  iterator()=default
virtual Point< spacedim > push_forward(const Point< chartdim > &chart_point) const =0
const FlatManifold< chartdim, chartdim > sub_manifold
Definition manifold.h:1091
virtual void get_new_points(const ArrayView< const Point< spacedim > > &surrounding_points, const Table< 2, double > &weights, ArrayView< Point< spacedim > > new_points) const override
Definition manifold.cc:1056
virtual Point< chartdim > pull_back(const Point< spacedim > &space_point) const =0
virtual Tensor< 1, spacedim > get_tangent_vector(const Point< spacedim > &x1, const Point< spacedim > &x2) const override
Definition manifold.cc:1095
virtual DerivativeForm< 1, chartdim, spacedim > push_forward_gradient(const Point< chartdim > &chart_point) const
Definition manifold.cc:1082
const Tensor< 1, chartdim > & get_periodicity() const
Definition manifold.cc:1127
virtual ~ChartManifold() override=default
virtual Point< spacedim > get_intermediate_point(const Point< spacedim > &p1, const Point< spacedim > &p2, const double w) const override
Definition manifold.cc:1021
virtual Point< spacedim > get_new_point(const ArrayView< const Point< spacedim > > &surrounding_points, const ArrayView< const double > &weights) const override
Definition manifold.cc:1035
virtual Tensor< 1, spacedim > normal_vector(const typename Triangulation< dim, spacedim >::face_iterator &face, const Point< spacedim > &p) const override
virtual void get_normals_at_vertices(const typename Triangulation< dim, spacedim >::face_iterator &face, typename Manifold< dim, spacedim >::FaceVertexNormals &face_vertex_normals) const override
virtual Tensor< 1, spacedim > get_tangent_vector(const Point< spacedim > &x1, const Point< spacedim > &x2) const override
double get_tolerance() const
virtual Point< spacedim > project_to_manifold(const ArrayView< const Point< spacedim > > &points, const Point< spacedim > &candidate) const override
const Tensor< 1, spacedim > & get_periodicity() const
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const override
virtual Point< spacedim > get_new_point(const ArrayView< const Point< spacedim > > &surrounding_points, const ArrayView< const double > &weights) const override
const Tensor< 1, spacedim > periodicity
Definition manifold.h:800
FlatManifold(const Tensor< 1, spacedim > &periodicity=Tensor< 1, spacedim >(), const double tolerance=1e-10)
const double tolerance
Definition manifold.h:814
virtual void get_new_points(const ArrayView< const Point< spacedim > > &surrounding_points, const Table< 2, double > &weights, ArrayView< Point< spacedim > > new_points) const override
virtual Point< spacedim > get_new_point_on_hex(const typename Triangulation< dim, spacedim >::hex_iterator &hex) const
virtual Point< spacedim > get_new_point_on_line(const typename Triangulation< dim, spacedim >::line_iterator &line) const
virtual Point< spacedim > project_to_manifold(const ArrayView< const Point< spacedim > > &surrounding_points, const Point< spacedim > &candidate) const
virtual void get_new_points(const ArrayView< const Point< spacedim > > &surrounding_points, const Table< 2, double > &weights, ArrayView< Point< spacedim > > new_points) const
virtual void get_normals_at_vertices(const typename Triangulation< dim, spacedim >::face_iterator &face, FaceVertexNormals &face_vertex_normals) const
virtual ~Manifold() override=default
virtual Tensor< 1, spacedim > get_tangent_vector(const Point< spacedim > &x1, const Point< spacedim > &x2) const
std::array< Tensor< 1, spacedim >, GeometryInfo< dim >::vertices_per_face > FaceVertexNormals
Definition manifold.h:304
virtual Point< spacedim > get_intermediate_point(const Point< spacedim > &p1, const Point< spacedim > &p2, const double w) const
Point< spacedim > get_new_point_on_face(const typename Triangulation< dim, spacedim >::face_iterator &face) const
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const =0
virtual Point< spacedim > get_new_point_on_quad(const typename Triangulation< dim, spacedim >::quad_iterator &quad) const
virtual Tensor< 1, spacedim > normal_vector(const typename Triangulation< dim, spacedim >::face_iterator &face, const Point< spacedim > &p) const
Point< spacedim > get_new_point_on_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
virtual Point< spacedim > get_new_point(const ArrayView< const Point< spacedim > > &surrounding_points, const ArrayView< const double > &weights) const
Definition point.h:111
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_ASSERT_UNREACHABLE()
static ::ExceptionBase & ExcPeriodicBox(int arg1, Point< spacedim > arg2, double arg3)
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
#define DeclException3(Exception3, type1, type2, type3, outsequence)
typename IteratorSelector::hex_iterator hex_iterator
Definition tria.h:1756
typename IteratorSelector::quad_iterator quad_iterator
Definition tria.h:1732
typename IteratorSelector::line_iterator line_iterator
Definition tria.h:1708
std::pair< std::array< Point< MeshIteratorType::AccessorType::space_dimension >, n_default_points_per_cell< MeshIteratorType >()>, std::array< double, n_default_points_per_cell< MeshIteratorType >()> > get_default_points_and_weights(const MeshIteratorType &iterator, const bool with_interpolation=false)
constexpr std::size_t n_default_points_per_cell()
Definition manifold.h:51