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 |