38 struct RINGMesh2Feflow {
43 static RINGMesh2Feflow feflow_tet_descriptor = { 6, { 0, 1, 2, 3 } };
45 static RINGMesh2Feflow feflow_hex_descriptor = { 8, { 2, 6, 7, 3, 0, 4, 5, 1 } };
47 static RINGMesh2Feflow feflow_prism_descriptor = { 7, { 3, 4, 5, 0, 1, 2 } };
49 static RINGMesh2Feflow feflow_pyramid_descriptor = { 9, { 0, 1, 2, 3, 4 } };
51 static RINGMesh2Feflow* cell_type_to_feflow_cell_descriptor[4] = {
52 &feflow_tet_descriptor, &feflow_hex_descriptor, &feflow_prism_descriptor,
53 &feflow_pyramid_descriptor };
55 class FeflowIOHandler final:
public GeoModelIOHandler< 3 > {
57 static const index_t STARTING_OFFSET = 1;
59 void load(
const std::string& filename, GeoModel3D& geomodel )
final 63 throw RINGMeshException(
"I/O",
64 "Loading of a GeoModel from Feflow not implemented yet" );
66 void save(
const GeoModel3D& geomodel,
const std::string& filename )
final 68 std::ofstream out( filename.c_str() );
72 write_dimensions( geomodel, out );
73 write_elements( geomodel, out );
74 write_vertices( geomodel, out );
75 write_regions( geomodel, out );
76 write_wells( geomodel, out );
78 out <<
"END" << std::endl;
83 void write_header( std::ofstream& out )
const 86 out <<
"CLASS (v.7.006.14742)\n";
90 out <<
" 0 0 0 3 0 0 8 8 0 0\n";
92 void write_dimensions(
const GeoModel3D& geomodel, std::ofstream& out )
const 94 const GeoModelMesh3D& mesh = geomodel.mesh;
96 out <<
SPACE << mesh.vertices.nb() <<
SPACE << mesh.cells.nb()
97 <<
" 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0\n";
100 void write_elements(
const GeoModel3D& geomodel, std::ofstream& out )
const 102 const GeoModelMeshCells3D& cells = geomodel.mesh.cells;
104 out <<
SPACE << cells.nb();
105 index_t min_nb_vertices_per_element { 0 };
106 index_t max_nb_vertices_per_element { 0 };
107 if( cells.nb_tet() > 0 ) {
108 min_nb_vertices_per_element = 4;
109 }
else if( cells.nb_pyramid() > 0 ) {
110 min_nb_vertices_per_element = 5;
111 }
else if( cells.nb_prism() > 0 ) {
112 min_nb_vertices_per_element = 6;
113 }
else if( cells.nb_hex() > 0 ) {
114 min_nb_vertices_per_element = 8;
118 if( cells.nb_hex() > 0 ) {
119 max_nb_vertices_per_element = 8;
120 }
else if( cells.nb_prism() > 0 ) {
121 max_nb_vertices_per_element = 6;
122 }
else if( cells.nb_pyramid() > 0 ) {
123 max_nb_vertices_per_element = 5;
124 }
else if( cells.nb_tet() > 0 ) {
125 max_nb_vertices_per_element = 4;
129 out <<
SPACE << min_nb_vertices_per_element <<
SPACE 130 << max_nb_vertices_per_element <<
"\n";
132 for(
auto c : range( cells.nb() ) ) {
133 const RINGMesh2Feflow& descriptor =
136 out <<
SPACE << descriptor.entity_type;
137 for(
auto v : range( cells.nb_vertices( c ) ) ) {
140 ElementLocalVertex( c, descriptor.vertices[v] ) )
146 void write_vertices(
const GeoModel3D& geomodel, std::ofstream& out )
const 148 const GeoModelMeshVertices3D& vertices = geomodel.mesh.vertices;
149 out <<
"XYZCOOR\n" << std::scientific;
150 for(
auto v : range( vertices.nb() ) ) {
151 const vec3& point = vertices.vertex( v );
152 std::string sep =
"";
153 for(
auto i : range( 3 ) ) {
154 out << sep <<
SPACE << point[i];
161 void write_regions(
const GeoModel3D& geomodel, std::ofstream& out )
const 163 out <<
"ELEMENTALSETS\n";
165 for(
const auto& region : geomodel.regions() ) {
166 out <<
SPACE << region.name() <<
SPACE << offset + STARTING_OFFSET;
167 offset += region.nb_mesh_elements();
168 out <<
"-" << offset <<
"\n";
171 void write_wells(
const GeoModel3D& geomodel, std::ofstream& out )
const 173 const WellGroup3D* wells = geomodel.wells();
179 <<
" <?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?>\n";
180 out <<
" <fractures>\n";
181 write_well_edges( geomodel, out );
182 out <<
" <properties>\n";
183 out <<
" </properties>\n";
184 write_well_groups( geomodel, out );
185 out <<
" </fractures>\n";
187 void write_well_edges(
const GeoModel3D& geomodel, std::ofstream& out )
const 189 const GeoModelMeshWells3D& wells = geomodel.mesh.wells;
190 out <<
" <nop count=\"" << wells.nb_edges() <<
"\">\n";
192 for(
auto w : range( wells.nb_wells() ) ) {
193 for(
auto e : range( wells.nb_edges( w ) ) ) {
194 out <<
"\n 0, 2, " << wells.vertex( w, e, 0 ) + STARTING_OFFSET
195 <<
", " << wells.vertex( w, e, 1 ) + STARTING_OFFSET;
201 void write_well_groups(
202 const GeoModel3D& geomodel,
203 std::ofstream& out )
const 205 const GeoModelMeshWells3D& well_edges = geomodel.mesh.wells;
206 const WellGroup3D* wells = geomodel.wells();
208 out <<
" <groups count=\"" << well_edges.nb_wells() <<
"\">\n";
209 for(
auto w : range( well_edges.nb_wells() ) ) {
210 out <<
" <group name=\"" << wells->well( w ).name()
211 <<
"\" mode=\"unstructured\">\n";
212 out <<
" <elements count=\"" << well_edges.nb_edges( w ) <<
"\">\n";
213 out <<
" <![CDATA[ " << offset + STARTING_OFFSET;
214 offset += well_edges.nb_edges( w );
215 out <<
"-" << offset <<
"]]>\n";
216 out <<
" </elements>\n";
217 out <<
" </group>\n";
219 out <<
" </groups>\n";
void ringmesh_unused(const T &)
auto to_underlying_type(Enum e) -> typename std::underlying_type< Enum >::type
#define ringmesh_assert_not_reached