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 /*!
18   \file SubdivisionMesh.hpp
19   \author Y. Lafranche
20   \since 22 May 2008
21   \date 08 Mar 2014
22 
23   \brief Definition of the xlifepp::subdivision::SubdivisionMesh class
24 
25   This class is an abstract base class used as a frame for different
26   kind of meshes consisting of the same geometric figures, such as triangles and
27   tetrahedrons. These meshes are built by a subdivision process, starting from
28   an initial configuration of elements.
29 
30   inheriting classes
31   ------------------
32     - xlifepp::subdivision::GeomFigureMesh
33 */
34 
35 #ifndef SUBDIVISION_MESH_HPP
36 #define SUBDIVISION_MESH_HPP
37 
38 #include "Vertex.hpp"
39 #include "types.hpp"
40 #include "GeomFigure.hpp"
41 
42 #include <iostream>
43 #include <map>
44 #include <vector>
45 
46 namespace xlifepp {
47 namespace subdivision {
48 
49 /*!
50    \class SubdivisionMesh
51 */
52 class SubdivisionMesh
53 {
54 public:
55 //-------------------------------------------------------------------------------
56 //  Constructors, Destructor
57 //-------------------------------------------------------------------------------
58    //! main constructor
59    SubdivisionMesh(const number_t nbsubdiv, const number_t order, const number_t type,
60                    const number_t minVertexNum, const number_t minElementNum);
61 
62    //! destructor
63    virtual ~SubdivisionMesh();
64 //-------------------------------------------------------------------------------
65 //  Public Access functions
66 //-------------------------------------------------------------------------------
67    //! returns the description of boundary num, num >=1
boundaryDescription(const number_t num) const68    std::string boundaryDescription(const number_t num) const { return TG_.descriptionOf(boundaryArea,num); }
69 
70    //! returns the description of interface num, num >=1
interfaceDescription(const number_t num) const71    std::string interfaceDescription(const number_t num) const { return TG_.descriptionOf(interfaceArea,num); }
72 
73    //! returns the description of subdomain num, num >=1
subdomainDescription(const number_t num) const74    std::string subdomainDescription(const number_t num) const { return TG_.descriptionOf(subdomainArea,num); }
75 
76 
77    //! returns the name of boundary num, num >=1
boundaryName(const number_t num) const78    std::string boundaryName(const number_t num) const { return TG_.nameOf(boundaryArea,num); }
79 
80    //! returns the name of interface num, num >=1
interfaceName(const number_t num) const81    std::string interfaceName(const number_t num) const { return TG_.nameOf(interfaceArea,num); }
82 
83    //! returns the name of subdomain num, num >=1
subdomainName(const number_t num) const84    std::string subdomainName(const number_t num) const { return TG_.nameOf(subdomainArea,num); }
85 
86    /*!
87      returns the list of all the vertices of element num,
88      each given by its number, with num such that
89      minElementNum_ <= num <= numberOfElements+minElementNum_-1
90     */
91    virtual std::vector<number_t> element(const number_t num) const = 0;
92 
93    /*!
94      returns a normal vector to the face number i >= 1 of element num,
95      with num such that minElementNum_ <= num <= numberOfElements+minElementNum_-1
96      The vector is not normalized and is oriented towards the exterior of the element.
97     */
98    virtual std::vector<real_t> faceExtNormalVec(const number_t num, const number_t i) const = 0;
99 
100    /*!
101      returns the orientation of the face number i >= 1 of element num, with num such that
102      minElementNum_ <= num <= numberOfElements+minElementNum_-1. The function:
103       - returns 1 if the first three vertices (i,j,k) of the face define a vector ij x ik
104         oriented towards the exterior of the element,
105       - returns -1 otherwise.
106     */
107    virtual int faceOrientation(const number_t num, const number_t i) const = 0;
108 
109    //! returns the number of boundaries of the mesh
numberOfBoundaries() const110    number_t numberOfBoundaries() const { return TG_.numberOf(boundaryArea); }
111 
112    //! returns the number of interfaces of the mesh
numberOfInterfaces() const113    number_t numberOfInterfaces() const { return TG_.numberOf(interfaceArea); }
114 
115    //! returns the number of subdomains of the mesh
numberOfSubdomains() const116    number_t numberOfSubdomains() const { return TG_.numberOf(subdomainArea); }
117 
118    //! number of boundary patches
numberOfBndryPatches() const119    number_t numberOfBndryPatches() const {return TG_.numberOfBndryPatches(); }
120    //! number of interface patches
numberOfIntrfPatches() const121    number_t numberOfIntrfPatches() const {return TG_.numberOfIntrfPatches(); }
122    //! number of subdomain patches
numberOfSbDomPatches() const123    number_t numberOfSbDomPatches() const {return TG_.numberOfSbDomPatches(); }
124 
125    //! returns the number of elements in the mesh
126    virtual number_t numberOfElements() const = 0;
127 
128    //! returns the total number of vertices in the mesh
numberOfVertices() const129    number_t numberOfVertices() const { return listV_.size(); }
130 
131    /*!
132      returns the number of vertices of order 1 in the mesh
133      (equals numberOfVertices() if order=1)
134     */
numberOfMainVertices() const135    number_t numberOfMainVertices() const { return nb_main_vertices_; }
136 
137    //! returns the number of vertices of order 1 per element
138    number_t numberOfMainVerticesByElement() const;
139 
140    /*!
141      returns the smallest number associated to an element
142      among all the elements in the mesh
143     */
minElementNumber() const144    number_t minElementNumber() const { return minElementNum_; }
145 
146    /*!
147      returns the smallest number associated to a vertex among
148      all the vertices in the mesh
149     */
minVertexNumber() const150    number_t minVertexNumber() const { return minVertexNum_; }
151 
152    //! returns the total number of vertices of each element
153    virtual number_t numberOfVerticesByElement() const = 0;
154 
155    //! returns the title of the mesh
title() const156    std::string title() const { return title_; }
157 
158    //! returns the order of the mesh
order() const159    number_t order() const { return order_; }
160 
161    //! returns the coordinates of a vertex, given its number num, num >= minVertexNum_
162    std::vector<real_t> vertexCoord(const number_t num) const ;
163 
164    //! returns the coordinates of a vertex, given its rank rk>=0 in the global list of vertices
165    std::vector<real_t> rkvertexCoord(const number_t rk) const ;
166 
167    std::vector<Point> unifMesh(const std::vector< std::vector<number_t> >& genmesh,
168                                const std::vector<std::pair<short,short> >& rkEV,
169                                const std::vector<number_t>& rkUnk, const std::vector<number_t>& rkData);
170 
171 //-------------------------------------------------------------------------------
172 //  I/O utilities
173 //-------------------------------------------------------------------------------
174    //! prints, on stream os, the general informations about the mesh
175    void printInfo(std::ostream& os, const bool forTeX=false) const ;
printInfo(PrintStream & os,const bool forTeX=false) const176    void printInfo(PrintStream& os, const bool forTeX=false) const {printInfo(os.currentStream());}
177 
178    //! prints, on stream os, the mesh with vertices coordinates
179    virtual void printall(std::ostream& os) const = 0;
180    virtual void printall(PrintStream& os) const = 0;
181 
182 
183    //! prints, on stream os, the mesh with vertices numbers
184    virtual void print(std::ostream& os) const = 0;
185    virtual void print(PrintStream& os) const = 0;
186 
187    /*!
188      prints, on stream ftex, fig4tex instructions to draw a mesh with
189      observation direction defined by longitude psi and latitude theta
190     */
191    virtual void printTeX(std::ostream& ftex, const float psi=-30, const float theta=25,
192                          const number_t nbviews=1, const std::string& DimProj="4cm,orthogonal",
193                          const bool withInterface=true, const bool withElems=false) const = 0;
194    virtual void printTeX(PrintStream& ftex, const float psi=-30, const float theta=25,
195                          const number_t nbviews=1, const std::string& DimProj="4cm,orthogonal",
196                          const bool withInterface=true, const bool withElems=false) const = 0;
197 
198 //-------------------------------------------------------------------------------
199 //  Other public member functions
200 //-------------------------------------------------------------------------------
201    /*!
202      initializes the user attribute of the geometrical areas of the mesh,
203      boundaries, interfaces and subdomains, given in this order
204     */
205    void initUserAttribute(const std::vector<std::string>& attribute);
206 
207    //! returns the number of the internal vertices of any order in the mesh
208    number_t numberOfVerticesInside() const ;
209 
210    /*!
211      returns the number of vertices of any order in the mesh, belonging to
212      an area of kind TA or belonging to any area of kind TA if num=0
213     */
214    number_t numberOfVerticesIn(const topologicalArea TA, const number_t num = 0) const ;
215 
216    //! redefines boundaries
setBoundaries(const std::vector<std::vector<number_t>> & group)217    bool setBoundaries(const std::vector< std::vector<number_t> >& group) {
218                                          return TG_.setBoundaries(group); }
219    //! redefines subdomains
setSubdomains(const std::vector<std::vector<number_t>> & group)220    bool setSubdomains(const std::vector< std::vector<number_t> >& group) {
221                                          return TG_.setSubdomains(group); }
222    /*!
223      returns the list of the internal vertices of any order in the mesh
224      (given by their number)
225     */
226    std::vector<number_t> verticesInside() const ;
227 
228    /*!
229      returns the list of vertices of any order in the mesh, belonging to an area
230      of kind TA or belonging to any area of kind TA if num=0 (given by their number)
231     */
232    std::vector<number_t> verticesIn(const topologicalArea TA, const number_t num = 0) const ;
233 
234    //! returns the list of vertices of order 1 in the mesh (given by their number)
235    std::vector<number_t> verticesOfOrder1() const ;
236 
237 protected:
238    //! short description of the mesh
239    std::string title_;
240    //! subdivision level (0 = no subdivision)
241    number_t subdiv_level_;
242    //! order of the tetrahedra in the final mesh (order > 0)
243    number_t order_;
244    //! type of the subdivision (flat or taking into account an underlying surface)
245    number_t type_;
246    //! number of main vertices in the final mesh, i.e. number of vertices of order 1
247    number_t nb_main_vertices_;
248    //! smallest vertex number
249    number_t minVertexNum_;
250    //! smallest element number
251    number_t minElementNum_;
252    //! definition of the topological and geometrical informations
253    TopoGeom TG_;
254    /*!
255      list of all the vertices in the final mesh
256      the number assigned to the vertex listV_[k] is equal to k+1
257     */
258    std::vector<Vertex> listV_;
259    //! pointer to function that computes a point associated to a new vertex
260    PtCompFun newVertexPt_;
261    //! Exception handling
262 //   static HOV_error PB;
263 
264 //-------------------------------------------------------------------------------
265 //  Protected member functions
266 //-------------------------------------------------------------------------------
267    //! detects or creates a new vertex starting from a list of vertices and returns vertex rank
268    number_t createVertex(number_t& VertexNum, const std::vector<number_t>& rkVert);
269 
270    //! detects or creates a new vertex starting from the two endpoints of an edge and returns vertex rank
271    number_t createVertex(number_t& VertexNum, const pair_nn Edge, map_pair_num& SeenEdges);
272 
273    //! detects or creates a new vertex starting from the vertices of a face and returns vertex rank
274    number_t createVertex(number_t& VertexNum, const std::vector<number_t>& rkVFace, map_set_num& SeenFaces);
275 
276 
277    //--- Utilitary functions
278 
279    /*!
280      returns reference number (localization code) of an area
281      or of all the areas of kind TA if num=0
282     */
283    refnum_t lCodeOf(const topologicalArea TA, const number_t num) const ;
284 
285    //! get color associated to the area num, num>=1, of kind TA
286    std::string colorOf(const topologicalArea TA, const number_t num) const ;
287 
288    /*!
289      initializes the user attribute of the geometrical areas of the mesh,
290      boundaries, interfaces and subdomains, given in this order, by a color.
291     */
292    void initDefaultUserAttribute(void);
293 
294    //! rotate and translate points
295    void rotNtrans(const std::vector<std::pair<real_t, dimen_t> >& rots, const Vect& U, std::vector<Point>& Pt);
296 
297    //! create the boundary shapes to be used at both ends of a truncated cone
298    std::vector<PatchGeometry *> endBoundaryShapes(const std::vector<ShapeInfo>& vSI,
299                                                   const SurfCone& SC);
300 
301    //! Defines a set of points used to build the initial mesh in a cube.
302    std::vector<Point> cubePoints(const real_t edLen, const std::vector<std::pair<real_t, dimen_t> >& rots, const Point& Center);
303 
304   //!  Start mesh building process for revolution objects.
305 
306    void initRevMesh(const number_t nbslices, const real_t radius1, const real_t radius2,
307                     const std::vector<Point>& CharacPts, const std::vector<ShapeInfo>& vSI,
308                     real_t& R1, real_t& R2, Point& P1, Point& P2, std::vector<ShapeInfo>& cvSI,
309                     std::string& bottomPt, std::string& topPt, bool& iscone, std::string& shape,
310                     DefaultGeometry *& DG, SurfPlane *& SP, SurfCone *& SC,
311                     std::vector <PatchGeometry *>& EBS, int& nb_sl, real_t& slice_height);
312 
313    //--- Fig4TeX printing functions
314 
315    /*!
316      prints, on stream ftex, fig4tex instructions to define vertices (action = 0)
317      or to display vertices (action = 1) of any order in a mesh.
318      The vertices belong to an area of kind TA, or to any area of kind TA if num=0.
319     */
320    void printTeXInArea(std::ostream& ftex, const number_t action,
321                        const topologicalArea TA = boundaryArea, const number_t num = 0) const ;
322 
323    //! prints, on stream ftex, fig4tex instructions to define vertices of V
324    void printTeXfigpt(std::ostream& ftex, const std::vector<number_t>& V) const ;
325 
326    //! prints, on stream ftex, fig4tex instructions to display vertices of V
327    void printTeXfigwrite(std::ostream& ftex, const std::vector<number_t>& V) const ;
328 
329    /*!
330      prints, on stream ftex, Fig4TeX instructions to draw faces of a mesh
331      belonging to an area ok kind TA
332     */
333    void printTeXFacesInArea(std::ostream& ftex, const topologicalArea TA, const number_t num) const ;
334 
335    //--- Low level utilitary functions
336 
337    //! replace the rank in the internal list by the vertex number
338    void rankToNum(std::vector<number_t>& V) const ;
339 
340    //! replace the rank in the internal list by the vertex number
341    void rankToNum(pair_nn& V) const ;
342 
343    /*!
344      returns the list of the internal vertices of any order in the mesh
345      (given by their rank)
346     */
347    std::vector<number_t> rk_verticesInside() const ;
348 
349    /*!
350      returns the list of vertices of any order in the mesh, belonging to an area of kind TA
351      or belonging to any area of kind TA if num=0 (given by their rank)
352     */
353    std::vector<number_t> rk_verticesIn(const topologicalArea TA, const number_t num = 0) const ;
354 
355    /*!
356      returns the list of faces of the mesh belonging to an area of kind TA
357      or belonging to any area of kind TA if num=0 (given by their rank)
358     */
359    virtual std::vector< std::vector<number_t> > rk_facesIn(const topologicalArea TA, const number_t num = 0) const = 0;
360 
361    //--- For high order vertices generation
362 
363    /*!
364      comparison of two vectors (used in createHOfV)
365      (this function could be external and defined before its use in the .cpp file)
366     */
367    static bool cmpvect(const std::vector<number_t>& U, const std::vector<number_t>& V);
368 
369 //-------------------------------------------------------------------------------
370 //  Private member functions
371 //-------------------------------------------------------------------------------
372 private:
373    //! default function that computes the geometrical point associated to a new vertex
374    Point newVertexPtDef(const refnum_t localcod, const real_t *coef, const std::vector<Point>& VP) const;
375    //! general function that computes the geometrical point associated to a new vertex
376    Point newVertexPtGen(const refnum_t localcod, const real_t *coef, const std::vector<Point>& VP) const;
377 
378    //! initialization of attributes of areas of kind TA
379    void initAttribute_(const topologicalArea TA, const std::vector<std::string>& attribute, size_t& k);
380 
381 }; // end of Class SubdivisionMesh
382 
383 } // end of namespace subdivision
384 } // end of namespace xlifepp
385 #endif /* SUBDIVISION_MESH_HPP */
386