LifeV
ImporterMesh2D.hpp
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 mesh2D files
30 
31  @author Luca Formaggia <luca.formaggia@polimi.it>
32  @contributor Nur Aiman Fadel <nur.fadel@mail.polimi.it>
33  @maintainer Nur Aiman Fadel <nur.fadel@mail.polimi.it>
34 
35  @date 19-08-1999
36 
37  Mesh reader that it is able to read 2D meshes from freefem and gmsh files.<br>
38  ImporterMesh2D reads only triangle meshes.<br>
39  readMppFiles handles only liner&quad triangles.<br>
40  */
41 
42 #ifndef _IMPORTERMESH2D_HH_
43 #define _IMPORTERMESH2D_HH_ 1
44 
45 
46 #include <boost/lambda/lambda.hpp>
47 
48 
49 #include <lifev/core/util/FortranWrapper.hpp>
50 #include <lifev/core/util/StringUtility.hpp>
51 
52 #include <lifev/core/mesh/RegionMesh.hpp>
53 
54 #include <lifev/core/mesh/MeshChecks.hpp>
55 
56 namespace LifeV
57 {
58 
59 // ===================================================
60 // Macros for Fortran interface
61 // ===================================================
62 
63 // Subroutine readmesh2d
64 SUBROUTINE_F77 F77NAME ( readmesh2d ) ( I_F77& ne, I_F77& np,
65  I_F77& nptot, I_F77& nb, I_F77& nps, I_F77& nx,
66  I_F77& ndimn, I_F77& npe, I_F77& npb,
67  I_F77& npc, I_F77* iel,
68  I_F77& nd, R4_F77* coor, I_F77& ndc,
69  R4_F77& xmin, R4_F77& xmax, R4_F77& ymin,
70  R4_F77& ymax, I_F77* ib, I_F77& nbd,
71  I_F77* ic, I_F77* bc, I_F77* ie,
72  I_F77* cpl, R4_F77* xmed, I_F77& isw,
73  I_F77& ierr, FortranCharacterString filename );
74 
75 // Subroutine read_mesh2d_head(filename,ne,np,nptot,npe,nb,nx,npc,ierr)
76 SUBROUTINE_F77 F77NAME ( readmesh2dhead ) ( I_F77& ne, I_F77& np,
77  I_F77& nptot, I_F77& npe, I_F77& nb,
78  I_F77& nps, I_F77& nx,
79  I_F77& npc, I_F77& ierr, FortranCharacterString filename );
80 
81 //! importerMesh2D - reads a mesh in mesh2D(LF) format.
82 /*!
83  It reads a gmsh mesh (2D) file and store it in a RegionMesh.
84 
85  @param mesh, the mesh data structure to fill in.
86  @param fileName, the name of the mesh file to read.
87  @param regionFlag, the identifier for the region.
88  @return true if everything went fine, false otherwise.
89 */
90 
91 /*
92 template <typename RegionMesh>
93 bool
94 importerMesh2D( RegionMesh & mesh, //importerMesh2D
95  const std::string & fileName,
96  markerID_Type regionFlag )
97 {
98  UInt i, i1, i2, i3;
99  UInt nVe, nBVe, nFa, nPo, nBPo, nEd, nBEd;
100  UInt p1, p2, p3;
101 
102  bool p2meshstored, p2meshwanted;
103 
104  typedef typename RegionMesh::ElementShape ElementShape;
105 
106  if ( ElementShape::S_shape != TRIANGLE )
107  {
108  std::cerr << "Sorry, importerMesh2D reads only triangle meshes" << std::endl;
109  std::abort();
110  }
111 
112  if ( ElementShape::S_numPoints > 6 )
113  {
114  std::cerr << "Sorry, readMppFiles handles only liner&quad triangles" << std::endl;
115  std::abort();
116  }
117 
118  FortranCharacterString filename( const_cast<char *>( fileName.c_str() ), fileName.length() );
119 
120  I_F77 ne, np, nptot, npe, nb, nx, npc, ierr, nps, ndimn, npb;
121 
122  F77NAME( readmesh2dhead ) ( ne, np, nptot, npe, nb, nps, nx, npc, ierr, filename );
123 
124  if ( ierr != 0 )
125  {
126  std::cout << " Error in importerMesh2D: file " << fileName << std::endl
127  << " not accessible or incorrectly formatted" << std::endl;
128  std::abort();
129  }
130 
131  std::cout << " Information on 2D mesh as read from mesh2D file" << std::endl
132  << " See mesh2D docs for explanation" << std::endl << std::endl
133  << " ne = " << ne << std::endl
134  << " np = " << np << std::endl
135  << " nptot = " << nptot << std::endl
136  << " npe = " << npe << std::endl
137  << " nb = " << nb << std::endl
138  << " nx = " << nx << std::endl
139  << " npc = " << npc << std::endl
140  << " nps = " << nps << std::endl
141  << " ierr = " << ierr << std::endl;
142 
143  // Dimensioning all arrays
144  I_F77 nd( npe );
145  I_F77 nbd( nps );
146  I_F77 ndc( 3 );
147  I_F77 isw( 0 );
148 
149  FortranMatrix<I_F77> iel( npe, ne );
150  FortranMatrix<I_F77> ib( nps, nb );
151  FortranMatrix<I_F77> ic( nb );
152  FortranMatrix<I_F77> bc( nb );
153  FortranMatrix<I_F77> ie( nb );
154  FortranMatrix<I_F77> cpl( npc );
155  FortranMatrix<R4_F77> coor( 3, nptot );
156  FortranMatrix<R4_F77> xmed( 3, nb );
157  R4_F77 xmin, xmax, ymin, ymax;
158 
159  // Reading
160  F77NAME( readmesh2d ) ( ne, np, nptot, nb, nps, nx, ndimn, npe, npb,
161  npc, iel, nd, coor, ndc, xmin, xmax, ymin, ymax, ib, nbd,
162  ic, bc, ie, cpl, xmed, isw, ierr, filename );
163 
164  switch ( ierr )
165  {
166  case 1:
167  std::cerr << " Error in importerMesh2D: file incorrectly formatted" << std::endl;
168  std::abort();
169 
170  case 0:
171  std::cout << " File succesfully read" << std::endl;
172  break;
173 
174  default:
175  std::cerr << " Error in importerMesh2D: file incomplete" << std::endl;
176  std::abort();
177  }
178 
179  //I use explicit constructors instead of relying on implicit conversion rules
180  //This to make things more explicit: mesh2D files are (so far) single precision!
181 
182 
183  nFa = UInt( ne );
184  nBEd = UInt( nb );
185  nVe = UInt( np );
186  nBVe = UInt( nb );
187 
188 
189  //I Assume that the mesh is OK, so the number of boundary vertices coincides
190  //with the number of boundary sides: mesh checkers have still to be implemented
191 
192 
193  // Do I want a P2 mesh?
194  p2meshwanted = ( ElementShape::S_numPoints == 6 );
195 
196  // Do I have a P2 mesh?
197  p2meshstored = ( npe == 6 );
198 
199  // I still have not yet implemented converters p1->p2 for 2D meshes
200  if ( p2meshwanted && ! p2meshstored )
201  {
202  std::cerr << " Warning in importerMesh2D:" << std::endl;
203  std::cout << "file " << fileName << std::endl
204  << "contains a P1 mesh, while we request a P2 mesh" << std::endl
205  << "Construction of 2D P2 mesh from P1 data not yet implemented" << std::endl;
206  std::abort();
207  }
208 
209  if ( !p2meshwanted )
210  {
211  nPo = nVe;
212  nBPo = nBVe;
213  }
214 
215  else
216  {
217  nPo = UInt( nptot );
218  nBPo = 2 * nBVe;
219  }
220 
221  std::cout << "Using Euler formula to compute number of internal edges, assuming connected domain"
222  << std::endl;
223  std::cout << "(More precise technique still to be implemented)" << std::endl;
224 
225  nEd = 3 * ( nFa - nBEd ) / 2;
226 
227  std::cout << "Number of Vertices = " << nVe << std::endl
228  << "Number of BVertices= " << nBVe << std::endl
229  << "Number of Faces = " << nFa << std::endl
230  << "Number of Edges = " << nEd << std::endl
231  << "Number of BEdges = " << nBEd << std::endl
232  << "Number of Points = " << nPo << std::endl
233  << "Number of BPoints = " << nBPo << std::endl;
234 
235  // I store all the points
236  mesh.setMaxNumPoints( nPo, true );
237  mesh.setNumBPoints( nBPo );
238  mesh.numVertices() = nVe;
239  mesh.numBVertices() = nBVe;
240 
241  // Only Boundary Edges
242  mesh.setMaxNumEdges( nBEd );
243  mesh.setNumEdges( nEd );
244 
245 
246  //Here the REAL number of edges (all of them) even if I store only BEdges.
247 
248 
249  mesh.setNumBEdges( nBEd );
250 
251  // Triangular faces
252  mesh.setMaxNumFaces( nFa, true );
253 
254  // Add Marker to mesh
255  mesh.setMarkerID( regionFlag );
256 
257  // Now put the whole lot into the RegionMesh structure
258  typename RegionMesh::point_Type * pp = 0;
259  typename RegionMesh::edge_Type * pe = 0;
260  typename RegionMesh::face_Type * pf = 0;
261 
262 
263  // first the vertices
264  for ( i = 0; i < nVe; i++ )
265  {
266  pp = &mesh.addPoint( i < nBVe );
267  pp->x() = Real( coor( 0, i ) );
268  pp->y() = Real( coor( 1, i ) );
269  }
270 
271  // now the points
272  for ( i = nVe; i < nPo; i++ )
273  {
274  pp = &mesh.addPoint( i - nVe < nBPo );
275  pp->x() = Real( coor( 0, i ) );
276  pp->y() = Real( coor( 1, i ) );
277  }
278 
279  std::cout << "Vertices and Points Created " << std::endl;
280 
281  // now the boundary edges
282  ID ia1;
283  Int test;
284  markerID_Type ibc;
285 
286  for ( i = 0; i < nBEd; i++ )
287  {
288  pe = &mesh.addEdge( true ); // Only boundary edges.
289  p1 = ID( ib( 0, i ) ); // Explicit conversion to ID
290  p2 = ID( ib( 1, i ) );
291  ibc = markerID_Type( bc( i ) ); //Explicit conversion to marker ID
292 
293  // Boundary condition marker
294  pe->setMarkerID( ibc );
295  pe->setPoint( 0, mesh.point( p1 ) ); // set edge conn.
296  pe->setPoint( 1, mesh.point( p2 ) ); // set edge conn.
297 
298  if ( p2meshwanted )
299  {
300  pe->setPoint( 1, mesh.point( ID( ib( 2, i ) ) ) );
301  }
302 
303  // fix bedge adjacency information
304  ia1 = ID( ie( i ) );
305  pe->firstAdjacentElementIdentity() = ia1--; // Later I use ia1 to have an offset so I postdecrement it by 1
306 
307  i1 = iel( 0, ia1 );
308  i2 = iel( 1, ia1 );
309  i3 = iel( 2, ia1 );
310 
311  test = i1 - p1 + i2 - p2 + i3; // Get the other node
312 
313  if ( test == i1 )
314  {
315  pe->firstAdjacentElementPosition() = 2;
316  }
317 
318  else if ( test == i2 )
319  {
320  pe->firstAdjacentElementPosition() = 3;
321  }
322 
323  else if ( test == i3 )
324  {
325  pe->firstAdjacentElementPosition() = 1;
326  }
327 
328  else
329  std::cerr << "Information on adjacency of boundary edge is wrong!" << std::endl;
330  }
331  std::cout << "Boundary Edges Created " << std::endl;
332 
333  // Finally the triangular faces!
334  for ( i = 0; i < nFa; i++ )
335  {
336  p1 = ID( iel( 0, i ) );
337  p2 = ID( iel( 1, i ) );
338  p3 = ID( iel( 2, i ) );
339  pf = &( mesh.addFace() ); // Only boundary faces
340 
341  pf->setMarkerID( markerID_Type( ibc ) );
342  pf->setPoint( 0, mesh.point( p1 ) ); // set face conn.
343  pf->setPoint( 1, mesh.point( p2 ) ); // set face conn.
344  pf->setPoint( 2, mesh.point( p3 ) ); // set face conn.
345 
346  if ( p2meshwanted )
347  {
348  p1 = ID( iel( 3, i ) );
349  p2 = ID( iel( 4, i ) );
350  p3 = ID( iel( 5, i ) );
351  pf->setPoint( 3, mesh.point( p1 ) ); // set face conn.
352  pf->setPoint( 4, mesh.point( p2 ) ); // set face conn.
353  pf->setPoint( 5, mesh.point( p3 ) ); // set face conn.
354  }
355  }
356  std::cout << "Triangular Faces Created " << std::endl;
357 
358  return ierr == 0;
359 } // Function importerMesh2D
360 */
361 
362 
363 //! readGmshFile - reads a mesh in GMSH 2D format.
364 /*!
365  It reads a gmsh mesh (2D) file and store it in a RegionMesh.
366 
367  @param mesh, the mesh data structure to fill in.
368  @param fileName, the name of the gmsh mesh file to read.
369  @param regionFlag, the identifier for the region.
370  @return true if everything went fine, false otherwise.
371 */
372 
373 /*
374 template <typename GeoShape, typename MC>
375 
376 bool
377 readGmshFile( RegionMesh<GeoShape, MC> & mesh,
378  const std::string & fileName,
379  markerID_Type regionFlag )
380 {
381  std::ifstream __is ( fileName.c_str() );
382 
383  char buffer[256];
384  __is >> buffer;
385 
386 #ifdef DEBUG
387  debugStream ( 8000 ) << "buffer: "<< buffer << "\n";
388 #endif
389 
390  UInt __n;
391  __is >> __n;
392 
393 #ifdef DEBUG
394  debugStream ( 8000 ) << "number of nodes: " << __n;
395 #endif
396 
397  // Add Marker to list of Markers
398  mesh.setMarkerID( regionFlag );
399 
400  std::vector<Real> __x( 3 * __n );
401  std::vector<bool> __isonboundary( __n );
402  std::vector<UInt> __whichboundary( __n );
403 
404 #ifdef DEBUG
405  debugStream ( 8000 ) << "reading "<< __n << " nodes\n";
406 #endif
407 
408  std::map<int,int> itoii;
409 
410  for ( UInt __i = 0; __i < __n; ++__i )
411  {
412  UInt __ni;
413  __is >> __ni
414  >> __x[ 3 * __i ]
415  >> __x[ 3 * __i + 1 ]
416  >> __x[ 3 * __i + 2 ];
417 
418  itoii[ __ni - 1 ] = __i;
419  }
420  __is >> buffer;
421 
422 #ifdef DEBUG
423  debugStream ( 8000 ) << "buffer: "<< buffer << "\n";
424 #endif
425 
426  __is >> buffer;
427 
428 #ifdef DEBUG
429  debugStream ( 8000 ) << "buffer: "<< buffer << "\n";
430 #endif
431 
432  UInt __nele;
433  __is >> __nele;
434 
435  typename RegionMesh<GeoShape, MC>::edge_Type * pe = 0;
436  typename RegionMesh<GeoShape, MC>::face_Type * pf = 0;
437 
438 #ifdef DEBUG
439  debugStream ( 8000 ) << "number of elements: " << __nele << "\n";
440 #endif
441 
442  std::vector<std::vector<int> > __e( __nele );
443  std::vector<int> __et( __nele );
444  std::vector<int> __etype( __nele );
445  std::vector<int> __gt( 16 );
446 
447  __gt.assign( 16, 0 );
448 
449  for ( UInt __i = 0; __i < __nele; ++__i )
450  {
451  Int __ne, __t, __tag, __np, __dummy;
452  __is >> __ne
453  >> __t
454  >> __tag
455  >> __dummy
456  >> __np;
457 
458  ++__gt[ __t ];
459 
460  __etype[ __i ] = __t;
461  __et[ __i ] = __tag;
462 
463  __e[ __i ].resize( __np );
464 
465  Int __p = 0;
466 
467  while ( __p != __np )
468  {
469  __is >> __e[ __i ][ __p ];
470  __e[ __i ][ __p ] = itoii[ __e[ __i ][ __p ] - 1 ];
471 
472  ++__p;
473  }
474  }
475 
476  std::for_each( __gt.begin(), __gt.end(), std::cout << boost::lambda::_1 << " " );
477  std::cout << "\n";
478 
479  // Euler formulas
480  UInt n_elements = __gt[ 2 ];
481 
482  // Only Boundary Edges (in a next version I will allow for different choices)
483  mesh.setMaxNumEdges( __gt[ 1 ] );
484 
485  // Here the REAL number of edges (all of them)
486  mesh.setNumEdges(__gt[ 1 ]);
487  mesh.setNumBEdges( __gt[ 1 ] );
488 
489 #ifdef DEBUG
490  debugStream ( 8000 ) << "number of edges= " << __gt[ 1 ] << "\n";
491 #endif
492 
493  // Only Boundary Faces
494  mesh.setMaxNumFaces( n_elements);
495 
496  // Here the REAL number of edges (all of them)
497  mesh.setNumFaces( n_elements );
498 
499 #ifdef DEBUG
500  debugStream ( 8000 ) << "number of faces= " << n_elements << "\n";
501 #endif
502 
503  __isonboundary.assign ( __n, false );
504  __whichboundary.assign( __n, 0 );
505 
506  for ( UInt __i = 0; __i < __nele; ++__i )
507  {
508  switch ( __etype[ __i ] )
509  {
510  // triangular faces (linear)
511  case 2:
512  {
513  __isonboundary[ __e[ __i ][ 0 ] ] = true;
514  __isonboundary[ __e[ __i ][ 1 ] ] = true;
515  __isonboundary[ __e[ __i ][ 2 ] ] = true;
516 
517  __whichboundary[ __e[ __i ][ 0 ] ] = __et[ __i ];
518  __whichboundary[ __e[ __i ][ 1 ] ] = __et[ __i ];
519  __whichboundary[ __e[ __i ][ 2 ] ] = __et[ __i ];
520  }
521  }
522  }
523  // add the point to the mesh
524  typename RegionMesh<GeoShape, MC>::point_Type * pp = 0;
525 
526  mesh.setMaxNumPoints( __n, true );
527  mesh.setNumVertices (__n);
528  mesh.numBVertices () = std::count( __isonboundary.begin(), __isonboundary.end(), true );
529  mesh.setNumBPoints ( mesh.numBVertices() );
530 
531 #ifdef DEBUG
532  debugStream ( 8000 ) << "number of points : " << mesh.numPoints() << "\n";
533  debugStream ( 8000 ) << "number of boundary points : " << mesh.numBPoints() << "\n";
534  debugStream ( 8000 ) << "number of vertices : " << mesh.numVertices() << "\n";
535  debugStream ( 8000 ) << "number of boundary vertices : " << mesh.numBVertices() << "\n";
536 #endif
537 
538  for ( UInt __i = 0; __i < __n; ++__i )
539  {
540  pp = &mesh.addPoint( __isonboundary[ __i ] );
541  pp->setMarkerID( __whichboundary[ __i ] );
542  pp->x() = __x[ 2 * __i ];
543  pp->y() = __x[ 2 * __i + 1 ];
544  }
545 
546  // add the element to the mesh
547  for ( UInt __i = 0; __i < __nele; ++__i )
548  {
549  switch ( __etype[ __i ] )
550  {
551  // segment(linear)
552  case 1:
553  {
554  pe = &( mesh.addEdge( true ) );
555  pe->setMarkerID( markerID_Type( __et[ __i ] ) );
556  pe->setPoint( 0, mesh.point( __e[ __i ][ 0 ] ) );
557  pe->setPoint( 1, mesh.point( __e[ __i ][ 1 ] ) );
558  }
559  break;
560 
561  // triangular faces (linear)
562  case 2:
563  {
564  pf = &( mesh.addFace() );
565  pf->setMarkerID( markerID_Type( __et[ __i ] ) );
566  pf->setPoint( 0, mesh.point( __e[ __i ][ 0 ] ) );
567  pf->setPoint( 1, mesh.point( __e[ __i ][ 1 ] ) );
568  pf->setPoint( 2, mesh.point( __e[ __i ][ 2 ] ) );
569  }
570  break;
571 
572  // quadrangular faces(linear)
573  case 3:
574  {
575  pf = &( mesh.addFace() );
576  pf->setMarkerID( markerID_Type( __et[ __i ] ) );
577  pf->setPoint( 0, mesh.point( __e[ __i ][ 0 ] ) );
578  pf->setPoint( 1, mesh.point( __e[ __i ][ 1 ] ) );
579  pf->setPoint( 2, mesh.point( __e[ __i ][ 2 ] ) );
580  pf->setPoint( 3, mesh.point( __e[ __i ][ 3 ] ) );
581  }
582  break;
583  }
584  }
585  return true;
586 } // Function readGmshFile
587 */
588 
589 //! readFreeFemFile - reads a mesh in FreeFem 2D format.
590 /*!
591 read a freefem mesh (2D) file and store it in a RegionMesh.
592 
593 @param mesh, the mesh data structure to fill in.
594 @param fileName, the name of the freefem mesh file to read.
595 @param regionFlag, the identifier for the region.
596 @param bool verbose, verbosity (not used)
597 @return true if everything went fine, false otherwise.
598  */
599 
600 template <typename MC>
601 bool
602 readFreeFemFile ( RegionMesh<LinearTriangle, MC>& mesh,
603  const std::string& fileName,
604  markerID_Type regionFlag, bool /*useless*/ = false)
605 {
607  std::pair<BareEdge, bool> _edge;
608 
609  typedef LinearTriangle GeoShape;
610 
611  typename RegionMesh<GeoShape, MC>::point_Type* pp = 0;
612  typename RegionMesh<GeoShape, MC>::edge_Type* pe = 0;
613  typename RegionMesh<GeoShape, MC>::face_Type* pf = 0;
614 
615  std::ifstream __is ( fileName.c_str() );
616  if ( __is.fail() )
617  {
618  std::cerr << " Error in readFreeFemFile: File " << fileName
619  << " not found or locked"
620  << std::endl;
621  abort();
622  }
623 
624  // first row: how many vertices, triangles, edges
625  UInt __nv, __nt, __ne, i1, i2, i3;
626  __is >> __nv >> __nt >> __ne;
627 
628 #ifdef DEBUG
629  debugStream ( 8000 ) << "number of vertices: " << __nv << "\n";
630  debugStream ( 8000 ) << "number of triangles: " << __nt << "\n";
631  debugStream ( 8000 ) << "number of edges: " << __ne << "\n";
632 #endif
633 
634  // first section: read the list of vertices
635  // on each row find the two coordinates and the label for each node
636  std::vector<Real> __x (2 * __nv);
637  std::vector<bool> __isonboundary (__nv);
638  std::vector<UInt> __whichboundary (__nv);
639 
640 #ifdef DEBUG
641  debugStream ( 8000 ) << "reading " << __nv << " nodes\n";
642 #endif
643 
644  // count the number of nodes on the boundary
645  UInt __nbv ( 0 );
646 
647  // reading vertices
648  for ( UInt __i = 0; __i < __nv; ++ __i )
649  {
650  __is >> __x[ 2 * __i ] >> __x[ 2 * __i + 1 ] >> __whichboundary[ __i ];
651  __isonboundary[ __i ] = __whichboundary[ __i ];
652  __nbv += __isonboundary[ __i ];
653  }
654 
655  // second section: read the list of triangles
656  // on each row find the three nodes and the label for each triangle
657  std::vector<int> __triangle_nodes ( 3 * __nt );
658  std::vector<int> __triangle_label ( __nt );
659 
660 #ifdef DEBUG
661  debugStream ( 8000 ) << "reading " << __nt << " triangles\n";
662 #endif
663 
664  std::map<UInt, UInt> edge_to_firstAdjacentElementIdentity, edge_to_firstAdjacentElementPosition;
665 
666  // reading vertices
667  for ( UInt __i = 0; __i < __nt; ++__i )
668  {
669  __is >> __triangle_nodes[ 3 * __i ]
670  >> __triangle_nodes[ 3 * __i + 1 ]
671  >> __triangle_nodes[ 3 * __i + 2 ]
672  >> __triangle_label[ __i ];
673 
674  //from 1-based numbering to 0-based numbering
675  __triangle_nodes[3 * __i]--;
676  __triangle_nodes[3 * __i + 1]--;
677  __triangle_nodes[3 * __i + 2]--;
678 
679  // dump first the existing edges, to maintain the correct numbering
680  // if everything is correct the numbering in the bareedge
681  // structure will reflect the actual edge numbering
682 
683  std::pair<UInt, bool> _check;
684 
685  i1 = __triangle_nodes[ 3 * __i ];
686  i2 = __triangle_nodes[ 3 * __i + 1 ];
687  i3 = __triangle_nodes[ 3 * __i + 2 ];
688 
689  _edge = makeBareEdge ( i1, i2 );
690  _check = _be.addIfNotThere ( _edge.first );
691  edge_to_firstAdjacentElementIdentity[ _check.first ] = __i;
692  edge_to_firstAdjacentElementPosition[ _check.first ] = 0;
693 
694  _edge = makeBareEdge ( i2, i3 );
695  _check = _be.addIfNotThere ( _edge.first );
696  edge_to_firstAdjacentElementIdentity[ _check.first ] = __i;
697  edge_to_firstAdjacentElementPosition[ _check.first ] = 1;
698 
699  _edge = makeBareEdge ( i3, i1 );
700  _check = _be.addIfNotThere ( _edge.first );
701  edge_to_firstAdjacentElementIdentity[ _check.first ] = __i;
702  edge_to_firstAdjacentElementPosition[ _check.first ] = 2;
703  }
704 
705  // ( __triangle[ 3 * i + 2] > __triangle[ 3 * i + 1 ] )
706 
707  // third section: read the list of edges
708  // NOTE: only boundary edges are stored
709  // on each row find the two nodes and the label for each edge
710  std::vector<int> __edge_nodes ( 2 * __ne );
711  std::vector<int> __edge_label ( __ne );
712 
713  // reading edges
714 
715  for ( UInt __i = 0; __i < __ne; ++__i )
716  {
717  __is >> __edge_nodes[ 2 * __i ] >> __edge_nodes[ 2 * __i + 1 ] >> __edge_label[ __i ];
718  }
719 
720  //from 1-based numbering to 0-based numbering
721  for (UInt i (0); i < __edge_nodes.size(); i++)
722  {
723  __edge_nodes[i]--;
724  }
725 
726  // Set mesh properties
727  // Add Marker to list of Markers
728  mesh.setMarkerID ( regionFlag );
729 
730  // Till now I only have information about boundary edges - I don't know the MAX num of edges
731  // Euler formula: ne = nv + nt - 1
732  mesh.setMaxNumEdges ( _be.size() );
733  mesh.setMaxNumGlobalEdges ( _be.size() );
734 
735  // Here the REAL number of edges (all of them)
736  mesh.setNumEdges ( _be.size() );
737 
738  mesh.setNumBEdges ( __ne );
739  mesh.setMaxNumFaces ( __nt );
740  mesh.setMaxNumGlobalFaces ( __nt );
741 
742  // Here the REAL number of edges (all of them)
743  mesh.setNumFaces ( __nt);
744 
745  mesh.setMaxNumPoints ( __nv, true );
746  mesh.setMaxNumGlobalPoints ( __nv );
747 
748  mesh.setNumVertices ( __nv );
749  mesh.setNumGlobalVertices ( __nv );
750 
751  mesh.numBVertices() = __nbv;
752  mesh.setNumBPoints ( mesh.numBVertices() );
753 
754 #ifdef DEBUG
755  debugStream ( 8000 ) << "number of points : " << mesh.numPoints() << "\n";
756  debugStream ( 8000 ) << "number of boundary points : " << mesh.numBPoints() << "\n";
757  debugStream ( 8000 ) << "number of vertices : " << mesh.numVertices() << "\n";
758  debugStream ( 8000 ) << "number of boundary vertices : " << mesh.numBVertices() << "\n";
759 #endif
760 
761  for ( UInt __i = 0; __i < __nv; ++__i )
762  {
763  pp = &mesh.addPoint ( __isonboundary[ __i ], true );
764  pp->setMarkerID ( __whichboundary[ __i ] );
765  pp->x() = __x[ 2 * __i ];
766  pp->y() = __x[ 2 * __i + 1 ];
767  pp->z() = 0;
768  pp->setId ( __i );
769  }
770 
771  // add the edges to the mesh
772  for ( UInt __i = 0; __i < __ne; ++__i )
773  {
774  pe = & ( mesh.addEdge ( true ) );
775  pe->setMarkerID ( markerID_Type ( __edge_label[ __i ] ) );
776  pe->setPoint ( 0, mesh.point ( __edge_nodes[ 2 * __i ] ) );
777  pe->setPoint ( 1, mesh.point ( __edge_nodes[ 2 * __i + 1 ] ) );
778  pe->setId ( __i );
779  _edge = makeBareEdge ( __edge_nodes[ 2 * __i ], __edge_nodes[ 2 * __i + 1 ] );
780  UInt map_it ( _be.id ( _edge.first ) );
781  pe->firstAdjacentElementIdentity() = edge_to_firstAdjacentElementIdentity[ map_it ];
782  pe->firstAdjacentElementPosition() = edge_to_firstAdjacentElementPosition[ map_it ];
783  }
784 
785  // add the triangles to the mesh
786  for ( UInt __i = 0; __i < __nt; ++__i )
787  {
788  pf = & ( mesh.addFace (true) );
789  pf->setId ( __i );
790  pf->setMarkerID ( markerID_Type ( __triangle_label[ __i ] ) );
791  pf->setPoint ( 0, mesh.point ( __triangle_nodes[ 3 * __i ] ) );
792  pf->setPoint ( 1, mesh.point ( __triangle_nodes[ 3 * __i + 1 ] ) );
793  pf->setPoint ( 2, mesh.point ( __triangle_nodes[ 3 * __i + 2 ] ) );
794  }
795 
796  return true;
797 } // Function readFreeFemFile
798 
799 } // Namespace LifeV
800 
801 #endif /* IMPORTERMESH2D_H */
A Geometric Shape.
#define F77NAME(X)
ID markerID_Type
markerID_Type is the type used to store the geometric entity marker IDs
Definition: Marker.hpp:81
The Edge basis class.
Class for 3D, 2D and 1D Mesh.
Definition: RegionMesh.hpp:87
#define SUBROUTINE_F77
container_Type::const_iterator containerConstIterator_Type
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191