// ============================================================================
// == ==
// == AMDiS - Adaptive multidimensional simulations ==
// == ==
// ============================================================================
// == ==
// == TU Dresden ==
// == ==
// == Institut für Wissenschaftliches Rechnen ==
// == Zellescher Weg 12-14 ==
// == 01069 Dresden ==
// == germany ==
// == ==
// ============================================================================
// == ==
// == https://gforge.zih.tu-dresden.de/projects/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