Skip to content
Snippets Groups Projects
Commit 4107ae26 authored by Dmitri Naumov's avatar Dmitri Naumov
Browse files

[MeL] Extract common HexRule subclass

parent 5fa82b0f
No related branches found
No related tags found
No related merge requests found
/**
* \file
* \copyright
* Copyright (c) 2012-2023, 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 "HexRule.h"
#include "MathLib/GeometricBasics.h"
#include "MeshLib/Node.h"
#include "Quad.h"
namespace MeshLib
{
double HexRule::computeVolume(Node const* const* _nodes)
{
return MathLib::calcTetrahedronVolume(
*_nodes[4], *_nodes[7], *_nodes[5], *_nodes[0]) +
MathLib::calcTetrahedronVolume(
*_nodes[5], *_nodes[3], *_nodes[1], *_nodes[0]) +
MathLib::calcTetrahedronVolume(
*_nodes[5], *_nodes[7], *_nodes[3], *_nodes[0]) +
MathLib::calcTetrahedronVolume(
*_nodes[5], *_nodes[7], *_nodes[6], *_nodes[2]) +
MathLib::calcTetrahedronVolume(
*_nodes[1], *_nodes[3], *_nodes[5], *_nodes[2]) +
MathLib::calcTetrahedronVolume(
*_nodes[3], *_nodes[7], *_nodes[5], *_nodes[2]);
}
bool HexRule::isPntInElement(Node const* const* nodes,
MathLib::Point3d const& pnt,
double eps)
{
return (MathLib::isPointInTetrahedron(
pnt, *nodes[4], *nodes[7], *nodes[5], *nodes[0], eps) ||
MathLib::isPointInTetrahedron(
pnt, *nodes[5], *nodes[3], *nodes[1], *nodes[0], eps) ||
MathLib::isPointInTetrahedron(
pnt, *nodes[5], *nodes[7], *nodes[3], *nodes[0], eps) ||
MathLib::isPointInTetrahedron(
pnt, *nodes[5], *nodes[7], *nodes[6], *nodes[2], eps) ||
MathLib::isPointInTetrahedron(
pnt, *nodes[1], *nodes[3], *nodes[5], *nodes[2], eps) ||
MathLib::isPointInTetrahedron(
pnt, *nodes[3], *nodes[7], *nodes[5], *nodes[2], eps));
}
ElementErrorCode HexRule::validate(const Element* e)
{
ElementErrorCode error_code;
error_code[ElementErrorFlag::ZeroVolume] = hasZeroVolume(*e);
for (unsigned i = 0; i < 6; ++i)
{
if (error_code.all())
{
break;
}
const MeshLib::Element* quad(e->getFace(i));
error_code |= quad->validate();
delete quad;
}
error_code[ElementErrorFlag::NodeOrder] = !e->testElementNodeOrder();
return error_code;
}
} // end namespace MeshLib
/**
* \file
* \copyright
* Copyright (c) 2012-2023, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include "CellRule.h"
#include "Element.h"
#include "MeshLib/MeshEnums.h"
namespace MeshLib
{
class HexRule : public CellRule
{
public:
/// Constant: The number of base nodes for this element
static const unsigned n_base_nodes = 8u;
/// Constant: The geometric type of the element
static const MeshElemType mesh_elem_type = MeshElemType::HEXAHEDRON;
/// Constant: The number of faces
static const unsigned n_faces = 6;
/// Constant: The number of edges
static const unsigned n_edges = 12;
/// Constant: The number of neighbors
static const unsigned n_neighbors = 6;
/**
* \copydoc MeshLib::Element::isPntInElement()
* \param nodes the nodes of the element.
*/
static bool isPntInElement(Node const* const* nodes,
MathLib::Point3d const& pnt, double eps);
/**
* Tests if the element is geometrically valid.
*/
static ElementErrorCode validate(const Element* e);
/// Calculates the volume of a convex hexahedron by partitioning it into six
/// tetrahedra.
static double computeVolume(Node const* const* _nodes);
protected:
template <std::size_t N>
static unsigned identifyFace(Node const* const* _nodes,
Node const* nodes[3],
unsigned const face_nodes[6][N])
{
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])
{
flag++;
}
}
}
if (flag == 3)
{
return i;
}
}
return std::numeric_limits<unsigned>::max();
}
};
} // namespace MeshLib
......@@ -10,10 +10,8 @@
#pragma once
#include "MeshLib/MeshEnums.h"
#include "Element.h"
#include "EdgeReturn.h"
#include "HexRule8.h"
#include "HexRule.h"
namespace MeshLib
{
......@@ -43,7 +41,7 @@ namespace MeshLib
*
* \endcode
*/
class HexRule20 : public HexRule8
class HexRule20 : public HexRule
{
public:
/// Constant: The number of all nodes for this element
......@@ -64,6 +62,12 @@ public:
/// Returns the i-th face of the element.
static const Element* getFace(const Element* e, unsigned i);
/// Returns the ID of a face given an array of nodes.
static unsigned identifyFace(Node const* const* _nodes,
Node const* nodes[3])
{
return HexRule::identifyFace(_nodes, nodes, face_nodes);
}
}; /* class */
} // namespace MeshLib
......@@ -58,82 +58,4 @@ const Element* HexRule8::getFace(const Element* e, unsigned i)
ERR("Error in MeshLib::Element::getFace() - Index {:d} does not exist.", i);
return nullptr;
}
double HexRule8::computeVolume(Node const* const* _nodes)
{
return MathLib::calcTetrahedronVolume(
*_nodes[4], *_nodes[7], *_nodes[5], *_nodes[0]) +
MathLib::calcTetrahedronVolume(
*_nodes[5], *_nodes[3], *_nodes[1], *_nodes[0]) +
MathLib::calcTetrahedronVolume(
*_nodes[5], *_nodes[7], *_nodes[3], *_nodes[0]) +
MathLib::calcTetrahedronVolume(
*_nodes[5], *_nodes[7], *_nodes[6], *_nodes[2]) +
MathLib::calcTetrahedronVolume(
*_nodes[1], *_nodes[3], *_nodes[5], *_nodes[2]) +
MathLib::calcTetrahedronVolume(
*_nodes[3], *_nodes[7], *_nodes[5], *_nodes[2]);
}
bool HexRule8::isPntInElement(Node const* const* nodes,
MathLib::Point3d const& pnt,
double eps)
{
return (MathLib::isPointInTetrahedron(
pnt, *nodes[4], *nodes[7], *nodes[5], *nodes[0], eps) ||
MathLib::isPointInTetrahedron(
pnt, *nodes[5], *nodes[3], *nodes[1], *nodes[0], eps) ||
MathLib::isPointInTetrahedron(
pnt, *nodes[5], *nodes[7], *nodes[3], *nodes[0], eps) ||
MathLib::isPointInTetrahedron(
pnt, *nodes[5], *nodes[7], *nodes[6], *nodes[2], eps) ||
MathLib::isPointInTetrahedron(
pnt, *nodes[1], *nodes[3], *nodes[5], *nodes[2], eps) ||
MathLib::isPointInTetrahedron(
pnt, *nodes[3], *nodes[7], *nodes[5], *nodes[2], eps));
}
unsigned HexRule8::identifyFace(Node const* const* _nodes, Node const* 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])
{
flag++;
}
}
}
if (flag == 3)
{
return i;
}
}
return std::numeric_limits<unsigned>::max();
}
ElementErrorCode HexRule8::validate(const Element* e)
{
ElementErrorCode error_code;
error_code[ElementErrorFlag::ZeroVolume] = hasZeroVolume(*e);
for (unsigned i = 0; i < 6; ++i)
{
if (error_code.all())
{
break;
}
const MeshLib::Element* quad(e->getFace(i));
error_code |= quad->validate();
delete quad;
}
error_code[ElementErrorFlag::NodeOrder] = !e->testElementNodeOrder();
return error_code;
}
} // end namespace MeshLib
......@@ -10,14 +10,11 @@
#pragma once
#include "MeshLib/MeshEnums.h"
#include "Element.h"
#include "EdgeReturn.h"
#include "CellRule.h"
#include "HexRule.h"
namespace MeshLib
{
/**
* A 8-nodes Hexahedron Element.
* \code
......@@ -43,30 +40,15 @@ namespace MeshLib
*
* \endcode
*/
class HexRule8 : public CellRule
class HexRule8 : public HexRule
{
public:
/// Constant: The number of base nodes for this element
static const unsigned n_base_nodes = 8u;
/// Constant: The number of all nodes for this element
static const unsigned n_all_nodes = 8u;
/// Constant: The geometric type of the element
static const MeshElemType mesh_elem_type = MeshElemType::HEXAHEDRON;
/// Constant: The FEM type of the element
static const CellType cell_type = CellType::HEX8;
/// Constant: The number of faces
static const unsigned n_faces = 6;
/// Constant: The number of edges
static const unsigned n_edges = 12;
/// Constant: The number of neighbors
static const unsigned n_neighbors = 6;
/// Constant: Local node index table for faces
static const unsigned face_nodes[6][4];
......@@ -79,25 +61,12 @@ public:
/// Returns the i-th face of the element.
static const Element* getFace(const Element* e, unsigned i);
/**
* \copydoc MeshLib::Element::isPntInElement()
* \param nodes the nodes of the element.
*/
static bool isPntInElement(Node const* const* nodes,
MathLib::Point3d const& pnt, double eps);
/**
* Tests if the element is geometrically valid.
*/
static ElementErrorCode validate(const Element* e);
/// Returns the ID of a face given an array of nodes.
static unsigned identifyFace(Node const* const* /*_nodes*/,
Node const* nodes[3]);
/// Calculates the volume of a convex hexahedron by partitioning it into six tetrahedra.
static double computeVolume(Node const* const* _nodes);
static unsigned identifyFace(Node const* const* _nodes,
Node const* nodes[3])
{
return HexRule::identifyFace(_nodes, nodes, face_nodes);
}
}; /* class */
} // namespace MeshLib
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