OGS 6.2.1-97-g73d1aeda3
BoundaryElementsAlongPolyline.cpp
Go to the documentation of this file.
1 
10 
11 #include <algorithm>
12 #include <typeinfo>
13 
14 #include "BaseLib/quicksort.h"
15 #include "GeoLib/Polyline.h"
16 
17 #include "MeshLib/Mesh.h"
18 #include "MeshLib/Node.h"
20 #include "MeshLib/Elements/Line.h"
22 
24 
25 namespace MeshGeoToolsLib
26 {
28  MeshLib::Mesh const& mesh, MeshNodeSearcher const& mshNodeSearcher,
29  GeoLib::Polyline const& ply)
30  : _mesh(mesh), _ply(ply)
31 {
32  // search nodes and elements located along the polyline
33  auto node_ids_on_poly = mshNodeSearcher.getMeshNodeIDsAlongPolyline(ply);
35  es.searchByNodeIDs(node_ids_on_poly);
36  auto &ele_ids_near_ply = es.getSearchedElementIDs();
37 
38  // check all edges of the elements near the polyline
39  for (auto ele_id : ele_ids_near_ply) {
40  auto* e = _mesh.getElement(ele_id);
41  // skip line elements
42  if (e->getDimension() == 1)
43  {
44  continue;
45  }
46  // skip internal elements
47  if (!e->isBoundaryElement())
48  {
49  continue;
50  }
51  // find edges on the polyline
52  for (unsigned i=0; i<e->getNumberOfEdges(); i++) {
53  auto* edge = e->getEdge(i);
54  // check if all edge nodes are along the polyline (if yes, store a distance)
55  std::vector<std::size_t> edge_node_distances_along_ply;
56  if (includesAllEdgeNodeIDs(node_ids_on_poly, *edge,
57  edge_node_distances_along_ply))
58  {
59  auto* new_edge = modifyEdgeNodeOrdering(
60  *edge, ply, edge_node_distances_along_ply,
61  node_ids_on_poly);
62  if (edge != new_edge)
63  {
64  delete edge;
65  }
66  _boundary_elements.push_back(new_edge);
67  } else {
68  delete edge;
69  }
70  }
71  }
72 
73  // The sort was necessary in OGS-5 for some reason. I'm not sure if it is
74  // needed anymore in OGS-6.
75  // sort picked edges according to a distance of their first node along the
76  // polyline
77  std::sort(
79  [&](MeshLib::Element* e1, MeshLib::Element* e2) {
80  std::size_t dist1 = std::distance(
81  node_ids_on_poly.begin(),
82  std::find(node_ids_on_poly.begin(), node_ids_on_poly.end(),
83  e1->getNodeIndex(0)));
84  std::size_t dist2 = std::distance(
85  node_ids_on_poly.begin(),
86  std::find(node_ids_on_poly.begin(), node_ids_on_poly.end(),
87  e2->getNodeIndex(0)));
88  return (dist1 < dist2);
89  });
90 }
91 
93 {
94  for (auto p : _boundary_elements)
95  {
96  delete p;
97  }
98 }
99 
100 bool BoundaryElementsAlongPolyline::includesAllEdgeNodeIDs(const std::vector<std::size_t> &vec_node_ids, const MeshLib::Element &edge, std::vector<std::size_t> &edge_node_distances) const
101 {
102  unsigned j=0;
103  for (; j<edge.getNumberOfBaseNodes(); j++) {
104  auto itr = std::find(vec_node_ids.begin(), vec_node_ids.end(), edge.getNodeIndex(j));
105  if (itr != vec_node_ids.end())
106  {
107  edge_node_distances.push_back(std::distance(vec_node_ids.begin(), itr));
108  }
109  else
110  {
111  break;
112  }
113  }
114  return (j==edge.getNumberOfBaseNodes());
115 }
116 
118  const MeshLib::Element& edge, const GeoLib::Polyline& ply,
119  const std::vector<std::size_t>& edge_node_distances_along_ply,
120  const std::vector<std::size_t>& node_ids_on_poly) const
121 {
122  // The first node of the edge should be always closer to the beginning of
123  // the polyline than other nodes.
124  if (edge_node_distances_along_ply.front() >
125  edge_node_distances_along_ply.back() ||
126  (ply.isClosed() &&
127  edge_node_distances_along_ply.back() == node_ids_on_poly.size() - 1))
128  { // Create a new element with reversed local node index
129  auto new_nodes = new MeshLib::Node*[edge.getNumberOfNodes()];
130  if (auto const* e = dynamic_cast<MeshLib::Line const*>(&edge))
131  {
132  new_nodes[0] = const_cast<MeshLib::Node*>(e->getNode(1));
133  new_nodes[1] = const_cast<MeshLib::Node*>(e->getNode(0));
134  }
135  else if (auto const* e = dynamic_cast<MeshLib::Line3 const*>(&edge))
136  {
137  new_nodes[0] = const_cast<MeshLib::Node*>(e->getNode(1));
138  new_nodes[1] = const_cast<MeshLib::Node*>(e->getNode(0));
139  new_nodes[2] = const_cast<MeshLib::Node*>(e->getNode(2));
140  }
141  else
142  {
143  OGS_FATAL("Not implemented for element type %s",
144  typeid(edge).name());
145  }
146 
147  return edge.clone(new_nodes, edge.getID());
148  }
149 
150  // Return the original edge otherwise.
151  return const_cast<MeshLib::Element*>(&edge);
152 }
153 } // end namespace MeshGeoToolsLib
154 
Implementation of heuristic search length strategy.
virtual unsigned getNumberOfBaseNodes() const =0
Definition of the PolyLine class.
Definition of the Line class.
const Element * getElement(std::size_t idx) const
Get the element with the given index.
Definition: Mesh.h:87
Element search class.
Definition: ElementSearch.h:26
std::vector< std::size_t > const & getMeshNodeIDsAlongPolyline(GeoLib::Polyline const &ply) const
Definition of the Node class.
bool isClosed() const
Definition: Polyline.cpp:208
BoundaryElementsAlongPolyline(MeshLib::Mesh const &mesh, MeshNodeSearcher const &mshNodeSearcher, GeoLib::Polyline const &ply)
Definition of the Mesh class.
virtual Element * clone() const =0
MeshLib::Element * modifyEdgeNodeOrdering(const MeshLib::Element &edge, const GeoLib::Polyline &ply, const std::vector< std::size_t > &edge_node_distances_along_ply, const std::vector< std::size_t > &node_ids_on_poly) const
std::size_t searchByNodeIDs(const std::vector< std::size_t > &nodes)
Marks all elements connecting to any of the given nodes.
bool includesAllEdgeNodeIDs(const std::vector< std::size_t > &vec_node_ids, const MeshLib::Element &edge, std::vector< std::size_t > &edge_node_distances) const
std::size_t getNodeIndex(unsigned i) const
Definition: Element.cpp:182
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition: Polyline.h:50
virtual const Element * getEdge(unsigned i) const =0
Returns the i-th edge of the element.
const std::vector< std::size_t > & getSearchedElementIDs() const
return marked elements
Definition: ElementSearch.h:32
virtual std::size_t getID() const final
Returns the ID of the element.
Definition: Element.h:90
#define OGS_FATAL(fmt,...)
Definition: Error.h:63
virtual unsigned getNumberOfNodes() const =0
Returns the number of all nodes including both linear and nonlinear nodes.
Definition of the Element class.