Skip to content
Snippets Groups Projects
Commit aadef2db authored by Tom Fischer's avatar Tom Fischer
Browse files

created class template TemplateTri and defined a template class Tri (= TemplateTri<1,3>)

parent 51af837e
No related branches found
No related tags found
No related merge requests found
/**
* 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;
}
}
...@@ -13,8 +13,13 @@ ...@@ -13,8 +13,13 @@
#ifndef TRI_H_ #ifndef TRI_H_
#define TRI_H_ #define TRI_H_
#include "Edge.h"
#include "Node.h"
#include "Face.h" #include "Face.h"
#include "MathTools.h"
namespace MeshLib { namespace MeshLib {
/** /**
...@@ -34,20 +39,39 @@ namespace MeshLib { ...@@ -34,20 +39,39 @@ namespace MeshLib {
* *
* @endcode * @endcode
*/ */
class Tri : public Face template <unsigned ORDER, unsigned NNODES>
class TemplateTri : public Face
{ {
public: public:
/// Constructor with an array of mesh nodes. /// Constructor with an array of mesh nodes.
Tri(Node* nodes[3], unsigned value = 0); TemplateTri(Node* nodes[NNODES], unsigned value = 0) : Face(value)
{
/// Constructor using single mesh nodes. _nodes = nodes;
Tri(Node* n0, Node* n1, Node* n2, unsigned value = 0); _neighbors = new Element*[3];
for (unsigned i=0; i<3; i++)
_neighbors[i] = NULL;
this->_area = this->computeVolume();
}
/// Copy constructor /// 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 /// Destructor
virtual ~Tri(); virtual ~TemplateTri() {};
/// Get the number of edges for this element. /// Get the number of edges for this element.
unsigned getNEdges() const { return 3; }; unsigned getNEdges() const { return 3; };
...@@ -56,7 +80,10 @@ public: ...@@ -56,7 +80,10 @@ public:
unsigned getNNeighbors() const { return 3; }; unsigned getNNeighbors() const { return 3; };
/// Get the number of nodes for this element. /// 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. * Method returns the type of the element. In this case TRIANGLE will be returned.
...@@ -65,13 +92,25 @@ public: ...@@ -65,13 +92,25 @@ public:
virtual MshElemType::type getType() const { return MshElemType::TRIANGLE; } virtual MshElemType::type getType() const { return MshElemType::TRIANGLE; }
/// Returns true if these two indices form an edge and false otherwise /// 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 * @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 * This method should be called after at least two nodes of the triangle
...@@ -81,23 +120,65 @@ public: ...@@ -81,23 +120,65 @@ public:
* object of class Edge. * object of class Edge.
* @return an Edge object or NULL * @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: protected:
/// Calculates the area of the triangle by returning half of the area of the corresponding parallelogram. /// 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: protected:
/// Return a specific edge node. /// Return a specific edge node.
inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; }; 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. /// 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]; static const unsigned _edge_nodes[3][2];
}; /* class */ }; /* 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 */ } /* namespace */
#endif /* TRI_H_ */ #endif /* TRI_H_ */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment