/****************************************************************************** * * AMDiS - Adaptive multidimensional simulations * * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis * * Authors: * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * * This file is part of AMDiS * * See also license.opensource.txt in the distribution. * ******************************************************************************/ /** \file Triangle.h */ #ifndef AMDIS_TRIANGLE_H #define AMDIS_TRIANGLE_H #include "Element.h" namespace AMDiS { /** \ingroup Triangulation * \brief * A Triangle is a 2-dimensional Element. * * A Triangle and its refinements: * * */ class Triangle : public Element { public: /// calls base class contructor. Triangle(Mesh* aMesh) : Element(aMesh) {} ~Triangle() {} /// implements Element::clone inline Element *clone() { return new Triangle(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; /// implements Element::getGeo inline int getGeo(GeoIndex i) const { switch (i) { case VERTEX: case PARTS: case NEIGH: return 3; break; case EDGE: return 3; case FACE: return 0; case CENTER: return 1; break; case DIMEN: return 2; break; case BOUNDARY: return 6; break; case PROJECTION: return 3; break; default: ERROR_EXIT("invalid geo-index\n"); return 0; } } /// implements Element::hasSide bool hasSide(Element* sideElem) const; /// implements Element::sortFaceIndices void sortFaceIndices(int face, FixVec &vec) const; /// implements Element::isLine. Returns false because this element is a Triangle inline bool isLine() const { return false; } /// implements Element::isTriangle. Returns true because this element is a Triangle inline bool isTriangle() const { return true; } /// implements Element::isTetrahedron. Returns false because this element is a Triangle inline bool isTetrahedron() const { return false; } /// Element type number is not used in 2d, so return 0. inline int getChildType(int) const { return 0; } /// implements Element::getSideOfChild() virtual int getSideOfChild(int child, int side, int) const { FUNCNAME_DBG("Triangle::getSideOfChild()"); TEST_EXIT_DBG(child == 0 || child == 1)("child must be in (0,1)\n"); TEST_EXIT_DBG(side >= 0 && side <= 2)("side must be between 0 and 2\n"); return sideOfChild[child][side]; } int getSubObjOfChild(int childnr, GeoIndex subObj, int ithObj, int elType) const { FUNCNAME_DBG("Triangle::getSubObjOfChild()"); TEST_EXIT_DBG(subObj == EDGE)("Not yet implemented!\n"); return getSideOfChild(childnr, ithObj, elType); } /// implements Element::getVertexOfParent() virtual int getVertexOfParent(int child, int side, int = 0) const { FUNCNAME_DBG("Triangle::getVertexOfParent()"); TEST_EXIT_DBG(child == 0 || child == 1)("child must be in (0,1)\n"); TEST_EXIT_DBG(side >= 0 && side <= 2)("side must be between 0 and 2\n"); return vertexOfParent[child][side]; } virtual int getPositionOfVertex(int side, int vertex) const { FUNCNAME_DBG("Triangle::getPositionOfVertex()"); TEST_EXIT_DBG(side >= 0 && side <= 2)("Wrong side number %d!\n", side); TEST_EXIT_DBG(vertex >= 0 && vertex <= 2)("Wrong vertex number %d!\n", vertex); static const int positionOfVertex[3][3] = {{-1, 0, 1}, {1, -1, 0}, {0, 1, -1}}; return positionOfVertex[side][vertex]; } inline int getEdgeOfFace(int face, int edge) const { FUNCNAME_DBG("Triangle::getEdgeOfFace()"); TEST_EXIT_DBG(face == 0)("face must be zero at triangle\n"); TEST_EXIT_DBG(edge >= 0 && edge < 3)("invalid edge\n"); return edge; } DofEdge getEdge(int localEdgeIndex) const { FUNCNAME_DBG("Triangle::getEdge()"); TEST_EXIT_DBG(localEdgeIndex >= 0 && localEdgeIndex < 3)("invalid edge\n"); DegreeOfFreedom dof0 = dof[vertexOfEdge[localEdgeIndex][0]][0]; DegreeOfFreedom dof1 = dof[vertexOfEdge[localEdgeIndex][1]][0]; DofEdge edge = std::make_pair(std::min(dof0, dof1), std::max(dof0, dof1)); return edge; } DofFace getFace(int localFaceIndex) const { ERROR_EXIT("This does not work in 1D!\n"); return DofFace(); } std::string getTypeName() const { return "Triangle"; } void getNodeDofs(const FiniteElemSpace* feSpace, BoundaryObject bound, DofContainer& dofs, bool baseDofPtr = false) const; void getHigherOrderDofs(const FiniteElemSpace* feSpace, BoundaryObject bound, DofContainer& dofs, bool baseDofPtr = false, vector* dofGeoIndex = nullptr) const; void prepareNextBound(BoundaryObject &bound, int ithChild) const; void getSubBoundary(BoundaryObject bound, vector &subBound) const; protected: /// vertexOfEdge[i][j] is the local number of the j-th vertex of the i-th /// edge of this element. static const int vertexOfEdge[3][2]; static const int sideOfChild[2][3]; static const int vertexOfParent[2][3]; }; } #endif // AMDIS_TRIANGLE_H