RINGMesh  Version 5.0.0
A programming library for geological model meshes
io_csmp.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  struct RINGMesh2CSMP {
38  index_t entity_type;
39  index_t nb_vertices;
40  index_t vertices[8];
41  index_t nb_polygons;
42  index_t polygon[6];
43  };
44 
45  static RINGMesh2CSMP tet_descriptor = { 4, // type
46  4, // nb vertices
47  { 0, 1, 2, 3 }, // vertices
48  4, // nb polygons
49  { 0, 1, 2, 3 } // polygons
50  };
51 
52  static RINGMesh2CSMP hex_descriptor = { 6, // type
53  8, // nb vertices
54  { 0, 4, 5, 1, 2, 6, 7, 3 }, // vertices
55  6, // nb polygons
56  { 2, 0, 5, 1, 4, 3 } // polygons
57  };
58 
59  static RINGMesh2CSMP prism_descriptor = { 12, // type
60  6, // nb vertices
61  { 0, 1, 2, 3, 4, 5 }, // vertices
62  5, // nb polygons
63  { 0, 2, 4, 3, 1 } // polygons
64  };
65 
66  static RINGMesh2CSMP pyramid_descriptor = { 18, // type
67  5, // nb vertices
68  { 0, 1, 2, 3, 4 }, // vertices
69  5, // nb polygons
70  { 1, 4, 3, 2, 0 } // polygons
71  };
72 
73  static RINGMesh2CSMP* cell_type_to_cell_descriptor[4] = { &tet_descriptor,
74  &hex_descriptor,
75  &prism_descriptor,
76  &pyramid_descriptor };
77 
78  class CSMPIOHandler final: public GeoModelIOHandler< 3 > {
79  public:
80  CSMPIOHandler()
81  {
82  clear();
83  }
84 
85  void load( const std::string& filename, GeoModel3D& geomodel ) final
86  {
87  ringmesh_unused( filename );
88  ringmesh_unused( geomodel );
89  throw RINGMeshException( "I/O",
90  "Loading of a GeoModel from CSMP not implemented yet" );
91  }
92  void save( const GeoModel3D& geomodel, const std::string& filename ) final
93  {
94  initialize( geomodel );
95 
96  std::string directory = GEO::FileSystem::dir_name( filename );
97  std::string file = GEO::FileSystem::base_name( filename );
98 
99  std::ostringstream oss_ascii;
100  oss_ascii << directory << "/" << file << ".asc";
101  std::ofstream ascii( oss_ascii.str().c_str() );
102  ascii.precision( 16 );
103 
104  ascii << geomodel.name() << EOL;
105  ascii << "Model generated from RINGMesh" << EOL;
106 
107  std::ostringstream oss_data;
108  oss_data << directory << "/" << file << ".dat";
109  std::ofstream data( oss_data.str().c_str() );
110  data.precision( 16 );
111 
112  std::ostringstream oss_regions;
113  oss_regions << directory << "/" << file << "-regions.txt";
114  std::ofstream regions( oss_regions.str().c_str() );
115  regions << "'" << oss_regions.str() << EOL;
116  regions << "no properties" << EOL;
117 
118  const GeoModelMesh3D& mesh = geomodel.mesh;
119  const GeoModelMeshPolygons3D& polygons = mesh.polygons;
120  index_t count = 0;
121  // Conversion from (X,Y,Z) to (X,Z,-Y)
122  signed_index_t conversion_sign[3] = { 1, 1, -1 };
123  index_t conversion_axis[3] = { 0, 2, 1 };
124  data << mesh.vertices.nb() << " # PX, PY, PZ" << EOL;
125  for( auto dim : range( 3 ) ) {
126  for( auto v : range( mesh.vertices.nb() ) ) {
127  data << " "
128  << conversion_sign[dim]
129  * mesh.vertices.vertex( v )[conversion_axis[dim]];
130  new_line( count, 5, data );
131  }
132  reset_line( count, data );
133  }
134  reset_line( count, data );
135 
136  index_t nb_families = 0;
137  index_t nb_interfaces = geomodel.nb_geological_entities(
138  Interface3D::type_name_static() );
139  std::vector< index_t > nb_triangle_interface( nb_interfaces, 0 );
140  std::vector< index_t > nb_quad_interface( nb_interfaces, 0 );
141  for( auto i : range( nb_interfaces ) ) {
142  const GeoModelGeologicalEntity3D& interf =
143  geomodel.geological_entity( Interface3D::type_name_static(), i );
144  for( auto s : range( interf.nb_children() ) ) {
145  index_t s_id = interf.child_gmme( s ).index();
146  nb_triangle_interface[i] += polygons.nb_triangle( s_id );
147  nb_quad_interface[i] += polygons.nb_quad( s_id );
148  }
149  if( nb_triangle_interface[i] > 0 ) nb_families++;
150  if( nb_quad_interface[i] > 0 ) nb_families++;
151  }
152  for( auto r : range( geomodel.nb_regions() ) ) {
153  if( mesh.cells.nb_tet( r ) > 0 ) nb_families++;
154  if( mesh.cells.nb_pyramid( r ) > 0 ) nb_families++;
155  if( mesh.cells.nb_prism( r ) > 0 ) nb_families++;
156  if( mesh.cells.nb_hex( r ) > 0 ) nb_families++;
157  }
158  if( geomodel.wells() ) nb_families += geomodel.wells()->nb_wells();
159 
160  ascii << nb_families << " # Number of families" << EOL;
161  ascii << "# Object name" << TAB << "Entity type" << TAB << "Material-ID"
162  << TAB << "Number of entities" << EOL;
163  for( const auto& region : geomodel.regions() ) {
164  regions << region.name() << EOL;
165  std::string entity_type[4] = { "TETRA_4", "HEXA_8", "PENTA_6",
166  "PYRA_5" };
167  for( auto type : range(
168  to_underlying_type( CellType::TETRAHEDRON ),
169  to_underlying_type( CellType::UNCLASSIFIED ) ) ) {
170  CellType T = static_cast< CellType >( type );
171  if( mesh.cells.nb_cells( region.index(), T ) > 0 ) {
172  ascii << region.name() << TAB << entity_type[type] << TAB
173  << 0 << TAB << mesh.cells.nb_cells( region.index(), T )
174  << EOL;
175  }
176  }
177  }
178  for( auto i : range( nb_interfaces ) ) {
179  regions << interface_csmp_name( i, geomodel ) << EOL;
180  if( nb_triangle_interface[i] > 0 ) {
181  ascii << interface_csmp_name( i, geomodel ) << TAB << "TRI_3"
182  << TAB << 0 << TAB << nb_triangle_interface[i] << EOL;
183  }
184  if( nb_quad_interface[i] > 0 ) {
185  ascii << interface_csmp_name( i, geomodel ) << TAB << "QUAD_4"
186  << TAB << 0 << TAB << nb_quad_interface[i] << EOL;
187  }
188  }
189  if( geomodel.wells() ) {
190  for( auto w : range( geomodel.wells()->nb_wells() ) ) {
191  const Well3D& well = geomodel.wells()->well( w );
192  regions << well.name() << EOL;
193  ascii << well.name() << TAB << "BAR_2" << TAB << 0 << TAB
194  << well.nb_edges() << EOL;
195  }
196  }
197 
198  data << "# PBFLAGS" << EOL;
199  for( auto p : range( mesh.vertices.nb() ) ) {
200  data << " " << std::setw( 3 ) << point_boundary( p );
201  new_line( count, 20, data );
202  }
203  reset_line( count, data );
204 
205  data << "# PBVALS" << EOL;
206  for( auto p : range( mesh.vertices.nb() ) ) {
207  ringmesh_unused( p );
208  data << " " << std::setw( 3 ) << 0;
209  new_line( count, 20, data );
210  }
211  reset_line( count, data );
212 
213  index_t nb_total_entities = mesh.cells.nb_cells()
214  + polygons.nb_polygons() + mesh.wells.nb_edges();
215  data << nb_total_entities << " # PELEMENT" << EOL;
216  for( auto r : range( geomodel.nb_regions() ) ) {
217  index_t entity_type[4] = { 4, 6, 12, 18 };
218  for( auto type : range(
219  to_underlying_type( CellType::TETRAHEDRON ),
220  to_underlying_type( CellType::UNCLASSIFIED ) ) ) {
221  CellType T = static_cast< CellType >( type );
222  for( auto el : range( mesh.cells.nb_cells( r, T ) ) ) {
223  ringmesh_unused( el );
224  data << " " << std::setw( 3 ) << entity_type[type];
225  new_line( count, 20, data );
226  }
227  }
228  }
229  for( auto i : range( nb_interfaces ) ) {
230  for( auto el : range( nb_triangle_interface[i] ) ) {
231  ringmesh_unused( el );
232  data << " " << std::setw( 3 ) << 8;
233  new_line( count, 20, data );
234  }
235  for( auto el : range( nb_quad_interface[i] ) ) {
236  ringmesh_unused( el );
237  data << " " << std::setw( 3 ) << 14;
238  new_line( count, 20, data );
239  }
240  }
241  if( geomodel.wells() ) {
242  for( auto w : range( geomodel.wells()->nb_wells() ) ) {
243  const Well3D& well = geomodel.wells()->well( w );
244  for( auto e : range( well.nb_edges() ) ) {
245  ringmesh_unused( e );
246  data << " " << std::setw( 3 ) << 2;
247  new_line( count, 20, data );
248  }
249  }
250  }
251  reset_line( count, data );
252 
253  ascii
254  << "# now the entities which make up each object are listed in sequence"
255  << EOL;
256  index_t cur_cell = 0;
257  for( auto r : range( geomodel.nb_regions() ) ) {
258  const RINGMesh::GeoModelEntity3D& region = geomodel.region( r );
259  std::string entity_type[4] = { "TETRA_4", "HEXA_8", "PENTA_6",
260  "PYRA_5" };
261  for( auto type : range(
262  to_underlying_type( CellType::TETRAHEDRON ),
263  to_underlying_type( CellType::UNCLASSIFIED ) ) ) {
264  CellType T = static_cast< CellType >( type );
265  if( mesh.cells.nb_cells( r, T ) > 0 ) {
266  ascii << region.name() << " " << entity_type[type] << " "
267  << mesh.cells.nb_cells( r, T ) << EOL;
268  for( auto el : range( mesh.cells.nb_cells( r, T ) ) ) {
269  ringmesh_unused( el );
270  ascii << cur_cell++ << " ";
271  new_line( count, 10, ascii );
272  }
273  reset_line( count, ascii );
274  }
275  }
276  }
277  for( auto i : range( nb_interfaces ) ) {
278  if( nb_triangle_interface[i] > 0 ) {
279  ascii << interface_csmp_name( i, geomodel ) << " " << "TRI_3"
280  << " " << nb_triangle_interface[i] << EOL;
281  for( auto el : range( nb_triangle_interface[i] ) ) {
282  ringmesh_unused( el );
283  ascii << cur_cell++ << " ";
284  new_line( count, 10, ascii );
285  }
286  reset_line( count, ascii );
287  }
288  if( nb_quad_interface[i] > 0 ) {
289  ascii << interface_csmp_name( i, geomodel ) << " " << "QUAD_4"
290  << " " << nb_quad_interface[i] << EOL;
291  for( auto el : range( nb_quad_interface[i] ) ) {
292  ringmesh_unused( el );
293  ascii << cur_cell++ << " ";
294  new_line( count, 10, ascii );
295  }
296  reset_line( count, ascii );
297  }
298  }
299  if( geomodel.wells() ) {
300  for( auto w : range( geomodel.wells()->nb_wells() ) ) {
301  const Well3D& well = geomodel.wells()->well( w );
302  ascii << well.name() << " " << "BAR_2" << " " << well.nb_edges()
303  << EOL;
304  for( auto e : range( well.nb_edges() ) ) {
305  ringmesh_unused( e );
306  ascii << cur_cell++ << " ";
307  new_line( count, 10, ascii );
308  }
309  reset_line( count, ascii );
310  }
311  }
312 
313  index_t nb_plist = 3 * polygons.nb_triangle() + 4 * polygons.nb_quad()
314  + 4 * mesh.cells.nb_tet() + 5 * mesh.cells.nb_pyramid()
315  + 6 * mesh.cells.nb_prism() + 8 * mesh.cells.nb_hex()
316  + 2 * mesh.wells.nb_edges();
317  data << nb_plist << " # PLIST" << EOL;
318  for( auto r : range( geomodel.nb_regions() ) ) {
319  for( auto type : range(
320  to_underlying_type( CellType::TETRAHEDRON ),
321  to_underlying_type( CellType::UNCLASSIFIED ) ) ) {
322  CellType T = static_cast< CellType >( type );
323  RINGMesh2CSMP& descriptor = *cell_type_to_cell_descriptor[type];
324  for( auto el : range( mesh.cells.nb_cells( r, T ) ) ) {
325  index_t cell = mesh.cells.cell( r, el, T );
326  for( auto p : range( descriptor.nb_vertices ) ) {
327  index_t csmp_p = descriptor.vertices[p];
328  index_t vertex_id = mesh.cells.vertex(
329  ElementLocalVertex( cell, csmp_p ) );
330  data << " " << std::setw( 7 ) << vertex_id;
331  new_line( count, 10, data );
332  }
333  }
334  }
335  }
336  for( auto i : range( nb_interfaces ) ) {
337  const GeoModelGeologicalEntity3D& interf =
338  geomodel.geological_entity( Interface3D::type_name_static(), i );
339  for( auto s : range( interf.nb_children() ) ) {
340  index_t s_id = interf.child_gmme( s ).index();
341  for( auto el : range( polygons.nb_triangle( s_id ) ) ) {
342  index_t tri = polygons.triangle( s_id, el );
343  for( auto p : range( polygons.nb_vertices( tri ) ) ) {
344  index_t vertex_id = polygons.vertex(
345  ElementLocalVertex( tri, p ) );
346  data << " " << std::setw( 7 ) << vertex_id;
347  new_line( count, 10, data );
348  }
349  }
350  for( auto el : range( polygons.nb_quad( s_id ) ) ) {
351  index_t quad = polygons.quad( s_id, el );
352  for( auto p : range( polygons.nb_vertices( quad ) ) ) {
353  index_t vertex_id = polygons.vertex(
354  ElementLocalVertex( quad, p ) );
355  data << " " << std::setw( 7 ) << vertex_id;
356  new_line( count, 10, data );
357  }
358  }
359  }
360  }
361  for( auto w : range( mesh.wells.nb_wells() ) ) {
362  for( auto e : range( mesh.wells.nb_edges( w ) ) ) {
363  for( auto v : range( 2 ) ) {
364  index_t vertex_id = mesh.wells.vertex( w, e, v );
365  data << " " << std::setw( 7 ) << vertex_id;
366  new_line( count, 10, data );
367  }
368  }
369  }
370  reset_line( count, data );
371 
372  index_t nb_polygons = 3 * polygons.nb_triangle() + 4 * polygons.nb_quad()
373  + 4 * mesh.cells.nb_tet() + 5 * mesh.cells.nb_pyramid()
374  + 5 * mesh.cells.nb_prism() + 6 * mesh.cells.nb_hex()
375  + 2 * mesh.wells.nb_edges();
376  data << nb_polygons << " # PFVERTS" << EOL;
377  for( auto r : range( geomodel.nb_regions() ) ) {
378  for( auto type : range(
379  to_underlying_type( CellType::TETRAHEDRON ),
380  to_underlying_type( CellType::UNCLASSIFIED ) ) ) {
381  CellType T = static_cast< CellType >( type );
382  RINGMesh2CSMP& descriptor = *cell_type_to_cell_descriptor[type];
383  for( auto el : range( mesh.cells.nb_cells( r, T ) ) ) {
384  index_t cell = mesh.cells.cell( r, el );
385  for( auto p : range( descriptor.nb_polygons ) ) {
386  index_t csmp_f = descriptor.polygon[p];
387  index_t adj = mesh.cells.adjacent( cell, csmp_f );
388  if( adj == GEO::NO_CELL ) {
389  data << " " << std::setw( 7 ) << -28;
390  } else {
391  data << " " << std::setw( 7 ) << adj;
392  }
393  new_line( count, 10, data );
394  }
395  }
396  }
397  }
398  for( auto i : range( nb_interfaces ) ) {
399  const GeoModelGeologicalEntity3D& interf =
400  geomodel.geological_entity( Interface3D::type_name_static(), i );
401  for( auto s : range( interf.nb_children() ) ) {
402  index_t s_id = interf.child_gmme( s ).index();
403  for( auto el : range( polygons.nb_triangle( s_id ) ) ) {
404  index_t tri = polygons.triangle( s_id, el );
405  for( auto e : range( polygons.nb_vertices( tri ) ) ) {
406  index_t adj = polygons.adjacent(
407  PolygonLocalEdge( tri, e ) );
408  if( adj == GEO::NO_FACET ) {
409  data << " " << std::setw( 7 ) << -28;
410  } else {
411  data << " " << std::setw( 7 ) << adj;
412  }
413  new_line( count, 10, data );
414  }
415  }
416  for( auto el : range( polygons.nb_quad( s_id ) ) ) {
417  index_t quad = polygons.quad( s_id, el );
418  for( auto e : range( polygons.nb_vertices( quad ) ) ) {
419  index_t adj = polygons.adjacent(
420  PolygonLocalEdge( quad, e ) );
421  if( adj == GEO::NO_FACET ) {
422  data << " " << std::setw( 7 ) << -28;
423  } else {
424  data << " " << std::setw( 7 ) << adj;
425  }
426  new_line( count, 10, data );
427  }
428  }
429  }
430  }
431  index_t edge_offset = polygons.nb() + mesh.cells.nb();
432  index_t cur_edge = 0;
433  for( auto w : range( mesh.wells.nb_wells() ) ) {
434  data << " " << std::setw( 7 ) << -28;
435  new_line( count, 10, data );
436  if( mesh.wells.nb_edges( w ) > 1 ) {
437  data << " " << std::setw( 7 ) << edge_offset + cur_edge + 1;
438  cur_edge++;
439  new_line( count, 10, data );
440  for( index_t e = 1; e < mesh.wells.nb_edges( w ) - 1;
441  e++, cur_edge++ ) {
442  data << " " << std::setw( 7 ) << edge_offset + cur_edge - 1;
443  new_line( count, 10, data );
444  data << " " << std::setw( 7 ) << edge_offset + cur_edge + 1;
445  new_line( count, 10, data );
446  }
447  data << " " << std::setw( 7 ) << edge_offset + cur_edge - 1;
448  new_line( count, 10, data );
449  }
450  data << " " << std::setw( 7 ) << -28;
451  cur_edge++;
452  new_line( count, 10, data );
453  }
454  reset_line( count, data );
455 
456  data << nb_total_entities << " # PMATERIAL" << EOL;
457  for( auto i : range( nb_total_entities ) ) {
458  ringmesh_unused( i );
459  data << " " << std::setw( 3 ) << 0;
460  new_line( count, 20, data );
461  }
462 
463  ascii << std::flush;
464  data << std::flush;
465  regions << std::flush;
466  }
467 
468  private:
469  void new_line(
470  index_t& count,
471  index_t number_of_counts,
472  std::ofstream& out ) const
473  {
474  count++;
475  if( count == number_of_counts ) {
476  count = 0;
477  out << EOL;
478  }
479  }
480  void reset_line( index_t& count, std::ofstream& out ) const
481  {
482  if( count != 0 ) {
483  count = 0;
484  out << EOL;
485  }
486  }
487  void clear()
488  {
489  point_boundaries_.clear();
490  box_model_ = false;
491  back_ = NO_ID;
492  top_ = NO_ID;
493  front_ = NO_ID;
494  bottom_ = NO_ID;
495  left_ = NO_ID;
496  right_ = NO_ID;
497  corner_boundary_flags_.clear();
498  edge_boundary_flags_.clear();
499  surface_boundary_flags_.clear();
500  }
501  void initialize( const GeoModel3D& gm )
502  {
503  clear();
504 
505  const GeoModel3D& geomodel = gm;
506  std::string cmsp_filename = GEO::CmdLine::get_arg( "out:csmp" );
507  box_model_ = cmsp_filename != "";
508  if( box_model_ ) {
509  GEO::LineInput parser( cmsp_filename );
510  if( !parser.OK() ) {
511  throw RINGMeshException( "I/O", "Cannot open file: ",
512  cmsp_filename );
513  }
514  parser.get_line();
515  parser.get_fields();
516  while( !parser.eof() ) {
517  if( parser.nb_fields() == 0 ) continue;
518  if( parser.nb_fields() != 3 ) return;
519  std::string type = parser.field( 1 );
520  index_t interface_id = NO_ID;
521  if( type == "NAME" ) {
522  std::string name = parser.field( 2 );
523  GeologicalEntityType type = Interface3D::type_name_static();
524  for( auto& cur_interface : geomodel.geol_entities( type ) ) {
525  if( cur_interface.name() == name ) {
526  interface_id = cur_interface.index();
527  break;
528  }
529  }
530  } else if( type == "ID" ) {
531  interface_id = parser.field_as_uint( 2 );
532  } else {
533  throw RINGMeshException( "I/O", "Unknown type: ", type );
534  }
535 
536  std::string keyword = parser.field( 0 );
537  if( keyword == "BACK" ) {
538  back_ = interface_id;
539  } else if( keyword == "TOP" ) {
540  top_ = interface_id;
541  } else if( keyword == "FRONT" ) {
542  front_ = interface_id;
543  } else if( keyword == "BOTTOM" ) {
544  bottom_ = interface_id;
545  } else if( keyword == "LEFT" ) {
546  left_ = interface_id;
547  } else if( keyword == "RIGHT" ) {
548  right_ = interface_id;
549  } else {
550  throw RINGMeshException( "I/O", "Unknown keyword: ",
551  keyword );
552  }
553  parser.get_line();
554  parser.get_fields();
555  }
556 
557  if( back_ == NO_ID || top_ == NO_ID || front_ == NO_ID
558  || bottom_ == NO_ID || left_ == NO_ID || right_ == NO_ID ) {
559  throw RINGMeshException( "I/O",
560  "Missing box shape information" );
561  }
562 
563  surface_boundary_flags_[back_] = -7;
564  surface_boundary_flags_[top_] = -5;
565  surface_boundary_flags_[front_] = -6;
566  surface_boundary_flags_[bottom_] = -4;
567  surface_boundary_flags_[left_] = -2;
568  surface_boundary_flags_[right_] = -3;
569 
570  std::set< index_t > back_bottom;
571  back_bottom.insert( back_ );
572  back_bottom.insert( bottom_ );
573  edge_boundary_flags_[back_bottom] = -16;
574  std::set< index_t > back_right;
575  back_right.insert( back_ );
576  back_right.insert( right_ );
577  edge_boundary_flags_[back_right] = -17;
578  std::set< index_t > back_top;
579  back_top.insert( back_ );
580  back_top.insert( top_ );
581  edge_boundary_flags_[back_top] = -18;
582  std::set< index_t > back_left;
583  back_left.insert( back_ );
584  back_left.insert( left_ );
585  edge_boundary_flags_[back_left] = -19;
586  std::set< index_t > right_bottom;
587  right_bottom.insert( right_ );
588  right_bottom.insert( bottom_ );
589  edge_boundary_flags_[right_bottom] = -20;
590  std::set< index_t > right_top;
591  right_top.insert( right_ );
592  right_top.insert( top_ );
593  edge_boundary_flags_[right_top] = -21;
594  std::set< index_t > left_top;
595  left_top.insert( left_ );
596  left_top.insert( top_ );
597  edge_boundary_flags_[left_top] = -22;
598  std::set< index_t > left_bottom;
599  left_bottom.insert( left_ );
600  left_bottom.insert( bottom_ );
601  edge_boundary_flags_[left_bottom] = -23;
602  std::set< index_t > front_bottom;
603  front_bottom.insert( front_ );
604  front_bottom.insert( bottom_ );
605  edge_boundary_flags_[front_bottom] = -24;
606  std::set< index_t > front_right;
607  front_right.insert( front_ );
608  front_right.insert( right_ );
609  edge_boundary_flags_[front_right] = -25;
610  std::set< index_t > front_top;
611  front_top.insert( front_ );
612  front_top.insert( top_ );
613  edge_boundary_flags_[front_top] = -26;
614  std::set< index_t > front_left;
615  front_left.insert( front_ );
616  front_left.insert( left_ );
617  edge_boundary_flags_[front_left] = -27;
618 
619  std::set< index_t > back_top_left;
620  back_top_left.insert( back_ );
621  back_top_left.insert( top_ );
622  back_top_left.insert( left_ );
623  corner_boundary_flags_[back_top_left] = -13;
624  std::set< index_t > back_top_right;
625  back_top_right.insert( back_ );
626  back_top_right.insert( top_ );
627  back_top_right.insert( right_ );
628  corner_boundary_flags_[back_top_right] = -14;
629  std::set< index_t > back_bottom_left;
630  back_bottom_left.insert( back_ );
631  back_bottom_left.insert( bottom_ );
632  back_bottom_left.insert( left_ );
633  corner_boundary_flags_[back_bottom_left] = -8;
634  std::set< index_t > back_bottom_right;
635  back_bottom_right.insert( back_ );
636  back_bottom_right.insert( bottom_ );
637  back_bottom_right.insert( right_ );
638  corner_boundary_flags_[back_bottom_right] = -10;
639  std::set< index_t > front_top_left;
640  front_top_left.insert( front_ );
641  front_top_left.insert( top_ );
642  front_top_left.insert( left_ );
643  corner_boundary_flags_[front_top_left] = -15;
644  std::set< index_t > front_top_right;
645  front_top_right.insert( front_ );
646  front_top_right.insert( top_ );
647  front_top_right.insert( right_ );
648  corner_boundary_flags_[front_top_right] = -9;
649  std::set< index_t > front_bottom_left;
650  front_bottom_left.insert( front_ );
651  front_bottom_left.insert( bottom_ );
652  front_bottom_left.insert( left_ );
653  corner_boundary_flags_[front_bottom_left] = -12;
654  std::set< index_t > front_bottom_right;
655  front_bottom_right.insert( front_ );
656  front_bottom_right.insert( bottom_ );
657  front_bottom_right.insert( right_ );
658  corner_boundary_flags_[front_bottom_right] = -11;
659  }
660 
661  point_boundaries_.resize( gm.mesh.vertices.nb() );
662  for( const auto& surface : surface_range < 3 > ( gm ) ) {
663  index_t interface_id = surface.parent_gmge( 0 ).index();
664  for( auto p : range(
665  gm.mesh.polygons.nb_polygons( surface.index() ) ) ) {
666  index_t p_id = gm.mesh.polygons.polygon( surface.index(), p );
667  for( auto v : range( gm.mesh.polygons.nb_vertices( p_id ) ) ) {
668  index_t vertex_id = gm.mesh.polygons.vertex(
669  ElementLocalVertex( p_id, v ) );
670  point_boundaries_[vertex_id].insert( interface_id );
671  }
672  }
673  }
674  }
675  std::string interface_csmp_name(
676  index_t i,
677  const GeoModel3D& geomodel ) const
678  {
679  if( box_model_ ) {
680  if( i == back_ ) {
681  return "BACK";
682  } else if( i == top_ ) {
683  return "TOP";
684  } else if( i == front_ ) {
685  return "FRONT";
686  } else if( i == bottom_ ) {
687  return "BOTTOM";
688  } else if( i == left_ ) {
689  return "LEFT";
690  } else if( i == right_ ) {
691  return "RIGHT";
692  }
693  }
694  return geomodel.geological_entity( Interface3D::type_name_static(), i ).name();
695  }
696  signed_index_t point_boundary( index_t p ) const
697  {
698  ringmesh_assert( p < point_boundaries_.size() );
699  const std::set< unsigned int >& boundaries = point_boundaries_[p];
700  if( box_model_ ) {
701  if( boundaries.size() == 1 ) {
702  auto it = surface_boundary_flags_.find( *boundaries.begin() );
703  ringmesh_assert( it != surface_boundary_flags_.end() );
704  return it->second;
705  } else if( boundaries.size() == 2 ) {
706  auto it = edge_boundary_flags_.find( boundaries );
707  ringmesh_assert( it != edge_boundary_flags_.end() );
708  return it->second;
709  } else if( boundaries.size() == 3 ) {
710  auto it = corner_boundary_flags_.find( boundaries );
711  ringmesh_assert( it != corner_boundary_flags_.end() );
712  return it->second;
713  } else {
714  return 0;
715  }
716  } else {
717  if( boundaries.empty() )
718  return 0;
719  else
720  return -28;
721  }
722  }
723  private:
724  std::vector< std::set< index_t > > point_boundaries_;
725 
726  bool box_model_;
727  index_t back_;
728  index_t top_;
729  index_t front_;
730  index_t bottom_;
731  index_t left_;
732  index_t right_;
733 
734  std::map< std::set< index_t >, signed_index_t > corner_boundary_flags_;
735  std::map< std::set< index_t >, signed_index_t > edge_boundary_flags_;
736  std::map< index_t, signed_index_t > surface_boundary_flags_;
737  };
738 
739 }
void ringmesh_unused(const T &)
Definition: common.h:105
auto to_underlying_type(Enum e) -> typename std::underlying_type< Enum >::type
Definition: types.h:114
CellType
Definition: types.h:89
#define ringmesh_assert(x)
const char TAB
Definition: io.h:47
const char EOL
Definition: io.h:45