Loading [MathJax]/extensions/tex2jax.js
OGS
Element.cpp
Go to the documentation of this file.
1
15#include "Element.h"
16
17#include "BaseLib/Logging.h"
18#include "Line.h"
20#include "MathLib/MathTools.h"
21#include "MeshLib/Node.h"
22
23namespace MeshLib
24{
25Element::Element(std::size_t id) : _id(id), _neighbors(nullptr) {}
26
28{
29 delete[] this->_neighbors;
30}
31
32void Element::setNeighbor(Element* neighbor, unsigned const face_id)
33{
34 if (neighbor == this)
35 {
36 return;
37 }
38
39 this->_neighbors[face_id] = neighbor;
40}
41
42std::optional<unsigned> Element::addNeighbor(Element* e)
43{
44 const unsigned dim(this->getDimension());
45 if (e == this || e == nullptr || e->getDimension() != dim)
46 {
47 return std::optional<unsigned>();
48 }
49
50 if (areNeighbors(this, e))
51 {
52 return std::optional<unsigned>();
53 }
54
55 Node const* face_nodes[3];
56 const unsigned nNodes(this->getNumberOfBaseNodes());
57 const unsigned eNodes(e->getNumberOfBaseNodes());
58 const Node* const* e_nodes = e->getNodes();
59 unsigned count(0);
60 for (unsigned i(0); i < nNodes; i++)
61 {
62 for (unsigned j(0); j < eNodes; j++)
63 {
64 if (getNode(i) == e_nodes[j])
65 {
66 face_nodes[count] = getNode(i);
67 // increment shared nodes counter and check if enough nodes are
68 // similar to be sure e is a neighbour of this
69 if ((++count) >= dim)
70 {
71 auto const this_face_id = this->identifyFace(face_nodes);
72 if (this_face_id == std::numeric_limits<unsigned>::max())
73 {
75 "Could not find face of {} for the face nodes [{}, "
76 "{}, {}].",
77 *this, *face_nodes[0], *face_nodes[1],
78 *face_nodes[2]);
79 }
80 _neighbors[this_face_id] = e;
81 auto const neighbors_face_id = e->identifyFace(face_nodes);
82 if (neighbors_face_id ==
83 std::numeric_limits<unsigned>::max())
84 {
86 "Could not find face of the neighbour {} for the "
87 "face nodes [{}, {}, {}].\n"
88 "For the {} the face id {} was identified.",
89 *e, *face_nodes[0], *face_nodes[1], *face_nodes[2],
90 *this, this_face_id);
91 }
92 return neighbors_face_id;
93 }
94 }
95 }
96 }
97
98 return std::optional<unsigned>();
99}
100
102{
103 return std::any_of(_neighbors, _neighbors + this->getNumberOfNeighbors(),
104 [](MeshLib::Element const* const e)
105 { return e == nullptr; });
106}
107
108std::ostream& operator<<(std::ostream& os, Element const& e)
109{
110 os << "element #" << e._id << " @ " << &e << " with "
111 << e.getNumberOfNeighbors() << " neighbours\n";
112
113 unsigned const nnodes = e.getNumberOfNodes();
114 MeshLib::Node* const* const nodes = e.getNodes();
115 os << "MeshElemType: " << MeshLib::MeshElemType2String(e.getGeomType())
116 << " with " << nnodes << " nodes: {\n";
117 for (unsigned n = 0; n < nnodes; ++n)
118 {
119 os << " " << *nodes[n] << " @ " << nodes[n] << '\n';
120 }
121 return os << '}';
122}
123
124bool areNeighbors(Element const* const element, Element const* const other)
125{
126 unsigned nNeighbors(element->getNumberOfNeighbors());
127 for (unsigned i = 0; i < nNeighbors; i++)
128 {
129 if (element->getNeighbor(i) == other)
130 {
131 return true;
132 }
133 }
134 return false;
135}
136
137bool hasZeroVolume(MeshLib::Element const& element)
138{
139 return element.getContent() < std::numeric_limits<double>::epsilon();
140}
141
143{
144 const unsigned nNodes(element.getNumberOfBaseNodes());
145 MathLib::Point3d center{{0, 0, 0}};
146 for (unsigned i = 0; i < nNodes; ++i)
147 {
148 center.asEigenVector3d() += element.getNode(i)->asEigenVector3d();
149 }
150 center.asEigenVector3d() /= nNodes;
151 return center;
152}
153
154std::pair<double, double> computeSqrNodeDistanceRange(
155 MeshLib::Element const& element, bool const check_allnodes)
156{
157 double min = std::numeric_limits<double>::max();
158 double max = 0;
159 const unsigned nnodes = check_allnodes ? element.getNumberOfNodes()
160 : element.getNumberOfBaseNodes();
161 for (unsigned i = 0; i < nnodes; i++)
162 {
163 for (unsigned j = i + 1; j < nnodes; j++)
164 {
165 const double dist(
166 MathLib::sqrDist(*element.getNode(i), *element.getNode(j)));
167 min = std::min(dist, min);
168 max = std::max(dist, max);
169 }
170 }
171 return {min, max};
172}
173
174std::pair<double, double> computeSqrEdgeLengthRange(Element const& element)
175{
176 double min = std::numeric_limits<double>::max();
177 double max = 0;
178 const unsigned nEdges(element.getNumberOfEdges());
179 for (unsigned i = 0; i < nEdges; i++)
180 {
181 const double dist(MathLib::sqrDist(*element.getEdgeNode(i, 0),
182 *element.getEdgeNode(i, 1)));
183 min = std::min(dist, min);
184 max = std::max(dist, max);
185 }
186 return {min, max};
187}
188
190{
191 for (std::size_t i(0); i < e.getNumberOfBaseNodes(); ++i)
192 {
193 if (MathLib::sqrDist2d(p, *e.getNode(i)) <
194 std::numeric_limits<double>::epsilon())
195 {
196 return true;
197 }
198 }
199
201 {
202 MathLib::Point3d const& n0(*e.getNode(0));
203 MathLib::Point3d const& n1(*e.getNode(1));
204 MathLib::Point3d const& n2(*e.getNode(2));
205
206 return MathLib::isPointInTriangleXY(p, n0, n1, n2);
207 }
209 {
210 MathLib::Point3d const& n0(*e.getNode(0));
211 MathLib::Point3d const& n1(*e.getNode(1));
212 MathLib::Point3d const& n2(*e.getNode(2));
213 MathLib::Point3d const& n3(*e.getNode(3));
214
215 return MathLib::isPointInTriangleXY(p, n0, n1, n2) ||
216 MathLib::isPointInTriangleXY(p, n0, n2, n3);
217 }
218
219 WARN("isPointInElementXY: element type '{:s}' is not supported.",
221 return false;
222}
223
224unsigned getNodeIDinElement(Element const& element, const MeshLib::Node* node)
225{
226 const unsigned nNodes(element.getNumberOfNodes());
227 for (unsigned i(0); i < nNodes; i++)
228 {
229 if (node == element.getNode(i))
230 {
231 return i;
232 }
233 }
234 return std::numeric_limits<unsigned>::max();
235}
236
237std::size_t getNodeIndex(Element const& element, unsigned const idx)
238{
239#ifndef NDEBUG
240 if (idx >= element.getNumberOfNodes())
241 {
242 ERR("Error in MeshLib::getNodeIndex() - Index does not "
243 "exist.");
244 return std::numeric_limits<std::size_t>::max();
245 }
246#endif
247 return element.getNode(idx)->getID();
248}
249
250} // namespace MeshLib
Definition of the Element class.
#define OGS_FATAL(...)
Definition Error.h:26
Definition of the Line class.
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
Definition of the Node class.
std::size_t getID() const
Eigen::Vector3d const & asEigenVector3d() const
Definition Point3d.h:64
virtual MeshElemType getGeomType() const =0
void setNeighbor(Element *neighbor, unsigned const face_id)
Definition Element.cpp:32
virtual ~Element()
Destructor.
Definition Element.cpp:27
virtual unsigned getNumberOfNodes() const =0
virtual double getContent() const =0
Returns the length, area or volume of a 1D, 2D or 3D element.
Element ** _neighbors
Definition Element.h:204
Element(std::size_t id)
Definition Element.cpp:25
virtual unsigned getNumberOfBaseNodes() const =0
virtual bool isBoundaryElement() const
Definition Element.cpp:101
virtual const Node * getNode(unsigned idx) const =0
virtual unsigned getNumberOfNeighbors() const =0
Get the number of neighbors for this element.
std::size_t _id
Definition Element.h:202
virtual unsigned getNumberOfEdges() const =0
Get the number of edges for this element.
virtual constexpr unsigned getDimension() const =0
Get dimension of the mesh element.
std::optional< unsigned > addNeighbor(Element *e)
Tries to add an element e as neighbour to this element. If the elements really are neighbours,...
Definition Element.cpp:42
virtual Node *const * getNodes() const =0
Get array of element nodes.
virtual const Element * getNeighbor(unsigned i) const =0
Get the specified neighbor.
virtual Node * getEdgeNode(unsigned edge_id, unsigned node_id) const =0
Return a specific edge node.
virtual unsigned identifyFace(Node const *nodes[3]) const =0
Returns the ID of a face given an array of nodes.
double sqrDist2d(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.h:123
double sqrDist(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.cpp:26
bool isPointInTriangleXY(MathLib::Point3d const &p, MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &c)
std::pair< double, double > computeSqrNodeDistanceRange(MeshLib::Element const &element, bool const check_allnodes)
Compute the minimum and maximum node distances for this element.
Definition Element.cpp:154
bool isPointInElementXY(MathLib::Point3d const &p, Element const &e)
Definition Element.cpp:189
bool hasZeroVolume(MeshLib::Element const &element)
Returns true if the element has zero length/area/volume.
Definition Element.cpp:137
std::string MeshElemType2String(const MeshElemType t)
Given a MeshElemType this returns the appropriate string.
Definition MeshEnums.cpp:21
std::pair< double, double > computeSqrEdgeLengthRange(Element const &element)
Compute the minimum and maximum squared edge length for this element.
Definition Element.cpp:174
std::size_t getNodeIndex(Element const &element, unsigned const idx)
Definition Element.cpp:237
unsigned getNodeIDinElement(Element const &element, const MeshLib::Node *node)
Returns the position of the given node in the node array of this element.
Definition Element.cpp:224
MathLib::Point3d getCenterOfGravity(Element const &element)
Calculates the center of gravity for the mesh element.
Definition Element.cpp:142
std::ostream & operator<<(std::ostream &os, Element const &e)
Definition Element.cpp:108
bool areNeighbors(Element const *const element, Element const *const other)
Returns true if elem is a neighbour of this element and false otherwise.
Definition Element.cpp:124