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 | #include <gridformat/common/filtered_range.hpp> | ||
22 | |||
23 | #include <gridformat/grid/cell_type.hpp> | ||
24 | #include <gridformat/grid/traits.hpp> | ||
25 | |||
26 | namespace GridFormat::MFEM { | ||
27 | |||
28 | #ifndef DOXYGEN | ||
29 | namespace Detail { | ||
30 | 9966 | CellType cell_type(mfem::Element::Type ct) { | |
31 |
5/9✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
✓ Branch 2 taken 6244 times.
✓ Branch 3 taken 1681 times.
✓ Branch 4 taken 1260 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 210 times.
✗ Branch 8 not taken.
|
9966 | switch (ct) { |
32 | ✗ | case mfem::Element::Type::POINT: return GridFormat::CellType::vertex; | |
33 | 571 | case mfem::Element::Type::SEGMENT: return GridFormat::CellType::segment; | |
34 | 6244 | case mfem::Element::Type::TRIANGLE: return GridFormat::CellType::triangle; | |
35 | 1681 | case mfem::Element::Type::QUADRILATERAL: return GridFormat::CellType::quadrilateral; | |
36 | 1260 | case mfem::Element::Type::TETRAHEDRON: return GridFormat::CellType::tetrahedron; | |
37 | ✗ | case mfem::Element::Type::WEDGE: break; | |
38 | ✗ | case mfem::Element::Type::PYRAMID: break; | |
39 | 210 | case mfem::Element::Type::HEXAHEDRON: return GridFormat::CellType::hexahedron; | |
40 | } | ||
41 | ✗ | throw NotImplemented("Support for given mfem cell type"); | |
42 | } | ||
43 | } // namespace Detail | ||
44 | #endif // DOXYGEN | ||
45 | |||
46 | using Point = int; | ||
47 | using Cell = int; | ||
48 | |||
49 | } // namespace GridFormat::MFEM | ||
50 | |||
51 | // Specializations of the traits required for the `UnstructuredGrid` concept for mfem::Mesh | ||
52 | namespace GridFormat::Traits { | ||
53 | |||
54 | template<> | ||
55 | struct Points<mfem::Mesh> { | ||
56 | 29 | static std::ranges::range auto get(const mfem::Mesh& mesh) { | |
57 |
1/2✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
|
29 | return std::views::iota(0, mesh.GetNV()); |
58 | } | ||
59 | }; | ||
60 | |||
61 | template<> | ||
62 | struct Cells<mfem::Mesh> { | ||
63 | 45 | static std::ranges::range auto get(const mfem::Mesh& mesh) { | |
64 |
1/2✓ Branch 2 taken 45 times.
✗ Branch 3 not taken.
|
45 | return std::views::iota(0, mesh.GetNE()); |
65 | } | ||
66 | }; | ||
67 | |||
68 | template<> | ||
69 | struct CellType<mfem::Mesh, GridFormat::MFEM::Cell> { | ||
70 | 9966 | static GridFormat::CellType get(const mfem::Mesh& mesh, const GridFormat::MFEM::Cell& cell) { | |
71 | 9966 | return GridFormat::MFEM::Detail::cell_type(mesh.GetElement(cell)->GetType()); | |
72 | } | ||
73 | }; | ||
74 | |||
75 | template<> | ||
76 | struct CellPoints<mfem::Mesh, GridFormat::MFEM::Cell> { | ||
77 | 3705 | static std::ranges::range decltype(auto) get(const mfem::Mesh& mesh, const GridFormat::MFEM::Cell& cell) { | |
78 | 3705 | const auto element = mesh.GetElement(cell); | |
79 | 3705 | auto begin = element->GetVertices(); | |
80 |
1/2✓ Branch 1 taken 3705 times.
✗ Branch 2 not taken.
|
3705 | return std::ranges::subrange(begin, begin + element->GetNVertices()); |
81 | } | ||
82 | }; | ||
83 | |||
84 | template<> | ||
85 | struct PointId<mfem::Mesh, GridFormat::MFEM::Point> { | ||
86 | 10580 | static auto get(const mfem::Mesh&, const GridFormat::MFEM::Point& point) { | |
87 | 10580 | return point; | |
88 | } | ||
89 | }; | ||
90 | |||
91 | template<> | ||
92 | struct PointCoordinates<mfem::Mesh, GridFormat::MFEM::Point> { | ||
93 | 1100 | static std::ranges::range decltype(auto) get(const mfem::Mesh& mesh, const GridFormat::MFEM::Point& point) { | |
94 | 1100 | std::array<double, 3> coords = {}; | |
95 | 1100 | auto begin = mesh.GetVertex(point); | |
96 | 1100 | std::copy(begin, begin + mesh.SpaceDimension(), coords.begin()); | |
97 | 1100 | return coords; | |
98 | } | ||
99 | }; | ||
100 | |||
101 | template<> | ||
102 | struct NumberOfPoints<mfem::Mesh> { | ||
103 | 125 | static std::integral auto get(const mfem::Mesh& mesh) { | |
104 | 125 | return mesh.GetNV(); | |
105 | } | ||
106 | }; | ||
107 | |||
108 | template<> | ||
109 | struct NumberOfCells<mfem::Mesh> { | ||
110 | 110 | static std::integral auto get(const mfem::Mesh& mesh) { | |
111 | 110 | return mesh.GetNE(); | |
112 | } | ||
113 | }; | ||
114 | |||
115 | template<> | ||
116 | struct NumberOfCellPoints<mfem::Mesh, GridFormat::MFEM::Cell> { | ||
117 | 5685 | static std::integral auto get(const mfem::Mesh& mesh, const GridFormat::MFEM::Cell& cell) { | |
118 | 5685 | return mesh.GetElement(cell)->GetNVertices(); | |
119 | } | ||
120 | }; | ||
121 | |||
122 | } // namespace GridFormat::Traits | ||
123 | |||
124 | #endif // GRIDFORMAT_TRAITS_MFEM_HPP_ | ||
125 |