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 MTRIHEDRON_H
7 #define MTRIHEDRON_H
8 
9 #include "MElement.h"
10 
11 /*
12  * MTrihedron
13  * A MTrihedron is a plane element composed of
14  * a quadrangle and two triangles.
15  * It serves as an interface between two non-conforming
16  * elements
17  *
18  *         v
19  *         ^
20  *         |
21  *   3-----------2
22  *   |'\   |     |
23  *   |  '\ |     |
24  *   |     +---- | --> u
25  *   |      '\   |
26  *   |        '\ |
27  *   0-----------1
28  *
29  */
30 
31 class MTrihedron : public MElement {
32 protected:
33   MVertex *_v[4];
_getEdgeVertices(const int num,std::vector<MVertex * > & v)34   void _getEdgeVertices(const int num, std::vector<MVertex *> &v) const
35   {
36     v[0] = _v[edges_trihedron(num, 0)];
37     v[1] = _v[edges_trihedron(num, 1)];
38   }
_getFaceVertices(const int num,std::vector<MVertex * > & v)39   void _getFaceVertices(const int num, std::vector<MVertex *> &v) const
40   {
41     if(num > 0) {
42       v[0] = _v[faces_trihedron(num, 0)];
43       v[1] = _v[faces_trihedron(num, 1)];
44       v[2] = _v[faces_trihedron(num, 2)];
45     }
46     else {
47       v[0] = _v[0];
48       v[1] = _v[1];
49       v[2] = _v[2];
50       v[3] = _v[3];
51     }
52   }
53 
54 public:
55   MTrihedron(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3, int num = 0,
56              int part = 0)
MElement(num,part)57     : MElement(num, part)
58   {
59     _v[0] = v0;
60     _v[1] = v1;
61     _v[2] = v2;
62     _v[3] = v3;
63   }
64   MTrihedron(const std::vector<MVertex *> &v, int num = 0, int part = 0)
MElement(num,part)65     : MElement(num, part)
66   {
67     for(int i = 0; i < 4; i++) _v[i] = v[i];
68   }
~MTrihedron()69   ~MTrihedron() {}
getDim()70   virtual int getDim() const { return 3; } // Can have a volume...
getNumVertices()71   virtual std::size_t getNumVertices() const { return 4; }
getVertex(int num)72   virtual MVertex *getVertex(int num) { return _v[num]; }
getVertex(int num)73   virtual const MVertex *getVertex(int num) const { return _v[num]; }
setVertex(int num,MVertex * v)74   virtual void setVertex(int num, MVertex *v) { _v[num] = v; }
getNumEdges()75   virtual int getNumEdges() const { return 5; }
getEdge(int num)76   virtual MEdge getEdge(int num) const
77   {
78     return MEdge(_v[edges_trihedron(num, 0)], _v[edges_trihedron(num, 1)]);
79   }
getNumEdgesRep(bool curved)80   virtual int getNumEdgesRep(bool curved) { return 5; }
getEdgeRep(bool curved,int num,double * x,double * y,double * z,SVector3 * n)81   virtual void getEdgeRep(bool curved, int num, double *x, double *y, double *z,
82                           SVector3 *n)
83   {
84     MEdge e(getEdge(num));
85     _getEdgeRep(e.getVertex(0), e.getVertex(1), x, y, z, n, 0);
86   }
getEdgeVertices(const int num,std::vector<MVertex * > & v)87   virtual void getEdgeVertices(const int num, std::vector<MVertex *> &v) const
88   {
89     v.resize(2);
90     _getEdgeVertices(num, v);
91   }
getNumFaces()92   virtual int getNumFaces() { return 3; }
getFace(int num)93   virtual MFace getFace(int num) const
94   {
95     if(num > 0)
96       return MFace(_v[faces_trihedron(num, 0)], _v[faces_trihedron(num, 1)],
97                    _v[faces_trihedron(num, 2)]);
98     else
99       return MFace(_v[0], _v[1], _v[2], _v[3]);
100   }
101 
getNumFacesRep(bool curved)102   virtual int getNumFacesRep(bool curved) { return 2; }
getFaceRep(bool curved,int num,double * x,double * y,double * z,SVector3 * n)103   virtual void getFaceRep(bool curved, int num, double *x, double *y, double *z,
104                           SVector3 *n)
105   {
106     static const int f[2][3] = {{0, 1, 3}, {1, 2, 3}};
107     _getFaceRep(getVertex(f[num][0]), getVertex(f[num][1]),
108                 getVertex(f[num][2]), x, y, z, n);
109   }
getFaceVertices(const int num,std::vector<MVertex * > & v)110   virtual void getFaceVertices(const int num, std::vector<MVertex *> &v) const
111   {
112     v.resize((num == 0) ? 4 : 3);
113     _getFaceVertices(num, v);
114   }
getType()115   virtual int getType() const { return TYPE_TRIH; }
getTypeForMSH()116   virtual int getTypeForMSH() const { return MSH_TRIH_4; }
117 
reverse()118   virtual void reverse()
119   {
120     MVertex *tmp = _v[1];
121     _v[1] = _v[3];
122     _v[3] = tmp;
123   }
getVolumeSign()124   virtual int getVolumeSign() { return 0; };
getVolume()125   virtual double getVolume() { return 0; };
setVolumePositive()126   virtual bool setVolumePositive() { return false; };
getNode(int num,double & u,double & v,double & w)127   virtual void getNode(int num, double &u, double &v, double &w) const
128   {
129     w = 0;
130     switch(num) {
131     case 0:
132       u = -1.;
133       v = -1.;
134       break;
135     case 1:
136       u = 1.;
137       v = -1.;
138       break;
139     case 2:
140       u = 1.;
141       v = 1.;
142       break;
143     case 3:
144       u = -1.;
145       v = 1.;
146       break;
147     default:
148       u = 0.;
149       v = 0.;
150       break;
151     }
152   }
barycenterUVW()153   virtual SPoint3 barycenterUVW() const { return SPoint3(0., 0., 0.); }
isInside(double u,double v,double w)154   virtual bool isInside(double u, double v, double w) const
155   {
156     double tol = getTolerance();
157     if(u < -(1. + tol) || v < -(1. + tol) || u > (1. + tol) || v > (1. + tol) ||
158        fabs(w) > tol)
159       return false;
160     return true;
161   }
edges_trihedron(const int edge,const int vert)162   static int edges_trihedron(const int edge, const int vert)
163   {
164     static const int e[5][2] = {
165       {0, 1}, {1, 2}, {2, 3}, {3, 0}, {1, 3},
166     };
167     return e[edge][vert];
168   }
faces_trihedron(const int face,const int vert)169   static int faces_trihedron(const int face, const int vert)
170   {
171     static const int f[3][4] = {
172       {0, 1, 2, 3},
173       {0, 3, 1, -1},
174       {1, 3, 2, -1},
175     };
176     return f[face][vert];
177   }
178 
179   // Return the number of nodes that this element must have with the other in
180   // order to put an edge between them in the dual graph used during the
181   // partitioning.
182   virtual int numCommonNodesInDualGraph(const MElement *const other) const;
183 };
184 
185 #endif
186