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)