1%%%%%%%%%%%%%%%%%%%
2% XLiFE++ is an extended library of finite elements written in C++
3%     Copyright (C) 2014  Lunéville, Eric; Kielbasiewicz, Nicolas; Lafranche, Yvon; Nguyen, Manh-Ha; Chambeyron, Colin
4%
5%     This program is free software: you can redistribute it and/or modify
6%     it under the terms of the GNU General Public License as published by
7%     the Free Software Foundation, either version 3 of the License, or
8%     (at your option) any later version.
9%     This program is distributed in the hope that it will be useful,
10%     but WITHOUT ANY WARRANTY; without even the implied warranty of
11%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12%     GNU General Public License for more details.
13%     You should have received a copy of the GNU General Public License
14%     along with this program.  If not, see <http://www.gnu.org/licenses/>.
15%%%%%%%%%%%%%%%%%%%
16
17\section{Mesh management}
18
19The {\class Mesh} class handles mesh description, that is a collection of mesh elements.
20{\class Mesh} objects are built either from internal meshing tools or from mesh files provided
21by external meshing tools as \gmsh for instance. To avoid complexity to end users, we
22decide to have a unique mesh class with no inheritance. It means that each meshing tool should
23be a member function of the {\class Mesh} class. These member functions are distributed in
24various files (see the Meshing tools section). \\
25
26Basically, a mesh is a collection of points (vertices and intermediate points), of geometric
27elements ({\class GeomElement}) to carry the computation domain partition, of geometric domains
28({\class Domain}): a list of elements or a list of sides of elements. Note that curved elements
29are supported using geometric interpolation of order greater than one. This {\class Mesh} class
30supports also mesh of surface in 3D space and mesh of line in 2D space. Besides the basic geometric
31data, it is also able to manage global list of sides (say faces of a 3D mesh, edges of a 2D
32mesh) or global list of sides of sides (edges of a 3D mesh). By default these lists are not
33constructed.\\
34
35General informations on a mesh such as mesh name, space dimension, name of variables, bounding
36box are collected in the {\class Geometry} class. In future, this class should be developed
37to handle other informations, in particular boundary parametrisations useful to describe in
38an analytical way the domain to mesh, allowing to provide high order mesh and refinement meshing
39tools.
40
41\subsection{The {\classtitle Mesh} class}
42\vspace{.1cm}
43\begin{lstlisting}[deletekeywords={[3] nodes}]
44class Mesh
45{
46 public :
47  Geometry* geometry_p;                   // global geometric information
48  std::vector<Point> nodes;               // list of all mesh nodes
49  Number lastIndex_;                      // last index of GeomElements
50
51 protected :
52  String name_;                           // name for documentation purposes
53  String comment_;                        // comment documentation purposes
54  std::vector<GeomElement*> elements_;    // list of geometric elements (MeshElement)
55  std::vector<GeomDomain*> domains_;      // list of geometric domains
56  std::vector<Number> vertices_;          // list of vertices indexed by their number in nodes vector
57  bool isMadeOfSimplices_;                // only segments, triangles or tetrahedra
58  Dimen order_;                           // order of the mesh = max of element orders
59  std::vector<GeomElement*> sides_;       // list of sides (edges in 2D, face in 3D), built if required
60  std::vector<GeomElement*> sideOfSides_; // list of sides of sides (edges in 3D), built if required
61  std::vector<std::vector<GeoNumPair> > vertexElements_; // for each vertex v, list of elements having vertex v, built if required
62  mutable Mesh* firstOrderMesh_p;         // underlying first order mesh when mesh has elements of order greater than one
63...
64\end{lstlisting}
65\vspace{.1cm}
66{\class GeomElement} class is described in detail in section \ref{sec_GeomElement}. In few
67words, the {\class GeomElement} class stores in a {\class MeshElement} object the numbering
68vectors of a mesh element (node numbers, vertex numbers, side numbers, side of side numbers)
69and a pointer to the reference element ({\class RefElement}) supporting the geometric interpolation
70of the element (define the map to reference geometric element). In case of a side element,
71the {\class GeomElement} class stores the parent sides and the side numbers. Note that in that
72case, {\class MeshElement} object does not necessarily exist! \\
73
74Regarding meshing tools, the {\class Mesh} class provides various constructor : one reading a mesh file, two general constructors from any geometry, a constructor meshing one reference element, a constructor extruding a 1D/2D mesh and a constructor converting mesh elements to an other type:
75\vspace{.1cm}
76\begin{lstlisting}[]
77Mesh();
78Mesh(const String& filename, const String&, IOFormat mft = _undefFormat);
79Mesh(const Mesh&);
80~Mesh();
81Mesh(const Geometry& g, Number order = 1, MeshGenerator mg = _defaultGenerator,
82     const String& name = ""); // for 1D geometry
83Mesh(const Geometry& g, ShapeType sh, Number order = 1, MeshGenerator mg = _defaultGenerator, const String& name = ""); // for 2D and 3D geometries
84Mesh(ShapeType shape); // for reference element
85Mesh(const Mesh& ms, const Point& O, const Point& d , number_t nbl, number_t namingDomain=0, number_t namingSection=0, number_t namingSide=0, const string_t& meshName="")  //for extruded mesh
86Mesh(const Mesh& mesh, ShapeType sh, const string_t name=""); // for element converter
87\end{lstlisting}
88See \autoref{ss.meshtools} for an exhaustive list of meshing tools.\\
89
90As most of members are protected, there are useful accessors:
91\vspace{.1cm}
92\begin{lstlisting}[]
93const std::vector<GeomElement*>& elements() const;
94const std::vector<Domain*>& domains() const;
95const std::vector<GeomElement*>& sides()const;
96const std::vector<GeomElement*>& sideOfSides()const;
97const std::vector<Number>& vertices()const;
98const String& name() const;
99bool isMadeOfSimplices()const;
100const GeomElement& element(Number i) const;
101const Domain& domains(Number i) const;
102const GeomElement& side(Number i) const;
103const GeomElement& sideOfSide(Number i) const;
104const Number vertex(Number i) const;
105const Point& vertexPoint(Number i) const;
106Dimen spaceDim() const ;
107Dimen meshDim() const;
108Number nbOfElements() const;
109Number nbOfDomains() const;
110Number nbOfSides() const;
111Number nbOfSideOfSides() const;
112Number nbOfVertices() const;
113Number nbOfNodes() const;
114\end{lstlisting}
115\vspace{.1cm}
116There are all constant and some are useful shortcuts.\\
117
118The {\class Mesh} class provides four important member functions to complete on demand the construction of a mesh: functions to build the list of sides, the list of sides of sides and the list of vertex elements and a function to compute element orientation (sign of jacobian determinant) and the measure
119of element and its sides:
120\vspace{.1cm}
121\begin{lstlisting}[]
122void buildSides();
123void buildSideOfSides();
124void buildVertexElements();
125void buildGeomData();
126\end{lstlisting}
127\vspace{.1cm}
128Note that {\cmd buildSides}  and {\cmd buildSideOfSides} functions update some data of
129{\class GeomElement}s.\\
130
131Finally, the class has usual printing facilities:
132\vspace{.1cm}
133\begin{lstlisting}[]
134void print(std::ostream &) const;
135friend std::ostream& operator<<(std::ostream&, const Mesh&);
136\end{lstlisting}
137\vspace{.2cm}
138\subsubsection*{Example}
139We give a basic example of using the {\class Mesh} class. It concerns the meshing of the rectangle
140$[0,1]\times[1,3]$ with regular P1 geometric elements ($20$ by $40$) where the boundary $[0,1]\times\{1\}$
141is named Gamma\_1 and the boundary $\{0\}\times[1,3]$ is named Gamma\_2:
142\vspace{.1cm}
143\begin{lstlisting}[]
144std::vector<String> sidenames(4,"");sidenames[0]="Gamma_1";sidenames[2]="Gamma_2";
145Mesh mesh2d(Rectangle(0,1,1,3),_triangle,20,40,sidenames,"P1 mesh of [0,1]x[1,3]");
146mesh2d.buildSides();   //build sides list
147verboseLevel(3);std::cout<<mesh2d;
148\end{lstlisting}
149\vspace{.2cm}
150It produces the following output:
151\vspace{.1cm}
152\scriptsize
153\begin{verbatim}
154Mesh'P1 mesh of [0,1]x[1,3]'
155  space dimension : 2, element dimension : 2
156  Geometry rectangle [0,1]x[1,3] of dimension 2, BoundingBox [0,1]x[1,3], names of variable : x y
157  number of elements : 1600, number of vertices : 861, number of nodes : 861, number of domains : 3 ( Omega Gamma_1 Gamma_2 )
158list of elements (1600) :
159geometric element 1 : triangle_Lagrange_1, orientation +1 measure = 0.00125
160   nodes : 2 ->(0.05, 0) 22 ->(0, 0.05) 1 ->(0, 0)
161   vertices : 2 ->(0.05, 0) 22 ->(0, 0.05) 1 ->(0, 0)
162   measure of sides = 0.0707107 0.05 0.05
163   sides : 61 21 1    sideOfSides : unset   adjacent elements : 2
164geometric element 2 : triangle_Lagrange_1, orientation +1 measure = 0.00125
165   nodes : 22 ->(0, 0.05) 2 ->(0.05, 0) 23 ->(0.05, 0.05)
166   vertices : 22 ->(0, 0.05) 2 ->(0.05, 0) 23 ->(0.05, 0.05)
167   measure of sides = 0.0707107 0.05 0.05
168   sides : 61 62 63    sideOfSides : unset   adjacent elements : 1 3 41
169geometric element 3 : triangle_Lagrange_1, orientation +1 measure = 0.00125
170   nodes : 3 ->(0.1, 0) 23 ->(0.05, 0.05) 2 ->(0.05, 0)
171   vertices : 3 ->(0.1, 0) 23 ->(0.05, 0.05) 2 ->(0.05, 0)
172   measure of sides = 0.0707107 0.05 0.05
173   sides : 64 62 2    sideOfSides : unset   adjacent elements : 2 4
174...
175geometric element 1600 : triangle_Lagrange_1, orientation +1 measure = 0.00125
176   nodes : 860 ->(0.95, 2) 840 ->(1, 1.95) 861 ->(1, 2)
177   vertices : 860 ->(0.95, 2) 840 ->(1, 1.95) 861 ->(1, 2)
178   measure of sides = 0.0707107 0.05 0.05
179   sides : 2458 2459 2460    sideOfSides : unset   adjacent elements : 1599
180list of vertices (861) :
1811 -> (0, 0)
1822 -> (0.05, 0)
1833 -> (0.1, 0)
184...
185861 -> (1, 2)
186list of nodes (861) :
1871 -> (0, 0)
1882 -> (0.05, 0)
1893 -> (0.1, 0)
190...
191861 -> (1, 2)
192list of sides (2460) :
193side 1 -> geometric side element 1601 : side 3 of element 1
194side 2 -> geometric side element 1602 : side 3 of element 3
195side 3 -> geometric side element 1603 : side 3 of element 5
196...
197side 2460 -> geometric side element 4059 : side 3 of element 1600
198list of sides of sides (0) : unset
199list of domains (3) :
200 Domain 'Omega' of dimension 2 from mesh 'P1 mesh of [0,1]x[1,3]'
201geometric element 1 : triangle_Lagrange_1, orientation +1 measure = 0.00125
202geometric element 2 : triangle_Lagrange_1, orientation +1 measure = 0.00125
203geometric element 3 : triangle_Lagrange_1, orientation +1 measure = 0.00125
204...
205geometric element 1600 : triangle_Lagrange_1, orientation +1 measure = 0.00125
206 Domain 'Gamma_1' of dimension 1 from mesh 'P1 mesh of [0,1]x[1,3]'
207geometric side element 1601 : side 3 of element 1
208geometric side element 1602 : side 3 of element 3
209geometric side element 1603 : side 3 of element 5
210...
211geometric side element 1620 : side 3 of element 39
212 Domain 'Gamma_2' of dimension 1 from mesh 'P1 mesh of [0,1]x[1,3]'
213geometric side element 1621 : side 2 of element 1
214geometric side element 1622 : side 2 of element 41
215geometric side element 1623 : side 2 of element 81
216...
217geometric side element 1660 : side 2 of element 1561
218\end{verbatim}
219\normalsize
220
221
222\subsection{Meshing tools}\label{ss.meshtools}
223
224In this section, we will study in details how work the {\class Mesh} constructors from {\class Geometry}.
225
226\begin{lstlisting}[deletekeywords={[3] name, order}]
227Mesh(const Geometry& g, Number order = 1, MeshGenerator mg = _defaultGenerator, const String& name = ""); // constructor from 1D geometry
228Mesh(const Geometry& g, ShapeType sh, Number order = 1, MeshGenerator mg = _defaultGenerator, const String& name = ""); // constructor from 2D and 3D geometries
229\end{lstlisting}
230
231The {\class MeshGenerator} argument can have the following values :
232
233\begin{lstlisting}
234enum MeshGenerator
235{
236  _defaultGenerator=0,
237  _structured, structured=_structured,
238  _subdiv, subdiv=_subdiv,
239  _gmsh, gmsh=_gmsh
240};
241\end{lstlisting}
242
243We will now look at the behavior of the different generators :
244
245\subsubsection{Structured meshes}
246
247The "structured" generator works only on {\class Segment}, {\class Rectangle}, and {\class Parallelepiped}
248geometries, and for P1, Q1, prisme 1 or pyramid 1 finite elements. In this way, you call the following underlying methods :
249
250\begin{lstlisting}[]
251void meshP1Segment(const Segment&, Number, const std::vector<String>&, const String& na = "");
252void meshP1Rectangle(const Rectangle&, Number, Number, const std::vector<String>&, const String& na = "");
253void meshQ1Rectangle(const Rectangle&, Number, Number, const std::vector<String>&, const String& na = "");
254void meshP1Parallelepiped(const Parallelepiped& , Number, Number, Number, const std::vector<String>&, const String& na = "");
255void meshQ1Parallelepiped(const Parallelepiped& , Number, Number, Number, const std::vector<String>&, const String& na = "");
256void meshPr1Parallelepiped(Parallelepiped& , number_t, number_t, number_t, const std::vector<string_t>&, const string_t& na = "");
257void meshPy1Parallelepiped(Parallelepiped& , number_t, number_t, number_t, const std::vector<string_t>&, const string_t& na = "");
258\end{lstlisting}
259
260\subsubsection{Meshes with {\em subdivision} algorithm}
261
262The subdivision algorithm enables to mesh a wide set of geometries with triangles, quadrangles, tetrahedrons
263or hexahedrons: {\class Ball}, {\class Cube}, {\class RevCylindricVolume} and {\class SetOfElems}. This
264algorithm takes into account 2 main parameters : {\var nbsubdiv} and {\var order}. The first one controls
265the number of subdivisions to be done (mesh refinement), and the second one is the polynomial order of
266approximation of the geometry, which can take any (positive integer) value.
267\par\smallskip
268To use subdivision algorithm, dedicated constructors for the geometries are available:
269\par\medskip
270\begin{lstlisting}[deletekeywords={[3] x, y, z, edgeLen, type}]
271Cube(Real x, Real y, Real z, Real edgeLen = 1., int nboctants=1, number_t nbsubdiv=0);
272Cube(const Point& p1, const Point& p2, const Point& p3, const Point& p4, int nboctants, number_t nbsubdiv);
273Cube(Real x, Real y, Real z, Real edgeLen, Real theta1, Dimen axis1, int nboctants=1, number_t nbsubdiv=0);
274Cube(Real x, Real y, Real z, Real edgeLen, Real theta1, Dimen axis1, Real theta2, Dimen axis2, int nboctants=1, number_t nbsubdiv=0);
275Cube(Real x, Real y, Real z, Real edgeLen, Real theta1, Dimen axis1, Real theta2, Dimen axis2, Real theta3, Dimen axis3, int nboctants=1, number_t nbsubdiv=0);
276Ball(Real x, Real y, Real z, Real radius = 1., int nboctants=8, number_t nbsubdiv=0, number_t type=1);
277Ball(Real x, Real y, Real z, Real radius, Real theta1, Dimen axis1, int nboctants=8, number_t nbsubdiv=0, number_t type=1);
278Ball(Real x, Real y, Real z, Real radius, Real theta1, Dimen axis1, Real theta2, Dimen axis2, int nboctants=8, number_t nbsubdiv=0, number_t type=1);
279Ball(Real x, Real y, Real z, Real radius, Real theta1, Dimen axis1, Real theta2, Dimen axis2, Real theta3, Dimen axis3, int nboctants=8, number_t nbsubdiv=0, number_t type=1);
280RevCylindricVolume(Point p1, Point p2, Real radius, int nbslices=0, number_t nbsubdiv=0, number_t type=1, CylinderEndShape endShape1=_cesFlat, CylinderEndShape endShape2=_cesFlat, Real distance1=0., Real distance2=0.);
281SetOfElems(const std::vector<Point>& pts, const std::vector<std::vector<number_t> >& tri, const std::vector<std::vector<number_t> >& bound, const number_t nbsubdiv=1);
282\end{lstlisting}
283\par\medskip
284The parameter {\tt nboctants} determines which part of the geometry is to be meshed ; it is clarified in the
285following figures :
286
287\begin{figure}[H]
288 \begin{center}
289  \includePict[scale=0.9]{P1VolMeshTetSphere1.pdf}
290  \includePict[scale=0.9]{P1VolMeshTetSphere2.pdf}
291  \includePict[scale=0.9]{P1VolMeshTetSphere3.pdf}
292  \includePict[scale=0.9]{P1VolMeshTetSphere4.pdf}
293 \end{center}
294 \begin{center}
295  \includePict[scale=0.9]{P1VolMeshTetSphere5.pdf}
296  \includePict[scale=0.9]{P1VolMeshTetSphere6.pdf}
297  \includePict[scale=0.9]{P1VolMeshTetSphere7.pdf}
298  \includePict[scale=0.9]{P1VolMeshTetSphere8.pdf}
299 \end{center}
300 \caption{Meshes of the different portions of the sphere according to the number of octants.}
301 \label{sphere_meshes}
302\end{figure}
303
304\begin{figure}[H]
305 \begin{center}
306  \includePict[scale=0.8]{P1VolMeshHexCube1.pdf}
307  \includePict[scale=0.8]{P1VolMeshHexCube2.pdf}
308  \includePict[scale=0.8]{P1VolMeshHexCube3.pdf}
309  \includePict[scale=0.8]{P1VolMeshHexCube4.pdf}
310 \end{center}
311 \begin{center}
312  \includePict[scale=0.8]{P1VolMeshHexCube5.pdf}
313  \includePict[scale=0.8]{P1VolMeshHexCube6.pdf}
314  \includePict[scale=0.8]{P1VolMeshHexCube7.pdf}
315  \includePict[scale=0.8]{P1VolMeshHexCube8.pdf}
316 \end{center}
317 \caption{Meshes of the different portions of the cube according to the number of octants.}
318 \label{cube_meshes}
319\end{figure}
320
321
322In this way, you call the following underlying methods :
323
324\begin{lstlisting}[deletekeywords={[3] name, type, order, shape, bounds}]
325void subdvMesh(Ball& sph, const ShapeType shape, const int nboctants, const number_t nbsubdiv=0, const number_t order=1, const number_t type=1, const string_t& name = "", const string_t& TeXFilename = "");
326void subdvMesh(Cube& cub, const ShapeType shape, const int nboctants, const number_t nbsubdiv=0, const number_t order=1, const string_t& name = "", const string_t& TeXFilename = "");
327void subdvMesh(RevTrunk& cyl, const ShapeType shape, const number_t nbSubDomains=1, const number_t nbsubdiv=0, const number_t order=1, const number_t type=1, const string_t& name = "", const string_t& TeXFilename = "");
328void subdvMesh(Disk& carc, const ShapeType shape, const number_t nbsubdiv, const number_t order, const number_t type, const string_t& name, const string_t& TeXFilename);
329void subdvMesh(const std::vector<Point>& pts, const std::vector<std::vector<number_t> >& elems, const std::vector<std::vector<number_t> >& bounds, const ShapeType shape, const number_t nbsubdiv=0, const number_t order=1, const string_t& name = "", const string_t& TeXFilename = "");
330\end{lstlisting}
331
332\subsubsection{Meshes with nested calls to \gmsh}
333
334This generator enables to mesh whatever geometry, canonical, "composite" or "loop". To use it, you need \gmsh installed on your computer before \xlifepp is installed, in order to be detected. You can define meshes as if it was \gmsh directly, so that finite elements up to order 5 are allowed here.
335
336In this way, you call the underlying external functions :
337
338\begin{lstlisting}[deletekeywords={[3] order}]
339void Mesh::saveToGeo(Geometry& g, number_t order, const string_t& filename);
340void Mesh::saveToGeo(Geometry& g, ShapeType sh, number_t order, const string_t& filename);
341void saveSegmentToGeo(Segment& s, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
342void saveEllArcToGeo(EllArc& a, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
343void saveCircArcToGeo(CircArc& a, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
344void savePolygonToGeo(Polygon& p, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
345void saveTriangleToGeo(Triangle& t, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
346void saveQuadrangleToGeo(Quadrangle& q, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
347void saveEllipseToGeo(Ellipse& e, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
348void savePolyhedronToGeo(Polyhedron& p, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
349void saveTetrahedronToGeo(Tetrahedron& t, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
350void saveHexahedronToGeo(Hexahedron& h, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
351void saveEllipsoidToGeo(Ellipsoid& e, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
352void saveTrunkToGeo(Trunk& t, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
353void saveCylinderToGeo(Cylinder& c, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
354void saveConeToGeo(Cone& c, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
355void saveRevTrunkToGeo(RevTrunk& t, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
356void saveRevCylinderToGeo(RevCylinder& c, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
357void saveRevConeToGeo(RevCone& c, ShapeType sh, std::ofstream& fout, std::vector<PhysicalData>& pids, bool withLoopsStorage = true, bool withSideNames = true);
358\end{lstlisting}
359\subsubsection{Meshes from extrusion}
360The extrusion constructor can extrude any 1D or 2D mesh in the $\vec{OD}$ direction using $nbl$ layers of same width (regular extrusion). More precisely, any point $M$ of the section mesh is extruded in $nbl$ points :
361$$M_k=M + O +k*\vec{OD}.$$
362When a 1D section, extruded mesh is made with quadrangles. When a 2D triangular mesh section, extruded mesh is made with prisms and  when a 2D quadrangular mesh section, extruded mesh is made with hexahedra.
363
364\begin{lstlisting}[deletekeywords={[3] order}]
365Mesh(const Mesh& ms, const Point& O, const Point& D , number_t nbl,
366     number_t namingDomain=0, number_t namingSection=0, number_t namingSide=0,
367     const string_t& meshName=""); //constructor
368void buildExtrusion(const Mesh& ms, const Point& O, const Point& D,
369    number_t nbl, number_t namingDomain, number_t namingSection,
370    number_t namingSide, const string_t& meshName); //effective
371\end{lstlisting}
372
373The boundary domains created by the extrusion process come from the boundary domains of the original section. This process is controlled by the 3 parameters {\var namingDomain}, {\var namingSection}, {\var namingSide} taking one of of the values 0, 1 or 2, with the following rules:\\
374\mbox{}\hspace{0.2cm}$\bullet$ 0 : domains are not created \\
375\mbox{}\hspace{0.2cm}$\bullet$ 1 : one extruded domain is created for any domain of the original section \\
376\mbox{}\hspace{0.2cm}$\bullet$ 2 : for each layer, one extruded domain is created for any domain of the original section \\
377\\
378Be cautious, the side domains of extruded domain are created from side domains of the given section. Thus, if the given section has no side domains, the extruded domains will have no side domains! The naming convention is the following:\\
379\mbox{}\hspace{0.2cm}$\bullet$ Domains and side domains keep their name with the extension "\_e"  or "\_e1", "\_e2", ..., "\_en" \\
380\mbox{}\hspace{0.2cm}$\bullet$ Section domains have the name of original domains with the extension "\_0",...,"\_n"  \\
381\mbox{}\hspace{0.2cm}$\bullet$ When {\var namingDomain=0}, the full domain is always created and named "Omega".\\
382
383The figure \ref{mesh_extrusion} illustrates the naming rules of domains.
384\begin{figure}[H]
385\begin{center}
386\includePict[scale=0.8]{mesh_extrusion.png}
387\end{center}
388\caption{Mesh extrusion, domains naming}
389\label{mesh_extrusion}
390\end{figure}
391Note that the {\var  meshPr1Parallelepiped} function uses this extrusion process.
392
393\subsubsection{Meshes from element splitting}
394Sometimes it may be useful to split elements into elements of an other type, for instance to produce mesh of pyramids that are not provided by standard meshing softwares.To do this, a general constructor is offered :
395\begin{lstlisting}[deletekeywords={[3] order}]
396Mesh(const Mesh& mesh, ShapeType sh, const string_t name="");
397\end{lstlisting}
398that calls the effective functions that processes the splitting.\\
399
400Up to now, only one splitting function is available:
401\begin{lstlisting}[deletekeywords={[3] order}]
402void buildPyramidFromHexadron(const Mesh& hexMesh,const string_t& meshName="");
403\end{lstlisting}
404that produces a pyramid mesh from an hexahedron mesh.\\
405
406Note that the {\var  meshPy1Parallelepiped} function uses this splitting function.
407
408
409\displayInfos{library=geometry, header=Mesh.hpp, implementation={Mesh.cpp, subdivision/SubdvMesh.cpp}, test=test\_Mesh.cpp,
410header dep={config.h, utils.h, GeomElement.hpp, Domain.hpp, Geometry.hpp}}
411
412