From ecd24e06aa0623651475f4edecd777d56dbe701f Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Wed, 20 Jan 2021 18:38:12 -0700 Subject: [PATCH] Make the special ReferenceCell objects objects, not enums. --- include/deal.II/grid/reference_cell.h | 118 +++++++--------- .../deal.II/grid/tria_accessor.templates.h | 130 +++++++++--------- .../numerics/data_out_dof_data.templates.h | 84 +++++------ source/distributed/tria_base.cc | 3 +- source/grid/grid_out.cc | 38 +++-- source/grid/reference_cell.cc | 11 ++ 6 files changed, 184 insertions(+), 200 deletions(-) diff --git a/include/deal.II/grid/reference_cell.h b/include/deal.II/grid/reference_cell.h index 636e671abb..8d6eb83463 100644 --- a/include/deal.II/grid/reference_cell.h +++ b/include/deal.II/grid/reference_cell.h @@ -51,18 +51,15 @@ namespace ReferenceCell class Type { public: - enum CellKinds : std::uint8_t - { - Vertex = 0, - Line = 1, - Tri = 2, - Quad = 3, - Tet = 4, - Pyramid = 5, - Wedge = 6, - Hex = 7, - Invalid = static_cast(-1) - }; + static const Type Vertex; + static const Type Line; + static const Type Tri; + static const Type Quad; + static const Type Tet; + static const Type Pyramid; + static const Type Wedge; + static const Type Hex; + static const Type Invalid; /** * Default constructor. Initialize this object as an invalid object. @@ -72,7 +69,7 @@ namespace ReferenceCell /** * Constructor. */ - Type(const CellKinds kind); + Type(const std::uint8_t kind); /** * Return the dimension of the reference cell represented by the current @@ -155,13 +152,13 @@ namespace ReferenceCell * Operator for equality comparison. */ bool - operator==(const CellKinds &type) const; + operator==(const std::uint8_t &type) const; /** * Operator for inequality comparison. */ bool - operator!=(const CellKinds &type) const; + operator!=(const std::uint8_t &type) const; /** * Write and read the data of this object from a stream for the purpose @@ -182,7 +179,7 @@ namespace ReferenceCell /** * The variable that stores what this object actually corresponds to. */ - CellKinds kind; + std::uint8_t kind; }; @@ -193,7 +190,7 @@ namespace ReferenceCell - inline Type::Type(const CellKinds kind) + inline Type::Type(const std::uint8_t kind) : kind(kind) {} @@ -223,7 +220,7 @@ namespace ReferenceCell inline bool - Type::operator==(const CellKinds &type) const + Type::operator==(const std::uint8_t &type) const { return kind == type; } @@ -231,7 +228,7 @@ namespace ReferenceCell inline bool - Type::operator!=(const CellKinds &type) const + Type::operator!=(const std::uint8_t &type) const { return kind != type; } @@ -242,12 +239,7 @@ namespace ReferenceCell inline void Type::serialize(Archive &archive, const unsigned int /*version*/) { - // Serialize the state as an 8-bit int. When saving the state, the - // last of the following 3 lines is a no-op. When loading, the first - // of these lines is a no-op. - std::uint8_t kind_as_int = static_cast(kind); - archive & kind_as_int; - kind = static_cast(kind_as_int); + archive &kind; } @@ -323,23 +315,18 @@ namespace ReferenceCell inline unsigned int Type::get_dimension() const { - switch (kind) - { - case Type::Vertex: - return 0; - case Type::Line: - return 1; - case Type::Tri: - case Type::Quad: - return 2; - case Type::Tet: - case Type::Pyramid: - case Type::Wedge: - case Type::Hex: - return 3; - default: - return numbers::invalid_unsigned_int; - } + if (*this == Vertex) + return 0; + else if (*this == Line) + return 1; + else if ((*this == Tri) || (*this == Quad)) + return 2; + else if ((*this == Tet) || (*this == Pyramid) || (*this == Wedge) || + (*this == Hex)) + return 3; + + Assert(false, ExcNotImplemented()); + return numbers::invalid_unsigned_int; } @@ -350,29 +337,26 @@ namespace ReferenceCell inline std::string Type::to_string() const { - switch (kind) - { - case Type::Vertex: - return "Vertex"; - case Type::Line: - return "Line"; - case Type::Tri: - return "Tri"; - case Type::Quad: - return "Quad"; - case Type::Tet: - return "Tet"; - case Type::Pyramid: - return "Pyramid"; - case Type::Wedge: - return "Wedge"; - case Type::Hex: - return "Hex"; - case Type::Invalid: - return "Invalid"; - default: - Assert(false, ExcNotImplemented()); - } + if (*this == Vertex) + return "Vertex"; + else if (*this == Line) + return "Line"; + else if (*this == Tri) + return "Tri"; + else if (*this == Quad) + return "Quad"; + else if (*this == Tet) + return "Tet"; + else if (*this == Pyramid) + return "Pyramid"; + else if (*this == Wedge) + return "Wedge"; + else if (*this == Hex) + return "Hex"; + else if (*this == Invalid) + return "Invalid"; + + Assert(false, ExcNotImplemented()); return "Invalid"; } @@ -434,8 +418,8 @@ namespace ReferenceCell AssertIndexRange(n_vertices, 9); const auto X = Type::Invalid; - static constexpr std::array, - 4> + static const std::array, + 4> table = { {// dim 0 {{X, Type::Vertex, X, X, X, X, X, X, X}}, diff --git a/include/deal.II/grid/tria_accessor.templates.h b/include/deal.II/grid/tria_accessor.templates.h index 055cb2b891..9a4646649d 100644 --- a/include/deal.II/grid/tria_accessor.templates.h +++ b/include/deal.II/grid/tria_accessor.templates.h @@ -54,74 +54,68 @@ namespace internal GeometryInfo::vertices_per_cell> vertices) { - switch (ReferenceCell::n_vertices_to_type(dim, vertices.size())) - { - case ReferenceCell::Type::Line: - // Return the distance between the two vertices - return (vertices[1] - vertices[0]).norm(); - - case ReferenceCell::Type::Tri: - // Return the longest of the three edges - return std::max({(vertices[1] - vertices[0]).norm(), - (vertices[2] - vertices[1]).norm(), - (vertices[2] - vertices[0]).norm()}); - - case ReferenceCell::Type::Quad: - // Return the longer one of the two diagonals of the quadrilateral - return std::max({(vertices[3] - vertices[0]).norm(), - (vertices[2] - vertices[1]).norm()}); - - case ReferenceCell::Type::Tet: - // Return the longest of the six edges of the tetrahedron - return std::max({(vertices[1] - vertices[0]).norm(), - (vertices[2] - vertices[0]).norm(), - (vertices[2] - vertices[1]).norm(), - (vertices[3] - vertices[0]).norm(), - (vertices[3] - vertices[1]).norm(), - (vertices[3] - vertices[2]).norm()}); - - case ReferenceCell::Type::Pyramid: - // Return ... - return std::max({// the longest diagonal of the quadrilateral base - // of the pyramid or ... - (vertices[3] - vertices[0]).norm(), - (vertices[2] - vertices[1]).norm(), - // the longest edge connected with the apex of the - // pyramid - (vertices[4] - vertices[0]).norm(), - (vertices[4] - vertices[1]).norm(), - (vertices[4] - vertices[2]).norm(), - (vertices[4] - vertices[3]).norm()}); - - case ReferenceCell::Type::Wedge: - // Return ... - return std::max({// the longest of the 2*3=6 diagonals of the three - // quadrilateral sides of the wedge or ... - (vertices[4] - vertices[0]).norm(), - (vertices[3] - vertices[1]).norm(), - (vertices[5] - vertices[1]).norm(), - (vertices[4] - vertices[2]).norm(), - (vertices[5] - vertices[0]).norm(), - (vertices[3] - vertices[2]).norm(), - // the longest of the 3*2=6 edges of the two - // triangular faces of the wedge - (vertices[1] - vertices[0]).norm(), - (vertices[2] - vertices[1]).norm(), - (vertices[2] - vertices[0]).norm(), - (vertices[4] - vertices[3]).norm(), - (vertices[5] - vertices[4]).norm(), - (vertices[5] - vertices[3]).norm()}); - - case ReferenceCell::Type::Hex: - // Return the longest of the four diagonals of the hexahedron - return std::max({(vertices[7] - vertices[0]).norm(), - (vertices[6] - vertices[1]).norm(), - (vertices[2] - vertices[5]).norm(), - (vertices[3] - vertices[4]).norm()}); - default: - Assert(false, ExcNotImplemented()); - return -1e10; - } + const ReferenceCell::Type reference_cell_type = + ReferenceCell::n_vertices_to_type(dim, vertices.size()); + + if (reference_cell_type == ReferenceCell::Type::Line) + // Return the distance between the two vertices + return (vertices[1] - vertices[0]).norm(); + else if (reference_cell_type == ReferenceCell::Type::Tri) + // Return the longest of the three edges + return std::max({(vertices[1] - vertices[0]).norm(), + (vertices[2] - vertices[1]).norm(), + (vertices[2] - vertices[0]).norm()}); + else if (reference_cell_type == ReferenceCell::Type::Quad) + // Return the longer one of the two diagonals of the quadrilateral + return std::max({(vertices[3] - vertices[0]).norm(), + (vertices[2] - vertices[1]).norm()}); + else if (reference_cell_type == ReferenceCell::Type::Tet) + // Return the longest of the six edges of the tetrahedron + return std::max({(vertices[1] - vertices[0]).norm(), + (vertices[2] - vertices[0]).norm(), + (vertices[2] - vertices[1]).norm(), + (vertices[3] - vertices[0]).norm(), + (vertices[3] - vertices[1]).norm(), + (vertices[3] - vertices[2]).norm()}); + else if (reference_cell_type == ReferenceCell::Type::Pyramid) + // Return ... + return std::max({// the longest diagonal of the quadrilateral base + // of the pyramid or ... + (vertices[3] - vertices[0]).norm(), + (vertices[2] - vertices[1]).norm(), + // the longest edge connected with the apex of the + // pyramid + (vertices[4] - vertices[0]).norm(), + (vertices[4] - vertices[1]).norm(), + (vertices[4] - vertices[2]).norm(), + (vertices[4] - vertices[3]).norm()}); + else if (reference_cell_type == ReferenceCell::Type::Wedge) + // Return ... + return std::max({// the longest of the 2*3=6 diagonals of the three + // quadrilateral sides of the wedge or ... + (vertices[4] - vertices[0]).norm(), + (vertices[3] - vertices[1]).norm(), + (vertices[5] - vertices[1]).norm(), + (vertices[4] - vertices[2]).norm(), + (vertices[5] - vertices[0]).norm(), + (vertices[3] - vertices[2]).norm(), + // the longest of the 3*2=6 edges of the two + // triangular faces of the wedge + (vertices[1] - vertices[0]).norm(), + (vertices[2] - vertices[1]).norm(), + (vertices[2] - vertices[0]).norm(), + (vertices[4] - vertices[3]).norm(), + (vertices[5] - vertices[4]).norm(), + (vertices[5] - vertices[3]).norm()}); + else if (reference_cell_type == ReferenceCell::Type::Hex) + // Return the longest of the four diagonals of the hexahedron + return std::max({(vertices[7] - vertices[0]).norm(), + (vertices[6] - vertices[1]).norm(), + (vertices[2] - vertices[5]).norm(), + (vertices[3] - vertices[4]).norm()}); + + Assert(false, ExcNotImplemented()); + return -1e10; } } // namespace TriaAccessorImplementation } // namespace internal diff --git a/include/deal.II/numerics/data_out_dof_data.templates.h b/include/deal.II/numerics/data_out_dof_data.templates.h index efa7446471..9e56b71f62 100644 --- a/include/deal.II/numerics/data_out_dof_data.templates.h +++ b/include/deal.II/numerics/data_out_dof_data.templates.h @@ -114,27 +114,24 @@ namespace internal for (const auto &fe : finite_elements) for (unsigned int i = 0; i < fe->size(); ++i) - switch ((*fe)[i].reference_cell_type()) - { - case ReferenceCell::Type::Vertex: - case ReferenceCell::Type::Line: - case ReferenceCell::Type::Quad: - case ReferenceCell::Type::Hex: - needs_hypercube_setup |= true; - break; - case ReferenceCell::Type::Tri: - case ReferenceCell::Type::Tet: - needs_simplex_setup |= true; - break; - case ReferenceCell::Type::Wedge: - needs_wedge_setup |= true; - break; - case ReferenceCell::Type::Pyramid: - needs_pyramid_setup |= true; - break; - default: - Assert(false, ExcNotImplemented()); - } + { + const auto reference_cell_type = (*fe)[i].reference_cell_type(); + + if ((reference_cell_type == ReferenceCell::Type::Vertex) || + (reference_cell_type == ReferenceCell::Type::Line) || + (reference_cell_type == ReferenceCell::Type::Quad) || + (reference_cell_type == ReferenceCell::Type::Hex)) + needs_hypercube_setup |= true; + else if ((reference_cell_type == ReferenceCell::Type::Tri) || + (reference_cell_type == ReferenceCell::Type::Tet)) + needs_simplex_setup |= true; + else if (reference_cell_type == ReferenceCell::Type::Wedge) + needs_wedge_setup |= true; + else if (reference_cell_type == ReferenceCell::Type::Pyramid) + needs_pyramid_setup |= true; + else + Assert(false, ExcNotImplemented()); + } std::unique_ptr> quadrature_simplex; std::unique_ptr> quadrature_hypercube; @@ -201,27 +198,30 @@ namespace internal dealii::hp::QCollection quadrature; for (unsigned int j = 0; j < finite_elements[i]->size(); ++j) - switch ((*finite_elements[i])[j].reference_cell_type()) - { - case ReferenceCell::Type::Vertex: - case ReferenceCell::Type::Line: - case ReferenceCell::Type::Quad: - case ReferenceCell::Type::Hex: - quadrature.push_back(*quadrature_hypercube); - break; - case ReferenceCell::Type::Tri: - case ReferenceCell::Type::Tet: - quadrature.push_back(*quadrature_simplex); - break; - case ReferenceCell::Type::Wedge: - quadrature.push_back(*quadrature_wedge); - break; - case ReferenceCell::Type::Pyramid: - quadrature.push_back(*quadrature_pyramid); - break; - default: - Assert(false, ExcNotImplemented()); - } + { + const auto reference_cell_type = + (*finite_elements[i])[j].reference_cell_type(); + + if ((reference_cell_type == + ReferenceCell::Type::Vertex) || + (reference_cell_type == ReferenceCell::Type::Line) || + (reference_cell_type == ReferenceCell::Type::Quad) || + (reference_cell_type == ReferenceCell::Type::Hex)) + quadrature.push_back(*quadrature_hypercube); + else if ((reference_cell_type == + ReferenceCell::Type::Tri) || + (reference_cell_type == + ReferenceCell::Type::Tet)) + quadrature.push_back(*quadrature_simplex); + else if (reference_cell_type == + ReferenceCell::Type::Wedge) + quadrature.push_back(*quadrature_wedge); + else if (reference_cell_type == + ReferenceCell::Type::Pyramid) + quadrature.push_back(*quadrature_pyramid); + else + Assert(false, ExcNotImplemented()); + } x_fe_values[i] = std::make_shared>( diff --git a/source/distributed/tria_base.cc b/source/distributed/tria_base.cc index c605c37f04..a5cb108513 100644 --- a/source/distributed/tria_base.cc +++ b/source/distributed/tria_base.cc @@ -309,8 +309,7 @@ namespace parallel // transform back and store result this->reference_cell_types.clear(); for (const auto &i : reference_cell_types_ui) - this->reference_cell_types.emplace_back( - static_cast(i)); + this->reference_cell_types.emplace_back(static_cast(i)); } diff --git a/source/grid/grid_out.cc b/source/grid/grid_out.cc index fadc5d4fb5..ed8ac97d70 100644 --- a/source/grid/grid_out.cc +++ b/source/grid/grid_out.cc @@ -3218,29 +3218,25 @@ GridOut::write_vtk(const Triangulation &tria, for (const unsigned int i : cell->vertex_indices()) { out << ' '; - switch (cell->reference_cell_type()) + const auto reference_cell_type = cell->reference_cell_type(); + + if ((reference_cell_type == ReferenceCell::Type::Vertex) || + (reference_cell_type == ReferenceCell::Type::Line) || + (reference_cell_type == ReferenceCell::Type::Quad) || + (reference_cell_type == ReferenceCell::Type::Hex)) + out << cell->vertex_index(GeometryInfo::ucd_to_deal[i]); + else if ((reference_cell_type == ReferenceCell::Type::Tri) || + (reference_cell_type == ReferenceCell::Type::Tet) || + (reference_cell_type == ReferenceCell::Type::Wedge)) + out << cell->vertex_index(i); + else if (reference_cell_type == ReferenceCell::Type::Pyramid) { - case ReferenceCell::Type::Vertex: - case ReferenceCell::Type::Line: - case ReferenceCell::Type::Quad: - case ReferenceCell::Type::Hex: - out << cell->vertex_index(GeometryInfo::ucd_to_deal[i]); - break; - case ReferenceCell::Type::Tri: - case ReferenceCell::Type::Tet: - case ReferenceCell::Type::Wedge: - out << cell->vertex_index(i); - break; - case ReferenceCell::Type::Pyramid: - { - static const std::array permutation_table{ - {0, 1, 3, 2, 4}}; - out << cell->vertex_index(permutation_table[i]); - break; - } - default: - Assert(false, ExcNotImplemented()); + static const std::array permutation_table{ + {0, 1, 3, 2, 4}}; + out << cell->vertex_index(permutation_table[i]); } + else + Assert(false, ExcNotImplemented()); } out << '\n'; } diff --git a/source/grid/reference_cell.cc b/source/grid/reference_cell.cc index d7b2e33f1a..9e473a0592 100644 --- a/source/grid/reference_cell.cc +++ b/source/grid/reference_cell.cc @@ -32,6 +32,17 @@ DEAL_II_NAMESPACE_OPEN namespace ReferenceCell { + const Type Type::Vertex = Type(0); + const Type Type::Line = Type(1); + const Type Type::Tri = Type(2); + const Type Type::Quad = Type(3); + const Type Type::Tet = Type(4); + const Type Type::Pyramid = Type(5); + const Type Type::Wedge = Type(6); + const Type Type::Hex = Type(7); + const Type Type::Invalid = Type(static_cast(-1)); + + template void make_triangulation(const Type & reference_cell, -- 2.39.5