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 _neighbors[this->identifyFace(face_nodes)] = e;
72 return std::optional<unsigned>(e->identifyFace(face_nodes));
73 }
74 }
75 }
76 }
77
78 return std::optional<unsigned>();
79}
80
82{
83 return std::any_of(_neighbors, _neighbors + this->getNumberOfNeighbors(),
84 [](MeshLib::Element const* const e)
85 { return e == nullptr; });
86}
87
88std::ostream& operator<<(std::ostream& os, Element const& e)
89{
90 os << "Element #" << e._id << " @ " << &e << " with "
91 << e.getNumberOfNeighbors() << " neighbours\n";
92
93 unsigned const nnodes = e.getNumberOfNodes();
94 MeshLib::Node* const* const nodes = e.getNodes();
95 os << "MeshElemType: "
96 << static_cast<std::underlying_type<MeshElemType>::type>(e.getGeomType())
97 << " with " << nnodes << " nodes: {\n";
98 for (unsigned n = 0; n < nnodes; ++n)
99 {
100 os << " #" << nodes[n]->getID() << " @ " << nodes[n] << " coords ["
101 << *nodes[n] << "]\n";
102 }
103 return os << '}';
104}
105
106bool areNeighbors(Element const* const element, Element const* const other)
107{
108 unsigned nNeighbors(element->getNumberOfNeighbors());
109 for (unsigned i = 0; i < nNeighbors; i++)
110 {
111 if (element->getNeighbor(i) == other)
112 {
113 return true;
114 }
115 }
116 return false;
117}
118
119bool hasZeroVolume(MeshLib::Element const& element)
120{
121 return element.getContent() < std::numeric_limits<double>::epsilon();
122}
123
125{
126 const unsigned nNodes(element.getNumberOfBaseNodes());
127 MathLib::Point3d center{{0, 0, 0}};
128 for (unsigned i = 0; i < nNodes; ++i)
129 {
130 center.asEigenVector3d() += element.getNode(i)->asEigenVector3d();
131 }
132 center.asEigenVector3d() /= nNodes;
133 return center;
134}
135
136std::pair<double, double> computeSqrNodeDistanceRange(
137 MeshLib::Element const& element, bool const check_allnodes)
138{
139 double min = std::numeric_limits<double>::max();
140 double max = 0;
141 const unsigned nnodes = check_allnodes ? element.getNumberOfNodes()
142 : element.getNumberOfBaseNodes();
143 for (unsigned i = 0; i < nnodes; i++)
144 {
145 for (unsigned j = i + 1; j < nnodes; j++)
146 {
147 const double dist(
148 MathLib::sqrDist(*element.getNode(i), *element.getNode(j)));
149 min = std::min(dist, min);
150 max = std::max(dist, max);
151 }
152 }
153 return {min, max};
154}
155
156std::pair<double, double> computeSqrEdgeLengthRange(Element const& element)
157{
158 double min = std::numeric_limits<double>::max();
159 double max = 0;
160 const unsigned nEdges(element.getNumberOfEdges());
161 for (unsigned i = 0; i < nEdges; i++)
162 {
163 const double dist(MathLib::sqrDist(*element.getEdgeNode(i, 0),
164 *element.getEdgeNode(i, 1)));
165 min = std::min(dist, min);
166 max = std::max(dist, max);
167 }
168 return {min, max};
169}
170
172{
173 for (std::size_t i(0); i < e.getNumberOfBaseNodes(); ++i)
174 {
175 if (MathLib::sqrDist2d(p, *e.getNode(i)) <
176 std::numeric_limits<double>::epsilon())
177 {
178 return true;
179 }
180 }
181
183 {
184 MathLib::Point3d const& n0(*e.getNode(0));
185 MathLib::Point3d const& n1(*e.getNode(1));
186 MathLib::Point3d const& n2(*e.getNode(2));
187
188 return MathLib::isPointInTriangleXY(p, n0, n1, n2);
189 }
191 {
192 MathLib::Point3d const& n0(*e.getNode(0));
193 MathLib::Point3d const& n1(*e.getNode(1));
194 MathLib::Point3d const& n2(*e.getNode(2));
195 MathLib::Point3d const& n3(*e.getNode(3));
196
197 return MathLib::isPointInTriangleXY(p, n0, n1, n2) ||
198 MathLib::isPointInTriangleXY(p, n0, n2, n3);
199 }
200
201 WARN("isPointInElementXY: element type '{:s}' is not supported.",
203 return false;
204}
205
206unsigned getNodeIDinElement(Element const& element, const MeshLib::Node* node)
207{
208 const unsigned nNodes(element.getNumberOfNodes());
209 for (unsigned i(0); i < nNodes; i++)
210 {
211 if (node == element.getNode(i))
212 {
213 return i;
214 }
215 }
216 return std::numeric_limits<unsigned>::max();
217}
218
219std::size_t getNodeIndex(Element const& element, unsigned const idx)
220{
221#ifndef NDEBUG
222 if (idx >= element.getNumberOfNodes())
223 {
224 ERR("Error in MeshLib::getNodeIndex() - Index does not "
225 "exist.");
226 return std::numeric_limits<std::size_t>::max();
227 }
228#endif
229 return element.getNode(idx)->getID();
230}
231
232} // namespace MeshLib
Definition of the Element class.
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:202
Element(std::size_t id)
Definition Element.cpp:25
virtual unsigned getNumberOfBaseNodes() const =0
virtual bool isBoundaryElement() const
Definition Element.cpp:81
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:200
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:136
bool isPointInElementXY(MathLib::Point3d const &p, Element const &e)
Definition Element.cpp:171
bool hasZeroVolume(MeshLib::Element const &element)
Returns true if the element has zero length/area/volume.
Definition Element.cpp:119
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:156
std::size_t getNodeIndex(Element const &element, unsigned const idx)
Definition Element.cpp:219
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:206
MathLib::Point3d getCenterOfGravity(Element const &element)
Calculates the center of gravity for the mesh element.
Definition Element.cpp:124
std::ostream & operator<<(std::ostream &os, Element const &e)
Definition Element.cpp:88
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:106