LifeV
ImporterMesh3D.cpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief Mesh reader from mesh3d files
30 
31  @author Luca Formaggia <luca.formaggia@polimi.it>
32  @contributor JFG, Nur Aiman Fadel <nur.fadel@mail.polimi.it>
33  @maintainer Nur Aiman Fadel <nur.fadel@mail.polimi.it>
34 
35  @date 29-06-2002
36 
37  Mesh reader that it is able to read 3d meshes.<br>
38  */
39 
40 #include <lifev/core/filter/ImporterMesh3D.hpp>
41 
42 namespace LifeV
43 {
44 
45 // ===================================================
46 // Mpp mesh readers
47 // ===================================================
48 
49 bool
50 readMppFileHead ( std::ifstream& myStream,
51  UInt& numberVertices,
52  UInt& numberBoundaryVertices,
53  UInt& numberBoundaryFaces,
54  UInt& numberBoundaryEdges,
55  UInt& numberVolumes )
56 {
57  std::string line;
58 
59  Real x, y, z;
60 
61  Int ity, ity_id;
62 
63  UInt done = 0;
64  UInt i, ibc;
65  UInt p1, p2, p3;
66 
67  while ( nextGoodLine ( myStream, line ).good() )
68  {
69  if ( line.find ( "odes" ) != std::string::npos )
70  {
71  std::string node_s = line.substr ( line.find_last_of ( ":" ) + 1 );
72  numberVertices = atoi ( node_s );
73  done++;
74  numberBoundaryVertices = 0;
75 
76  for ( i = 0; i < numberVertices; i++ )
77  {
78  myStream >> x >> y >> z >> ity >> ibc;
79  if ( ity != 3 )
80  {
81 
82 #ifndef OLDMPPFILE
83  myStream >> ibc;
84 #endif
85 
86  numberBoundaryVertices++;
87  }
88  }
89  }
90 
91  if ( line.find ( "iangular" ) != std::string::npos )
92  {
93  std::string node_s = line.substr ( line.find_last_of ( ":" ) + 1 );
94  numberBoundaryFaces = atoi ( node_s );
95  done++;
96 
97  for ( i = 0; i < numberBoundaryFaces; i++ )
98  {
99 #ifdef OLDMPPFILE
100  myStream >> p1 >> p2 >> p3 >> ity >> ibc;
101 #else
102 
103  myStream >> p1 >> p2 >> p3 >> ity >> ity_id >> ibc;
104 #endif
105  }
106  }
107 
108  if ( line.find ( "oundary" ) != std::string::npos )
109  {
110  std::string node_s = line.substr ( line.find_last_of ( ":" ) + 1 );
111  numberBoundaryEdges = atoi ( node_s );
112 
113  for ( i = 0; i < numberBoundaryEdges; i++ )
114  {
115 #ifdef OLDMPPFILE
116  myStream >> p1 >> p2 >> ity >> ibc;
117 #else
118  myStream >> p1 >> p2 >> ity >> ity_id >> ibc;
119 #endif
120  }
121  done++;
122  }
123 
124  if ( line.find ( "etrahedral" ) != std::string::npos )
125  {
126  std::string node_s = line.substr ( line.find_last_of ( ":" ) + 1 );
127  numberVolumes = atoi ( node_s );
128  done++;
129  }
130  }
131 
132  return done == 4 ;
133 }// Function readMppFileHead
134 
135 // ===================================================
136 // INRIA mesh readers
137 // ===================================================
138 
139 Int
140 nextIntINRIAMeshField ( std::string const& line,
141  std::istream& myStream )
142 {
143  /*
144  first control if line has something.
145  If so use atoi (the version from util_string.h)
146  to extract the integer.
147  Otherwise get if from the input stream
148  */
149 
150  for ( std::string::const_iterator is = line.begin(); is != line.end(); ++is )
151  {
152  if ( *is != ' ' )
153  {
154  return atoi ( line );
155  }
156  }
157  Int dummy;
158  myStream >> dummy;
159 
160  return dummy;
161 }// Function nextIntINRIAMeshField
162 
163 /*
164  It Reads all basic info from INRIA MESH file
165  so as to be able to properly dimension all arrays
166 */
167 bool
168 readINRIAMeshFileHead ( std::ifstream& myStream,
169  UInt& numberVertices,
170  UInt& numberBoundaryVertices,
171  UInt& numberBoundaryFaces,
172  UInt& numberBoundaryEdges,
173  UInt& numberVolumes,
174  UInt& numberStoredFaces,
175  ReferenceShapes& shape,
176  InternalEntitySelector iSelect )
177 {
178  const int idOffset = 1; //IDs in INRIA files start from 1
179 
180  std::string line;
181 
182  Real x, y, z;
183 
184  Int idummy;
185 
186  UInt i, ibc;
187  UInt done = 0;
188  UInt p1, p2, p3, p4, p5, p6, p7, p8;
189  UInt numReadFaces = 0;
190  numberStoredFaces = 0;
191 
192  //shape = NONE;
193  std::vector<bool> isboundary;
194  //streampos start=myStream.tellg();
195 
196  while ( nextGoodLine ( myStream, line ).good() )
197  {
198  if ( line.find ( "MeshVersionFormatted" ) != std::string::npos )
199  {
200  idummy = nextIntINRIAMeshField ( line.substr ( line.find_last_of ( "d" ) + 1 ), myStream );
201  ASSERT_PRE0 ( idummy == 1, "I can read only formatted INRIA Mesh files, sorry" );
202  }
203 
204  if ( line.find ( "Dimension" ) != std::string:: npos )
205  {
206  idummy = nextIntINRIAMeshField ( line.substr ( line.find_last_of ( "n" ) + 1 ), myStream );
207  ASSERT_PRE0 ( idummy == 3, "I can read only 3D INRIA Mesh files, sorry" );
208  }
209 
210  // I assume that internal vertices have their Ref value set to 0 (not clear from medit manual)
211  if ( line.find ( "Vertices" ) != std::string::npos )
212  {
213  numberVertices = nextIntINRIAMeshField ( line.substr ( line.find_last_of ( "s" ) + 1 ), myStream );
214  done++;
215  numberBoundaryVertices = 0;
216  isboundary.resize ( numberVertices, false );
217 
218  for ( i = 0; i < numberVertices; ++i )
219  {
220  myStream >> x >> y >> z >> ibc;
221  if ( ! iSelect ( markerID_Type ( ibc ) ) )
222  {
223  numberBoundaryVertices++;
224  isboundary[ i ] = true;
225  }
226  }
227  }
228 
229  if ( line.find ( "Triangles" ) != std::string::npos )
230  {
231  ASSERT_PRE0 ( shape != HEXA, " Cannot have triangular faces in an HEXA INRIA MESH" );
232  shape = TETRA;
233  numReadFaces = nextIntINRIAMeshField ( line.substr ( line.find_last_of ( "s" ) + 1 ), myStream );
234  numberBoundaryFaces = 0;
235 
236  done++;
237 
238  for ( UInt k = 0; k < numReadFaces; k++ )
239  {
240  myStream >> p1 >> p2 >> p3 >> ibc;
241  if ( isboundary[ p1 - idOffset ] && isboundary [ p2 - idOffset ] && isboundary[ p3 - idOffset ])
242  {
243  if ( iSelect ( markerID_Type ( ibc ) ) )
244  {
245  std::cerr << "ATTENTION: Face (1-based numbering) "
246  << p1 << " "
247  << p2 << " "
248  << p3 << " has all vertices on the boundary yet is marked as interior: "
249  << ibc << std::endl;
250  }
251  ++numberBoundaryFaces;
252  }
253  else
254  {
255  if ( !iSelect ( markerID_Type ( ibc ) ) )
256  {
257  std::cerr << "ATTENTION: Face (1-based numbering) "
258  << p1 << " "
259  << p2 << " "
260  << p3
261  << " has vertices in the interior yet is marked as boundary: "
262  << ibc << std::endl;
263  }
264  }
265  }
266  numberStoredFaces = numReadFaces;
267  }
268 
269 
270  if ( line.find ( "Quadrilaterals" ) != std::string::npos )
271  {
272  ASSERT_PRE0 ( shape != TETRA, " Cannot have quad faces in an TETRA INRIA MESH" );
273  shape = HEXA;
274  numReadFaces = nextIntINRIAMeshField ( line.substr ( line.find_last_of ( "s" ) + 1 ), myStream );
275  done++;
276  numberBoundaryFaces = 0;
277 
278  for ( UInt k = 0; k < numReadFaces; k++ )
279  {
280  myStream >> p1 >> p2 >> p3 >> p4 >> ibc;
281  if ( isboundary[ p1 - idOffset ] && isboundary[ p2 - idOffset ]
282  && isboundary[ p3 - idOffset ] && isboundary[ p4 - idOffset ] )
283  {
284  if ( iSelect ( markerID_Type ( ibc ) ) )
285  {
286  std::cerr << "ATTENTION: Face (1-based numbering) "
287  << p1 << " "
288  << p2 << " "
289  << p3 << " "
290  << p4
291  << " has all vertices on the boundary yet is marked as interior: "
292  << ibc << std::endl;
293  }
294  ++numberBoundaryFaces;
295  }
296 
297  }
298  numberStoredFaces = numReadFaces;
299  }
300  // To cope with a mistake in INRIA Mesh files
301  if ( line.find ( "Tetrahedra" ) != std::string::npos )
302  {
303  ASSERT_PRE0 ( shape != HEXA, " Cannot have tetras in a HEXA INRIA MESH" );
304  shape = TETRA;
305  numberVolumes = nextIntINRIAMeshField ( line.substr ( line.find_last_of ( "a" ) + 1 ), myStream );
306  done++;
307 
308  for ( i = 0; i < numberVolumes; i++ )
309  {
310  myStream >> p1 >> p2 >> p3 >> p4 >> ibc;
311  }
312  }
313 
314  if ( line.find ( "Hexahedra" ) != std::string::npos )
315  {
316  ASSERT_PRE0 ( shape != TETRA, " Cannot have Hexahedra in a TETRA INRIA MESH" );
317  shape = HEXA;
318  numberVolumes = nextIntINRIAMeshField ( line.substr ( line.find_last_of ( "a" ) + 1 ), myStream );
319  done++;
320 
321  for ( i = 0; i < numberVolumes; i++ )
322  {
323  myStream >> p1 >> p2 >> p3 >> p4 >> p5 >> p6 >> p7 >> p8 >> ibc;
324  }
325  }
326  // I assume we are storing only boundary edges
327  if ( line.find ( "Edges" ) != std::string::npos )
328  {
329  numberBoundaryEdges = nextIntINRIAMeshField ( line.substr ( line.find_last_of ( "s" ) + 1 ), myStream );
330  done++;
331  for ( i = 0; i < numberBoundaryEdges; i++ )
332  {
333  myStream >> p1 >> p2 >> ibc;
334  }
335  }
336  }
337 
338  LIFEV_UNUSED (idummy);
339  return true ;
340 }// Function readINRIAMeshFileHead
341 
342 } // Namespace LifeV
#define ASSERT_PRE0(X, A)
Definition: LifeAssert.hpp:72
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
double Real
Generic real data.
Definition: LifeV.hpp:175
#define LIFEV_UNUSED(x)
Definition: LifeV.hpp:125
bool readMppFileHead(std::ifstream &myStream, UInt &numberVertices, UInt &numberBoundaryVertices, UInt &numberBoundaryFaces, UInt &numberBoundaryEdges, UInt &numberVolumes)
readMppFileHead - reads mesh++ Tetra meshes.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191