39 static const index_t cell_type_mfem[4] = { 4, 5, NO_ID, NO_ID };
43 static const index_t polygon_type_mfem[3] = { 2, 3, NO_ID };
49 static const index_t cell2mfem[8] = { 0, 1, 3, 2, 4, 5, 7, 6 };
52 static const index_t mfem_offset = 1;
55 POINT = 0, SEGMENT = 1, TRIANGLE = 2, SQUARE = 3, TETRAHEDRON = 4, CUBE = 5
64 template< index_t DIMENSION >
65 class MFEMIOHandler final:
public GeoModelIOHandler< DIMENSION > {
67 void load(
const std::string& filename, GeoModel< DIMENSION >& geomodel )
final 71 throw RINGMeshException(
"I/O",
72 "Loading of a GeoModel from MFEM not implemented yet" );
75 const GeoModel< DIMENSION >& geomodel,
76 const std::string& filename )
final 78 const auto& geomodel_mesh = geomodel.mesh;
79 test_if_mesh_is_valid( geomodel.mesh );
81 std::ofstream out( filename.c_str() );
85 write_elements( geomodel_mesh, out );
86 write_boundaries( geomodel_mesh, out );
87 write_vertices( geomodel_mesh, out );
92 void test_if_mesh_is_valid(
const GeoModelMesh< DIMENSION >& geomodel_mesh );
99 void write_header( std::ofstream& out )
const 101 out <<
"MFEM mesh v1.0" <<
EOL;
103 out <<
"dimension" <<
EOL;
104 out << DIMENSION <<
EOL;
109 const GeoModelMesh< DIMENSION >& geomodel_mesh,
110 std::ofstream& out )
const;
112 void write_boundaries(
113 const GeoModelMesh< DIMENSION >& geomodel_mesh,
114 std::ofstream& out )
const;
124 const GeoModelMesh< DIMENSION >& geomodel_mesh,
125 std::ofstream& out )
const 127 out <<
"vertices" <<
EOL;
128 out << geomodel_mesh.vertices.nb() <<
EOL;
129 out << DIMENSION <<
EOL;
130 for(
auto v : range( geomodel_mesh.vertices.nb() ) ) {
131 out << geomodel_mesh.vertices.vertex( v ) <<
EOL;
139 void MFEMIOHandler3D::test_if_mesh_is_valid(
140 const GeoModelMesh3D& geomodel_mesh )
142 index_t nb_cells { geomodel_mesh.cells.nb() };
143 if( geomodel_mesh.cells.nb_tet() != nb_cells
144 && geomodel_mesh.cells.nb_hex() != nb_cells ) {
145 throw RINGMeshException(
"I/O",
146 "Export to MFEM format works only with full tet or full hex format" );
151 void MFEMIOHandler2D::test_if_mesh_is_valid(
152 const GeoModelMesh2D& geomodel_mesh )
154 if( geomodel_mesh.polygons.nb() != geomodel_mesh.polygons.nb_triangle() ) {
155 throw RINGMeshException(
"I/O",
156 "Export to MFEM format works only with triangles in 2D" );
171 void MFEMIOHandler3D::write_elements(
172 const GeoModelMesh3D& geomodel_mesh,
173 std::ofstream& out )
const 175 index_t nb_cells { geomodel_mesh.cells.nb() };
176 out <<
"elements" <<
EOL;
177 out << nb_cells <<
EOL;
178 for(
auto c : range( nb_cells ) ) {
179 out << geomodel_mesh.cells.region( c ) + mfem_offset <<
" ";
183 for(
auto v : range( geomodel_mesh.cells.nb_vertices( c ) ) ) {
185 << geomodel_mesh.cells.vertex(
186 ElementLocalVertex( c, cell2mfem[v] ) ) <<
" ";
194 void MFEMIOHandler2D::write_elements(
195 const GeoModelMesh2D& geomodel_mesh,
196 std::ofstream& out )
const 198 index_t nb_triangles { geomodel_mesh.polygons.nb_triangle() };
199 out <<
"elements" <<
EOL;
200 out << nb_triangles <<
EOL;
201 for(
auto c : range( nb_triangles ) ) {
202 out << geomodel_mesh.polygons.surface( c ) + mfem_offset <<
" ";
203 out << TRIANGLE <<
" ";
204 for(
auto v : range( geomodel_mesh.polygons.nb_vertices( c ) ) ) {
205 out << geomodel_mesh.polygons.vertex( ElementLocalVertex( c, v ) )
224 void MFEMIOHandler3D::write_boundaries(
225 const GeoModelMesh3D& geomodel_mesh,
226 std::ofstream& out )
const 228 const GeoModelMeshPolygons3D& polygons = geomodel_mesh.polygons;
229 out <<
"boundary" <<
EOL;
230 out << polygons.nb() <<
EOL;
231 for(
auto p : range( polygons.nb() ) ) {
232 out << polygons.surface( p ) + mfem_offset <<
" ";
234 std::tie( polygon_type, std::ignore ) = polygons.type( p );
236 for(
auto v : range( polygons.nb_vertices( p ) ) ) {
237 out << polygons.vertex( ElementLocalVertex( p, v ) ) <<
" ";
245 void MFEMIOHandler2D::write_boundaries(
246 const GeoModelMesh2D& geomodel_mesh,
247 std::ofstream& out )
const 249 const GeoModelMeshEdges2D& edges = geomodel_mesh.edges;
250 out <<
"boundary" <<
EOL;
251 out << edges.nb() <<
EOL;
252 for(
auto p : range( edges.nb() ) ) {
253 out << edges.line( p ) + mfem_offset <<
" ";
254 out << SEGMENT <<
" ";
255 for(
auto v : range( 2 ) ) {
256 out << edges.vertex( ElementLocalVertex( p, v ) ) <<
" ";
void ringmesh_unused(const T &)
auto to_underlying_type(Enum e) -> typename std::underlying_type< Enum >::type
#define ALIAS_2D_AND_3D(Class)