28 #ifndef PARSER_INRIA_MESH_HPP__ 29 #define PARSER_INRIA_MESH_HPP__ 31 #include <lifev/core/LifeV.hpp> 32 #include <lifev/core/mesh/BareMesh.hpp> 33 #include <lifev/core/mesh/InternalEntitySelector.hpp> 62 nextIntINRIAMeshField ( std::string
const& line,
63 std::istream& myStream )
72 for ( std::string::const_iterator is = line.begin(); is != line.end(); ++is )
102 readINRIAMeshFileHead ( std::ifstream& myStream,
103 UInt& numberVertices,
104 UInt& numberBoundaryVertices,
105 UInt& numberBoundaryFaces,
106 UInt& numberBoundaryEdges,
108 UInt& numberStoredFaces,
110 InternalEntitySelector iSelect )
112 const int idOffset = 1;
115 numberBoundaryVertices = 0;
116 numberBoundaryFaces = 0;
117 numberBoundaryEdges = 0;
119 numberStoredFaces = 0;
129 UInt p1, p2, p3, p4, p5, p6, p7, p8;
130 UInt numReadFaces = 0;
131 numberStoredFaces = 0;
134 std::vector<
bool> isboundary;
137 while ( nextGoodLine ( myStream, line ).good() )
139 if ( line.find (
"MeshVersionFormatted" ) != std::string::npos )
141 idummy = nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"d" ) + 1 ), myStream );
142 ASSERT_PRE0 ( idummy == 1,
"I can read only formatted INRIA Mesh files, sorry" );
145 if ( line.find (
"Dimension" ) != std::string:: npos )
147 idummy = nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"n" ) + 1 ), myStream );
148 ASSERT_PRE0 ( idummy == 3,
"I can read only 3D INRIA Mesh files, sorry" );
152 if ( line.find (
"Vertices" ) != std::string::npos )
154 numberVertices = nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"s" ) + 1 ), myStream );
156 numberBoundaryVertices = 0;
157 isboundary.resize ( numberVertices,
false );
159 for ( i = 0; i < numberVertices; ++i )
161 myStream >> x >> y >> z >> ibc;
162 if ( ! iSelect ( markerID_Type ( ibc ) ) )
164 numberBoundaryVertices++;
165 isboundary[ i ] =
true;
170 if ( line.find (
"Triangles" ) != std::string::npos )
172 ASSERT_PRE0 ( shape != HEXA,
" Cannot have triangular faces in an HEXA INRIA MESH" );
174 numReadFaces = nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"s" ) + 1 ), myStream );
175 numberBoundaryFaces = 0;
179 for ( UInt k = 0; k < numReadFaces; k++ )
181 myStream >> p1 >> p2 >> p3 >> ibc;
182 if ( isboundary[ p1 - idOffset ] && isboundary [ p2 - idOffset ] && isboundary[ p3 - idOffset ])
184 if ( iSelect ( markerID_Type ( ibc ) ) )
186 std::cerr <<
"ATTENTION: Face (1-based numbering) " 189 << p3 <<
" has all vertices on the boundary yet is marked as interior: " 192 ++numberBoundaryFaces;
196 if ( !iSelect ( markerID_Type ( ibc ) ) )
198 std::cerr <<
"ATTENTION: Face (1-based numbering) " 202 <<
" has vertices in the interior yet is marked as boundary: " 207 numberStoredFaces = numReadFaces;
211 if ( line.find (
"Quadrilaterals" ) != std::string::npos )
213 ASSERT_PRE0 ( shape != TETRA,
" Cannot have quad faces in an TETRA INRIA MESH" );
215 numReadFaces = nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"s" ) + 1 ), myStream );
217 numberBoundaryFaces = 0;
219 for ( UInt k = 0; k < numReadFaces; k++ )
221 myStream >> p1 >> p2 >> p3 >> p4 >> ibc;
222 if ( isboundary[ p1 - idOffset ] && isboundary[ p2 - idOffset ]
223 && isboundary[ p3 - idOffset ] && isboundary[ p4 - idOffset ] )
225 if ( iSelect ( markerID_Type ( ibc ) ) )
227 std::cerr <<
"ATTENTION: Face (1-based numbering) " 232 <<
" has all vertices on the boundary yet is marked as interior: " 235 ++numberBoundaryFaces;
239 numberStoredFaces = numReadFaces;
242 if ( line.find (
"Tetrahedra" ) != std::string::npos )
244 ASSERT_PRE0 ( shape != HEXA,
" Cannot have tetras in a HEXA INRIA MESH" );
246 numberVolumes = nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"a" ) + 1 ), myStream );
249 for ( i = 0; i < numberVolumes; i++ )
251 myStream >> p1 >> p2 >> p3 >> p4 >> ibc;
255 if ( line.find (
"Hexahedra" ) != std::string::npos )
257 ASSERT_PRE0 ( shape != TETRA,
" Cannot have Hexahedra in a TETRA INRIA MESH" );
259 numberVolumes = nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"a" ) + 1 ), myStream );
262 for ( i = 0; i < numberVolumes; i++ )
264 myStream >> p1 >> p2 >> p3 >> p4 >> p5 >> p6 >> p7 >> p8 >> ibc;
268 if ( line.find (
"Edges" ) != std::string::npos )
270 numberBoundaryEdges = nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"s" ) + 1 ), myStream );
272 for ( i = 0; i < numberBoundaryEdges; i++ )
274 myStream >> p1 >> p2 >> ibc;
294 template <
typename GeoShape>
297 std::string
const& fileName,
299 bool verbose =
false,
300 InternalEntitySelector iSelect = InternalEntitySelector() )
302 const int idOffset = 1;
304 std::string line, faceName, volumeName;
310 UInt numberPoints, numberBoundaryPoints;
311 UInt numberVertices, numberBoundaryVertices;
312 UInt numberEdges, numberBoundaryEdges;
313 UInt numberBoundaryFaces, numberStoredFaces;
316 std::stringstream discardedLog;
320 std::ostream& oStr = verbose ? std::cout : discardedLog;
324 std::ifstream hstream ( fileName.c_str() );
328 std::cout <<
"Reading from file " << fileName << std::endl;
331 if ( hstream.fail() )
333 std::cerr <<
" Error in readINRIAMeshFile = file " << fileName
334 <<
" not found or locked" << std::endl;
340 std::cout <<
"Reading INRIA mesh file" << fileName << std::endl;
343 if ( !
MeshIO::readINRIAMeshFileHead ( hstream, numberVertices, numberBoundaryVertices,
344 numberBoundaryFaces, numberBoundaryEdges,
345 numberVolumes, numberStoredFaces, shape, iSelect) )
347 std::cerr <<
" Error while reading INRIA mesh file headers" << std::endl;
354 std::ifstream myStream ( fileName.c_str() );
356 if ( myStream.fail() )
358 std::cerr <<
" Error in readINRIAMeshFile = file " << fileName
359 <<
" not found or locked" << std::endl;
365 numberPoints = numberVertices;
366 numberBoundaryPoints = numberBoundaryVertices;
375 std::cout <<
"Linear Hexa mesh" << std::endl;
377 faceName =
"Quadrilaterals";
378 volumeName =
"Hexahedra";
382 if ( GeoShape::S_numPoints == 4 )
386 std::cout <<
"Linear Tetra Mesh" << std::endl;
389 else if ( GeoShape::S_numPoints == 10 )
393 std::cout <<
"Quadratic Tetra mesh (from linear geometry)" << std::endl;
395 numberPoints += numberEdges;
396 numberBoundaryPoints += numberBoundaryEdges;
403 faceName =
"Triangles";
404 volumeName =
"Tetrahedra";
407 ERROR_MSG (
"Current version of INRIA Mesh file reader only accepts TETRA and HEXA" );
411 bareMesh.numBoundaryPoints = numberBoundaryPoints;
412 bareMesh.numVertices = numberVertices;
413 bareMesh.numBoundaryVertices = numberBoundaryVertices;
414 bareMesh.points.reshape ( 3, numberPoints );
415 bareMesh.pointMarkers.resize ( numberPoints );
416 bareMesh.pointIDs.resize ( numberPoints );
418 bareMesh.ridges.reshape ( GeoShape::GeoBShape::GeoBShape::S_numPoints, numberBoundaryEdges );
419 bareMesh.ridgeMarkers.resize ( numberBoundaryEdges );
420 bareMesh.ridgeIDs.resize ( numberBoundaryEdges );
422 bareMesh.numBoundaryFacets = numberBoundaryFaces;
423 bareMesh.facets.reshape ( GeoShape::GeoBShape::S_numPoints, numberStoredFaces );
424 bareMesh.facetMarkers.resize ( numberStoredFaces );
425 bareMesh.facetIDs.resize ( numberStoredFaces );
427 bareMesh.elements.reshape ( GeoShape::S_numPoints, numberVolumes );
428 bareMesh.elementMarkers.resize ( numberVolumes );
429 bareMesh.elementIDs.resize ( numberVolumes );
431 bareMesh.regionMarkerID = regionFlag;
437 if ( numberStoredFaces > numberBoundaryFaces )
439 oStr <<
"WARNING: The mesh file (apparently) contains " 440 << numberStoredFaces - numberBoundaryFaces <<
" internal faces" << std::endl;
443 while ( nextGoodLine ( myStream, line ).good() )
445 if ( line.find (
"Vertices" ) != std::string::npos )
447 nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"s" ) + 1 ), myStream );
449 for ( UInt i = 0; i < numberVertices; i++ )
451 myStream >> x >> y >> z >> ibc;
453 if ( !iSelect (markerID_Type (ibc) ) )
458 bareMesh.points ( 0, i ) = x;
459 bareMesh.points ( 1, i ) = y;
460 bareMesh.points ( 2, i ) = z;
461 bareMesh.pointMarkers[ i ] = ibc;
462 bareMesh.pointIDs[i] = i;
466 if ( count != numberBoundaryVertices )
468 std::cerr <<
"Number boundary points inconsistent!" << std::endl;
472 if ( line.find ( faceName ) != std::string::npos )
474 nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"s" ) + 1 ), myStream );
475 oStr <<
"Reading boundary faces " << std::endl;
477 for ( UInt i = 0; i < numberStoredFaces; i++ )
479 for ( UInt k = 0; k < GeoShape::GeoBShape::S_numPoints; k++ )
482 bareMesh.facets ( k, i ) = buffer - idOffset;
485 bareMesh.facetMarkers[ i ] = ibc;
486 bareMesh.facetIDs[ i ] = i;
489 oStr <<
"Boundary faces read " << std::endl;
493 if ( line.find (
"Edges" ) != std::string::npos )
495 nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"s" ) + 1 ), myStream );
496 oStr <<
"Reading boundary edges " << std::endl;
498 for ( UInt i = 0; i < numberBoundaryEdges; i++ )
500 for ( UInt k = 0; k < GeoShape::GeoBShape::GeoBShape::S_numPoints; k++ )
503 bareMesh.ridges ( k, i ) = buffer - idOffset;
506 bareMesh.ridgeMarkers[ i ] = ibc;
507 bareMesh.ridgeIDs[ i ] = i;
509 oStr <<
"Boundary edges read " << std::endl;
513 if ( line.find ( volumeName ) != std::string::npos )
516 nextIntINRIAMeshField ( line.substr ( line.find_last_of (
"a" ) + 1 ), myStream );
517 oStr <<
"Reading volumes " << std::endl;
519 for ( UInt i = 0; i < numberVolumes; i++ )
521 for ( UInt k = 0; k < GeoShape::S_numPoints; k++ )
524 bareMesh.elements ( k, i ) = buffer - idOffset;
527 bareMesh.elementMarkers[ i ] = ibc;
528 bareMesh.elementIDs[ i ] = i;
531 oStr << count <<
" Volume elements read" << std::endl;
#define ASSERT_PRE0(X, A)
int32_type Int
Generic integer data.
ID markerID_Type
markerID_Type is the type used to store the geometric entity marker IDs
double Real
Generic real data.
Assert & error(const char *strMsg=0)
A struct for a bare mesh.
uint32_type UInt
generic unsigned integer (used mainly for addressing)