RINGMesh  Version 5.0.0
A programming library for geological model meshes
io_abaqus.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 
38  struct RINGMesh2Abaqus {
39  std::string entity_type;
40  index_t vertices[8];
41  };
42 
43  static RINGMesh2Abaqus tet_descriptor_abaqus = { "C3D4", // type
44  { 0, 1, 2, 3 } // vertices
45  };
46 
47  static RINGMesh2Abaqus hex_descriptor_abaqus = { "C3D8", // type
48  { 0, 4, 5, 1, 2, 6, 7, 3 } // vertices
49  };
50 
51  class AbaqusIOHandler final: public GeoModelIOHandler< 3 > {
52  public:
53  static const index_t NB_ENTRY_PER_LINE = 16;
54 
55  void load( const std::string& filename, GeoModel3D& geomodel ) final
56  {
57  ringmesh_unused( filename );
58  ringmesh_unused( geomodel );
59  throw RINGMeshException( "I/O",
60  "Loading of a GeoModel from abaqus not implemented yet" );
61  }
62  void save(
63  const GeoModel3D& geomodel,
64  const std::string& filename ) final
65  {
66  std::ofstream out( filename.c_str() );
67  out.precision( 16 );
68 
69  out << "*HEADING" << EOL;
70  out << "**Mesh exported from RINGMesh" << EOL;
71  out << "**https://bitbucket.org/ring_team/ringmesh" << EOL;
72 
73  out << "*PART, name=Part-1" << EOL;
74 
75  save_vertices( geomodel, out );
76  save_nb_polygons( geomodel, out );
77  save_cells( geomodel, out );
78 
79  out << "*END PART" << EOL;
80  out << std::flush;
81  }
82  private:
83  void save_vertices( const GeoModel3D& geomodel, std::ofstream& out ) const
84  {
85  const GeoModelMeshVertices3D& vertices = geomodel.mesh.vertices;
86  out << "*NODE" << EOL;
87  for( auto v : range( vertices.nb() ) ) {
88  out << v + 1;
89  const vec3& vertex = vertices.vertex( v );
90  for( auto i : range( 3 ) ) {
91  out << COMMA << SPACE << vertex[i];
92  }
93  out << EOL;
94  }
95 
96  }
97  void save_nb_polygons(
98  const GeoModel3D& geomodel,
99  std::ofstream& out ) const
100  {
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 );
105  }
106  }
107  void save_interface(
108  const GeoModel3D& geomodel,
109  index_t interface_id,
110  std::ofstream& out ) const
111  {
112  const GeoModelMeshPolygons3D& polygons = geomodel.mesh.polygons;
113  const GeoModelGeologicalEntity3D& entity = geomodel.geological_entity(
114  Interface3D::type_name_static(), interface_id );
115  std::string sep;
116  index_t count = 0;
117  std::vector< bool > vertex_exported( geomodel.mesh.vertices.nb(),
118  false );
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;
130  sep = COMMA + SPACE;
131  new_line_if_needed( count, out, sep );
132  }
133  }
134  }
135  out << EOL;
136  }
137 
138  void save_tets( const GeoModel3D& geomodel, std::ofstream& out ) const
139  {
140  const GeoModelMeshCells3D& cells = geomodel.mesh.cells;
141  if( cells.nb_tet() > 0 ) {
142  out << "*ELEMENT, type=" << tet_descriptor_abaqus.entity_type
143  << EOL;
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 );
147  out << tetra + 1;
148  for( auto v : range( 4 ) ) {
149  index_t vertex_id = tet_descriptor_abaqus.vertices[v];
150  out << COMMA << SPACE
151  << cells.vertex(
152  ElementLocalVertex( tetra, vertex_id ) ) + 1;
153  }
154  out << EOL;
155  }
156  }
157  }
158  }
159  void save_hex( const GeoModel3D& geomodel, std::ofstream& out ) const
160  {
161  const GeoModelMeshCells3D& cells = geomodel.mesh.cells;
162  if( cells.nb_hex() > 0 ) {
163  out << "*ELEMENT, type=" << hex_descriptor_abaqus.entity_type
164  << EOL;
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 );
168  out << hex + 1;
169  for( auto v : range( 8 ) ) {
170  index_t vertex_id = hex_descriptor_abaqus.vertices[v];
171  out << COMMA << SPACE
172  << cells.vertex(
173  ElementLocalVertex( hex, vertex_id ) ) + 1;
174  }
175  out << EOL;
176  }
177  }
178  }
179  }
180  void save_regions( const GeoModel3D& geomodel, std::ofstream& out ) const
181  {
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;
186  index_t count = 0;
187  std::string sep;
188  for( auto c : range( cells.nb_tet( r ) ) ) {
189  index_t tetra = cells.tet( r, c );
190  out << sep << tetra + 1;
191  sep = COMMA + SPACE;
192  new_line_if_needed( count, out, sep );
193 
194  }
195  for( auto c : range( cells.nb_hex( r ) ) ) {
196  index_t hex = cells.hex( r, c );
197  out << sep << hex + 1;
198  sep = COMMA + SPACE;
199  new_line_if_needed( count, out, sep );
200  }
201  reset_line( count, out );
202 
203  out << "*NSET, nset=" << name << ", elset=" << name << EOL;
204  }
205  }
206  void save_cells( const GeoModel3D& geomodel, std::ofstream& out ) const
207  {
208  save_tets( geomodel, out );
209  save_hex( geomodel, out );
210  save_regions( geomodel, out );
211  }
212  void new_line_if_needed(
213  index_t& count,
214  std::ofstream& out,
215  std::string& sep ) const
216  {
217  count++;
218  if( count == NB_ENTRY_PER_LINE ) {
219  count = 0;
220  sep = "";
221  out << EOL;
222  }
223  }
224  void reset_line( index_t& count, std::ofstream& out ) const
225  {
226  if( count != 0 ) {
227  count = 0;
228  out << EOL;
229  }
230  }
231  };
232 
233 }
const char SPACE
Definition: io.h:46
vecn< 3 > vec3
Definition: types.h:76
void ringmesh_unused(const T &)
Definition: common.h:105
const char COMMA
Definition: io.h:44
const char EOL
Definition: io.h:45