38     struct RINGMesh2Abaqus {
    39         std::string entity_type;
    43     static RINGMesh2Abaqus tet_descriptor_abaqus = { 
"C3D4",                  
    47     static RINGMesh2Abaqus hex_descriptor_abaqus = { 
"C3D8",                  
    48         { 0, 4, 5, 1, 2, 6, 7, 3 }     
    51     class AbaqusIOHandler final: 
public GeoModelIOHandler< 3 > {
    53         static const index_t NB_ENTRY_PER_LINE = 16;
    55         void load( 
const std::string& filename, GeoModel3D& geomodel ) 
final    59             throw RINGMeshException( 
"I/O",
    60                 "Loading of a GeoModel from abaqus not implemented yet" );
    63             const GeoModel3D& geomodel,
    64             const std::string& filename ) 
final    66             std::ofstream out( filename.c_str() );
    69             out << 
"*HEADING" << 
EOL;
    70             out << 
"**Mesh exported from RINGMesh" << 
EOL;
    71             out << 
"**https://bitbucket.org/ring_team/ringmesh" << 
EOL;
    73             out << 
"*PART, name=Part-1" << 
EOL;
    75             save_vertices( geomodel, out );
    76             save_nb_polygons( geomodel, out );
    77             save_cells( geomodel, out );
    79             out << 
"*END PART" << 
EOL;
    83         void save_vertices( 
const GeoModel3D& geomodel, std::ofstream& out )
 const    85             const GeoModelMeshVertices3D& vertices = geomodel.mesh.vertices;
    86             out << 
"*NODE" << 
EOL;
    87             for( 
auto v : range( vertices.nb() ) ) {
    89                 const vec3& vertex = vertices.vertex( v );
    90                 for( 
auto i : range( 3 ) ) {
    97         void save_nb_polygons(
    98             const GeoModel3D& geomodel,
    99             std::ofstream& out )
 const   101             const GeologicalEntityType& type = Interface3D ::type_name_static();
   102             index_t nb_interfaces = geomodel.nb_geological_entities( type );
   103             for( 
auto i : range( nb_interfaces ) ) {
   104                 save_interface( geomodel, i, out );
   108             const GeoModel3D& geomodel,
   109             index_t interface_id,
   110             std::ofstream& out )
 const   112             const GeoModelMeshPolygons3D& polygons = geomodel.mesh.polygons;
   113             const GeoModelGeologicalEntity3D& entity = geomodel.geological_entity(
   114                 Interface3D::type_name_static(), interface_id );
   117             std::vector< bool > vertex_exported( geomodel.mesh.vertices.nb(),
   119             out << 
"*NSET, nset=" << entity.name() << 
EOL;
   120             for( 
auto s : range( entity.nb_children() ) ) {
   121                 index_t surface_id = entity.child_gmme( s ).index();
   122                 for( 
auto p : range( polygons.nb_polygons( surface_id ) ) ) {
   123                     index_t polygon_id = polygons.polygon( surface_id, p );
   124                     for( 
auto v : range( polygons.nb_vertices( polygon_id ) ) ) {
   125                         index_t vertex_id = polygons.vertex(
   126                             ElementLocalVertex( polygon_id, v ) );
   127                         if( vertex_exported[vertex_id] ) 
continue;
   128                         vertex_exported[vertex_id] = 
true;
   129                         out << sep << vertex_id + 1;
   131                         new_line_if_needed( count, out, sep );
   138         void save_tets( 
const GeoModel3D& geomodel, std::ofstream& out )
 const   140             const GeoModelMeshCells3D& cells = geomodel.mesh.cells;
   141             if( cells.nb_tet() > 0 ) {
   142                 out << 
"*ELEMENT, type=" << tet_descriptor_abaqus.entity_type
   144                 for( 
auto r : range( geomodel.nb_regions() ) ) {
   145                     for( 
auto c : range( cells.nb_tet( r ) ) ) {
   146                         index_t tetra = cells.tet( r, c );
   148                         for( 
auto v : range( 4 ) ) {
   149                             index_t vertex_id = tet_descriptor_abaqus.vertices[v];
   152                                     ElementLocalVertex( tetra, vertex_id ) ) + 1;
   159         void save_hex( 
const GeoModel3D& geomodel, std::ofstream& out )
 const   161             const GeoModelMeshCells3D& cells = geomodel.mesh.cells;
   162             if( cells.nb_hex() > 0 ) {
   163                 out << 
"*ELEMENT, type=" << hex_descriptor_abaqus.entity_type
   165                 for( 
auto r : range( geomodel.nb_regions() ) ) {
   166                     for( 
auto c : range( cells.nb_hex( r ) ) ) {
   167                         index_t hex = cells.hex( r, c );
   169                         for( 
auto v : range( 8 ) ) {
   170                             index_t vertex_id = hex_descriptor_abaqus.vertices[v];
   173                                     ElementLocalVertex( hex, vertex_id ) ) + 1;
   180         void save_regions( 
const GeoModel3D& geomodel, std::ofstream& out )
 const   182             const GeoModelMeshCells3D& cells = geomodel.mesh.cells;
   183             for( 
auto r : range( geomodel.nb_regions() ) ) {
   184                 const std::string& name = geomodel.region( r ).name();
   185                 out << 
"*ELSET, elset=" << name << 
EOL;
   188                 for( 
auto c : range( cells.nb_tet( r ) ) ) {
   189                     index_t tetra = cells.tet( r, c );
   190                     out << sep << tetra + 1;
   192                     new_line_if_needed( count, out, sep );
   195                 for( 
auto c : range( cells.nb_hex( r ) ) ) {
   196                     index_t hex = cells.hex( r, c );
   197                     out << sep << hex + 1;
   199                     new_line_if_needed( count, out, sep );
   201                 reset_line( count, out );
   203                 out << 
"*NSET, nset=" << name << 
", elset=" << name << 
EOL;
   206         void save_cells( 
const GeoModel3D& geomodel, std::ofstream& out )
 const   208             save_tets( geomodel, out );
   209             save_hex( geomodel, out );
   210             save_regions( geomodel, out );
   212         void new_line_if_needed(
   215             std::string& sep )
 const   218             if( count == NB_ENTRY_PER_LINE ) {
   224         void reset_line( index_t& count, std::ofstream& out )
 const 
void ringmesh_unused(const T &)