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 std::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 
106 bool 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 
119 bool 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 
136 std::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 
156 std::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  }
190  if (e.getGeomType() == MeshElemType::QUAD)
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 
206 unsigned 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 
219 std::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:44
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition: Logging.h:39
Definition of the Node class.
std::size_t getID() const
Definition: Point3dWithID.h:62
Eigen::Vector3d const & asEigenVector3d() const
Definition: Point3d.h:67
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:202
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: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 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:325
double sqrDist2d(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition: Point3d.h:126
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
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
std::ostream & operator<<(std::ostream &os, Element const &e)
Definition: Element.cpp:88