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