Skip to content
Snippets Groups Projects
Commit dab073b7 authored by Norihiro Watanabe's avatar Norihiro Watanabe
Browse files

replace mesh element class with new implementation using TemplateElement class

parent 32467337
No related branches found
No related tags found
No related merge requests found
Showing
with 688 additions and 73 deletions
......@@ -16,14 +16,10 @@
#include "MathLib/Vector3.h"
#include "MeshLib/Node.h"
#include "MeshLib/Elements/Face.h"
namespace MeshLib {
#ifndef WIN32
/// \todo Windows compiler does not accept this definition and issues a linking error.
const unsigned Cell::dimension;
#endif // WIN32
/*
Cell::Cell(Node** nodes, MeshElemType type, unsigned value)
: Element(nodes, type, value)
......@@ -31,7 +27,7 @@ Cell::Cell(Node** nodes, MeshElemType type, unsigned value)
}
*/
Cell::Cell(unsigned value, std::size_t id)
: Element(value, id), _volume(-1.0) // init with invalid value to detect errors
: Element(value, id)
{
}
......
......@@ -16,7 +16,6 @@
#define CELL_H_
#include "Element.h"
#include "Face.h"
namespace MeshLib {
......@@ -26,28 +25,12 @@ namespace MeshLib {
class Cell : public Element
{
public:
/// Constant: Dimension of this mesh element
static const unsigned dimension = 3;
/// Returns the length, area or volume of a 1D, 2D or 3D element
double getContent() const { return _volume; }
/// Get dimension of the mesh element.
unsigned getDimension() const { return dimension; }
/// Get the volume of this 3d element.
virtual double getVolume() const { return _volume; }
virtual double getVolume() const { return getContent(); }
/// Destructor
virtual ~Cell();
/**
* This method is pure virtual and is inherited from class @sa Element.
* It has to be implemented in the derived classes of class Cell!
* @return a copy of the object
*/
virtual Element* clone() const = 0;
/**
* Checks if the node order of an element is correct by testing surface normals.
* For 3D elements true is returned if the normals of all faces points away from the centre of
......@@ -65,9 +48,6 @@ protected:
*/
/// Constructor for a generic mesh element without an array of mesh nodes.
Cell(unsigned value = 0, std::size_t id = std::numeric_limits<std::size_t>::max());
double _volume;
}; /* class */
}
......
/**
* \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "CellRule.h"
#include "logog/include/logog.hpp"
#include "GeoLib/AnalyticalGeometry.h"
#include "MeshLib/Node.h"
#include "Face.h"
namespace MeshLib
{
const unsigned CellRule::dimension;
bool CellRule::testElementNodeOrder(const Element* e)
{
const MathLib::Vector3 c (e->getCenterOfGravity());
const unsigned nFaces (e->getNFaces());
for (unsigned j=0; j<nFaces; ++j)
{
MeshLib::Face const*const face (dynamic_cast<const MeshLib::Face*>(e->getFace(j)));
const MeshLib::Node x (*(face->getNode(1)));
const MathLib::Vector3 cx (c, x);
const double s = MathLib::scalarProduct(face->getSurfaceNormal(), cx);
delete face;
if (s >= 0)
return false;
}
return true;
}
} // end namespace MeshLib
/**
* \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#ifndef CELLRULE_H_
#define CELLRULE_H_
#include "MeshLib/MeshEnums.h"
#include "Element.h"
namespace MeshLib {
/**
*/
class CellRule
{
public:
/// Constant: Dimension of this mesh element
static const unsigned dimension = 3u;
/**
* Checks if the node order of an element is correct by testing surface normals.
*/
static bool testElementNodeOrder(const Element* e);
}; /* class */
} /* namespace */
#endif /* HEXRULE_H_ */
/**
* \file
* \author Karsten Rink
* \date 2012-05-02
* \brief Definition of the Face class.
*
* \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#ifndef EDGE_H_
#define EDGE_H_
#include <limits>
#include "Element.h"
namespace MeshLib {
/**
* Virtual base class for 1d mesh elements.
*/
class Edge : public Element
{
public:
/// Get the length of this 1d element.
virtual double getLength() const { return _content; }
/// Destructor
virtual ~Edge() {}
/**
* Checks if the node order of an element is correct by testing surface normals.
* For 1D elements this always returns true.
*/
virtual bool testElementNodeOrder() const { return true; }
protected:
/// Constructor for a generic mesh element without an array of mesh nodes.
Edge(unsigned value = 0, std::size_t id = std::numeric_limits<std::size_t>::max()) : Element(value, id) {}
}; /* class */
} /* namespace */
#endif /* EDGE_H_ */
/**
* \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "EdgeReturn.h"
#include "logog/include/logog.hpp"
#include "MeshLib/Node.h"
#include "Element.h"
#include "Line.h"
namespace MeshLib
{
const Element* LinearEdgeReturn::getEdge(const Element* e, unsigned i)
{
if (i < e->getNEdges())
{
Node** nodes = new Node*[2];
nodes[0] = const_cast<Node*>(e->getEdgeNode(i,0));
nodes[1] = const_cast<Node*>(e->getEdgeNode(i,1));
return new Line(nodes);
}
ERR("Error in MeshLib::Element::getEdge() - Index does not exist.");
return nullptr;
}
const Element* QuadraticEdgeReturn::getEdge(const Element* e, unsigned i)
{
if (i < e->getNEdges())
{
Node** nodes = new Node*[3];
nodes[0] = const_cast<Node*>(e->getEdgeNode(i,0));
nodes[1] = const_cast<Node*>(e->getEdgeNode(i,1));
nodes[2] = const_cast<Node*>(e->getEdgeNode(i,2));
return new Line3(nodes);
}
ERR("Error in MeshLib::Element::getEdge() - Index does not exist.");
return nullptr;
}
} // end MeshLib
/**
* \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#ifndef EDGERETURN_H_
#define EDGERETURN_H_
#include "logog/include/logog.hpp"
namespace MeshLib
{
class Element;
/// Returns always null pointer
class DummyEdgeReturn
{
public:
/// Returns i-th edge of the given element
static const Element* getEdge(const Element* /*e*/, unsigned /*i*/)
{
return nullptr;
}
};
/// Returns linear order edge
class LinearEdgeReturn
{
public:
/// Returns i-th edge of the given element
static const Element* getEdge(const Element* e, unsigned i);
};
/// Returns quadratic order edge
class QuadraticEdgeReturn
{
public:
/// Returns i-th edge of the given element
static const Element* getEdge(const Element* e, unsigned i);
};
} // end MeshLib
#endif /* EDGERETURN_H_ */
......@@ -24,7 +24,7 @@
namespace MeshLib {
Element::Element(unsigned value, std::size_t id)
: _nodes(nullptr), _id(id), _value(value), _neighbors(nullptr)
: _nodes(nullptr), _id(id), _content(-1.0), _value(value), _neighbors(nullptr)
{
}
......
......@@ -57,7 +57,7 @@ public:
MeshLib::Node getCenterOfGravity() const;
/// Returns the length, area or volume of a 1D, 2D or 3D element
virtual double getContent() const = 0;
double getContent() const { return _content; }
/**
* Get node with local index i where i should be at most the number
......@@ -84,7 +84,7 @@ public:
virtual unsigned getDimension() const = 0;
/// Returns the i-th edge of the element.
const Element* getEdge(unsigned i) const;
virtual const Element* getEdge(unsigned i) const;
/// Returns the i-th face of the element.
virtual const Element* getFace(unsigned i) const = 0;
......@@ -207,6 +207,9 @@ public:
*/
virtual bool testElementNodeOrder() const = 0;
/// Return a specific edge node.
virtual Node* getEdgeNode(unsigned edge_id, unsigned node_id) const = 0;
#ifndef NDEBUG
friend std::ostream& operator<<(std::ostream& os, Element const& e);
#endif // NDEBUG
......@@ -215,14 +218,12 @@ protected:
/// Constructor for a generic mesh element without an array of mesh nodes.
Element(unsigned value = 0, std::size_t id = std::numeric_limits<std::size_t>::max());
/// Return a specific edge node.
virtual Node* getEdgeNode(unsigned edge_id, unsigned node_id) const = 0;
/// Sets the element ID.
virtual void setID(std::size_t id) { this->_id = id; }
Node** _nodes;
std::size_t _id;
double _content;
/**
* this is an index for external additional information like materials
*/
......
......@@ -21,11 +21,6 @@
namespace MeshLib {
#ifndef WIN32
/// \todo Windows compiler does not accept this definition and issues a linking error.
const unsigned Face::dimension;
#endif // WIN32
/*
Face::Face(Node** nodes, MeshElemType type, unsigned value)
: Element(nodes, type, value)
......@@ -33,7 +28,7 @@ Face::Face(Node** nodes, MeshElemType type, unsigned value)
}
*/
Face::Face(unsigned value, std::size_t id)
: Element(value, id), _area(-1.0) // init with invalid value to detect errors
: Element(value, id)
{
}
......
......@@ -31,26 +31,8 @@ namespace MeshLib {
class Face : public Element
{
public:
/// Constant: Dimension of this mesh element
static const unsigned dimension = 2;
/// Get the area of this 2d element.
virtual double getArea() const { return _area; }
/// Returns the length, area or volume of a 1D, 2D or 3D element
double getContent() const { return _area; }
/// Get dimension of the mesh element.
unsigned getDimension() const { return dimension; }
/// Returns the face i of the element.
const Element* getFace(unsigned i) const { return this->getEdge(i); }
/// Get the number of nodes for face i.
unsigned getNFaceNodes(unsigned i) const { (void)i; return 2; }
/// 2D elements have no faces.
unsigned getNFaces() const { return 0; }
virtual double getArea() const { return _content; }
/// Returns the surface normal of a 2D element.
MathLib::Vector3 getSurfaceNormal() const;
......@@ -58,13 +40,6 @@ public:
/// Destructor
virtual ~Face();
/**
* This method is pure virtual and is inherited from class @sa Element.
* It has to be implemented in the derived classes of class Face!
* @return a copy of the object
*/
virtual Element* clone() const = 0;
/**
* Checks if the node order of an element is correct by testing surface normals.
* For 2D elements true is returned if the normal points (roughly) upwards.
......@@ -79,8 +54,6 @@ protected:
/// Constructor for a generic mesh element without an array of mesh nodes.
Face(unsigned value = 0, std::size_t id = std::numeric_limits<std::size_t>::max());
double _area;
private:
......
/**
* \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "FaceRule.h"
namespace MeshLib {
const unsigned FaceRule::dimension;
} /* namespace */
/**
* \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#ifndef FACERULE_H_
#define FACERULE_H_
#include "MeshLib/MeshEnums.h"
#include "Element.h"
namespace MeshLib {
/**
*/
class FaceRule
{
public:
/// Constant: Dimension of this mesh element
static const unsigned dimension = 2;
/// Returns the face i of the element.
static const Element* getFace(const Element* e, unsigned i) { return e->getEdge(i); }
/// Get the number of nodes for face i.
static unsigned getNFaceNodes(unsigned /*i*/) { return 2; }
/// 2D elements have no faces.
static unsigned getNFaces() { return 0; }
}; /* class */
} /* namespace */
#endif /* FACERULE_H_ */
......@@ -15,10 +15,12 @@
#ifndef HEX_H_
#define HEX_H_
#include "TemplateHex.h"
#include "TemplateElement.h"
#include "Cell.h"
#include "HexRule8.h"
namespace MeshLib {
typedef TemplateHex<8, CellType::HEX8> Hex;
typedef TemplateElement<Cell, HexRule8> Hex;
}
#endif /* HEX_H_ */
/**
* \file
* \author Karsten Rink
* \date 2012-05-02
* \brief Implementation of the TemplateHex class.
*
* \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
......@@ -12,25 +7,23 @@
*
*/
#include "HexRule8.h"
#include "logog/include/logog.hpp"
#include "GeoLib/AnalyticalGeometry.h"
#include "MeshLib/Node.h"
#include "MeshLib/Node.h"
#include "Quad.h"
#include "Prism.h"
#include "Line.h"
namespace MeshLib {
template <unsigned NNODES, CellType CELLHEXTYPE>
const unsigned TemplateHex<NNODES, CELLHEXTYPE>::n_all_nodes;
const unsigned HexRule8::n_all_nodes;
template <unsigned NNODES, CellType CELLHEXTYPE>
const unsigned TemplateHex<NNODES, CELLHEXTYPE>::n_base_nodes;
const unsigned HexRule8::n_base_nodes;
template <unsigned NNODES, CellType CELLHEXTYPE>
const unsigned TemplateHex<NNODES,CELLHEXTYPE>::_face_nodes[6][4] =
const unsigned HexRule8::face_nodes[6][4] =
{
{0, 3, 2, 1}, // Face 0
{0, 1, 5, 4}, // Face 1
......@@ -40,8 +33,7 @@ const unsigned TemplateHex<NNODES,CELLHEXTYPE>::_face_nodes[6][4] =
{4, 5, 6, 7} // Face 5
};
template <unsigned NNODES, CellType CELLHEXTYPE>
const unsigned TemplateHex<NNODES,CELLHEXTYPE>::_edge_nodes[12][2] =
const unsigned HexRule8::edge_nodes[12][2] =
{
{0, 1}, // Edge 0
{1, 2}, // Edge 1
......@@ -57,115 +49,48 @@ const unsigned TemplateHex<NNODES,CELLHEXTYPE>::_edge_nodes[12][2] =
{3, 7} // Edge 11
};
template <unsigned NNODES, CellType CELLHEXTYPE>
TemplateHex<NNODES,CELLHEXTYPE>::TemplateHex(Node* nodes[NNODES], unsigned value, std::size_t id)
: Cell(value, id)
{
_nodes = nodes;
_neighbors = new Element*[6];
std::fill(_neighbors, _neighbors + 6, nullptr);
this->_volume = this->computeVolume();
}
template<unsigned NNODES, CellType CELLHEXTYPE>
TemplateHex<NNODES,CELLHEXTYPE>::TemplateHex(std::array<Node*, NNODES> const& nodes,
unsigned value, std::size_t id)
: Cell(value, id)
const Element* HexRule8::getFace(const Element* e, unsigned i)
{
_nodes = new Node*[NNODES];
std::copy(nodes.begin(), nodes.end(), _nodes);
_neighbors = new Element*[6];
std::fill(_neighbors, _neighbors + 6, nullptr);
this->_volume = this->computeVolume();
}
template <unsigned NNODES, CellType CELLHEXTYPE>
TemplateHex<NNODES,CELLHEXTYPE>::TemplateHex(const TemplateHex<NNODES,CELLHEXTYPE> &hex)
: Cell(hex.getValue(), hex.getID())
{
_nodes = new Node*[NNODES];
for (unsigned i=0; i<NNODES; i++)
_nodes[i] = hex._nodes[i];
_neighbors = new Element*[6];
for (unsigned i=0; i<6; i++)
_neighbors[i] = hex._neighbors[i];
_volume = hex.getVolume();
}
template <unsigned NNODES, CellType CELLHEXTYPE>
TemplateHex<NNODES,CELLHEXTYPE>::~TemplateHex()
{
}
template <unsigned NNODES, CellType CELLHEXTYPE>
double TemplateHex<NNODES,CELLHEXTYPE>::computeVolume()
{
return GeoLib::calcTetrahedronVolume(_nodes[4]->getCoords(), _nodes[7]->getCoords(), _nodes[5]->getCoords(), _nodes[0]->getCoords())
+ GeoLib::calcTetrahedronVolume(_nodes[5]->getCoords(), _nodes[3]->getCoords(), _nodes[1]->getCoords(), _nodes[0]->getCoords())
+ GeoLib::calcTetrahedronVolume(_nodes[5]->getCoords(), _nodes[7]->getCoords(), _nodes[3]->getCoords(), _nodes[0]->getCoords())
+ GeoLib::calcTetrahedronVolume(_nodes[5]->getCoords(), _nodes[7]->getCoords(), _nodes[6]->getCoords(), _nodes[2]->getCoords())
+ GeoLib::calcTetrahedronVolume(_nodes[1]->getCoords(), _nodes[3]->getCoords(), _nodes[5]->getCoords(), _nodes[2]->getCoords())
+ GeoLib::calcTetrahedronVolume(_nodes[3]->getCoords(), _nodes[7]->getCoords(), _nodes[5]->getCoords(), _nodes[2]->getCoords());
}
template <unsigned NNODES, CellType CELLHEXTYPE>
const Element* TemplateHex<NNODES,CELLHEXTYPE>::getFace(unsigned i) const
{
if (i<this->getNFaces())
if (i < n_faces)
{
unsigned nFaceNodes (this->getNFaceNodes(i));
unsigned nFaceNodes (getNFaceNodes(i));
Node** nodes = new Node*[nFaceNodes];
for (unsigned j=0; j<nFaceNodes; j++)
nodes[j] = _nodes[_face_nodes[i][j]];
nodes[j] = const_cast<Node*>(e->getNode(face_nodes[i][j]));
return new Quad(nodes);
}
ERR("Error in MeshLib::Element::getFace() - Index %d does not exist.", i);
return NULL;
}
template <unsigned NNODES, CellType CELLHEXTYPE>
bool TemplateHex<NNODES,CELLHEXTYPE>::isEdge(unsigned idx1, unsigned idx2) const
{
for (unsigned i(0); i<12; 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;
return nullptr;
}
template <unsigned NNODES, CellType CELLHEXTYPE>
bool TemplateHex<NNODES,CELLHEXTYPE>::isPntInElement(MathLib::Point3d const& pnt, double eps) const
double HexRule8::computeVolume(Node const* const* _nodes)
{
return (GeoLib::isPointInTetrahedron(pnt, *_nodes[4], *_nodes[7], *_nodes[5], *_nodes[0], eps) ||
GeoLib::isPointInTetrahedron(pnt, *_nodes[5], *_nodes[3], *_nodes[1], *_nodes[0], eps) ||
GeoLib::isPointInTetrahedron(pnt, *_nodes[5], *_nodes[7], *_nodes[3], *_nodes[0], eps) ||
GeoLib::isPointInTetrahedron(pnt, *_nodes[5], *_nodes[7], *_nodes[6], *_nodes[2], eps) ||
GeoLib::isPointInTetrahedron(pnt, *_nodes[1], *_nodes[3], *_nodes[5], *_nodes[2], eps) ||
GeoLib::isPointInTetrahedron(pnt, *_nodes[3], *_nodes[7], *_nodes[5], *_nodes[2], eps));
return GeoLib::calcTetrahedronVolume(_nodes[4]->getCoords(), _nodes[7]->getCoords(), _nodes[5]->getCoords(), _nodes[0]->getCoords())
+ GeoLib::calcTetrahedronVolume(_nodes[5]->getCoords(), _nodes[3]->getCoords(), _nodes[1]->getCoords(), _nodes[0]->getCoords())
+ GeoLib::calcTetrahedronVolume(_nodes[5]->getCoords(), _nodes[7]->getCoords(), _nodes[3]->getCoords(), _nodes[0]->getCoords())
+ GeoLib::calcTetrahedronVolume(_nodes[5]->getCoords(), _nodes[7]->getCoords(), _nodes[6]->getCoords(), _nodes[2]->getCoords())
+ GeoLib::calcTetrahedronVolume(_nodes[1]->getCoords(), _nodes[3]->getCoords(), _nodes[5]->getCoords(), _nodes[2]->getCoords())
+ GeoLib::calcTetrahedronVolume(_nodes[3]->getCoords(), _nodes[7]->getCoords(), _nodes[5]->getCoords(), _nodes[2]->getCoords());
}
template <unsigned NNODES, CellType CELLHEXTYPE>
Element* TemplateHex<NNODES,CELLHEXTYPE>::clone() const
bool HexRule8::isPntInElement(Node const* const* _nodes, MathLib::Point3d const& pnt, double eps)
{
return new TemplateHex<NNODES,CELLHEXTYPE>(*this);
return (GeoLib::isPointInTetrahedron(pnt, *_nodes[4], *_nodes[7], *_nodes[5], *_nodes[0], eps) ||
GeoLib::isPointInTetrahedron(pnt, *_nodes[5], *_nodes[3], *_nodes[1], *_nodes[0], eps) ||
GeoLib::isPointInTetrahedron(pnt, *_nodes[5], *_nodes[7], *_nodes[3], *_nodes[0], eps) ||
GeoLib::isPointInTetrahedron(pnt, *_nodes[5], *_nodes[7], *_nodes[6], *_nodes[2], eps) ||
GeoLib::isPointInTetrahedron(pnt, *_nodes[1], *_nodes[3], *_nodes[5], *_nodes[2], eps) ||
GeoLib::isPointInTetrahedron(pnt, *_nodes[3], *_nodes[7], *_nodes[5], *_nodes[2], eps));
}
template <unsigned NNODES, CellType CELLHEXTYPE>
unsigned TemplateHex<NNODES,CELLHEXTYPE>::identifyFace(Node* nodes[3]) const
unsigned HexRule8::identifyFace(Node const* const* _nodes, Node* nodes[3])
{
for (unsigned i=0; i<6; i++)
{
unsigned flag(0);
for (unsigned j=0; j<4; j++)
for (unsigned k=0; k<3; k++)
if (_nodes[_face_nodes[i][j]] == nodes[k])
if (_nodes[face_nodes[i][j]] == nodes[k])
flag++;
if (flag==3)
return i;
......@@ -173,22 +98,21 @@ unsigned TemplateHex<NNODES,CELLHEXTYPE>::identifyFace(Node* nodes[3]) const
return std::numeric_limits<unsigned>::max();
}
template <unsigned NNODES, CellType CELLHEXTYPE>
ElementErrorCode TemplateHex<NNODES,CELLHEXTYPE>::validate() const
ElementErrorCode HexRule8::validate(const Element* e)
{
ElementErrorCode error_code;
error_code[ElementErrorFlag::ZeroVolume] = this->hasZeroVolume();
error_code[ElementErrorFlag::ZeroVolume] = e->hasZeroVolume();
for (unsigned i=0; i<6; ++i)
{
if (error_code.all())
break;
const MeshLib::Element* quad (this->getFace(i));
const MeshLib::Element* quad (e->getFace(i));
error_code |= quad->validate();
delete quad;
}
error_code[ElementErrorFlag::NodeOrder] = !this->testElementNodeOrder();
error_code[ElementErrorFlag::NodeOrder] = !e->testElementNodeOrder();
return error_code;
}
......
/**
* \file
* \author Karsten Rink
* \date 2012-05-02
* \brief Definition of the TemplateHex class.
*
* \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
......@@ -12,17 +7,19 @@
*
*/
#ifndef TEMPLATEHEX_H_
#define TEMPLATEHEX_H_
#ifndef HEXRULE8_H_
#define HEXRULE8_H_
#include <array>
#include "MeshLib/MeshEnums.h"
#include "Cell.h"
#include "Element.h"
#include "CellRule.h"
#include "EdgeReturn.h"
namespace MeshLib {
namespace MeshLib
{
/**
* A 3d Hexahedron Element.
* A 8-nodes Hexahedron Element.
* @code
*
* Hex:
......@@ -46,111 +43,68 @@ namespace MeshLib {
*
* @endcode
*/
template <unsigned NNODES, CellType CELLHEXTYPE>
class TemplateHex : public Cell
class HexRule8 : public CellRule
{
public:
/// Constant: The number of all nodes for this element
static const unsigned n_all_nodes = NNODES;
/// Constant: The number of base nodes for this element
static const unsigned n_base_nodes = 8u;
/// Constructor with an array of mesh nodes.
TemplateHex(Node* nodes[NNODES], unsigned value = 0, std::size_t id = std::numeric_limits<std::size_t>::max());
/// Constructs a hex from array of Node pointers.
TemplateHex(std::array<Node*, NNODES> const& nodes, unsigned value = 0, std::size_t id = std::numeric_limits<std::size_t>::max());
/// Constant: The number of all nodes for this element
static const unsigned n_all_nodes = 8u;
/// Copy constructor
TemplateHex(const TemplateHex &hex);
/// Constant: The geometric type of the element
static const MeshElemType mesh_elem_type = MeshElemType::HEXAHEDRON;
/// Destructor
virtual ~TemplateHex();
/// Constant: The FEM type of the element
static const CellType cell_type = CellType::HEX8;
/// Returns the face i of the element.
const Element* getFace(unsigned i) const;
/// Constant: The number of faces
static const unsigned n_faces = 6;
/// Get the number of edges for this element.
unsigned getNEdges() const { return 12; }
/// Constant: The number of edges
static const unsigned n_edges = 12;
/// Get the number of nodes for face i.
unsigned getNFaceNodes(unsigned i) const { (void)i; return 4; }
/// Constant: The number of neighbors
static const unsigned n_neighbors = 6;
/// Get the number of faces for this element.
unsigned getNFaces() const { return 6; }
/// Constant: Local node index table for faces
static const unsigned face_nodes[6][4];
/// Get the number of neighbors for this element.
unsigned getNNeighbors() const { return 6; }
/// Constant: Local node index table for edge
static const unsigned edge_nodes[12][2];
/// Get the number of linear nodes for this element.
virtual unsigned getNBaseNodes() const
{
return n_base_nodes;
}
/// Returns the i-th edge of the element.
typedef LinearEdgeReturn EdgeReturn;
/// Get the number of all nodes for this element.
virtual unsigned getNNodes() const
{
return n_all_nodes;
}
/// Get the number of nodes for face i.
static unsigned getNFaceNodes(unsigned /*i*/) { return 4; }
/**
* Method returns the type of the element. In this case HEXAHEDRON will be returned.
* @return MeshElemType::HEXAHEDRON
*/
virtual MeshElemType getGeomType() const { return MeshElemType::HEXAHEDRON; }
/// Returns the i-th face of the element.
static const Element* getFace(const Element* e, unsigned i);
/**
* Method returns the FEM type of the element.
* @return
*/
virtual CellType getCellType() const { return CELLHEXTYPE; }
/// Returns true if these two indices form an edge and false otherwise
bool isEdge(unsigned i, unsigned j) const;
/**
* Checks if a point is inside the element.
* @param pnt a 3D MathLib::Point3d object
* @param pnt a 3D GeoLib::Point object
* @param eps tolerance for numerical algorithm used or computing the property
* @return true if the point is not outside the element, false otherwise
*/
bool isPntInElement(MathLib::Point3d const& pnt, double eps = std::numeric_limits<double>::epsilon()) const;
static bool isPntInElement(Node const* const* _nodes, MathLib::Point3d const& pnt, double eps);
/**
* Tests if the element is geometrically valid.
* @param check_zero_volume indicates if volume == 0 should be checked
*/
virtual ElementErrorCode validate() const;
/**
* Method clone is inherited from class Element. It makes a deep copy of the Hex instance.
* @return an exact copy of the object
*/
virtual Element* clone() const;
static ElementErrorCode validate(const Element* e);
/// Returns the ID of a face given an array of nodes.
unsigned identifyFace(Node* nodes[3]) const;
static unsigned identifyFace(Node const* const*, Node* nodes[3]);
protected:
/// Calculates the volume of a convex hexahedron by partitioning it into six tetrahedra.
double computeVolume();
/// Return a specific edge node.
inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const
{
return _nodes[_edge_nodes[edge_id][node_id]];
}
static const unsigned _face_nodes[6][4];
static const unsigned _edge_nodes[12][2];
static double computeVolume(Node const* const* _nodes);
}; /* class */
} /* namespace */
#include "TemplateHex-impl.h"
#endif /* TEMPLATEHEX_H_ */
#endif /* HEXRULE_H_ */
......@@ -15,11 +15,13 @@
#ifndef LINE_H_
#define LINE_H_
#include "TemplateLine.h"
#include "TemplateElement.h"
#include "Edge.h"
#include "LineRule2.h"
namespace MeshLib {
typedef TemplateLine<2,CellType::LINE2> Line;
typedef TemplateElement<Edge, LineRule2> Line;
}
......
/**
* \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "LineRule2.h"
#include "logog/include/logog.hpp"
#include "GeoLib/AnalyticalGeometry.h"
#include "MeshLib/Node.h"
namespace MeshLib {
const unsigned LineRule2::n_all_nodes;
const unsigned LineRule2::n_base_nodes;
const unsigned LineRule2::dimension;
const unsigned LineRule2::edge_nodes[1][2] =
{
{0, 1} // Edge 0
};
double LineRule2::computeVolume(Node const* const* _nodes)
{
return sqrt(MathLib::sqrDist(_nodes[0]->getCoords(), _nodes[1]->getCoords()));
}
bool LineRule2::isPntInElement(Node const* const* _nodes, MathLib::Point3d const& pnt, double eps)
{
double tmp;
double tmp_dst(0);
double const dist =MathLib::calcProjPntToLineAndDists(pnt.getCoords(), _nodes[0]->getCoords(), _nodes[1]->getCoords(), tmp, tmp_dst);
return (dist < eps);
}
unsigned LineRule2::identifyFace(Node const* const* _nodes, Node* nodes[1])
{
if (nodes[0] == _nodes[0])
return 0;
if (nodes[0] == _nodes[1])
return 1;
return std::numeric_limits<unsigned>::max();
}
ElementErrorCode LineRule2::validate(const Element* e)
{
ElementErrorCode error_code;
error_code[ElementErrorFlag::ZeroVolume] = e->hasZeroVolume();
return error_code;
}
} // end namespace MeshLib
/**
* \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#ifndef LINERULE2_H_
#define LINERULE2_H_
#include "MeshLib/MeshEnums.h"
#include "Element.h"
#include "EdgeReturn.h"
namespace MeshLib
{
/**
* A 1d Edge or Line Element.
* @code
* 0--------1
* @endcode
*/
class LineRule2
{
public:
/// Constant: The number of base nodes for this element
static const unsigned n_base_nodes = 2u;
/// Constant: The number of all nodes for this element
static const unsigned n_all_nodes = 2u;
/// Constant: Dimension of this mesh element
static const unsigned dimension = 1;
/// Constant: The geometric type of the element
static const MeshElemType mesh_elem_type = MeshElemType::LINE;
/// Constant: The FEM type of the element
static const CellType cell_type = CellType::LINE2;
/// Constant: The number of faces
static const unsigned n_faces = 0;
/// Constant: The number of edges
static const unsigned n_edges = 0;
/// Constant: The number of neighbors
static const unsigned n_neighbors = 2;
/// Constant: Local node index table for edge
static const unsigned edge_nodes[1][2];
/// Edge rule
typedef DummyEdgeReturn EdgeReturn;
/// Get the number of nodes for face i.
static unsigned getNFaceNodes(unsigned /*i*/) { return 0; }
/// Returns the i-th face of the element.
static const Element* getFace(const Element* /*e*/, unsigned /*i*/) { return nullptr; }
/**
* Checks if a point is inside the element.
* @param pnt a 3D GeoLib::Point object
* @param eps tolerance for numerical algorithm used or computing the property
* @return true if the point is not outside the element, false otherwise
*/
static bool isPntInElement(Node const* const* _nodes, MathLib::Point3d const& pnt, double eps);
/**
* Tests if the element is geometrically valid.
* @param check_zero_volume indicates if volume == 0 should be checked
*/
static ElementErrorCode validate(const Element* e);
/// Returns the ID of a face given an array of nodes.
static unsigned identifyFace(Node const* const*, Node* nodes[1]);
/// Calculates the length of a line
static double computeVolume(Node const* const* _nodes);
}; /* class */
} /* namespace */
#endif /* LINERULE2_H_ */
......@@ -15,11 +15,13 @@
#ifndef PRISM_H_
#define PRISM_H_
#include "TemplatePrism.h"
#include "TemplateElement.h"
#include "Cell.h"
#include "PrismRule6.h"
namespace MeshLib {
typedef TemplatePrism<6, CellType::PRISM6> Prism;
typedef TemplateElement<Cell, PrismRule6> Prism;
}
......
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