1 // Gmsh - Copyright (C) 1997-2021 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #ifndef GREGION_H
7 #define GREGION_H
8 
9 #include <list>
10 #include <string>
11 #include <vector>
12 #include <stdio.h>
13 #include "GmshDefines.h"
14 #include "GEntity.h"
15 #include "boundaryLayersData.h"
16 
17 class MElement;
18 class MTetrahedron;
19 class MHexahedron;
20 class MPrism;
21 class MPyramid;
22 class MPolyhedron;
23 class MTrihedron;
24 class ExtrudeParams;
25 class BoundaryLayerColumns;
26 
27 // A model region.
28 class GRegion : public GEntity {
29 protected:
30   std::vector<GFace *> l_faces;
31   std::vector<GVertex *> embedded_vertices;
32   std::vector<GFace *> embedded_faces;
33   std::vector<GEdge *> embedded_edges;
34   std::vector<int> l_dirs;
35   BoundaryLayerColumns _columns;
36 
37 public:
38   GRegion(GModel *model, int tag);
39   virtual ~GRegion();
40 
41   // delete mesh data
42   virtual void deleteMesh();
43 
44   // get the dimension of the region (3)
dim()45   virtual int dim() const { return 3; }
46 
47   // returns the parent entity for partitioned entities
getParentEntity()48   virtual GEntity *getParentEntity() { return nullptr; }
49 
50   // set the visibility flag
51   virtual void setVisibility(char val, bool recursive = false);
52 
53   // set color
54   virtual void setColor(unsigned int val, bool recursive = false);
55 
56   // add embedded vertices/edges/faces
addEmbeddedVertex(GVertex * v)57   void addEmbeddedVertex(GVertex *v) { embedded_vertices.push_back(v); }
addEmbeddedEdge(GEdge * e)58   void addEmbeddedEdge(GEdge *e) { embedded_edges.push_back(e); }
addEmbeddedFace(GFace * f)59   void addEmbeddedFace(GFace *f) { embedded_faces.push_back(f); }
60 
61   // get/set faces that bound the region
62   int delFace(GFace *face);
63 
faces()64   virtual std::vector<GFace *> faces() const { return l_faces; }
65 
faceOrientations()66   virtual std::vector<int> faceOrientations() const { return l_dirs; }
set(std::vector<GFace * > const & f)67   void set(std::vector<GFace *> const &f) { l_faces = f; }
setOrientations(const std::vector<int> & f)68   void setOrientations(const std::vector<int> &f) { l_dirs = f; }
setFace(GFace * const f,int const orientation)69   void setFace(GFace *const f, int const orientation)
70   {
71     l_faces.push_back(f);
72     l_dirs.push_back(orientation);
73   }
74   void setBoundFaces(const std::set<int> &tagFaces);
75   void setBoundFaces(const std::vector<int> &tagFaces,
76                      const std::vector<int> &signFaces);
77 
78   // direct access to embedded entities
embeddedVertices()79   std::vector<GVertex *> &embeddedVertices() { return embedded_vertices; }
embeddedEdges()80   std::vector<GEdge *> &embeddedEdges() { return embedded_edges; }
embeddedFaces()81   std::vector<GFace *> &embeddedFaces() { return embedded_faces; }
82   std::vector<MVertex *> getEmbeddedMeshVertices() const;
83 
84   // edges that bound the region
85   virtual std::vector<GEdge *> const &edges() const;
86 
87   // vertices that bound the region
88   virtual std::vector<GVertex *> vertices() const;
89 
90   // get the bounding box
91   virtual SBoundingBox3d bounds(bool fast = false);
92 
93   // get the oriented bounding box
94   virtual SOrientedBoundingBox getOBB();
95 
96   // check if the region is connected to another region by an edge
97   bool edgeConnected(GRegion *r) const;
98 
99   // compute volume, moment of intertia and center of gravity
100   double computeSolidProperties(std::vector<double> cg,
101                                 std::vector<double> inertia);
102 
103   // return a type-specific additional information string
104   virtual std::string getAdditionalInfoString(bool multline = false);
105 
106   // export in GEO format
107   virtual void writeGEO(FILE *fp);
108 
109   // types of elements
getElementTypes(std::vector<int> & types)110   virtual void getElementTypes(std::vector<int> &types) const
111   {
112     types.clear();
113     types.push_back(TYPE_TET);
114     types.push_back(TYPE_PYR);
115     types.push_back(TYPE_PRI);
116     types.push_back(TYPE_HEX);
117     types.push_back(TYPE_TRIH);
118     types.push_back(TYPE_POLYH);
119   };
120 
121   // get total/by-type number of elements in the mesh
122   std::size_t getNumMeshElements() const;
123   std::size_t getNumMeshElementsByType(const int familyType) const;
124   std::size_t getNumMeshParentElements();
125   void getNumMeshElements(unsigned *const c) const;
126 
127   // get the start of the array of a type of element
128   MElement *const *getStartElementType(int type) const;
129 
130   // get the element at the given index
131   MElement *getMeshElement(std::size_t index) const;
132   // get the element at the given index for a given familyType
133   MElement *getMeshElementByType(const int familyType,
134                                  const std::size_t index) const;
135 
136   // reset the mesh attributes to default values
137   virtual void resetMeshAttributes();
138 
139   struct {
140     // do we recombine the tetrahedra of the mesh into hex?
141     int recombine3D;
142     // is this surface meshed using a transfinite interpolation
143     char method;
144     // the extrusion parameters (if any)
145     ExtrudeParams *extrude;
146     // corners of the transfinite interpolation
147     std::vector<GVertex *> corners;
148     // structured/unstructured coupling using pyramids
149     int QuadTri;
150     // global mesh size constraint for the volume
151     double meshSize;
152   } meshAttributes;
153 
getMeshSize()154   virtual double getMeshSize() const { return meshAttributes.meshSize; }
155 
156   // a array for accessing the transfinite vertices using a triplet of
157   // indices
158   std::vector<std::vector<std::vector<MVertex *> > > transfinite_vertices;
159 
160   std::vector<MTetrahedron *> tetrahedra;
161   std::vector<MHexahedron *> hexahedra;
162   std::vector<MPrism *> prisms;
163   std::vector<MPyramid *> pyramids;
164   std::vector<MTrihedron *> trihedra;
165   std::vector<MPolyhedron *> polyhedra;
166 
addTetrahedron(MTetrahedron * t)167   void addTetrahedron(MTetrahedron *t) { tetrahedra.push_back(t); }
addHexahedron(MHexahedron * h)168   void addHexahedron(MHexahedron *h) { hexahedra.push_back(h); }
addPrism(MPrism * p)169   void addPrism(MPrism *p) { prisms.push_back(p); }
addPyramid(MPyramid * p)170   void addPyramid(MPyramid *p) { pyramids.push_back(p); }
addPolyhedron(MPolyhedron * p)171   void addPolyhedron(MPolyhedron *p) { polyhedra.push_back(p); }
addTrihedron(MTrihedron * t)172   void addTrihedron(MTrihedron *t) { trihedra.push_back(t); }
173   void addElement(int type, MElement *e);
174   void removeElement(int type, MElement *e);
175 
176   // get the boundary layer columns
getColumns()177   BoundaryLayerColumns *getColumns() { return &_columns; }
178 
179   virtual bool reorder(const int elementType,
180                        const std::vector<std::size_t> &ordering);
181 
182   // set the reverseMesh constraint in the bounding surfaces so that the
183   // boundary mesh has outward pointing normals, based on the STL triangulation
184   bool setOutwardOrientationMeshConstraint();
185 
186   virtual bool isFullyDiscrete();
187 };
188 
189 #endif
190