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 
23 namespace MeshLib
24 {
25 Element::Element(std::size_t id) : _id(id), _neighbors(nullptr) {}
26 
28 {
29  delete[] this->_neighbors;
30 }
31 
32 void 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 
42 std::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 {
84  [](MeshLib::Element const* const e)
85  { return e == nullptr; });
86 }
87 
88 #ifndef NDEBUG
89 std::ostream& operator<<(std::ostream& os, Element const& e)
90 {
91  os << "Element #" << e._id << " @ " << &e << " with "
92  << e.getNumberOfNeighbors() << " neighbours\n";
93 
94  unsigned const nnodes = e.getNumberOfNodes();
95  MeshLib::Node* const* const nodes = e.getNodes();
96  os << "MeshElemType: "
97  << static_cast<std::underlying_type<MeshElemType>::type>(e.getGeomType())
98  << " with " << nnodes << " nodes: { ";
99  for (unsigned n = 0; n < nnodes; ++n)
100  {
101  os << nodes[n]->getID() << " @ " << nodes[n] << " ";
102  }
103  os << "}\n";
104  return os;
105 }
106 #endif // NDEBUG
107 
108 bool areNeighbors(Element const* const element, Element const* const other)
109 {
110  unsigned nNeighbors(element->getNumberOfNeighbors());
111  for (unsigned i = 0; i < nNeighbors; i++)
112  {
113  if (element->getNeighbor(i) == other)
114  {
115  return true;
116  }
117  }
118  return false;
119 }
120 
121 bool hasZeroVolume(MeshLib::Element const& element)
122 {
123  return element.getContent() < std::numeric_limits<double>::epsilon();
124 }
125 
127 {
128  const unsigned nNodes(element.getNumberOfBaseNodes());
129  MeshLib::Node center(0, 0, 0);
130  for (unsigned i = 0; i < nNodes; ++i)
131  {
132  center[0] += (*element.getNode(i))[0];
133  center[1] += (*element.getNode(i))[1];
134  center[2] += (*element.getNode(i))[2];
135  }
136  center[0] /= nNodes;
137  center[1] /= nNodes;
138  center[2] /= nNodes;
139  return center;
140 }
141 
142 std::pair<double, double> computeSqrNodeDistanceRange(
143  MeshLib::Element const& element, bool const check_allnodes)
144 {
145  double min = std::numeric_limits<double>::max();
146  double max = 0;
147  const unsigned nnodes = check_allnodes ? element.getNumberOfNodes()
148  : element.getNumberOfBaseNodes();
149  for (unsigned i = 0; i < nnodes; i++)
150  {
151  for (unsigned j = i + 1; j < nnodes; j++)
152  {
153  const double dist(
154  MathLib::sqrDist(*element.getNode(i), *element.getNode(j)));
155  min = std::min(dist, min);
156  max = std::max(dist, max);
157  }
158  }
159  return {min, max};
160 }
161 
162 std::pair<double, double> computeSqrEdgeLengthRange(Element const& element)
163 {
164  double min = std::numeric_limits<double>::max();
165  double max = 0;
166  const unsigned nEdges(element.getNumberOfEdges());
167  for (unsigned i = 0; i < nEdges; i++)
168  {
169  const double dist(MathLib::sqrDist(*element.getEdgeNode(i, 0),
170  *element.getEdgeNode(i, 1)));
171  min = std::min(dist, min);
172  max = std::max(dist, max);
173  }
174  return {min, max};
175 }
176 
178 {
179  for (std::size_t i(0); i < e.getNumberOfBaseNodes(); ++i)
180  {
181  if (MathLib::sqrDist2d(p, *e.getNode(i)) <
182  std::numeric_limits<double>::epsilon())
183  {
184  return true;
185  }
186  }
187 
189  {
190  MathLib::Point3d const& n0(*e.getNode(0));
191  MathLib::Point3d const& n1(*e.getNode(1));
192  MathLib::Point3d const& n2(*e.getNode(2));
193 
194  return MathLib::isPointInTriangleXY(p, n0, n1, n2);
195  }
196  if (e.getGeomType() == MeshElemType::QUAD)
197  {
198  MathLib::Point3d const& n0(*e.getNode(0));
199  MathLib::Point3d const& n1(*e.getNode(1));
200  MathLib::Point3d const& n2(*e.getNode(2));
201  MathLib::Point3d const& n3(*e.getNode(3));
202 
203  return MathLib::isPointInTriangleXY(p, n0, n1, n2) ||
204  MathLib::isPointInTriangleXY(p, n0, n2, n3);
205  }
206 
207  WARN("isPointInElementXY: element type '{:s}' is not supported.",
209  return false;
210 }
211 
212 unsigned getNodeIDinElement(Element const& element, const MeshLib::Node* node)
213 {
214  const unsigned nNodes(element.getNumberOfNodes());
215  for (unsigned i(0); i < nNodes; i++)
216  {
217  if (node == element.getNode(i))
218  {
219  return i;
220  }
221  }
222  return std::numeric_limits<unsigned>::max();
223 }
224 
225 std::size_t getNodeIndex(Element const& element, unsigned const idx)
226 {
227 #ifndef NDEBUG
228  if (idx >= element.getNumberOfNodes())
229  {
230  ERR("Error in MeshLib::getNodeIndex() - Index does not "
231  "exist.");
232  return std::numeric_limits<std::size_t>::max();
233  }
234 #endif
235  return element.getNode(idx)->getID();
236 }
237 
238 } // namespace MeshLib
Definition of the Element class.
Definition of the Line class.
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:42
void WARN(char const *fmt, Args const &... args)
Definition: Logging.h:37
Definition of the Node class.
std::size_t getID() const
Definition: Point3dWithID.h:62
virtual MeshElemType getGeomType() const =0
void setNeighbor(Element *neighbor, unsigned const face_id)
Definition: Element.cpp:32
virtual Node *const * getNodes() const =0
Get array of element nodes.
virtual ~Element()
Destructor.
Definition: Element.cpp:27
virtual const Node * getNode(unsigned idx) const =0
virtual unsigned getNumberOfNodes() const =0
virtual double getContent() const =0
Returns the length, area or volume of a 1D, 2D or 3D element.
virtual const Element * getNeighbor(unsigned i) const =0
Get the specified neighbor.
Element ** _neighbors
Definition: Element.h:197
Element(std::size_t id)
Definition: Element.cpp:25
virtual unsigned getNumberOfBaseNodes() const =0
virtual Node * getEdgeNode(unsigned edge_id, unsigned node_id) const =0
Return a specific edge node.
virtual bool isBoundaryElement() const
Definition: Element.cpp:81
virtual unsigned getNumberOfNeighbors() const =0
Get the number of neighbors for this element.
std::size_t _id
Definition: Element.h:195
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 unsigned identifyFace(Node const *nodes[3]) const =0
Returns the ID of a face given an array of nodes.
constexpr bool any_of(List const &values)
Checks if any of the elements in the given list is true.
Definition: Algorithm.h:315
double sqrDist2d(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition: Point3d.h:58
double sqrDist(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition: Point3d.h:48
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:142
bool isPointInElementXY(MathLib::Point3d const &p, Element const &e)
Definition: Element.cpp:177
bool hasZeroVolume(MeshLib::Element const &element)
Returns true if the element has zero length/area/volume.
Definition: Element.cpp:121
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:162
std::size_t getNodeIndex(Element const &element, unsigned const idx)
Definition: Element.cpp:225
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:212
MeshLib::Node getCenterOfGravity(Element const &element)
Calculates the center of gravity for the mesh element.
Definition: Element.cpp:126
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:108
std::ostream & operator<<(std::ostream &os, Element const &e)
Definition: Element.cpp:89