OGS 6.1.0-1721-g6382411ad
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  continue;
44  // skip internal elements
45  if (!e->isBoundaryElement())
46  continue;
47  // find edges on the polyline
48  for (unsigned i=0; i<e->getNumberOfEdges(); i++) {
49  auto* edge = e->getEdge(i);
50  // check if all edge nodes are along the polyline (if yes, store a distance)
51  std::vector<std::size_t> edge_node_distances_along_ply;
52  if (includesAllEdgeNodeIDs(node_ids_on_poly, *edge,
53  edge_node_distances_along_ply))
54  {
55  auto* new_edge = modifyEdgeNodeOrdering(
56  *edge, ply, edge_node_distances_along_ply,
57  node_ids_on_poly);
58  if (edge != new_edge)
59  delete edge;
60  _boundary_elements.push_back(new_edge);
61  } else {
62  delete edge;
63  }
64  }
65  }
66 
67  // The sort was necessary in OGS-5 for some reason. I'm not sure if it is
68  // needed anymore in OGS-6.
69  // sort picked edges according to a distance of their first node along the
70  // polyline
71  std::sort(
73  [&](MeshLib::Element* e1, MeshLib::Element* e2) {
74  std::size_t dist1 = std::distance(
75  node_ids_on_poly.begin(),
76  std::find(node_ids_on_poly.begin(), node_ids_on_poly.end(),
77  e1->getNodeIndex(0)));
78  std::size_t dist2 = std::distance(
79  node_ids_on_poly.begin(),
80  std::find(node_ids_on_poly.begin(), node_ids_on_poly.end(),
81  e2->getNodeIndex(0)));
82  return (dist1 < dist2);
83  });
84 }
85 
87 {
88  for (auto p : _boundary_elements)
89  delete p;
90 }
91 
92 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
93 {
94  unsigned j=0;
95  for (; j<edge.getNumberOfBaseNodes(); j++) {
96  auto itr = std::find(vec_node_ids.begin(), vec_node_ids.end(), edge.getNodeIndex(j));
97  if (itr != vec_node_ids.end())
98  edge_node_distances.push_back(std::distance(vec_node_ids.begin(), itr));
99  else
100  break;
101  }
102  return (j==edge.getNumberOfBaseNodes());
103 }
104 
106  const MeshLib::Element& edge, const GeoLib::Polyline& ply,
107  const std::vector<std::size_t>& edge_node_distances_along_ply,
108  const std::vector<std::size_t>& node_ids_on_poly) const
109 {
110  // The first node of the edge should be always closer to the beginning of
111  // the polyline than other nodes.
112  if (edge_node_distances_along_ply.front() >
113  edge_node_distances_along_ply.back() ||
114  (ply.isClosed() &&
115  edge_node_distances_along_ply.back() == node_ids_on_poly.size() - 1))
116  { // Create a new element with reversed local node index
117  auto new_nodes = new MeshLib::Node*[edge.getNumberOfNodes()];
118  if (auto const* e = dynamic_cast<MeshLib::Line const*>(&edge))
119  {
120  new_nodes[0] = const_cast<MeshLib::Node*>(e->getNode(1));
121  new_nodes[1] = const_cast<MeshLib::Node*>(e->getNode(0));
122  }
123  else if (auto const* e = dynamic_cast<MeshLib::Line3 const*>(&edge))
124  {
125  new_nodes[0] = const_cast<MeshLib::Node*>(e->getNode(1));
126  new_nodes[1] = const_cast<MeshLib::Node*>(e->getNode(0));
127  new_nodes[2] = const_cast<MeshLib::Node*>(e->getNode(2));
128  }
129  else
130  OGS_FATAL("Not implemented for element type %s", typeid(edge).name());
131 
132  return edge.clone(new_nodes, edge.getID());
133  }
134 
135  // Return the original edge otherwise.
136  return const_cast<MeshLib::Element*>(&edge);
137 }
138 } // end namespace MeshGeoToolsLib
139 
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:190
BoundaryElementsAlongPolyline(MeshLib::Mesh const &mesh, MeshNodeSearcher const &mshNodeSearcher, GeoLib::Polyline const &ply)
Definition of the Mesh class.
std::size_t searchByNodeIDs(const std::vector< std::size_t > &node_ids)
Marks all elements connecting to any of the given nodes.
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
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:164
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:71
virtual unsigned getNumberOfNodes() const =0
Returns the number of all nodes including both linear and nonlinear nodes.
Definition of the Element class.