37 class GPRSIOHandler final:
public GeoModelIOHandler< 3 > {
40 Pipe( index_t v0_in, index_t v1_in )
41 : v0( v0_in ), v1( v1_in )
47 void load(
const std::string& filename, GeoModel3D& geomodel )
final 51 throw RINGMeshException(
"I/O",
52 "Loading of a GeoModel from GPRS not implemented yet" );
55 const GeoModel3D& geomodel,
56 const std::string& filename )
final 58 std::string path = GEO::FileSystem::dir_name( filename );
59 std::string directory = GEO::FileSystem::base_name( filename );
61 path = GEO::FileSystem::get_current_working_directory();
63 std::ostringstream oss;
64 oss << path <<
"/" << directory;
65 std::string full_path = oss.str();
66 GEO::FileSystem::create_directory( full_path );
68 std::ostringstream oss_pipes;
69 oss_pipes << full_path <<
"/pipes.in";
70 std::ofstream out_pipes( oss_pipes.str().c_str() );
72 std::ostringstream oss_vol;
73 oss_vol << full_path <<
"/vol.in";
74 std::ofstream out_vol( oss_vol.str().c_str() );
75 out_vol.precision( 16 );
77 std::ostringstream oss_xyz;
78 oss_xyz << full_path <<
"/gprs.xyz";
79 std::ofstream out_xyz( oss_xyz.str().c_str() );
80 out_xyz.precision( 16 );
82 const GeoModelMesh3D& mesh = geomodel.mesh;
83 std::deque< Pipe > pipes;
84 index_t cell_offset = mesh.cells.nb();
85 for(
auto c :range( mesh.cells.nb() ) ) {
86 for(
auto f : range( mesh.cells.nb_facets( c ) ) ) {
87 index_t facet { NO_ID };
89 if( mesh.cells.is_cell_facet_on_surface( c, f, facet,
91 pipes.emplace_back( c, facet + cell_offset );
93 index_t adj = mesh.cells.adjacent( c, f );
94 if( adj != GEO::NO_CELL && adj < c ) {
95 pipes.emplace_back( c, adj );
101 index_t nb_edges = 0;
102 for(
const auto& line : geomodel.lines() ) {
103 nb_edges += line.nb_mesh_elements();
105 std::vector< index_t > temp;
107 std::vector< std::vector< index_t > > edges( nb_edges, temp );
108 std::vector< vec3 > edge_vertices( nb_edges );
109 index_t count_edge = 0;
110 for(
const auto& line : geomodel.lines() ) {
111 for( index_t e : range( line.nb_mesh_elements() ) ) {
112 edge_vertices[count_edge++ ] = 0.5
113 * ( line.vertex( e ) + line.vertex( e + 1 ) );
116 NNSearch3D nn_search( edge_vertices,
false );
118 const GeoModelMeshPolygons3D& polygons = geomodel.mesh.polygons;
119 for( index_t p : range( polygons.nb() ) ) {
120 for( index_t e : range( polygons.nb_vertices( p ) ) ) {
121 index_t adj = polygons.adjacent( PolygonLocalEdge( p, e ) );
122 if( adj != GEO::NO_CELL && adj < p ) {
123 pipes.emplace_back( p + cell_offset, adj + cell_offset );
125 const vec3& e0 = mesh.vertices.vertex(
126 polygons.vertex( ElementLocalVertex( p, e ) ) );
127 const vec3& e1 = mesh.vertices.vertex(
129 ElementLocalVertex( p,
130 ( e + 1 ) % polygons.nb_vertices( p ) ) ) );
131 vec3 query = 0.5 * ( e0 + e1 );
132 std::vector< index_t > results = nn_search.get_neighbors(
133 query, geomodel.epsilon() );
134 if( !results.empty() ) {
135 edges[results[0]].push_back( cell_offset + p );
143 auto nb_pipes =
static_cast< index_t
> ( pipes.size() );
144 for(
const auto& vertices : edges ) {
145 nb_pipes += binomial_coef( static_cast< index_t > ( vertices.size() ) );
147 out_pipes << nb_pipes <<
EOL;
148 for(
const auto& pipe : pipes ) {
149 out_pipes << pipe.v0 <<
SPACE << pipe.v1 <<
EOL;
151 for(
const auto& vertices : edges ) {
152 for(
auto v0 : range( vertices.size() - 1 ) ) {
153 for(
auto v1 : range( v0 + 1, vertices.size() ) ) {
154 out_pipes << vertices[v0] <<
SPACE << vertices[v1]
161 <<
"Node geometry, not used by GPRS but useful to reconstruct a pipe-network" 163 for(
auto c : range( mesh.cells.nb() ) ) {
164 out_xyz << mesh.cells.barycenter( c ) <<
EOL;
165 out_vol << mesh.cells.volume( c ) <<
EOL;
167 for(
auto p : range( polygons.nb() ) ) {
168 out_xyz << polygons.center( p ) <<
EOL;
169 out_vol << polygons.area( p ) <<
EOL;
172 out_pipes << std::flush;
173 out_vol << std::flush;
174 out_xyz << std::flush;
176 index_t binomial_coef( index_t n )
const
void ringmesh_unused(const T &)
#define ringmesh_assert_not_reached