Reference documentation for deal.II version 9.0.0
manifold.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_tria_manifold_h
17 #define dealii_tria_manifold_h
18 
19 
20 /*---------------------------- manifold.h ---------------------------*/
21 
22 #include <deal.II/base/config.h>
23 #include <deal.II/base/array_view.h>
24 #include <deal.II/base/subscriptor.h>
25 #include <deal.II/base/quadrature_lib.h>
26 #include <deal.II/base/thread_management.h>
27 #include <deal.II/base/point.h>
28 #include <deal.II/base/derivative_form.h>
29 #include <deal.II/grid/tria.h>
30 
31 DEAL_II_NAMESPACE_OPEN
32 
33 // forward declaration
34 template <int, typename> class Table;
35 
40 namespace Manifolds
41 {
48  template <typename MeshIteratorType>
49  inline
50  constexpr std::size_t n_default_points_per_cell()
51  {
52  // Note that in C++11 a constexpr function can only have a return
53  // statement, so we cannot alias the structure dimension
58  - 1; // don't count the cell itself, just the bounding objects
59  }
60 
103  template <typename MeshIteratorType>
104  DEAL_II_DEPRECATED
106  get_default_quadrature(const MeshIteratorType &iterator,
107  const bool with_interpolation = false);
108 
151  template <typename MeshIteratorType>
152  std::pair<std::array<Point<MeshIteratorType::AccessorType::space_dimension>,
153  n_default_points_per_cell<MeshIteratorType>()>,
154  std::array<double, n_default_points_per_cell<MeshIteratorType>()> >
155  get_default_points_and_weights(const MeshIteratorType &iterator,
156  const bool with_interpolation = false);
157 }
158 
322 template <int dim, int spacedim=dim>
323 class Manifold : public Subscriptor
324 {
325 public:
326 
327  // explicitly check for sensible template arguments
328  static_assert (dim<=spacedim,
329  "The dimension <dim> of a Manifold must be less than or "
330  "equal to the space dimension <spacedim> in which it lives.");
331 
332 
345 
346 
351  virtual ~Manifold () = default;
352 
358  virtual std::unique_ptr<Manifold<dim,spacedim> > clone() const = 0;
359 
363 
382  virtual
385  const Point<spacedim> &p2,
386  const double w) const;
387 
404  virtual
406  get_new_point (const ArrayView<const Point<spacedim>> &surrounding_points,
407  const ArrayView<const double> &weights) const;
408 
409 
430  virtual
431  void
432  get_new_points (const ArrayView<const Point<spacedim>> &surrounding_points,
433  const Table<2,double> &weights,
434  ArrayView<Point<spacedim>> new_points) const;
435 
447  virtual
448  Point<spacedim> project_to_manifold (const ArrayView<const Point<spacedim>> &surrounding_points,
449  const Point<spacedim> &candidate) const;
450 
464  virtual
466  get_new_point_on_line (const typename Triangulation<dim,spacedim>::line_iterator &line) const;
467 
485  virtual
487  get_new_point_on_quad (const typename Triangulation<dim,spacedim>::quad_iterator &quad) const;
488 
507  virtual
509  get_new_point_on_hex (const typename Triangulation<dim,spacedim>::hex_iterator &hex) const;
510 
511 
520 
521 
530 
532 
536 
572  virtual
575  const Point<spacedim> &x2) const;
576 
578 
582 
629  virtual
632  const Point<spacedim> &p) const;
633 
648  virtual
649  void
651  FaceVertexNormals &face_vertex_normals) const;
652 
654 };
655 
656 
668 template <int dim, int spacedim=dim>
669 class FlatManifold : public Manifold<dim, spacedim>
670 {
671 public:
700  const double tolerance=1e-10);
701 
705  virtual std::unique_ptr<Manifold<dim,spacedim> > clone() const override;
706 
728  virtual
730  get_new_point(const ArrayView<const Point<spacedim>> &surrounding_points,
731  const ArrayView<const double> &weights) const override;
732 
733 
744  virtual
745  void
746  get_new_points (const ArrayView<const Point<spacedim>> &surrounding_points,
747  const Table<2,double> &weights,
748  ArrayView<Point<spacedim>> new_points) const override;
749 
757  virtual
759  project_to_manifold (const ArrayView<const Point<spacedim>> &points,
760  const Point<spacedim> &candidate) const override;
761 
783  virtual
786  const Point<spacedim> &x2) const override;
787 
795  virtual
798  const Point<spacedim> &p) const override;
799 
808  virtual
809  void
811  typename Manifold<dim, spacedim>::FaceVertexNormals &face_vertex_normals) const override;
812 
816  const Tensor<1,spacedim> &get_periodicity() const;
817 
818 private:
833 
835  << "The component number " << arg1 << " of the point [ " << arg2
836  << " ] is not in the interval [ 0, " << arg3 << "), bailing out.");
837 
842  const double tolerance;
843 };
844 
845 
934 template <int dim, int spacedim=dim, int chartdim=dim>
935 class ChartManifold : public Manifold<dim,spacedim>
936 {
937 public:
938  // explicitly check for sensible template arguments
939  static_assert (dim<=spacedim,
940  "The dimension <dim> of a ChartManifold must be less than or "
941  "equal to the space dimension <spacedim> in which it lives.");
942 
957  ChartManifold(const Tensor<1,chartdim> &periodicity = Tensor<1,chartdim>());
958 
963  virtual ~ChartManifold () override = default;
964 
969  virtual
972  const Point<spacedim> &p2,
973  const double w) const override;
974 
979  virtual
981  get_new_point(const ArrayView<const Point<spacedim>> &surrounding_points,
982  const ArrayView<const double> &weights) const override;
983 
1005  virtual
1006  void
1007  get_new_points (const ArrayView<const Point<spacedim>> &surrounding_points,
1008  const Table<2,double> &weights,
1009  ArrayView<Point<spacedim>> new_points) const override;
1016  virtual
1018  pull_back(const Point<spacedim> &space_point) const = 0;
1019 
1026  virtual
1028  push_forward(const Point<chartdim> &chart_point) const = 0;
1029 
1046  virtual
1048  push_forward_gradient(const Point<chartdim> &chart_point) const;
1049 
1105  virtual
1108  const Point<spacedim> &x2) const override;
1109 
1113  const Tensor<1,chartdim> &get_periodicity() const;
1114 
1115 private:
1128 };
1129 
1130 
1131 /* -------------- declaration of explicit specializations ------------- */
1132 
1133 #ifndef DOXYGEN
1134 
1135 template <>
1136 Point<1>
1139 
1140 template <>
1141 Point<2>
1144 
1145 
1146 template <>
1147 Point<3>
1150 
1151 
1152 template <>
1153 Point<1>
1155 get_new_point_on_quad (const Triangulation<1,1>::quad_iterator &) const;
1156 
1157 template <>
1158 Point<2>
1160 get_new_point_on_quad (const Triangulation<1,2>::quad_iterator &) const;
1161 
1162 
1163 template <>
1164 Point<3>
1166 get_new_point_on_quad (const Triangulation<1,3>::quad_iterator &) const;
1167 
1168 
1169 template <>
1170 Point<3>
1172 get_new_point_on_hex (const Triangulation<3,3>::hex_iterator &) const;
1173 
1174 /*---Templated functions---*/
1175 
1176 namespace Manifolds
1177 {
1178  template <typename MeshIteratorType>
1180  get_default_quadrature(const MeshIteratorType &iterator,
1181  const bool with_interpolation)
1182  {
1183  const auto points_and_weights = get_default_points_and_weights(iterator, with_interpolation);
1184  static const int spacedim = MeshIteratorType::AccessorType::space_dimension;
1185  return Quadrature<spacedim>
1186  (std::vector<Point<spacedim>>(points_and_weights.first.begin(),
1187  points_and_weights.first.end()),
1188  std::vector<double>(points_and_weights.second.begin(),
1189  points_and_weights.second.end()));
1190  }
1191 
1192 
1193 
1194  template <typename MeshIteratorType>
1195  std::pair<std::array<Point<MeshIteratorType::AccessorType::space_dimension>,
1196  n_default_points_per_cell<MeshIteratorType>()>,
1197  std::array<double, n_default_points_per_cell<MeshIteratorType>()> >
1198  get_default_points_and_weights(const MeshIteratorType &iterator,
1199  const bool with_interpolation)
1200  {
1201  const int dim = MeshIteratorType::AccessorType::structure_dimension;
1202  const int spacedim = MeshIteratorType::AccessorType::space_dimension;
1203  constexpr std::size_t points_per_cell = n_default_points_per_cell<MeshIteratorType>();
1204 
1205  std::pair<std::array<Point<spacedim>, points_per_cell>, std::array<double, points_per_cell> >
1206  points_weights;
1207 
1208 
1209  // note that the exact weights are chosen such as to minimize the
1210  // distortion of the four new quads from the optimal shape; their
1211  // derivation and values is copied over from the
1212  // interpolation function in the mapping
1213  switch (dim)
1214  {
1215  case 1:
1216  Assert(points_weights.first.size() == 2, ExcInternalError());
1217  Assert(points_weights.second.size() == 2, ExcInternalError());
1218  points_weights.first[0] = iterator->vertex(0);
1219  points_weights.second[0] = .5;
1220  points_weights.first[1] = iterator->vertex(1);
1221  points_weights.second[1] = .5;
1222  break;
1223  case 2:
1224  Assert(points_weights.first.size() == 8, ExcInternalError());
1225  Assert(points_weights.second.size() == 8, ExcInternalError());
1226 
1227  for (unsigned int i=0; i<4; ++i)
1228  {
1229  points_weights.first[i] = iterator->vertex(i);
1230  points_weights.first[4+i] = ( iterator->line(i)->has_children() ?
1231  iterator->line(i)->child(0)->vertex(1) :
1232  iterator->line(i)->get_manifold().get_new_point_on_line(iterator->line(i)) );
1233  }
1234 
1235  if (with_interpolation)
1236  {
1237  std::fill(points_weights.second.begin(), points_weights.second.begin()+4, -0.25);
1238  std::fill(points_weights.second.begin()+4, points_weights.second.end(), 0.5);
1239  }
1240  else
1241  std::fill(points_weights.second.begin(), points_weights.second.end(), 1.0/8.0);
1242  break;
1243  case 3:
1244  {
1246  = static_cast<TriaIterator<TriaAccessor<3, 3, 3> > >(iterator);
1247  const unsigned int np =
1251  Assert(points_weights.first.size() == np, ExcInternalError());
1252  Assert(points_weights.second.size() == np, ExcInternalError());
1253  auto *sp3 = reinterpret_cast<std::array<Point<3>, n_default_points_per_cell<decltype(hex)>()> *>
1254  (&points_weights.first);
1255 
1256  unsigned int j=0;
1257 
1258  // note that the exact weights are chosen such as to minimize the
1259  // distortion of the eight new hexes from the optimal shape through
1260  // transfinite interpolation from the faces and vertices, see
1261  // TransfiniteInterpolationManifold for a deeper explanation of the
1262  // mechanisms
1263  if (with_interpolation)
1264  {
1265  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i, ++j)
1266  {
1267  (*sp3)[j] = hex->vertex(i);
1268  points_weights.second[j] = 1.0/8.0;
1269  }
1270  for (unsigned int i=0; i<GeometryInfo<dim>::lines_per_cell; ++i, ++j)
1271  {
1272  (*sp3)[j] = (hex->line(i)->has_children() ?
1273  hex->line(i)->child(0)->vertex(1) :
1274  hex->line(i)->get_manifold().get_new_point_on_line(hex->line(i)));
1275  points_weights.second[j] = -1.0/4.0;
1276  }
1277  for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i, ++j)
1278  {
1279  (*sp3)[j] = (hex->quad(i)->has_children() ?
1280  hex->quad(i)->isotropic_child(0)->vertex(3) :
1281  hex->quad(i)->get_manifold().get_new_point_on_quad(hex->quad(i)));
1282  points_weights.second[j] = 1.0/2.0;
1283  }
1284  }
1285  else
1286  // Overwrite the weights with 1/np if we don't want to use
1287  // interpolation.
1288  std::fill(points_weights.second.begin(), points_weights.second.end(), 1.0/np);
1289  }
1290  break;
1291  default:
1292  Assert(false, ExcInternalError());
1293  break;
1294  }
1295  return points_weights;
1296  }
1297 }
1298 
1299 #endif // DOXYGEN
1300 
1301 DEAL_II_NAMESPACE_CLOSE
1302 
1303 #endif
const Tensor< 1, spacedim > periodicity
Definition: manifold.h:832
FlatManifold(const Tensor< 1, spacedim > &periodicity=Tensor< 1, spacedim >(), const double tolerance=1e-10)
Definition: manifold.cc:507
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)
virtual Tensor< 1, spacedim > normal_vector(const typename Triangulation< dim, spacedim >::face_iterator &face, const Point< spacedim > &p) const override
Definition: manifold.cc:841
const FlatManifold< chartdim, chartdim > sub_manifold
Definition: manifold.h:1127
const Tensor< 1, spacedim > & get_periodicity() const
Definition: manifold.cc:669
virtual Point< spacedim > get_new_point_on_hex(const typename Triangulation< dim, spacedim >::hex_iterator &hex) const
Definition: manifold.cc:440
virtual Point< spacedim > get_new_point(const ArrayView< const Point< spacedim >> &surrounding_points, const ArrayView< const double > &weights) const
Definition: manifold.cc:63
virtual ~ChartManifold() override=default
constexpr std::size_t n_default_points_per_cell()
Definition: manifold.h:50
virtual Point< spacedim > get_new_point_on_line(const typename Triangulation< dim, spacedim >::line_iterator &line) const
Definition: manifold.cc:306
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const =0
virtual Tensor< 1, spacedim > get_tangent_vector(const Point< spacedim > &x1, const Point< spacedim > &x2) const
Definition: manifold.cc:464
virtual DerivativeForm< 1, chartdim, spacedim > push_forward_gradient(const Point< chartdim > &chart_point) const
Definition: manifold.cc:1009
Quadrature< MeshIteratorType::AccessorType::space_dimension > get_default_quadrature(const MeshIteratorType &iterator, const bool with_interpolation=false)
virtual Point< spacedim > project_to_manifold(const ArrayView< const Point< spacedim >> &surrounding_points, const Point< spacedim > &candidate) const
Definition: manifold.cc:37
#define Assert(cond, exc)
Definition: exceptions.h:1142
virtual ~Manifold()=default
static ::ExceptionBase & ExcPeriodicBox(int arg1, Point< spacedim > arg2, double arg3)
Tensor< 1, spacedim > FaceVertexNormals[GeometryInfo< dim >::vertices_per_face]
Definition: manifold.h:330
const Tensor< 1, chartdim > & get_periodicity() const
Definition: manifold.cc:1050
virtual Point< spacedim > project_to_manifold(const ArrayView< const Point< spacedim >> &points, const Point< spacedim > &candidate) const override
Definition: manifold.cc:659
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const override
Definition: manifold.cc:518
const double tolerance
Definition: manifold.h:842
virtual Point< spacedim > get_intermediate_point(const Point< spacedim > &p1, const Point< spacedim > &p2, const double w) const
Definition: manifold.cc:49
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:980
virtual Tensor< 1, spacedim > get_tangent_vector(const Point< spacedim > &x1, const Point< spacedim > &x2) const override
Definition: manifold.cc:1022
virtual void get_new_points(const ArrayView< const Point< spacedim >> &surrounding_points, const Table< 2, double > &weights, ArrayView< Point< spacedim >> new_points) const
Definition: manifold.cc:114
virtual Tensor< 1, spacedim > get_tangent_vector(const Point< spacedim > &x1, const Point< spacedim > &x2) const override
Definition: manifold.cc:678
virtual Point< spacedim > get_new_point(const ArrayView< const Point< spacedim >> &surrounding_points, const ArrayView< const double > &weights) const override
Definition: manifold.cc:958
virtual Point< spacedim > get_new_point_on_quad(const typename Triangulation< dim, spacedim >::quad_iterator &quad) const
Definition: manifold.cc:320
virtual Point< spacedim > get_new_point(const ArrayView< const Point< spacedim >> &surrounding_points, const ArrayView< const double > &weights) const override
Definition: manifold.cc:528
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 Point< spacedim > push_forward(const Point< chartdim > &chart_point) const =0
Definition: table.h:34
virtual Tensor< 1, spacedim > normal_vector(const typename Triangulation< dim, spacedim >::face_iterator &face, const Point< spacedim > &p) const
Definition: manifold.cc:226
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:370
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:583
ChartManifold(const Tensor< 1, chartdim > &periodicity=Tensor< 1, chartdim >())
Definition: manifold.cc:933
Point< spacedim > get_new_point_on_face(const typename Triangulation< dim, spacedim >::face_iterator &face) const
Definition: manifold.cc:334
virtual void get_normals_at_vertices(const typename Triangulation< dim, spacedim >::face_iterator &face, FaceVertexNormals &face_vertex_normals) const
Definition: manifold.cc:291
virtual Point< chartdim > pull_back(const Point< spacedim > &space_point) const =0
virtual Point< spacedim > get_intermediate_point(const Point< spacedim > &p1, const Point< spacedim > &p2, const double w) const override
Definition: manifold.cc:943
static ::ExceptionBase & ExcInternalError()
Point< spacedim > get_new_point_on_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
Definition: manifold.cc:354