LifeV
MeshExtractor.hpp
Go to the documentation of this file.
1 /*
2  * MeshExtractor.hpp
3  *
4  * Created on: Jan 29, 2012
5  * Author: uvilla
6  */
7 
8 #ifndef MESHEXTRACTOR_HPP_
9 #define MESHEXTRACTOR_HPP_
10 
11 #include <lifev/core/mesh/RegionMesh.hpp>
12 
13 namespace LifeV
14 {
15 
16 template<typename geoShape_Type>
19 {
20  //(0) Some useful typedefs
21  typedef RegionMesh<geoShape_Type> mesh_Type;
22  typedef typename mesh_Type::facetShape_Type facetShape_Type;
23  typedef typename mesh_Type::facet_Type facet_Type;
24  typedef RegionMesh<facetShape_Type> boundaryRegionMesh_Type;
25 
26  //(1) Extract the list of faces with marker boundaryFaceMarker.
27  std::vector<facet_Type const*> boundaryFaces;
28  Predicates::EntityMarkerIDInterrogator<facet_Type> predicator (boundaryFaceMarker);
29  boundaryFaces = mesh3D.faceList.extractAccordingToPredicate (predicator);
30 
31  //(2) Extract the list of points
32  std::map<UInt, UInt> vertexIdMap, inverseVertexIdMap; // vertexIdMap[PointIdIn3DMesh] = NewPointIdIn2DMesh
33  for ( typename std::vector<facet_Type const*>::iterator it (boundaryFaces.begin() ); it != boundaryFaces.end(); ++it )
34  {
35  for (UInt i (0); i < boundaryRegionMesh_Type::face_Type::S_numPoints; ++i)
36  {
37  UInt originalId = (*it)->point (i).id();
38  vertexIdMap.insert (std::pair<UInt, UInt> (originalId, vertexIdMap.size() ) );
39  inverseVertexIdMap.insert (std::pair<UInt, UInt> (inverseVertexIdMap.size(), originalId) );
40  }
41  }
42 
43  //(3) Extract the list of points shared between the side I want to extract and its neighbor sides
44  std::map<UInt, UInt> boundaryPointsOnEdges;
45  //boundaryPointsOnEdges[PointIdIn3DMesh] = marker_of_the_other_side_who_shares_the_point
46  for (std::list<UInt>::const_iterator it (otherBoundaryFaceMarkerList.begin() ); it != otherBoundaryFaceMarkerList.end(); ++it)
47  {
48  UInt marker = *it;
49  Predicates::EntityMarkerIDInterrogator<facet_Type> predicator (marker);
50  std::vector<facet_Type const*> otherboundaryFaces;
51  otherboundaryFaces = ( mesh3D.faceList.extractAccordingToPredicate (predicator) );
52  std::cout << "Extract " << otherboundaryFaces.size() << " bd faces on Marker" << marker << "\n";
53  for ( typename std::vector<facet_Type const*>::iterator it1 (otherboundaryFaces.begin() ); it1 != otherboundaryFaces.end(); ++it1 )
54  {
55  for (UInt i (0); i < boundaryRegionMesh_Type::face_Type::S_numPoints; ++i)
56  {
57  UInt originalId = (*it1)->point (i).id();
58  if (vertexIdMap.count (originalId) )
59  {
60  boundaryPointsOnEdges.insert (std::pair<UInt, UInt> (originalId, marker) );
61  }
62  }
63  }
64  }
65 
66  //(4) Allocate memory for the new mesh
67  boundaryRegionMesh_Type* mesh2D (new boundaryRegionMesh_Type ( mesh3D.comm() ) );
68  typename boundaryRegionMesh_Type::point_Type* pp = 0;
69  typename boundaryRegionMesh_Type::edge_Type* pe = 0;
70  typename boundaryRegionMesh_Type::face_Type* pf = 0;
71 
72  UInt __nv (vertexIdMap.size() ), __ne (boundaryPointsOnEdges.size() ), __nt (boundaryFaces.size() );
73 
74  debugStream (8000) << "number of vertices: " << __nv << "\n";
75  debugStream (8000) << "number of edges: " << __ne << "\n";
76  debugStream (8000) << "number of triangles: " << __nt << "\n";
77 
78  //(5) Dump the BoundaryPoints coordinates and marker in a std::vector
79  std::vector<Real> __x (3 * __nv);
80  std::vector<bool> __isonboundary (__nv);
81  std::vector<UInt> __whichboundary (__nv);
82 
83  // count the number of nodes on the boundary
84  UInt __nbv ( 0 );
85 
86  // reading vertices
87  for ( std::map<UInt, UInt>::iterator it (vertexIdMap.begin() ); it != vertexIdMap.end(); ++it)
88  {
89  UInt pointId (it->second);
90  for (UInt icoor (0); icoor < 3; ++icoor)
91  {
92  __x[3 * pointId + icoor] = mesh3D.point (it->first).coordinatesArray() [icoor];
93  }
94 
95  if ( boundaryPointsOnEdges.count (it->first) )
96  {
97  __whichboundary[ pointId ] = boundaryPointsOnEdges[it->first];
98  __isonboundary[ pointId ] = true;
99  __nbv += 1;
100  }
101  else
102  {
103  __whichboundary[ pointId ] = 0;
104  __isonboundary[ pointId ] = false;
105  }
106  }
107 
108  //(5) Dump the (2D) element connectivity and markers in a std::vector
109  std::vector<int> __triangle_nodes ( 3 * __nt );
110  std::vector<int> __triangle_label ( __nt );
111 
113  std::pair<BareEdge, bool> _edge;
114  UInt counter = 0;
115  UInt nTotalEdges (0);
116  for ( typename std::vector<facet_Type const*>::iterator it (boundaryFaces.begin() ); it != boundaryFaces.end(); ++it, ++counter )
117  {
118  for (UInt i (0); i < boundaryRegionMesh_Type::face_Type::S_numPoints; ++i)
119  {
120  UInt originalId = (*it)->point (i).id();
121  __triangle_nodes[ boundaryRegionMesh_Type::face_Type::S_numPoints * counter + i] = vertexIdMap[originalId];
122  }
123 
124  std::pair<UInt, bool> _check;
125 
126  UInt i1 = __triangle_nodes[ 3 * counter ];
127  UInt i2 = __triangle_nodes[ 3 * counter + 1 ];
128  UInt i3 = __triangle_nodes[ 3 * counter + 2 ];
129 
130  _edge = makeBareEdge ( i1, i2 );
131  _check = _be.addIfNotThere ( _edge.first );
132  if (!_check.second)
133  {
134  _be.deleteIfThere ( _edge.first );
135  }
136  else
137  {
138  ++nTotalEdges;
139  }
140 
141  _edge = makeBareEdge ( i2, i3 );
142  _check = _be.addIfNotThere ( _edge.first );
143  if (!_check.second)
144  {
145  _be.deleteIfThere ( _edge.first );
146  }
147  else
148  {
149  ++nTotalEdges;
150  }
151 
152  _edge = makeBareEdge ( i3, i1 );
153  _check = _be.addIfNotThere ( _edge.first );
154  if (!_check.second)
155  {
156  _be.deleteIfThere ( _edge.first );
157  }
158  else
159  {
160  ++nTotalEdges;
161  }
162 
163  __triangle_label[ counter ] = 1;
164 
165  }
166 
167  debugStream (8000) << "Found " << _be.size() << " boundary edges \n";
168  debugStream (8000) << "Found " << nTotalEdges - _be.size() << " internal edges \n";
169  __ne = _be.size();
170 
171  //(6) Dump the (1D) boundary facet connectivity and markers in a std::vector
172  // Here there is some bug, I get too many boundary facets
173  std::vector<int> __edge_nodes;
174  __edge_nodes.reserve ( 2 * __ne );
175  std::vector<int> __edge_label;
176  __edge_label.reserve ( __ne );
177 
178  for (MeshElementBareHandler<BareEdge>::iterator it (_be.begin() ); it != _be.end(); ++it)
179  {
180  BareEdge edge (it->first);
181  UInt first2dId = edge.first;
182  UInt second2dId = edge.second;
183  __edge_nodes.push_back (first2dId);
184  __edge_nodes.push_back (second2dId);
185  __edge_label.push_back ( boundaryFaceMarker );
186  }
187 
188  // (7) Set mesh properties
189  mesh2D->setMarkerID ( 1 );
190 
191  mesh2D->setMaxNumEdges ( nTotalEdges );
192  mesh2D->setMaxNumGlobalEdges ( nTotalEdges );
193 
194  mesh2D->setNumEdges ( nTotalEdges );
195 
196  mesh2D->setNumBEdges ( __ne );
197 
198  mesh2D->setMaxNumFaces ( __nt );
199  mesh2D->setMaxNumGlobalFaces ( __nt );
200 
201  mesh2D->setNumFaces ( __nt);
202 
203  mesh2D->setMaxNumPoints ( __nv, true );
204  mesh2D->setMaxNumGlobalPoints ( __nv );
205 
206  mesh2D->setNumVertices ( __nv );
207  mesh2D->setNumGlobalVertices ( __nv );
208 
209  mesh2D->numBVertices() = __nbv;
210  mesh2D->setNumBPoints ( mesh2D->numBVertices() );
211 
212  debugStream (8000) << "number of points : " << mesh2D->numPoints() << "\n";
213  debugStream (8000) << "number of edges : " << mesh2D->numEdges() << "\n";
214  debugStream (8000) << "number of boundary edges : " << mesh2D->numBEdges() << "\n";
215  debugStream (8000) << "number of vertices : " << mesh2D->numVertices() << "\n";
216  debugStream (8000) << "number of boundary vertices : " << mesh2D->numBVertices() << "\n";
217 
218  // (8) Fill in the mesh
219  // add points to the mesh
220  for ( UInt __i = 0; __i < __nv; ++__i )
221  {
222  pp = & (mesh2D->addPoint ( __isonboundary[ __i ], false ) );
223  pp->setMarkerID ( __whichboundary[ __i ] );
224  pp->x() = __x[ 3 * __i ];
225  pp->y() = __x[ 3 * __i + 1 ];
226  pp->z() = __x[ 3 * __i + 2];
227  pp->setId ( __i );
228  }
229 
230  // add the edges to the mesh
231  for ( UInt __i = 0; __i < __ne; ++__i )
232  {
233  pe = & ( mesh2D->addEdge ( true ) );
234  pe->setId ( __i );
235  pe->setMarkerID ( markerID_Type ( __edge_label[ __i ] ) );
236  pe->setPoint ( 0, mesh2D->point ( __edge_nodes[ 2 * __i ] ) );
237  pe->setPoint ( 1, mesh2D->point ( __edge_nodes[ 2 * __i + 1 ] ) );
238  }
239 
240  // add the triangles to the mesh
241  for ( UInt __i = 0; __i < __nt; ++__i )
242  {
243  pf = & ( mesh2D->addFace (true) );
244  pf->setId ( __i );
245  pf->setMarkerID ( markerID_Type ( __triangle_label[ __i ] ) );
246  pf->setPoint ( 0, mesh2D->point ( __triangle_nodes[ 3 * __i ] ) );
247  pf->setPoint ( 1, mesh2D->point ( __triangle_nodes[ 3 * __i + 1 ] ) );
248  pf->setPoint ( 2, mesh2D->point ( __triangle_nodes[ 3 * __i + 2 ] ) );
249  }
250 
251 
252  //(9) Update all the facets
253  mesh2D->updateElementFacets (true);
254 
255 
256  return mesh2D;
257 }
258 }
259 
260 
261 #endif /* MESHEXTRACTOR_HPP_ */
#define debugStream
Definition: LifeDebug.hpp:182
RegionMesh< typename RegionMesh< geoShape_Type >::facetShape_Type > * extractBoundaryMesh(const RegionMesh< geoShape_Type > &mesh3D, const UInt &boundaryFaceMarker, const std::list< UInt > &otherBoundaryFaceMarkerList)
The Edge basis class.
container_Type::const_iterator containerConstIterator_Type
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191