OGS
TemplateElement.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <array>
7#include <limits>
8
9#include "MathLib/Point3d.h"
10
11#include "MeshLib/Node.h"
16
17namespace MeshLib
18{
19
26template <class ELEMENT_RULE>
28{
29public:
31 static const unsigned n_all_nodes = ELEMENT_RULE::n_all_nodes;
32
34 static const unsigned n_base_nodes = ELEMENT_RULE::n_base_nodes;
35
37 static const unsigned dimension = ELEMENT_RULE::dimension;
38
47 std::size_t id = std::numeric_limits<std::size_t>::max());
48
56 std::array<Node*, n_all_nodes> const& nodes,
57 std::size_t id = std::numeric_limits<std::size_t>::max());
58
60 explicit TemplateElement(const TemplateElement& e);
61
63 Element* clone() const override { return new TemplateElement(*this); }
64 Element* clone(Node** nodes, std::size_t id) const override
65 {
66 return new TemplateElement(nodes, id);
67 }
68
70 constexpr unsigned getDimension() const override { return dimension; }
72 const Element* getEdge(unsigned i) const override
73 {
74 return ELEMENT_RULE::EdgeReturn::getEdge(this, i);
75 }
76
78 const Element* getFace(unsigned i) const override
79 {
80 return ELEMENT_RULE::getFace(this, i);
81 }
82
84 const Element* getBoundary(unsigned i) const override
85 {
86 if constexpr (std::is_convertible<ELEMENT_RULE, FaceRule>::value)
87 {
88 return ELEMENT_RULE::EdgeReturn::getEdge(this, i);
89 }
90 if constexpr (std::is_convertible<ELEMENT_RULE, CellRule>::value)
91 {
92 return ELEMENT_RULE::getFace(this, i);
93 }
94 OGS_FATAL("TemplateElement::getBoundary for boundary {:d} failed.", i);
95 }
96
98 unsigned getNumberOfBoundaries() const override
99 {
100 if constexpr (std::is_convertible<ELEMENT_RULE, FaceRule>::value)
101 {
102 return ELEMENT_RULE::n_edges;
103 }
104 else
105 {
106 return ELEMENT_RULE::n_faces;
107 }
108 }
109
111 unsigned getNumberOfEdges() const override { return ELEMENT_RULE::n_edges; }
113 unsigned getNumberOfFaces() const override { return ELEMENT_RULE::n_faces; }
115 unsigned getNumberOfNeighbors() const override
116 {
117 return ELEMENT_RULE::n_neighbors;
118 }
119
120 const Element* getNeighbor(unsigned i) const override
121 {
122#ifndef NDEBUG
123 if (i < ELEMENT_RULE::n_neighbors)
124#endif
125 {
126 return _neighbors[i];
127 }
128#ifndef NDEBUG
129 ERR("Error in MeshLib::TemplateElement::getNeighbor() - Index {:d} "
130 "does not exist.",
131 i);
132 return nullptr;
133#endif
134 }
135
137 unsigned getNumberOfBaseNodes() const override { return n_base_nodes; }
139 unsigned getNumberOfNodes() const override { return n_all_nodes; }
141 MeshElemType getGeomType() const override
142 {
143 return ELEMENT_RULE::mesh_elem_type;
144 }
145
147 CellType getCellType() const override { return ELEMENT_RULE::cell_type; }
149 bool isEdge(unsigned idx1, unsigned idx2) const override;
150
158 MathLib::Point3d const& pnt,
159 double eps = std::numeric_limits<double>::epsilon()) const override
160 {
161 return ELEMENT_RULE::isPntInElement(_nodes.data(), pnt, eps);
162 }
163
167 ElementErrorCode validate() const override
168 {
169 return ELEMENT_RULE::validate(this);
170 }
171
173 unsigned identifyFace(Node const* nodes[3]) const override
174 {
175 return ELEMENT_RULE::identifyFace(_nodes.data(), nodes);
176 }
177
179 double computeVolume() override
180 {
181 return ELEMENT_RULE::computeVolume(_nodes.data());
182 }
183
184 const Node* getNode(unsigned idx) const override;
185 Node* getNode(unsigned idx) override;
186 void setNode(unsigned idx, Node* node) override;
187 Node* const* getNodes() const override { return _nodes.data(); }
188
190 inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const override
191 {
192 if (getNumberOfEdges() > 0)
193 {
194 return const_cast<Node*>(
195 _nodes[ELEMENT_RULE::edge_nodes[edge_id][node_id]]);
196 }
197
198 return nullptr;
199 }
200
205 bool testElementNodeOrder() const override
206 {
207 return ELEMENT_RULE::testElementNodeOrder(*this);
208 }
209
210 double getContent() const override final;
211
212 std::array<Node*, n_all_nodes> _nodes;
213};
214
215} // namespace MeshLib
216
217#include "TemplateElement-impl.h"
#define OGS_FATAL(...)
Definition Error.h:19
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
Collects error flags for mesh elements.
Element ** _neighbors
Definition Element.h:193
Element(std::size_t id)
Definition Element.cpp:14
constexpr std::span< Node *const > nodes() const
Span of element's nodes, their pointers actually.
Definition Element.h:63
double computeVolume() override
Calculates the volume of a convex hexahedron by partitioning it into six tetrahedra.
const Element * getBoundary(unsigned i) const override
Returns the boundary i of the element.
std::array< Node *, n_all_nodes > _nodes
const Element * getEdge(unsigned i) const override
Returns the edge i of the element.
Element * clone() const override
Returns a copy of this object.
unsigned getNumberOfBoundaries() const override
Returns the number of boundaries of the element.
unsigned getNumberOfNodes() const override
Get the number of all nodes for this element.
Node * getNode(unsigned idx) override
bool isEdge(unsigned idx1, unsigned idx2) const override
Returns true if these two indices form an edge and false otherwise.
MeshElemType getGeomType() const override
Get the type of this element.
unsigned getNumberOfNeighbors() const override
Get the number of neighbors for this element.
void setNode(unsigned idx, Node *node) override
const Element * getFace(unsigned i) const override
Returns the face i of the element.
ElementErrorCode validate() const override
TemplateElement(std::array< Node *, n_all_nodes > const &nodes, std::size_t id=std::numeric_limits< std::size_t >::max())
bool testElementNodeOrder() const override
unsigned getNumberOfFaces() const override
Get the number of faces for this element.
TemplateElement(Node *nodes[n_all_nodes], std::size_t id=std::numeric_limits< std::size_t >::max())
unsigned identifyFace(Node const *nodes[3]) const override
Returns the ID of a face given an array of nodes.
double getContent() const override final
Returns the length, area or volume of a 1D, 2D or 3D element.
const Element * getNeighbor(unsigned i) const override
Get the specified neighbor.
CellType getCellType() const override
Get the FEM type of this element.
bool isPntInElement(MathLib::Point3d const &pnt, double eps=std::numeric_limits< double >::epsilon()) const override
unsigned getNumberOfEdges() const override
Get the number of edges for this element.
Node *const * getNodes() const override
Get array of element nodes.
Node * getEdgeNode(unsigned edge_id, unsigned node_id) const override
Return a specific edge node.
constexpr unsigned getDimension() const override
Get dimension of the mesh element.
const Node * getNode(unsigned idx) const override
unsigned getNumberOfBaseNodes() const override
Get the number of linear nodes for this element.
Element * clone(Node **nodes, std::size_t id) const override
TemplateElement(const TemplateElement &e)
Copy constructor.
CellType
Types of mesh elements supported by OpenGeoSys.
Definition MeshEnums.h:53
MeshElemType
Types of mesh elements supported by OpenGeoSys. Values are from VTKCellType enum.
Definition MeshEnums.h:37