9#ifndef GRIDFORMAT_TRAITS_MFEM_HPP_
10#define GRIDFORMAT_TRAITS_MFEM_HPP_
18#include <mfem/mesh/mesh.hpp>
20#include <gridformat/common/exceptions.hpp>
21#include <gridformat/common/filtered_range.hpp>
23#include <gridformat/grid/cell_type.hpp>
24#include <gridformat/grid/traits.hpp>
26namespace GridFormat::MFEM {
30 CellType cell_type(mfem::Element::Type ct) {
32 case mfem::Element::Type::POINT:
return GridFormat::CellType::vertex;
33 case mfem::Element::Type::SEGMENT:
return GridFormat::CellType::segment;
34 case mfem::Element::Type::TRIANGLE:
return GridFormat::CellType::triangle;
35 case mfem::Element::Type::QUADRILATERAL:
return GridFormat::CellType::quadrilateral;
36 case mfem::Element::Type::TETRAHEDRON:
return GridFormat::CellType::tetrahedron;
37 case mfem::Element::Type::WEDGE:
break;
38 case mfem::Element::Type::PYRAMID:
break;
39 case mfem::Element::Type::HEXAHEDRON:
return GridFormat::CellType::hexahedron;
41 throw NotImplemented(
"Support for given mfem cell type");
52namespace GridFormat::Traits {
55struct Points<mfem::Mesh> {
56 static std::ranges::range
auto get(
const mfem::Mesh& mesh) {
57 return std::views::iota(0, mesh.GetNV());
62struct Cells<mfem::Mesh> {
63 static std::ranges::range
auto get(
const mfem::Mesh& mesh) {
64 return std::views::iota(0, mesh.GetNE());
69struct CellType<mfem::Mesh, GridFormat::MFEM::Cell> {
70 static GridFormat::CellType get(
const mfem::Mesh& mesh,
const GridFormat::MFEM::Cell& cell) {
71 return GridFormat::MFEM::Detail::cell_type(mesh.GetElement(cell)->GetType());
76struct CellPoints<mfem::Mesh, GridFormat::MFEM::Cell> {
77 static std::ranges::range
decltype(
auto) get(
const mfem::Mesh& mesh,
const GridFormat::MFEM::Cell& cell) {
78 const auto element = mesh.GetElement(cell);
79 auto begin = element->GetVertices();
80 return std::ranges::subrange(begin, begin + element->GetNVertices());
85struct PointId<mfem::Mesh, GridFormat::MFEM::Point> {
86 static auto get(
const mfem::Mesh&,
const GridFormat::MFEM::Point& point) {
92struct PointCoordinates<mfem::Mesh, GridFormat::MFEM::Point> {
93 static std::ranges::range
decltype(
auto) get(
const mfem::Mesh& mesh,
const GridFormat::MFEM::Point& point) {
94 std::array<double, 3> coords = {};
95 auto begin = mesh.GetVertex(point);
96 std::copy(begin, begin + mesh.SpaceDimension(), coords.begin());
102struct NumberOfPoints<mfem::Mesh> {
103 static std::integral
auto get(
const mfem::Mesh& mesh) {
109struct NumberOfCells<mfem::Mesh> {
110 static std::integral
auto get(
const mfem::Mesh& mesh) {
116struct NumberOfCellPoints<mfem::Mesh, GridFormat::MFEM::Cell> {
117 static std::integral
auto get(
const mfem::Mesh& mesh,
const GridFormat::MFEM::Cell& cell) {
118 return mesh.GetElement(cell)->GetNVertices();