// ============================================================================ // == == // == 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" #include "MemoryManager.h" namespace AMDiS { /** \ingroup Triangulation * \brief * A Tetrahedron is a 3-dimensional Element. * * A Tetrahedron and its refinements: * * */ class Tetrahedron : public Element { public: MEMORY_MANAGED(Tetrahedron); /** \brief * calls base class contructor. */ Tetrahedron(Mesh* aMesh) : Element(aMesh) {}; /** \brief * implements Element::clone */ inline Element *clone() { return NEW Tetrahedron(mesh); }; /** \brief * implements Element::getVertexOfEdge */ inline int getVertexOfEdge(int i, int j) const { return vertexOfEdge[i][j]; }; /** \brief * 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]; }; /** \brief * 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; } }; /** \brief * implements Element::hasSide */ bool hasSide(Element* sideElem) const; /** \brief * implements Element::sortFaceIndices */ const FixVec& sortFaceIndices(int face, FixVec *vec) const; /** \brief * 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; }; // ===== Serializable implementation ===== 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]; /** \brief * 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]; /** \brief * 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]; }; /** \brief * 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: /** \brief * vertexOfEdge[i][j] is the local number of the j-vertex of edge i */ static const int vertexOfEdge[6][2]; /** \brief * vertexOfFace[i][j] is the local number of the j-vertex of face i */ static const int vertexOfFace[4][3]; /** \brief * */ static const int sideOfChild[3][2][4]; /** \brief * */ static const int vertexOfParent[3][2][4]; }; } #endif // AMDIS_TETRAHEDRON_H