55 VTK_QUADRATIC_EDGE = 21,
56 VTK_QUADRATIC_TRIANGLE = 22,
57 VTK_QUADRATIC_QUAD = 23,
58 VTK_QUADRATIC_TETRA = 24,
59 VTK_QUADRATIC_HEXAHEDRON = 25,
60 VTK_QUADRATIC_WEDGE = 26,
61 VTK_QUADRATIC_PYRAMID = 27,
63 VTK_LAGRANGE_CURVE = 68,
64 VTK_LAGRANGE_TRIANGLE = 69,
65 VTK_LAGRANGE_QUADRILATERAL = 70,
66 VTK_LAGRANGE_TETRAHEDRON = 71,
67 VTK_LAGRANGE_HEXAHEDRON = 72,
68 VTK_LAGRANGE_WEDGE = 73,
69 VTK_LAGRANGE_PYRAMID = 74,
122 const unsigned int child_no,
123 const unsigned int vertex_no,
132 [[maybe_unused]]
const auto V = [](
const unsigned int d) {
136 switch (reference_cell)
144 if constexpr (dim == 1)
147 isotropic_child_vertices = {{
149 {{0.5 *
V(0),
V(0)}},
151 return isotropic_child_vertices[child_no][vertex_no];
160 if constexpr (dim == 2)
163 isotropic_child_vertices = {{
164 {{V0, 0.5 *
V(0), 0.5 *
V(1)}},
165 {{0.5 *
V(0),
V(0), 0.5 * (
V(0) +
V(1))}},
166 {{0.5 *
V(1), 0.5 *
V(0) + 0.5 *
V(1),
V(1)}},
167 {{0.5 *
V(0), 0.5 *
V(0) + 0.5 *
V(1), 0.5 *
V(1)}},
169 return isotropic_child_vertices[child_no][vertex_no];
176 if constexpr (dim == 2)
178 static constexpr Point<2> M = 0.5 * (
V(0) +
V(1));
182 {{V0, 0.5 *
V(0),
V(1),
V(1) + 0.5 *
V(0)}},
183 {{0.5 *
V(0),
V(0), 0.5 *
V(0) +
V(1),
V(0) +
V(1)}},
188 {{V0,
V(0), 0.5 *
V(1),
V(0) + 0.5 *
V(1)}},
189 {{0.5 *
V(1),
V(0) + 0.5 *
V(1),
V(1),
V(0) +
V(1)}},
193 isotropic_child_vertices = {{
194 {{V0, 0.5 *
V(0), 0.5 *
V(1), M}},
195 {{0.5 *
V(0),
V(0), M,
V(0) + 0.5 *
V(1)}},
196 {{0.5 *
V(1), M,
V(1),
V(1) + 0.5 *
V(0)}},
197 {{M,
V(0) + 0.5 *
V(1),
V(1) + 0.5 *
V(0),
V(0) +
V(1)}},
200 switch (refinement_case)
203 return cut_x_child_vertices[child_no][vertex_no];
205 return cut_y_child_vertices[child_no][vertex_no];
207 return isotropic_child_vertices[child_no][vertex_no];
233 const unsigned int face_no,
234 const unsigned int subface_no,
235 const unsigned int subface_vertex_no,
243 face_refinement_case));
245 ExcMessage(
"This function may only be called for subfaces."));
248 face_reference_cell(face_no).n_vertices());
251 for (
const unsigned int vertex_no :
258 face_refinement_case),
271 const unsigned int subface_no)
const
284 if constexpr (dim == 1)
292 if constexpr (dim == 2)
297 face_reference_cell(0).n_isotropic_children());
298 return std::make_pair(combined_face_orientation ==
304 else if constexpr (dim == 3)
368 static const unsigned int
392 static const RefinementCase<dim - 1> rotated_refinement_case[4] = {
397 const auto [face_orientation, face_rotation, face_flip] =
400 const auto equivalent_refinement_case =
401 equivalent_refine_case[subface_case][subface_no];
402 const unsigned int equivalent_subface_no =
403 equivalent_subface_number[subface_case][subface_no];
410 (face_orientation == face_rotation ?
411 rotated_refinement_case[equivalent_refinement_case] :
414 const unsigned int final_subface_no =
416 final_refinement_case),
418 equivalent_subface_no,
424 return std::make_pair(final_subface_no, final_refinement_case);
428 (void)combined_face_orientation;
440template <
int spacedim>
441std::unique_ptr<Mapping<dim, spacedim>>
445 return std::make_unique<MappingQ<dim, spacedim>>(degree);
448 return std::make_unique<MappingP1<dim, spacedim>>();
450 return std::make_unique<MappingFE<dim, spacedim>>(
453 return std::make_unique<MappingFE<dim, spacedim>>(
456 return std::make_unique<MappingFE<dim, spacedim>>(
463 return std::make_unique<MappingQ<dim, spacedim>>(degree);
469template <
int spacedim>
532 std::vector<Point<dim>> vertices(reference_cell.n_vertices());
533 for (
const unsigned int v : reference_cell.vertex_indices())
534 vertices[v] = reference_cell.vertex(v);
571 const unsigned int vertex_n)
const
582 constexpr std::array<unsigned int, 4> exodus_to_deal{{0, 1, 3, 2}};
583 return exodus_to_deal[vertex_n];
589 constexpr std::array<unsigned int, 8> exodus_to_deal{
590 {0, 1, 3, 2, 4, 5, 7, 6}};
591 return exodus_to_deal[vertex_n];
595 constexpr std::array<unsigned int, 6> exodus_to_deal{
597 return exodus_to_deal[vertex_n];
601 constexpr std::array<unsigned int, 5> exodus_to_deal{{0, 1, 3, 2, 4}};
602 return exodus_to_deal[vertex_n];
628 constexpr std::array<unsigned int, 4> exodus_to_deal{{2, 1, 3, 0}};
629 return exodus_to_deal[face_n];
633 constexpr std::array<unsigned int, 4> exodus_to_deal{{1, 3, 2, 0}};
634 return exodus_to_deal[face_n];
638 constexpr std::array<unsigned int, 6> exodus_to_deal{
640 return exodus_to_deal[face_n];
644 constexpr std::array<unsigned int, 6> exodus_to_deal{{3, 4, 2, 0, 1}};
645 return exodus_to_deal[face_n];
649 constexpr std::array<unsigned int, 5> exodus_to_deal{{3, 2, 4, 1, 0}};
650 return exodus_to_deal[face_n];
681 constexpr std::array<unsigned int, 4> unv_to_deal{{1, 0, 2, 3}};
682 return unv_to_deal[vertex_n];
686 constexpr std::array<unsigned int, 8> unv_to_deal{
687 {6, 7, 5, 4, 2, 3, 1, 0}};
688 return unv_to_deal[vertex_n];
705 return VTKCellType::VTK_VERTEX;
707 return VTKCellType::VTK_LINE;
709 return VTKCellType::VTK_TRIANGLE;
711 return VTKCellType::VTK_QUAD;
713 return VTKCellType::VTK_TETRA;
715 return VTKCellType::VTK_PYRAMID;
717 return VTKCellType::VTK_WEDGE;
719 return VTKCellType::VTK_HEXAHEDRON;
721 return VTKCellType::VTK_INVALID;
726 return VTKCellType::VTK_INVALID;
738 return VTKCellType::VTK_VERTEX;
740 return VTKCellType::VTK_QUADRATIC_EDGE;
742 return VTKCellType::VTK_QUADRATIC_TRIANGLE;
744 return VTKCellType::VTK_QUADRATIC_QUAD;
746 return VTKCellType::VTK_QUADRATIC_TETRA;
748 return VTKCellType::VTK_QUADRATIC_PYRAMID;
750 return VTKCellType::VTK_QUADRATIC_WEDGE;
752 return VTKCellType::VTK_QUADRATIC_HEXAHEDRON;
754 return VTKCellType::VTK_INVALID;
759 return VTKCellType::VTK_INVALID;
771 return VTKCellType::VTK_VERTEX;
773 return VTKCellType::VTK_LAGRANGE_CURVE;
775 return VTKCellType::VTK_LAGRANGE_TRIANGLE;
777 return VTKCellType::VTK_LAGRANGE_QUADRILATERAL;
779 return VTKCellType::VTK_LAGRANGE_TETRAHEDRON;
781 return VTKCellType::VTK_LAGRANGE_PYRAMID;
783 return VTKCellType::VTK_LAGRANGE_WEDGE;
785 return VTKCellType::VTK_LAGRANGE_HEXAHEDRON;
787 return VTKCellType::VTK_INVALID;
792 return VTKCellType::VTK_INVALID;
800 const std::array<unsigned, dim> &node_indices,
801 const std::array<unsigned, dim> &nodes_per_direction,
802 const bool legacy_format)
const
806 if constexpr (dim == 0)
811 else if constexpr (dim == 1)
817 const unsigned int i = node_indices[0];
819 const bool ibdy = (i == 0 || i == nodes_per_direction[0]);
821 const int nbdy = (ibdy ? 1 : 0);
828 const int offset = 2;
829 return (i - 1) + offset;
831 else if constexpr (dim == 2)
839 const unsigned int i = node_indices[0];
840 const unsigned int j = node_indices[1];
842 const bool ibdy = (i == 0 || i == nodes_per_direction[0]);
843 const bool jbdy = (j == 0 || j == nodes_per_direction[1]);
845 const int nbdy = (ibdy ? 1 : 0) + (jbdy ? 1 : 0);
849 return (i != 0u ? (j != 0u ? 2 : 1) : (j != 0u ? 3 : 0));
858 (j != 0u ? nodes_per_direction[0] - 1 +
859 nodes_per_direction[1] - 1 :
867 (i != 0u ? nodes_per_direction[0] - 1 :
868 2 * (nodes_per_direction[0] - 1) +
869 nodes_per_direction[1] - 1) +
874 offset += 2 * (nodes_per_direction[0] - 1 + nodes_per_direction[1] - 1);
876 return offset + (i - 1) + (nodes_per_direction[0] - 1) * ((j - 1));
878 else if constexpr (dim == 3)
892 const unsigned int i = node_indices[0];
893 const unsigned int j = node_indices[1];
894 const unsigned int k = node_indices[2];
896 const bool ibdy = (i == 0 || i == nodes_per_direction[0]);
897 const bool jbdy = (j == 0 || j == nodes_per_direction[1]);
898 const bool kbdy = (k == 0 || k == nodes_per_direction[2]);
900 const int nbdy = (ibdy ? 1 : 0) + (jbdy ? 1 : 0) + (kbdy ? 1 : 0);
904 return (i != 0u ? (j != 0u ? 2 : 1) : (j != 0u ? 3 : 0)) +
914 (j != 0u ? nodes_per_direction[0] - 1 +
915 nodes_per_direction[1] - 1 :
917 (k != 0u ? 2 * (nodes_per_direction[0] - 1 +
918 nodes_per_direction[1] - 1) :
925 (i != 0u ? nodes_per_direction[0] - 1 :
926 2 * (nodes_per_direction[0] - 1) +
927 nodes_per_direction[1] - 1) +
928 (k != 0u ? 2 * (nodes_per_direction[0] - 1 +
929 nodes_per_direction[1] - 1) :
935 4 * (nodes_per_direction[0] - 1) + 4 * (nodes_per_direction[1] - 1);
938 (nodes_per_direction[2] - 1) *
939 (i != 0u ? (j != 0u ? 3 : 1) : (j != 0u ? 2 : 0)) +
943 (nodes_per_direction[2] - 1) *
944 (i != 0u ? (j != 0u ? 2 : 1) : (j != 0u ? 3 : 0)) +
948 offset += 4 * (nodes_per_direction[0] - 1 + nodes_per_direction[1] - 1 +
949 nodes_per_direction[2] - 1);
954 return (j - 1) + ((nodes_per_direction[1] - 1) * (k - 1)) +
955 (i != 0u ? (nodes_per_direction[1] - 1) *
956 (nodes_per_direction[2] - 1) :
961 2 * (nodes_per_direction[1] - 1) * (nodes_per_direction[2] - 1);
964 return (i - 1) + ((nodes_per_direction[0] - 1) * (k - 1)) +
965 (j != 0u ? (nodes_per_direction[2] - 1) *
966 (nodes_per_direction[0] - 1) :
971 2 * (nodes_per_direction[2] - 1) * (nodes_per_direction[0] - 1);
973 return (i - 1) + ((nodes_per_direction[0] - 1) * (j - 1)) +
974 (k != 0u ? (nodes_per_direction[0] - 1) *
975 (nodes_per_direction[1] - 1) :
982 2 * ((nodes_per_direction[1] - 1) * (nodes_per_direction[2] - 1) +
983 (nodes_per_direction[2] - 1) * (nodes_per_direction[0] - 1) +
984 (nodes_per_direction[0] - 1) * (nodes_per_direction[1] - 1));
985 return offset + (i - 1) +
986 (nodes_per_direction[0] - 1) *
987 ((j - 1) + (nodes_per_direction[1] - 1) * ((k - 1)));
1000 const unsigned int vertex_index)
const
1013 return vertex_index;
1015 return vertex_index;
1017 return vertex_index;
1020 static constexpr std::array<unsigned int, 4> index_translation_table =
1022 return index_translation_table[vertex_index];
1025 return vertex_index;
1028 static constexpr std::array<unsigned int, 5> index_translation_table =
1030 return index_translation_table[vertex_index];
1033 return vertex_index;
1036 static constexpr std::array<unsigned int, 8> index_translation_table =
1037 {{0, 1, 3, 2, 4, 5, 7, 6}};
1038 return index_translation_table[vertex_index];
1144 std::pair<Point<dim>,
double>
1155 const double t = ((x1 - x0) * (p - x0)) / ((x1 - x0).norm_square());
1162 const auto p2 = x0 + t * (x1 - x0);
1163 return std::make_pair(p2, p2.distance_square(p));
1173 std::pair<Point<dim>,
double>
1174 project_to_quad(
const std::array<
Point<dim>, 3> & ,
1180 std::numeric_limits<double>::signaling_NaN());
1201 std::pair<Point<3>,
double>
1202 project_to_quad(
const std::array<
Point<3>, 3> &vertices,
1213 std::array<Point<3>, 3> shifted_vertices = vertices;
1215 for (
Point<3> &shifted_vertex : shifted_vertices)
1216 shifted_vertex +=
shift;
1225 const Point<3> vertex = shifted_vertices[0];
1235 e0 = shifted_vertices[1] - shifted_vertices[0];
1236 e1 = shifted_vertices[2] - shifted_vertices[0];
1241 e0 = shifted_vertices[1] - shifted_vertices[0];
1242 e1 = shifted_vertices[2] - shifted_vertices[0];
1247 const double c0 = e0 * (shifted_p - vertex) / e0.
norm_square();
1248 const double c1 = e1 * (shifted_p - vertex) / e1.norm_square();
1249 const Point<3> projected_shifted_p = vertex + c0 * e0 + c1 * e1;
1251 bool in_quad =
false;
1255 for (
unsigned int i = 0; i < 3; ++i)
1256 shifted_vertex_matrix[i] = shifted_vertices[i];
1259 bool is_convex_combination =
true;
1260 for (
unsigned int i = 0; i < 3; ++i)
1261 is_convex_combination = is_convex_combination &&
1262 (0.0 <= combination_coordinates[i]) &&
1263 (combination_coordinates[i] <= 1.0);
1264 in_quad = is_convex_combination;
1267 in_quad = (0.0 <= c0 && c0 <= 1.0 && 0.0 <= c1 && c1 <= 1.0);
1270 return std::make_pair(projected_shifted_p - shift,
1273 return std::make_pair(
Point<3>(), std::numeric_limits<double>::max());
1284 if constexpr (dim == 0)
1289 if constexpr (dim == 1)
1296 unsigned int closest_vertex_no = 0;
1297 double closest_vertex_distance_square =
vertex(0).distance_square(p);
1298 for (
unsigned int i = 1; i <
n_vertices(); ++i)
1300 const double new_vertex_distance_square =
1301 vertex(i).distance_square(p);
1302 if (new_vertex_distance_square < closest_vertex_distance_square)
1304 closest_vertex_no = i;
1305 closest_vertex_distance_square = new_vertex_distance_square;
1309 double min_distance_square = std::numeric_limits<double>::max();
1310 if constexpr (dim == 2)
1312 for (
const unsigned int face_no :
1318 auto pair = project_to_line(v0, v1, p);
1319 if (pair.second < min_distance_square)
1321 result = pair.first;
1322 min_distance_square = pair.second;
1340 const std::array<unsigned int, 5> all_pyramid_faces{{0, 1, 2, 3, 4}};
1345 for (
const unsigned int face_no : faces)
1350 std::array<Point<dim>, 3> vertices;
1351 for (
unsigned int vertex_no = 0; vertex_no < 3; ++vertex_no)
1355 auto pair = project_to_quad(vertices, p, face_cell);
1356 if (pair.second < min_distance_square)
1358 result = pair.first;
1359 min_distance_square = pair.second;
1363 for (
const unsigned int face_no :
1367 for (
const unsigned int face_line_no : face_cell.line_indices())
1369 const auto cell_line_no =
1377 auto pair = project_to_line(v0, v1, p);
1378 if (pair.second < min_distance_square)
1380 result = pair.first;
1381 min_distance_square = pair.second;
1387 Assert(min_distance_square < std::numeric_limits<double>::max(),
1397 constexpr unsigned int x_index = 0;
1398 constexpr unsigned int y_index = (dim >= 2 ? 1 : 0);
1399 constexpr unsigned int z_index = (dim >= 3 ? 2 : 0);
1410 for (
unsigned int d = 0; d < dim; ++d)
1411 result[d] = std::clamp(result[d], 0.0, 1.0);
1415 result[x_index] = std::clamp(result[x_index], 0.0, 1.0);
1417 std::clamp(result[y_index], 0.0, 1.0 - result[x_index]);
1420 result[x_index] = std::clamp(result[x_index], 0.0, 1.0);
1422 std::clamp(result[y_index], 0.0, 1.0 - result[x_index]);
1424 std::clamp(result[z_index],
1426 1.0 - result[x_index] - result[y_index]);
1430 result[x_index] = std::clamp(result[x_index], 0.0, 1.0);
1432 std::clamp(result[y_index], 0.0, 1.0 - result[x_index]);
1433 result[z_index] = std::clamp(result[z_index], 0.0, 1.0);
1437 result[x_index] = std::clamp(result[x_index], -1.0, 1.0);
1438 result[y_index] = std::clamp(result[y_index], -1.0, 1.0);
1441 const auto x_abs =
std::abs(result[x_index]);
1442 const auto y_abs =
std::abs(result[y_index]);
1446 std::clamp(result[z_index], 0.0, 1.0 - x_abs);
1449 std::clamp(result[z_index], 0.0, 1.0 - y_abs);
1460 4.0 * std::numeric_limits<double>::epsilon()),
1477 out << static_cast<unsigned int>(reference_cell.kind);
1492 reference_cell.kind =
static_cast<decltype(reference_cell.kind)
>(
value);
1506 "The reference cell kind just read does not correspond to one of the "
1507 "valid choices. There must be an error."));
1513#include "grid/reference_cell.inst"
1521template unsigned int
1524template unsigned int
1527template unsigned int
1530template unsigned int
1532 const unsigned int vertex_index)
const;
1540template std::ostream &
1543template std::istream &
Implementation of the classic affine transformation mapping used for simplices.
Abstract base class for mapping classes.
constexpr numbers::NumberTraits< Number >::real_type distance_square(const Point< dim, Number > &p) const
static constexpr Point< dim, Number > unit_vector(const unsigned int i)
unsigned int unv_vertex_to_deal_vertex(const unsigned int vertex_n) const
const Quadrature< dim > & get_nodal_type_quadrature() const
unsigned int face_to_cell_lines(const unsigned int face, const unsigned int line, const types::geometric_orientation face_orientation) const
constexpr bool is_simplex() const
constexpr unsigned int n_vertices() const
constexpr bool is_hyper_cube() const
ArrayView< const unsigned int > faces_for_given_vertex(const unsigned int vertex_index) const
unsigned int vtk_quadratic_type() const
Point< dim > closest_point(const Point< dim > &p) const
unsigned int vtk_lagrange_type() const
Quadrature< dim > get_gauss_type_quadrature(const unsigned n_points_1d) const
unsigned int line_to_cell_vertices(const unsigned int line, const unsigned int vertex) const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices() const
constexpr ReferenceCell< dim - 1 > face_reference_cell(const unsigned int face_index) const
unsigned int n_children(const RefinementCase< dim > ref_case=RefinementCase< dim >::isotropic_refinement) const
constexpr unsigned int n_faces() const
constexpr ReferenceCell()
unsigned int vtk_vertex_to_deal_vertex(const unsigned int vertex_index) const
Point< dim > vertex(const unsigned int v) const
std::pair< unsigned int, RefinementCase< dim - 1 > > equivalent_refinement_case(const types::geometric_orientation combined_face_orientation, const internal::SubfaceCase< dim > subface_case, const unsigned int subface_no) const
std::unique_ptr< Mapping< dim, spacedim > > get_default_mapping(const unsigned int degree) const
std::string to_string() const
unsigned int n_face_orientations(const unsigned int face_no) const
unsigned int vtk_lexicographic_to_node_index(const std::array< unsigned, dim > &node_indices, const std::array< unsigned, dim > &nodes_per_direction, const bool legacy_format) const
unsigned int gmsh_element_type() const
Point< dim > face_vertex_location(const unsigned int face, const unsigned int vertex) const
unsigned int face_to_cell_vertices(const unsigned int face, const unsigned int vertex, const types::geometric_orientation face_orientation) const
unsigned int exodusii_vertex_to_deal_vertex(const unsigned int vertex_n) const
const Mapping< dim, spacedim > & get_default_linear_mapping() const
Point< dim > subface_vertex_location(const unsigned int face_no, const unsigned int subface_no, const unsigned int subface_vertex_no, const RefinementCase< dim - 1 > face_refinement_case) const
bool contains_point(const Point< dim > &p, const double tolerance=0) const
unsigned int exodusii_face_to_deal_face(const unsigned int face_n) const
unsigned int vtk_linear_type() const
constexpr numbers::NumberTraits< Number >::real_type norm_square() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
const bool IsBlockVector< VectorType >::value
MappingQ< dim, spacedim > StaticMappingQ1< dim, spacedim >::mapping
constexpr ReferenceCell< 3 > Hexahedron
constexpr ReferenceCell< 2 > Quadrilateral
constexpr ReferenceCell< 1 > Line
constexpr ReferenceCell< 2 > Triangle
constexpr ReferenceCell< 3 > Tetrahedron
constexpr ReferenceCell< dim > Invalid
constexpr ReferenceCell< 3 > Pyramid
constexpr ReferenceCell< 3 > Wedge
constexpr ReferenceCell< 0 > Vertex
std::tuple< bool, bool, bool > split_face_orientation(const types::geometric_orientation combined_orientation)
constexpr unsigned int invalid_unsigned_int
constexpr types::geometric_orientation reverse_line_orientation
constexpr types::geometric_orientation default_geometric_orientation
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
std::uint8_t geometric_orientation
typename internal::ndarray::HelperArray< T, Ns... >::type ndarray
std::istream & operator>>(std::istream &in, ReferenceCell< dim > &reference_cell)
std::ostream & operator<<(std::ostream &out, const ReferenceCell< dim > &reference_cell)
static unsigned int child_cell_on_face(const RefinementCase< dim > &ref_case, const unsigned int face, const unsigned int subface, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false, const RefinementCase< dim - 1 > &face_refinement_case=RefinementCase< dim - 1 >::isotropic_refinement)
static constexpr unsigned int max_children_per_face
static MappingQ< dim, spacedim > mapping
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)