| Line | Branch | Exec | Source | 
|---|---|---|---|
| 1 | // SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de> | ||
| 2 | // SPDX-License-Identifier: MIT | ||
| 3 | /*! | ||
| 4 | * \file | ||
| 5 | * \ingroup PredefinedTraits | ||
| 6 | * \brief Traits specializations for | ||
| 7 | * <a href="https://docs.mfem.org/html/classmfem_1_1Mesh.html">mfem::Mesh</a> | ||
| 8 | */ | ||
| 9 | #ifndef GRIDFORMAT_TRAITS_MFEM_HPP_ | ||
| 10 | #define GRIDFORMAT_TRAITS_MFEM_HPP_ | ||
| 11 | |||
| 12 | #include <cassert> | ||
| 13 | #include <ranges> | ||
| 14 | #include <vector> | ||
| 15 | #include <array> | ||
| 16 | #include <type_traits> | ||
| 17 | |||
| 18 | #include <mfem/mesh/mesh.hpp> | ||
| 19 | |||
| 20 | #include <gridformat/common/exceptions.hpp> | ||
| 21 | |||
| 22 | #include <gridformat/grid/cell_type.hpp> | ||
| 23 | #include <gridformat/grid/traits.hpp> | ||
| 24 | |||
| 25 | namespace GridFormat::MFEM { | ||
| 26 | |||
| 27 | #ifndef DOXYGEN | ||
| 28 | namespace Detail { | ||
| 29 | 11925 | CellType cell_type(mfem::Element::Type ct) { | |
| 30 | 5/9✗ Branch 0 not taken. ✓ Branch 1 taken 615 times. ✓ Branch 2 taken 7840 times. ✓ Branch 3 taken 2000 times. ✓ Branch 4 taken 1260 times. ✗ Branch 5 not taken. ✗ Branch 6 not taken. ✓ Branch 7 taken 210 times. ✗ Branch 8 not taken. | 11925 | switch (ct) { | 
| 31 | ✗ | case mfem::Element::Type::POINT: return GridFormat::CellType::vertex; | |
| 32 | 615 | case mfem::Element::Type::SEGMENT: return GridFormat::CellType::segment; | |
| 33 | 7840 | case mfem::Element::Type::TRIANGLE: return GridFormat::CellType::triangle; | |
| 34 | 2000 | case mfem::Element::Type::QUADRILATERAL: return GridFormat::CellType::quadrilateral; | |
| 35 | 1260 | case mfem::Element::Type::TETRAHEDRON: return GridFormat::CellType::tetrahedron; | |
| 36 | ✗ | case mfem::Element::Type::WEDGE: break; | |
| 37 | ✗ | case mfem::Element::Type::PYRAMID: break; | |
| 38 | 210 | case mfem::Element::Type::HEXAHEDRON: return GridFormat::CellType::hexahedron; | |
| 39 | } | ||
| 40 | ✗ | throw NotImplemented("Support for given mfem cell type"); | |
| 41 | } | ||
| 42 | } // namespace Detail | ||
| 43 | #endif // DOXYGEN | ||
| 44 | |||
| 45 | using Point = int; | ||
| 46 | using Cell = int; | ||
| 47 | |||
| 48 | } // namespace GridFormat::MFEM | ||
| 49 | |||
| 50 | // Specializations of the traits required for the `UnstructuredGrid` concept for mfem::Mesh | ||
| 51 | namespace GridFormat::Traits { | ||
| 52 | |||
| 53 | template<> | ||
| 54 | struct Points<mfem::Mesh> { | ||
| 55 | 29 | static std::ranges::range auto get(const mfem::Mesh& mesh) { | |
| 56 | 1/2✓ Branch 2 taken 29 times. ✗ Branch 3 not taken. | 29 | return std::views::iota(0, mesh.GetNV()); | 
| 57 | } | ||
| 58 | }; | ||
| 59 | |||
| 60 | template<> | ||
| 61 | struct Cells<mfem::Mesh> { | ||
| 62 | 103 | static std::ranges::range auto get(const mfem::Mesh& mesh) { | |
| 63 | 1/2✓ Branch 2 taken 103 times. ✗ Branch 3 not taken. | 103 | return std::views::iota(0, mesh.GetNE()); | 
| 64 | } | ||
| 65 | }; | ||
| 66 | |||
| 67 | template<> | ||
| 68 | struct CellType<mfem::Mesh, GridFormat::MFEM::Cell> { | ||
| 69 | 11925 | static GridFormat::CellType get(const mfem::Mesh& mesh, const GridFormat::MFEM::Cell& cell) { | |
| 70 | 11925 | return GridFormat::MFEM::Detail::cell_type(mesh.GetElement(cell)->GetType()); | |
| 71 | } | ||
| 72 | }; | ||
| 73 | |||
| 74 | template<> | ||
| 75 | struct CellPoints<mfem::Mesh, GridFormat::MFEM::Cell> { | ||
| 76 | 4215 | static std::ranges::range decltype(auto) get(const mfem::Mesh& mesh, const GridFormat::MFEM::Cell& cell) { | |
| 77 | 4215 | const auto element = mesh.GetElement(cell); | |
| 78 | 4215 | auto begin = element->GetVertices(); | |
| 79 | 1/2✓ Branch 1 taken 4215 times. ✗ Branch 2 not taken. | 4215 | return std::ranges::subrange(begin, begin + element->GetNVertices()); | 
| 80 | } | ||
| 81 | }; | ||
| 82 | |||
| 83 | template<> | ||
| 84 | struct PointId<mfem::Mesh, GridFormat::MFEM::Point> { | ||
| 85 | 10580 | static auto get(const mfem::Mesh&, const GridFormat::MFEM::Point& point) { | |
| 86 | 10580 | return point; | |
| 87 | } | ||
| 88 | }; | ||
| 89 | |||
| 90 | template<> | ||
| 91 | struct PointCoordinates<mfem::Mesh, GridFormat::MFEM::Point> { | ||
| 92 | 1100 | static std::ranges::range decltype(auto) get(const mfem::Mesh& mesh, const GridFormat::MFEM::Point& point) { | |
| 93 | 1100 | std::array<double, 3> coords = {}; | |
| 94 | 1100 | auto begin = mesh.GetVertex(point); | |
| 95 | 1100 | std::copy(begin, begin + mesh.SpaceDimension(), coords.begin()); | |
| 96 | 1100 | return coords; | |
| 97 | } | ||
| 98 | }; | ||
| 99 | |||
| 100 | template<> | ||
| 101 | struct NumberOfPoints<mfem::Mesh> { | ||
| 102 | 125 | static std::integral auto get(const mfem::Mesh& mesh) { | |
| 103 | 125 | return mesh.GetNV(); | |
| 104 | } | ||
| 105 | }; | ||
| 106 | |||
| 107 | template<> | ||
| 108 | struct NumberOfCells<mfem::Mesh> { | ||
| 109 | 110 | static std::integral auto get(const mfem::Mesh& mesh) { | |
| 110 | 110 | return mesh.GetNE(); | |
| 111 | } | ||
| 112 | }; | ||
| 113 | |||
| 114 | template<> | ||
| 115 | struct NumberOfCellPoints<mfem::Mesh, GridFormat::MFEM::Cell> { | ||
| 116 | 5175 | static std::integral auto get(const mfem::Mesh& mesh, const GridFormat::MFEM::Cell& cell) { | |
| 117 | 5175 | return mesh.GetElement(cell)->GetNVertices(); | |
| 118 | } | ||
| 119 | }; | ||
| 120 | |||
| 121 | } // namespace GridFormat::Traits | ||
| 122 | |||
| 123 | #endif // GRIDFORMAT_TRAITS_MFEM_HPP_ | ||
| 124 |