// ============================================================================ // == == // == AMDiS - Adaptive multidimensional simulations == // == == // ============================================================================ // == == // == crystal growth group == // == == // == Stiftung caesar == // == Ludwig-Erhard-Allee 2 == // == 53175 Bonn == // == germany == // == == // ============================================================================ // == == // == http://www.caesar.de/cg/AMDiS == // == == // ============================================================================ /** \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: * * */ class Tetrahedron : public Element { public: /// calls base class contructor. Tetrahedron(Mesh* aMesh) : Element(aMesh) {} /// implements Element::clone inline Element *clone() { return NEW Tetrahedron(mesh); } /// implements Element::getVertexOfEdge inline int getVertexOfEdge(int i, int j) const { return vertexOfEdge[i][j]; } /// implements Element::getVertexOfPosition int getVertexOfPosition(GeoIndex position, int positionIndex, int vertexIndex) const; virtual int getPositionOfVertex(int side, int vertex) const { static int positionOfVertex[4][4] = {{-1,0,1,2}, {0,-1,1,2}, {0,1,-1,2}, {0,1,2,-1}}; return positionOfVertex[side][vertex]; } /// implements Element::getGeo inline int getGeo(GeoIndex i) const { switch(i) { 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; } } /// implements Element::hasSide bool hasSide(Element* sideElem) const; /// implements Element::sortFaceIndices const FixVec& sortFaceIndices(int face, FixVec *vec) const; /// implements Element::isLine. Returns false because this element is a Tetrahedron inline bool isLine() const { return false; } /** \brief * implements Element::isTriangle. Returns false because this element is a * Tetrahedron */ inline bool isTriangle() const { return false; } /** \brief * implements Element::isTetrahedron. Returns true because this element is a * Tetrahedron */ inline bool isTetrahedron() const { return true; } std::string getTypeName() const { return "Tetrahedron"; } 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]; /// edgeOfDOFs[i][j]: gives the local index of edge with vertices i and j static const unsigned char edgeOfDOFs[4][4]; /// static const int edgeOfFace[4][3]; /// implements Element::getSideOfChild() virtual int getSideOfChild(int child, int side, int elType = 0) const { FUNCNAME("Tetrahedron::getSideOfChild()"); 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"); return sideOfChild[elType][child][side]; } /// implements Element::getVertexOfParent() virtual int getVertexOfParent(int child, int side, int elType = 0) const { FUNCNAME("Tetrahedron::getVertexOfParent()"); 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"); return vertexOfParent[elType][child][side]; } inline int getEdgeOfFace(int face, int edge) const { TEST_EXIT_DBG(face >= 0 && face < 4)("invalid face\n"); TEST_EXIT_DBG(edge >= 0 && edge < 3)("invalid edge\n"); return edgeOfFace[face][edge]; } protected: /// vertexOfEdge[i][j] is the local number of the j-vertex of edge i static const int vertexOfEdge[6][2]; /// vertexOfFace[i][j] is the local number of the j-vertex of face i static const int vertexOfFace[4][3]; /// static const int sideOfChild[3][2][4]; /// static const int vertexOfParent[3][2][4]; }; } #endif // AMDIS_TETRAHEDRON_H