diff --git a/MeshLib/Elements/Tri.cpp b/MeshLib/Elements/Tri.cpp deleted file mode 100644 index 277099c680368715ba05e5a7e8acee08182e96ae..0000000000000000000000000000000000000000 --- a/MeshLib/Elements/Tri.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright (c) 2012, OpenGeoSys Community (http://www.opengeosys.org) - * Distributed under a Modified BSD License. - * See accompanying file LICENSE.txt or - * http://www.opengeosys.org/project/license - * - * - * \file Tri.cpp - * - * Created on 2012-05-02 by Karsten Rink - */ - -#include "Tri.h" -#include "Edge.h" -#include "Node.h" - -#include "MathTools.h" - -namespace MeshLib { - - -const unsigned Tri::_edge_nodes[3][2] = -{ - {0, 1}, // Edge 0 - {1, 2}, // Edge 1 - {0, 2} // Edge 2 -}; - - -Tri::Tri(Node* nodes[3], unsigned value) - : Face(value) -{ - _nodes = nodes; - _neighbors = new Element*[3]; - for (unsigned i=0; i<3; i++) - _neighbors[i] = NULL; - this->_area = this->computeVolume(); -} - -Tri::Tri(Node* n0, Node* n1, Node* n2, unsigned value) - : Face(value) -{ - _nodes = new Node*[3]; - _nodes[0] = n0; - _nodes[1] = n1; - _nodes[2] = n2; - _neighbors = new Element*[3]; - for (unsigned i=0; i<3; i++) - _neighbors[i] = NULL; - this->_area = this->computeVolume(); -} - -Tri::Tri(const Tri &tri) - : Face(tri.getValue()) -{ - _nodes = new Node*[3]; - _neighbors = new Element*[3]; - for (unsigned i=0; i<3; i++) - { - _nodes[i] = tri._nodes[i]; - _neighbors[i] = tri._neighbors[i]; - } - _area = tri.getArea(); -} - -Tri::~Tri() -{ -} - -bool Tri::isEdge(unsigned idx1, unsigned idx2) const -{ - for (unsigned i(0); i<3; i++) - { - if (_edge_nodes[i][0]==idx1 && _edge_nodes[i][1]==idx2) return true; - if (_edge_nodes[i][1]==idx1 && _edge_nodes[i][0]==idx2) return true; - } - return false; -} - -Element* Tri::clone() const -{ - return new Tri(*this); -} - -double Tri::computeVolume() -{ - return MathLib::calcTriangleArea(_nodes[0]->getCoords(), _nodes[1]->getCoords(), _nodes[2]->getCoords()); -} - -unsigned Tri::identifyFace(Node* nodes[3]) const -{ - for (unsigned i=0; i<3; i++) - { - unsigned flag(0); - for (unsigned j=0; j<2; j++) - for (unsigned k=0; k<2; k++) - if (_nodes[_edge_nodes[i][j]] == nodes[k]) - flag++; - if (flag==2) - return i; - } - return std::numeric_limits<unsigned>::max(); -} - -Element* Tri::reviseElement() const -{ - // try to create an edge - if (_nodes[0] == _nodes[1] || _nodes[1] == _nodes[2]) { - Node** nodes (new Node*[2]); - nodes[0] = _nodes[0]; - nodes[1] = _nodes[2]; - return new Edge(nodes, _value); - } - - if (_nodes[0] == _nodes[2]) { - Node** nodes (new Node*[2]); - nodes[0] = _nodes[0]; - nodes[1] = _nodes[1]; - return new Edge(nodes, _value); - } - - return NULL; -} - -} - diff --git a/MeshLib/Elements/Tri.h b/MeshLib/Elements/Tri.h index 496a1e2275ffffc379d9f6bf36e3fdedcdd689ac..7453efd28ffb66e4ca15893860db14a468b9ac46 100644 --- a/MeshLib/Elements/Tri.h +++ b/MeshLib/Elements/Tri.h @@ -13,8 +13,13 @@ #ifndef TRI_H_ #define TRI_H_ +#include "Edge.h" +#include "Node.h" #include "Face.h" +#include "MathTools.h" + + namespace MeshLib { /** @@ -34,20 +39,39 @@ namespace MeshLib { * * @endcode */ -class Tri : public Face +template <unsigned ORDER, unsigned NNODES> +class TemplateTri : public Face { public: /// Constructor with an array of mesh nodes. - Tri(Node* nodes[3], unsigned value = 0); - - /// Constructor using single mesh nodes. - Tri(Node* n0, Node* n1, Node* n2, unsigned value = 0); + TemplateTri(Node* nodes[NNODES], unsigned value = 0) : Face(value) + { + _nodes = nodes; + _neighbors = new Element*[3]; + for (unsigned i=0; i<3; i++) + _neighbors[i] = NULL; + this->_area = this->computeVolume(); + } /// Copy constructor - Tri(const Tri &tri); + TemplateTri(const TemplateTri<ORDER, NNODES> &tri) : Face(tri.getValue()) + { + _nodes = new Node*[NNODES]; + for (unsigned i=0; i<NNODES; i++) + { + _nodes[i] = tri._nodes[i]; + } + + _neighbors = new Element*[3]; + for (unsigned i=0; i<3; i++) { + _neighbors[i] = tri._neighbors[i]; + } + + _area = tri.getArea(); + } /// Destructor - virtual ~Tri(); + virtual ~TemplateTri() {}; /// Get the number of edges for this element. unsigned getNEdges() const { return 3; }; @@ -56,7 +80,10 @@ public: unsigned getNNeighbors() const { return 3; }; /// Get the number of nodes for this element. - virtual unsigned getNNodes(unsigned order = 1) const { return 3; }; + virtual unsigned getNNodes(unsigned order = 1) const + { + return order == ORDER ? NNODES : 3; + } /** * Method returns the type of the element. In this case TRIANGLE will be returned. @@ -65,13 +92,25 @@ public: virtual MshElemType::type getType() const { return MshElemType::TRIANGLE; } /// Returns true if these two indices form an edge and false otherwise - bool isEdge(unsigned i, unsigned j) const; + bool isEdge(unsigned idx1, unsigned idx2) const + { + for (unsigned i(0); i<3; i++) + { + if (_edge_nodes[i][0]==idx1 && _edge_nodes[i][1]==idx2) return true; + if (_edge_nodes[i][1]==idx1 && _edge_nodes[i][0]==idx2) return true; + } + return false; + } /** - * Method clone is inherited from class Element. It makes a deep copy of the Tri instance. + * Method clone is inherited from class Element. It makes a deep copy of the TemplateTri instance. * @return an exact copy of the object */ - virtual Element* clone() const; + virtual Element* clone() const + { + return new TemplateTri<ORDER, NNODES>(*this); + } + /** * This method should be called after at least two nodes of the triangle @@ -81,23 +120,65 @@ public: * object of class Edge. * @return an Edge object or NULL */ - virtual Element* reviseElement() const; + virtual Element* reviseElement() const + { + // try to create an edge + if (_nodes[0] == _nodes[1] || _nodes[1] == _nodes[2]) { + Node** nodes (new Node*[2]); + nodes[0] = _nodes[0]; + nodes[1] = _nodes[2]; + return new Edge(nodes, _value); + } + + if (_nodes[0] == _nodes[2]) { + Node** nodes (new Node*[2]); + nodes[0] = _nodes[0]; + nodes[1] = _nodes[1]; + return new Edge(nodes, _value); + } + + return NULL; + } protected: /// Calculates the area of the triangle by returning half of the area of the corresponding parallelogram. - double computeVolume(); + double computeVolume() + { + return MathLib::calcTriangleArea(_nodes[0]->getCoords(), _nodes[1]->getCoords(), _nodes[2]->getCoords()); + } protected: /// Return a specific edge node. inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; }; /// Returns the ID of a face given an array of nodes. - unsigned identifyFace(Node* nodes[3]) const; + unsigned identifyFace(Node* nodes[3]) const + { + for (unsigned i=0; i<3; i++) + { + unsigned flag(0); + for (unsigned j=0; j<2; j++) + for (unsigned k=0; k<2; k++) + if (_nodes[_edge_nodes[i][j]] == nodes[k]) + flag++; + if (flag==2) + return i; + } + return std::numeric_limits<unsigned>::max(); + } static const unsigned _edge_nodes[3][2]; - }; /* class */ +typedef TemplateTri<1,3> Tri; + +template <unsigned ORDER, unsigned NNODES> +const unsigned TemplateTri<ORDER, NNODES>::_edge_nodes[3][2] = { + {0, 1}, // Edge 0 + {1, 2}, // Edge 1 + {0, 2} // Edge 2 + }; + } /* namespace */ #endif /* TRI_H_ */