RINGMesh  Version 5.0.0
A programming library for geological model meshes
io_adeli.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2017, Association Scientifique pour la Geologie et ses
3  * Applications (ASGA). All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of ASGA nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ASGA BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * http://www.ring-team.org
28  *
29  * RING Project
30  * Ecole Nationale Superieure de Geologie - GeoRessources
31  * 2 Rue du Doyen Marcel Roubault - TSA 70605
32  * 54518 VANDOEUVRE-LES-NANCY
33  * FRANCE
34  */
35 
36 namespace {
37  // The reg phys field in the GMSH format is set to 0 for each element
38  static const index_t reg_phys = 0;
39 
40  static const index_t adeli_point_type = 15;
41  static const index_t adeli_line_type = 1;
42  static const index_t adeli_triangle_type = 2;
43  static const index_t adeli_tet_type = 4;
44  static const index_t adeli_cell_types[4] =
45  { adeli_point_type, adeli_line_type, adeli_triangle_type, adeli_tet_type };
46 
47  // The index begins at 1.
48  static const index_t id_offset_adeli = 1;
49 
61  class AdeliIOHandler final: public GeoModelIOHandler< 3 > {
62  public:
63  void load( const std::string& filename, GeoModel3D& geomodel ) final
64  {
65  ringmesh_unused( filename );
66  ringmesh_unused( geomodel );
67  throw RINGMeshException( "I/O",
68  "Loading of a GeoModel from Adeli .msh mesh not implemented yet" );
69  }
70  void save( const GeoModel3D& geomodel, const std::string& filename ) final
71  {
72  std::ofstream out( filename.c_str() );
73  out.precision( 16 );
74  const RINGMesh::GeoModelMesh3D& geomodel_mesh = geomodel.mesh;
75  if( geomodel_mesh.cells.nb() != geomodel_mesh.cells.nb_tet() ) {
76  {
77  throw RINGMeshException( "I/O",
78  "Adeli supports only tet meshes" );
79  }
80  }
81 
82  write_vertices( geomodel_mesh, out );
83 
84  write_mesh_elements( geomodel, out );
85  out << std::flush;
86  }
87 
88  private:
89  void write_vertices(
90  const GeoModelMesh3D& geomodel_mesh,
91  std::ofstream& out ) const
92  {
93  out << "$NOD" << EOL;
94  out << geomodel_mesh.vertices.nb() << EOL;
95  for( auto v : range( geomodel_mesh.vertices.nb() ) ) {
96  out << v + id_offset_adeli << " "
97  << geomodel_mesh.vertices.vertex( v ) << EOL;
98  }
99  out << "$ENDNOD" << EOL;
100  }
101 
102  index_t write_corners(
103  const GeoModel3D& geomodel,
104  std::ofstream& out ) const
105  {
106  out << "$ELM" << EOL;
107  out << nb_total_elements( geomodel ) << EOL;
108  index_t elt = 1;
109  for( const auto& corner : geomodel.corners() ) {
110  out << elt++ << " " << adeli_cell_types[0] << " " << reg_phys << " "
111  << corner.index() + id_offset_adeli << " "
112  << corner.nb_vertices() << " "
113  << geomodel.mesh.vertices.geomodel_vertex_id( corner.gmme(),
114  0 ) + id_offset_adeli << EOL;
115  }
116  return elt;
117  }
118 
119  void write_mesh_elements(
120  const GeoModel3D& geomodel,
121  std::ofstream& out ) const
122  {
123  index_t elt = write_corners( geomodel, out );
124  const MeshEntityTypeManager3D& manager =
125  geomodel.entity_type_manager().mesh_entity_manager;
126  const std::vector< MeshEntityType >& mesh_entity_types =
127  manager.mesh_entity_types();
128  // Corners are already written so we start this loop at 1
129  for( auto geomodel_mesh_entities : range( 1,
130  manager.nb_mesh_entity_types() ) ) {
131  for( auto entity : range(
132  geomodel.nb_mesh_entities(
133  mesh_entity_types[geomodel_mesh_entities] ) ) ) {
134  write_mesh_elements_for_a_mesh_entity(
135  geomodel.mesh_entity(
136  mesh_entity_types[geomodel_mesh_entities], entity ),
137  adeli_cell_types[geomodel_mesh_entities], elt, out );
138  }
139  }
140  out << "$ENDELM" << EOL;
141  }
142 
143  index_t nb_total_elements( const GeoModel3D& geomodel ) const
144  {
145  const MeshEntityTypeManager3D& manager =
146  geomodel.entity_type_manager().mesh_entity_manager;
147  const std::vector< MeshEntityType >& mesh_entity_types =
148  manager.mesh_entity_types();
149  // Because corners does not have mesh elements, but are considered as elements
150  // in adeli, we have to count the vertex of each corner in a different
151  // way
152  index_t nb_mesh_entities = geomodel.nb_corners();
153  for( auto geomodel_mesh_entities : range( 1,
154  manager.nb_mesh_entity_types() ) ) {
155  for( auto entity : range(
156  geomodel.nb_mesh_entities(
157  mesh_entity_types[geomodel_mesh_entities] ) ) ) {
158  nb_mesh_entities +=
159  geomodel.mesh_entity(
160  mesh_entity_types[geomodel_mesh_entities], entity ).nb_mesh_elements();
161  }
162  }
163  return nb_mesh_entities;
164  }
165 
166  void write_mesh_elements_for_a_mesh_entity(
167  const GeoModelMeshEntity3D& geomodel_mesh_entity,
168  index_t cell_descriptor,
169  index_t& elt_id,
170  std::ofstream& out ) const
171  {
172  for( auto elt : range( geomodel_mesh_entity.nb_mesh_elements() ) ) {
173  out << elt_id++ << " " << cell_descriptor << " " << reg_phys << " "
174  << geomodel_mesh_entity.index() + id_offset_adeli << " "
175  << geomodel_mesh_entity.nb_mesh_element_vertices( elt ) << " ";
176  for( auto v : range(
177  geomodel_mesh_entity.nb_mesh_element_vertices( elt ) ) ) {
178  out
179  << geomodel_mesh_entity.geomodel().mesh.vertices.geomodel_vertex_id(
180  geomodel_mesh_entity.gmme(),
181  ElementLocalVertex( elt, v ) ) + id_offset_adeli << " ";
182  }
183  out << EOL;
184  }
185  }
186  };
187 }
void ringmesh_unused(const T &)
Definition: common.h:105
const char EOL
Definition: io.h:45