Tetrahedron.h 9.5 KB
Newer Older
1
2
3
4
5
6
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
7
// ==  TU Dresden                                                            ==
8
// ==                                                                        ==
9
10
11
// ==  Institut fr Wissenschaftliches Rechnen                               ==
// ==  Zellescher Weg 12-14                                                  ==
// ==  01069 Dresden                                                         ==
12
13
14
15
// ==  germany                                                               ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
16
// ==  https://gforge.zih.tu-dresden.de/projects/amdis/                      ==
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// ==                                                                        ==
// ============================================================================

/** \file Tetrahedron.h */

#ifndef AMDIS_TETRAHEDRON_H
#define AMDIS_TETRAHEDRON_H

#include "Element.h"

namespace AMDiS {

  /** \ingroup Triangulation 
   * \brief
   * A Tetrahedron is a 3-dimensional Element. 
   *
   * A Tetrahedron and its refinements:
   *
   * <img src = "tetrahedron.png">
   */
  class Tetrahedron : public Element
  {
  public:
40
41
42
43
44
    
    /// calls base class contructor.
    Tetrahedron(Mesh* aMesh) 
      : Element(aMesh) 
    {}
45

46
    /// implements Element::clone
47
48
    inline Element *clone() 
    { 
Thomas Witkowski's avatar
Thomas Witkowski committed
49
      return new Tetrahedron(mesh); 
50
    }
51

52
    /// implements Element::getVertexOfEdge
53
54
    inline int getVertexOfEdge(int i, int j) const 
    {
55
      return vertexOfEdge[i][j];
56
    }
57

58
    /// implements Element::getVertexOfPosition
59
    int getVertexOfPosition(GeoIndex position,
60
61
			    int positionIndex,
			    int vertexIndex) const;
62
63


64
65
    virtual int getPositionOfVertex(int side, int vertex) const 
    {
66
67
68
69
      static int positionOfVertex[4][4] = {{-1, 0, 1, 2},
					   {0, -1, 1, 2},
					   {0, 1, -1, 2},
					   {0, 1, 2, -1}};
70
      return positionOfVertex[side][vertex];
71
    }
72

73
    /// implements Element::getGeo
74
75
76
    inline int getGeo(GeoIndex i) const 
    {
      switch (i) {
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
      case VERTEX: case PARTS: case NEIGH:
	return 4;
	break;
      case EDGE:
	return 6;
      case FACE:
	return 4;
      case CENTER:
	return 1;
	break;
      case DIMEN:
	return 3;
	break;
      case BOUNDARY:
	return 14;
	break;
      case PROJECTION:
	return 10;
	break;
      default:
	ERROR_EXIT("invalid geo-index\n");
	return 0;
      }
100
    }
101

102
    /// implements Element::hasSide
103
104
    bool hasSide(Element* sideElem) const;

105
    /// implements Element::sortFaceIndices
106
107
108
    const FixVec<int,WORLD>& sortFaceIndices(int face, 
					     FixVec<int,WORLD> *vec) const;

109
    /// Returns false because this element is a Tetrahedron.
110
111
    inline bool isLine() const 
    { 
112
      return false; 
113
    }
114

115
    /// Returns false because this element is a Tetrahedron.
116
117
    inline bool isTriangle() const 
    { 
118
      return false; 
119
    }
120
 
121
    /// Returns true because this element is a Tetrahedron.
122
123
    inline bool isTetrahedron() const 
    { 
124
      return true; 
125
    }
126
127
128
129
130
131

    /// Return the new element type of the children.
    inline int getChildType(int elType) const
    {
      return (elType + 1) % 3;
    }
132
 
133
134
    std::string getTypeName() const 
    { 
135
      return "Tetrahedron"; 
136
    }
137

138
139
    void getVertexDofs(FiniteElemSpace* feSpace, 
		       BoundaryObject bound,
140
		       DofContainer& dofs) const;
141

142
143
    void getVertexDofsAtFace(FiniteElemSpace* feSpace, 
			     BoundaryObject bound,
144
			     DofContainer& dofs) const;
145
146
147

    void getVertexDofsAtEdge(FiniteElemSpace* feSpace, 
			     BoundaryObject bound,
148
			     DofContainer& dofs) const;
149
150
151

    void getNonVertexDofs(FiniteElemSpace* feSpace,
			  BoundaryObject bound,
152
			  DofContainer& dofs) const;
153

154
155
    void prepareNextBound(BoundaryObject &bound, int ithChild) const;

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  public:
    /** \brief
     * nChildEdge[el_type][ichild][dir]                                      
     * gives local index of new edge on child[ichild] part of face [2+dir] on
     * the parent  
     */
    static const unsigned char nChildEdge[3][2][2];

    /** \brief
     * nChildFace[el_type][ichild][dir]                                     
     * gives local index of sub-face on child[ichild] part of face [2+dir] on
     * the parent   
     */
    static const unsigned char nChildFace[3][2][2];

    /** \brief
     * childVertex[el_type][child][i] =
     * parent's local vertex index of new vertex i.
     * 4 stands for the newly generated vertex                            
     */
    static const int childVertex[3][2][4];
 
    /** \brief
     * childEdge[el_type][child][i] =
     * parent's local edge index of new edge i
     * new edge 2 is half of old edge 0,
     * new edges 4,5 are really new edges, and value is different:
     * childEdge[][][4,5] = index of same edge in other child
     */
    static const int childEdge[3][2][6];

