OGS 6.2.0-244-g47b8a9a9d
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  return _neighbors[i];
137 #ifndef NDEBUG
138  ERR("Error in MeshLib::Element::getNeighbor() - Index does not exist.");
139  return nullptr;
140 #endif
141 }
142 
143 unsigned Element::getNodeIDinElement(const MeshLib::Node* node) const
144 {
145  const unsigned nNodes (this->getNumberOfNodes());
146  for (unsigned i(0); i < nNodes; i++)
147  {
148  if (node == _nodes[i])
149  {
150  return i;
151  }
152  }
153  return std::numeric_limits<unsigned>::max();
154 }
155 
156 const Node* Element::getNode(unsigned i) const
157 {
158 #ifndef NDEBUG
159  if (i < getNumberOfNodes())
160 #endif
161  return _nodes[i];
162 #ifndef NDEBUG
163  ERR("Error in MeshLib::Element::getNode() - Index %d in %s", i, MeshElemType2String(getGeomType()).c_str());
164  return nullptr;
165 #endif
166 }
167 
168 void Element::setNode(unsigned idx, Node* node)
169 {
170 #ifndef NDEBUG
171  if (idx < getNumberOfNodes())
172 #endif
173  _nodes[idx] = node;
174 }
175 
176 std::size_t Element::getNodeIndex(unsigned i) const
177 {
178 #ifndef NDEBUG
179  if (i<getNumberOfNodes())
180 #endif
181  return _nodes[i]->getID();
182 #ifndef NDEBUG
183  ERR("Error in MeshLib::Element::getNodeIndex() - Index does not exist.");
184  return std::numeric_limits<std::size_t>::max();
185 #endif
186 }
187 
188 bool Element::hasNeighbor(Element* elem) const
189 {
190  unsigned nNeighbors (this->getNumberOfNeighbors());
191  for (unsigned i = 0; i < nNeighbors; i++)
192  {
193  if (this->_neighbors[i] == elem)
194  {
195  return true;
196  }
197  }
198  return false;
199 }
200 
202 {
203  return std::any_of(_neighbors, _neighbors + this->getNumberOfNeighbors(),
204  [](MeshLib::Element const*const e){ return e == nullptr; });
205 }
206 
207 #ifndef NDEBUG
208 std::ostream& operator<<(std::ostream& os, Element const& e)
209 {
210  os << "Element #" << e._id << " @ " << &e << " with " << e.getNumberOfNeighbors()
211  << " neighbours\n";
212 
213  unsigned const nnodes = e.getNumberOfNodes();
214  MeshLib::Node* const* const nodes = e.getNodes();
215  os << "MeshElemType: "
216  << static_cast<std::underlying_type<MeshElemType>::type>(e.getGeomType())
217  << " with " << nnodes << " nodes: { ";
218  for (unsigned n = 0; n < nnodes; ++n)
219  os << nodes[n]->getID() << " @ " << nodes[n] << " ";
220  os << "}\n";
221  return os;
222 }
223 #endif // NDEBUG
224 
226 {
227  for(std::size_t i(0); i<e.getNumberOfBaseNodes(); ++i) {
228  if (MathLib::sqrDist2d(p, *e.getNode(i)) <
229  std::numeric_limits<double>::epsilon())
230  {
231  return true;
232  }
233  }
234 
236  {
237  MathLib::Point3d const& n0(*e.getNode(0));
238  MathLib::Point3d const& n1(*e.getNode(1));
239  MathLib::Point3d const& n2(*e.getNode(2));
240 
241  return MathLib::isPointInTriangleXY(p, n0, n1, n2);
242  }
243  if (e.getGeomType() == MeshElemType::QUAD)
244  {
245  MathLib::Point3d const& n0(*e.getNode(0));
246  MathLib::Point3d const& n1(*e.getNode(1));
247  MathLib::Point3d const& n2(*e.getNode(2));
248  MathLib::Point3d const& n3(*e.getNode(3));
249 
250  return MathLib::isPointInTriangleXY(p, n0, n1, n2) ||
251  MathLib::isPointInTriangleXY(p, n0, n2, n3);
252  }
253 
254  WARN("isPointInElementXY: element type '%s' is not supported.",
256  return false;
257 }
258 } // 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:143
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:201
friend std::ostream & operator<<(std::ostream &os, Element const &e)
Definition: Element.cpp:208
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:64
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:168
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:188
const std::string MeshElemType2String(const MeshElemType t)
Given a MeshElemType this returns the appropriate string.
Definition: MeshEnums.cpp:19
std::size_t getNodeIndex(unsigned i) const
Definition: Element.cpp:176
Interface for heuristic search length strategy.
Definition: ProjectData.h:29
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 std::size_t getID() const final
Returns the ID of the element.
Definition: Element.h:90
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:225
const Node * getNode(unsigned i) const
Definition: Element.cpp:156
virtual void computeSqrEdgeLengthRange(double &min, double &max) const
Compute the minimum and maximum squared edge length for this element.
Definition: Element.cpp:102