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