LifeV
RegionMesh2DStructured.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 Contains methods which generate 2D structured meshes.
30 
31  @author Iori Guido <guido.iori@mail.polimi.it>
32  @contributor -
33 
34  @date 23-05-2011
35 
36 */
37 
38 #ifndef STRUCTUREDMESH2D_HPP
39 #define STRUCTUREDMESH2D_HPP 1
40 
41 #include <lifev/core/LifeV.hpp>
42 #include <lifev/core/mesh/RegionMesh.hpp>
43 #include <lifev/core/mesh/MeshChecks.hpp>
44 
45 namespace LifeV
46 {
47 
48 // Labels for the structured 2D mesh
50 {
51 //! Label for the internal entities
53 
54 //! Label for the bottom boundary edge
56 
57 //! Label for the left boundary edge
58 const markerID_Type LEFT = 2;
59 
60 //! Label for the top boundary edge
61 const markerID_Type TOP = 3;
62 
63 //! Label for the right boundary edge
64 const markerID_Type RIGHT = 4;
65 
66 //! Label for the top and left boundary corner
68 
69 //! Label for the bottom and right boundary corner
71 
72 //! Label for the bottom and left boundary corner
74 
75 //! Label for the top and right boundary corner
77 
78 }
79 
80 /*!
81  @brief This method gives the flags for a rectangle
82 
83  @param i_x
84  @param i_y
85  @param n_x Number of elements along the length
86  @param n_y Number of elements along the width
87 */
89  const UInt& i_y,
90  const UInt& n_x,
91  const UInt& n_y );
92 
93 
94 /*!
95  @brief This method generate a rectangular structured mesh
96 
97  For the square \f$ [0,1]^2 \f$ the internal flag is 0.
98  <br>
99  For the corners the labels are:
100  <ul>
101  <li> BOTTOM and RIGHT = 5, i.e. \f$ x = 1 \f$ and \f$ y = 0 \f$ </li>
102  <li> TOP and RIGHT = 6, i.e. \f$ x = 1 \f$ and \f$ y = 1 \f$ </li>
103  <li> TOP and LEFT = 7, i.e. \f$ x = 0 \f$ and \f$ y = 1 \f$ </li>
104  <li> BOTTOM and LEFT = 8, i.e. \f$ x = 0 \f$ and \f$ y = 0 \f$ </li>
105  </ul>
106  For the edges the labels are:
107  <ul>
108  <li> LEFT = 1, i.e. \f$ x = 0 \f$ </li>
109  <li> BOTTOM = 2, i.e. \f$ y = 0 \f$ </li>
110  <li> RIGHT = 3, i.e. \f$ x = 1 \f$ </li>
111  <li> TOP = 4, i.e. \f$ y = 1 \f$ </li>
112  </ul>
113 
114  @param mesh The mesh that we want to generate
115  @param regionFlag Flag of the region
116  @param m_x Number of elements along the length
117  @param m_y Number of elements along the width
118  @param l_x length of the mesh
119  @param l_y width of the mesh
120  @param verbose Verbose mode enabled/disabled
121  @param t_x translation of the mesh along the x-axis
122  @param t_y translation of the mesh along the y-axis
123 */
124 template <typename MeshType>
125 void regularMesh2D ( MeshType& mesh,
126  markerID_Type regionFlag,
127  const UInt& m_x,
128  const UInt& m_y,
129  bool verbose = false,
130  const Real& l_x = 1.0,
131  const Real& l_y = 1.0,
132  const Real& t_x = 0.0,
133  const Real& t_y = 0.0 )
134 {
135  typedef MeshType mesh_Type;
136 
137  ASSERT ( ( mesh_Type::geoShape_Type::S_shape == TRIANGLE )
138  || ( mesh_Type::geoShape_Type::S_shape == QUAD ),
139  "Type of 2d structured mesh not available." );
140 
141  // discretization
142  const Real dx ( l_x / m_x );
143  const Real dy ( l_y / m_y );
144 
145  // Number of nodes along the side of the rectangle
146  const UInt n_x ( m_x + 1 );
147  const UInt n_y ( m_y + 1 );
148 
149  // Incremental values in order to get the indices of the nodes
150  // Due to the structure, if we add N_i to the number of the
151  // current node, we end up with the number of the next point
152  // in the i axis.
153  const UInt N_x ( 1 );
154  const UInt N_y ( n_x );
155 
156  // Data about the mesh
157 
158  //Total-inside points
159  const UInt verticesNumber ( n_x * n_y );
160  const UInt boundaryVerticesNumber ( verticesNumber - ( n_x - 2 ) * ( n_y - 2 ) );
161  const UInt boundaryEdgesNumber (2 * ( m_x + m_y ) );
162  const UInt edgesNumber (
163  // Edges that draws the rectangles
164  m_x * n_y +
165  n_x * m_y +
166  // Edges that go accross the rectangles
167  m_x * m_y
168  );
169 
170  // Faces
171  const UInt elementsNumber ( 2 * ( m_x * m_y ) );
172 
173  // Set the data
174 
175  // Note: The vertices are the nodes of the mesh while the points
176  // are the nodes and some new points added for example for
177  // the quadratic triangle
178 
179  // About points:
180  mesh.setNumBoundaryRidges ( boundaryVerticesNumber );
181  mesh.setMaxNumRidges ( verticesNumber, true );
182  mesh.setMaxNumGlobalRidges ( verticesNumber );
183 
184  // About vertices:
185  mesh.setNumVertices ( verticesNumber );
186  mesh.setNumGlobalVertices ( verticesNumber );
187  mesh.setNumBVertices ( boundaryVerticesNumber );
188 
189  // About edges:
190  mesh.setNumFacets ( edgesNumber );
191  mesh.setNumBoundaryFacets ( boundaryEdgesNumber );
192  mesh.setMaxNumFacets ( edgesNumber );
193  mesh.setMaxNumGlobalFacets ( edgesNumber );
194 
195  // About faces:
196  mesh.setMaxNumElements ( elementsNumber );
197  mesh.setMaxNumGlobalElements ( elementsNumber );
198 
199  mesh.setMaxNumFaces ( elementsNumber );
200  mesh.setMaxNumGlobalFaces ( elementsNumber );
201  mesh.setNumFaces ( elementsNumber );
202 
203 
204  mesh.setMarkerID ( regionFlag );
205 
206  // Declaration of pointers on the different mesh entities
207  typename mesh_Type::ridge_Type* pointPtr = 0;
208  typename mesh_Type::facet_Type* edgePtr = 0;
209  typename mesh_Type::element_Type* elementPtr = 0;
210 
211  // Build the points of the mesh
212  Real xPosition ( 0.0 ), yPosition ( 0.0 ), zPosition ( 0.0 );
213  markerID_Type nodeFlag ( 0 );
214  UInt nodeID ( 0 );
215  UInt P0 ( 0 ), P1 ( 0 ), P2 ( 0 ), P3 ( 0 );
216 
217  /*
218  P3___P2
219  | / |
220  |/__|
221  P0 P1
222  */
223 
224  for ( UInt j (0); j < n_y; ++j )
225  {
226  yPosition = dy * j;
227 
228  for ( UInt i (0); i < n_x; ++i )
229  {
230  xPosition = dx * i;
231  nodeFlag = regularMeshPointPosition2D (i, j, n_x, n_y );
232 
233  // We create the point
234  pointPtr = &mesh.addRidge ( nodeFlag > 0 ); // node flag determines if the point is on boundary
235 
236 
237  // We set the point properties
238  nodeID = j * N_y + i;
239  pointPtr->setId ( nodeID );
240 
241  pointPtr->setMarkerID ( nodeFlag );
242  pointPtr->x() = xPosition + t_x;
243  pointPtr->y() = yPosition + t_y;
244  pointPtr->z() = zPosition;
245  }
246  }
247 
248  // Build the faces
249  UInt faceID (0);
250 
251  for ( UInt j (0); j < m_y; ++j )
252  {
253  for ( UInt i (0); i < m_x; ++i )
254  {
255  faceID = ( j * m_x + i ) * 2;
256 
257  nodeID = j * N_y + i;
258  P0 = nodeID;
259  P1 = nodeID + N_x;
260  P2 = nodeID + N_x + N_y;
261  P3 = nodeID + N_y;
262 
263  // Triangle 1
264  elementPtr = &mesh.addElement();
265  elementPtr->setId ( faceID );
266  elementPtr->setPoint ( 0, mesh.point (P1) );
267  elementPtr->setPoint ( 1, mesh.point (P2) );
268  elementPtr->setPoint ( 2, mesh.point (P0) );
269  elementPtr->setMarkerID ( regionFlag );
270 
271  // Triangle 2
272  elementPtr = &mesh.addElement();
273  elementPtr->setId ( faceID + 1 );
274  elementPtr->setPoint ( 0, mesh.point (P3) );
275  elementPtr->setPoint ( 1, mesh.point (P0) );
276  elementPtr->setPoint ( 2, mesh.point (P2) );
277  elementPtr->setMarkerID ( regionFlag );
278  }
279  }
280 
281  // add the boundary edges to the mesh
282  for ( UInt i = 0; i < boundaryEdgesNumber ; ++i )
283  {
284  UInt edgeLabel = 0;
285  UInt adjID = 0;
286  UInt pos = 0;
287 
288  if (i < m_x)
289  {
290  nodeID = i;
291  P0 = nodeID;
292  P1 = nodeID + 1;
293  edgeLabel = Structured2DLabel::BOTTOM; //BOTTOMEDGE
294  adjID = 2 * i;
295  pos = 2;
296 
297  }
298  else if (i < m_x + m_y)
299  {
300  nodeID = (i + 1 - m_x) * n_x - 1;
301  P0 = nodeID;
302  P1 = nodeID + n_x;
303  edgeLabel = Structured2DLabel::RIGHT; //RIGHTEDGE
304  adjID = ( (i - m_x) * m_x + m_x - 1) * 2;
305  pos = 0;
306  }
307  else if (i < 2 * m_x + m_y)
308  {
309  nodeID = n_x * n_y - 1 - (i - m_x - m_y);
310  P0 = nodeID;
311  P1 = nodeID - 1;
312  edgeLabel = Structured2DLabel::TOP; //TOPEDGE
313  adjID = 2 * m_x * m_y - (i - m_x - m_y) * 2 - 1;
314  pos = 2;
315  }
316  else
317  {
318  nodeID = n_x * n_y - 1 - m_x - (i - 2 * m_x - m_y) * n_x ;
319  P0 = nodeID;
320  P1 = nodeID - n_x ;
321  edgeLabel = Structured2DLabel::LEFT; //LEFTEDGE
322  adjID = - (i - 2 * m_x - m_y) * (2 * m_x) + (m_x * (m_y - 1) ) * 2 + 1;
323  pos = 0;
324  }
325 
326 
327  edgePtr = &mesh.addFacet ( true ) ;
328  edgePtr->setId ( mesh.facetList().size() - 1 );
329  edgePtr->setMarkerID ( edgeLabel );
330  edgePtr->setPoint ( 0, mesh.point ( P0 ) );
331  edgePtr->setPoint ( 1, mesh.point ( P1 ) );
332  edgePtr->firstAdjacentElementIdentity() = adjID;
333  edgePtr->firstAdjacentElementPosition() = pos;
334  }
335 
336  // edges update
337  mesh.updateElementFacets ( true, verbose, edgesNumber );
338 
339 }
340 
341 
342 } // Namespace LifeV
343 
344 #endif /* STRUCTUREDMESH2D_HPP */
void regularMesh2D(MeshType &mesh, markerID_Type regionFlag, const UInt &m_x, const UInt &m_y, bool verbose=false, const Real &l_x=1.0, const Real &l_y=1.0, const Real &t_x=0.0, const Real &t_y=0.0)
This method generate a rectangular structured mesh.
const markerID_Type TOP_LEFT
Label for the top and left boundary corner.
const markerID_Type TOP
Label for the top boundary edge.
markerID_Type regularMeshPointPosition2D(const UInt &i_x, const UInt &i_y, const UInt &n_x, const UInt &n_y)
This method gives the flags for a rectangle.
ID markerID_Type
markerID_Type is the type used to store the geometric entity marker IDs
Definition: Marker.hpp:81
const markerID_Type BOTTOM
Label for the bottom boundary edge.
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
const markerID_Type BOTTOM_RIGHT
Label for the bottom and right boundary corner.
const markerID_Type LEFT
Label for the left boundary edge.
const markerID_Type RIGHT
Label for the right boundary edge.
double Real
Generic real data.
Definition: LifeV.hpp:175
const markerID_Type TOP_RIGHT
Label for the top and right boundary corner.
const markerID_Type INTERNAL
Label for the internal entities.
const markerID_Type BOTTOM_LEFT
Label for the bottom and left boundary corner.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191