OGS
BoundaryElementsAlongPolyline.cpp
Go to the documentation of this file.
1
11
12#include <algorithm>
13#include <typeinfo>
14
15#include "BaseLib/quicksort.h"
16#include "GeoLib/Polyline.h"
20#include "MeshLib/Mesh.h"
22#include "MeshLib/Node.h"
23
24namespace
25{
34bool includesAllEdgeNodeIDs(std::vector<std::size_t> const& vec_node_ids,
35 MeshLib::Element const& edge,
36 std::vector<std::size_t>& edge_node_distances)
37{
38 unsigned j = 0;
39 for (; j < edge.getNumberOfBaseNodes(); j++)
40 {
41 auto itr = std::find(vec_node_ids.begin(), vec_node_ids.end(),
42 getNodeIndex(edge, j));
43 if (itr != vec_node_ids.end())
44 {
45 edge_node_distances.push_back(
46 std::distance(vec_node_ids.begin(), itr));
47 }
48 else
49 {
50 break;
51 }
52 }
53 return j == edge.getNumberOfBaseNodes();
54}
55
68 const MeshLib::Element& edge, const GeoLib::Polyline& ply,
69 const std::vector<std::size_t>& edge_node_distances_along_ply,
70 const std::vector<std::size_t>& node_ids_on_poly)
71{
72 // The first node of the edge should be always closer to the beginning of
73 // the polyline than other nodes.
74 if (edge_node_distances_along_ply.front() >
75 edge_node_distances_along_ply.back() ||
76 (ply.isClosed() &&
77 edge_node_distances_along_ply.back() == node_ids_on_poly.size() - 1))
78 { // Create a new element with reversed local node index
79 if (auto const* e = dynamic_cast<MeshLib::Line const*>(&edge))
80 {
81 std::array nodes = {const_cast<MeshLib::Node*>(e->getNode(1)),
82 const_cast<MeshLib::Node*>(e->getNode(0))};
83 return new MeshLib::Line(nodes, e->getID());
84 }
85 if (auto const* e = dynamic_cast<MeshLib::Line3 const*>(&edge))
86 {
87 std::array nodes = {const_cast<MeshLib::Node*>(e->getNode(1)),
88 const_cast<MeshLib::Node*>(e->getNode(0)),
89 const_cast<MeshLib::Node*>(e->getNode(2))};
90 return new MeshLib::Line3(nodes, e->getID());
91 }
92 OGS_FATAL("Not implemented for element type {:s}", typeid(edge).name());
93 }
94
95 // Return the original edge otherwise.
96 return const_cast<MeshLib::Element*>(&edge);
97}
98} // namespace
99
100namespace MeshGeoToolsLib
101{
103 MeshLib::Mesh const& mesh, MeshNodeSearcher const& mshNodeSearcher,
104 GeoLib::Polyline const& ply)
105 : _ply(ply)
106{
107 // search nodes and elements located along the polyline
108 auto node_ids_on_poly = mshNodeSearcher.getMeshNodeIDs(ply);
109 MeshLib::ElementSearch es(mesh);
110 es.searchByNodeIDs(node_ids_on_poly);
111 auto const& ele_ids_near_ply = es.getSearchedElementIDs();
112
113 // check all edges of the elements near the polyline
114 for (auto ele_id : ele_ids_near_ply)
115 {
116 auto* e = mesh.getElement(ele_id);
117 // skip line elements
118 if (e->getDimension() == 1)
119 {
120 continue;
121 }
122 // skip internal elements
123 if (!e->isBoundaryElement())
124 {
125 continue;
126 }
127 // find edges on the polyline
128 for (unsigned i = 0; i < e->getNumberOfEdges(); i++)
129 {
130 auto* edge = e->getEdge(i);
131 // check if all edge nodes are along the polyline (if yes, store a
132 // distance)
133 std::vector<std::size_t> edge_node_distances_along_ply;
134 if (includesAllEdgeNodeIDs(node_ids_on_poly, *edge,
135 edge_node_distances_along_ply))
136 {
137 auto* new_edge = modifyEdgeNodeOrdering(
138 *edge, ply, edge_node_distances_along_ply,
139 node_ids_on_poly);
140 if (edge != new_edge)
141 {
142 delete edge;
143 }
144 _boundary_elements.push_back(new_edge);
145 }
146 else
147 {
148 delete edge;
149 }
150 }
151 }
152
153 // The sort was necessary in OGS-5 for some reason. I'm not sure if it is
154 // needed anymore in OGS-6.
155 // sort picked edges according to a distance of their first node along the
156 // polyline
157 std::sort(begin(_boundary_elements), end(_boundary_elements),
159 {
160 std::size_t dist1 = std::distance(
161 node_ids_on_poly.begin(),
162 std::find(node_ids_on_poly.begin(),
163 node_ids_on_poly.end(), getNodeIndex(*e1, 0)));
164 std::size_t dist2 = std::distance(
165 node_ids_on_poly.begin(),
166 std::find(node_ids_on_poly.begin(),
167 node_ids_on_poly.end(), getNodeIndex(*e2, 0)));
168 return (dist1 < dist2);
169 });
170}
171
173{
174 for (auto p : _boundary_elements)
175 {
176 delete p;
177 }
178}
179
180} // end namespace MeshGeoToolsLib
Definition of the Element class.
#define OGS_FATAL(...)
Definition Error.h:26
Definition of the Line class.
Definition of the Mesh class.
Definition of the Node class.
Definition of the PolyLine class.
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition Polyline.h:40
bool isClosed() const
Definition Polyline.cpp:119
BoundaryElementsAlongPolyline(MeshLib::Mesh const &mesh, MeshNodeSearcher const &mshNodeSearcher, GeoLib::Polyline const &ply)
std::vector< std::size_t > getMeshNodeIDs(GeoLib::GeoObject const &geoObj) const
Element search class.
const std::vector< std::size_t > & getSearchedElementIDs() const
return marked elements
std::size_t searchByNodeIDs(const std::vector< std::size_t > &nodes)
Marks all elements connecting to any of the given nodes.
virtual const Element * getEdge(unsigned i) const =0
Returns the i-th edge of the element.
virtual unsigned getNumberOfBaseNodes() const =0
const Element * getElement(std::size_t idx) const
Get the element with the given index.
Definition Mesh.h:94
TemplateElement< MeshLib::LineRule2 > Line
Definition Line.h:25
TemplateElement< MeshLib::LineRule3 > Line3
Definition Line.h:26
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)
bool includesAllEdgeNodeIDs(std::vector< std::size_t > const &vec_node_ids, MeshLib::Element const &edge, std::vector< std::size_t > &edge_node_distances)
Definition of the quicksort function.