    /** \brief
     * adjacentChild[position][ichild]                                      
     * gives number of the adjacent child on a neighbour element:             
     *   position = 0  same position of element and neigh at refinement edge, 
     *   position = 1  different ...                                         
     */
    static const unsigned char adjacentChild[2][2];

    /** \brief
     * childOrientation[el_type][child] =
     *   +1 if orientation is not changed during refinement, 
     *   -1 if orientation is changed during refinement
     */
    static const signed char childOrientation[3][2];

202
    /// edgeOfDOFs[i][j]: gives the local index of edge with vertices i and j 
203
204
    static const unsigned char edgeOfDOFs[4][4];

205
    ///
206
207
    static const int edgeOfFace[4][3];

208
    /// implements Element::getSideOfChild()
209
    int getSideOfChild(int child, int side, int elType = 0) const 
210
    {
211
      FUNCNAME("Tetrahedron::getSideOfChild()");
212
213
214
215
216

      TEST_EXIT_DBG(child == 0 || child == 1)("Child must be in (0,1)!\n");
      TEST_EXIT_DBG(side >= 0 && side <= 3)("Side must be between 0 and 3!\n");
      TEST_EXIT_DBG(elType >= 0 && elType <= 2)("ElType must be between 0 and 2!\n");

217
      return sideOfChild[elType][child][side];
218
    }
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
    /** \brief
     * Returns for an edge number its local edge number on a child element. See
     * \ref edgeOfChild for mor information.
     */
    inline int getEdgeOfChild(int child, int edge, int elType) const
    {
      FUNCNAME("Tetrahedron::getEdgeOfChild()");

      TEST_EXIT_DBG(child == 0 || child == 1)("Child must be in (0,1)!\n");
      TEST_EXIT_DBG(edge >= 0 && edge <= 5)("Side must be between 0 and 3!\n");
      TEST_EXIT_DBG(elType >= 0 && elType <= 2)("ElType must be between 0 and 2!\n");

      return edgeOfChild[elType][child][edge];
    }

    int getSubObjOfChild(int childnr, GeoIndex subObj, int ithObj, int elType) const
    {
      FUNCNAME("Tetrahedron::getSubObjOfChild()");

      TEST_EXIT_DBG(subObj == EDGE || subObj == FACE)("Not yet implemented!\n");

      if (subObj == FACE)
	return getSideOfChild(childnr, ithObj, elType);
      else
	return getEdgeOfChild(childnr, ithObj, elType);
    }

247
    /// implements Element::getVertexOfParent()
248
    int getVertexOfParent(int child, int side, int elType = 0) const 
249
    {
250
      FUNCNAME("Tetrahedron::getVertexOfParent()");
251
252
253
254
255

      TEST_EXIT_DBG(child == 0 || child == 1)("Child must be in (0,1)!\n");
      TEST_EXIT_DBG(side >= 0 && side <= 3)("Side must be between 0 and 3!\n");
      TEST_EXIT_DBG(elType >= 0 && elType <= 2)("ElType must be between 0 and 2!\n");

256
      return vertexOfParent[elType][child][side];
257
    }
258

259
260
    inline int getEdgeOfFace(int face, int edge) const 
    {
261
262
263
264
265
      FUNCNAME("Tetrahedron::getEdgeOfFace()");

      TEST_EXIT_DBG(face >= 0 && face < 4)("Invalid face number!\n");
      TEST_EXIT_DBG(edge >= 0 && edge < 3)("Invalid edge number!\n");

266
      return edgeOfFace[face][edge];
267
    }
268
   
269
270
271
272
273
274
275
276
277
278
279
280
    GlobalEdge getEdge(int localEdgeIndex) const
    {
      FUNCNAME("Tetrahedron::getEdge()");
      TEST_EXIT_DBG(localEdgeIndex >= 0 && localEdgeIndex < 6)("invalid edge\n");

      DegreeOfFreedom dof0 = dof[vertexOfEdge[localEdgeIndex][0]][0];
      DegreeOfFreedom dof1 = dof[vertexOfEdge[localEdgeIndex][1]][0];
      GlobalEdge edge = std::make_pair(min(dof0, dof1), max(dof0, dof1));

      return edge;
    }

281
282
  protected:

283
    /// vertexOfEdge[i][j] is the local number of the j-vertex of edge i
284
285
    static const int vertexOfEdge[6][2]; 

286
    /// vertexOfFace[i][j] is the local number of the j-vertex of face i
287
288
    static const int vertexOfFace[4][3];

Thomas Witkowski's avatar
Thomas Witkowski committed
289
    /// See \ref Element::getSideOfChild for more information.
290
    static const int sideOfChild[3][2][4];
291

292
293
294
295
296
297
298
299
    /** \brief
     * edgeOfChild[elType][i][j] is the local edge number of the j-th edge within the 
     * i-th children of an element of elType. If the value is -1, the edge is not 
     * included in the element's child. Note that the 0 edge is included in both
     * children only by its half.
     */
    static const int edgeOfChild[3][2][6];

Thomas Witkowski's avatar
Thomas Witkowski committed
300
    /// See \ref Element::getVertexOfParent for more information.
301
302
303
304
305
306
    static const int vertexOfParent[3][2][4];
  };

}

#endif // AMDIS_TETRAHEDRON_H