OGS
MeshNodeSearcher.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include "MeshNodeSearcher.h"
5
6#include <sstream>
7#include <typeinfo>
8
9#include "BaseLib/Logging.h"
10#include "GeoLib/Point.h"
11#include "GeoLib/Polyline.h"
12#include "GeoLib/Surface.h"
15#include "MeshLib/Mesh.h"
16#include "MeshLib/Node.h"
19#include "MeshNodesOnPoint.h"
20
21namespace MeshGeoToolsLib
22{
23std::vector<std::unique_ptr<MeshNodeSearcher>>
25
27 MeshLib::Mesh const& mesh,
28 std::unique_ptr<MeshGeoToolsLib::SearchLength>&& search_length_algorithm,
29 SearchAllNodes search_all_nodes)
30 : _mesh(mesh),
31 _mesh_grid(_mesh.getNodes().cbegin(), _mesh.getNodes().cend()),
32 _search_length_algorithm(std::move(search_length_algorithm)),
33 _search_all_nodes(search_all_nodes)
34{
35 DBUG("The search length for mesh '{:s}' is {:e}.", _mesh.getName(),
36 _search_length_algorithm->getSearchLength());
37}
38
40{
41 for (auto pointer : _mesh_nodes_on_points)
42 {
43 delete pointer;
44 }
45 for (auto pointer : _mesh_nodes_along_polylines)
46 {
47 delete pointer;
48 }
49 for (auto pointer : _mesh_nodes_along_surfaces)
50 {
51 delete pointer;
52 }
53}
54
55template <typename CacheType, typename GeometryType>
56std::vector<std::size_t> const& getMeshNodeIDs(
57 std::vector<CacheType*>& cached_elements,
58 std::function<GeometryType(CacheType const&)> getCachedItem,
59 GeometryType const& item, MeshLib::Mesh const& mesh,
60 GeoLib::Grid<MeshLib::Node> const& mesh_grid, double const search_length,
61 SearchAllNodes const search_all_nodes)
62{
63 if (auto const it = find_if(cbegin(cached_elements), cend(cached_elements),
64 [&](auto const& element)
65 { return getCachedItem(*element) == item; });
66 it != cend(cached_elements))
67 {
68 return (*it)->getNodeIDs();
69 }
70 // search IDs for geometry object
71 if constexpr (std::is_convertible<GeometryType, GeoLib::Point>::value)
72 {
73 cached_elements.push_back(new CacheType(
74 mesh, mesh_grid, item, search_length, search_all_nodes));
75 }
76 else
77 {
78 cached_elements.push_back(
79 new CacheType(mesh, item, search_length, search_all_nodes));
80 }
81 return cached_elements.back()->getNodeIDs();
82}
83
84std::vector<std::size_t> MeshNodeSearcher::getMeshNodeIDs(
85 GeoLib::GeoObject const& geoObj) const
86{
87 std::vector<std::size_t> vec_nodes;
88 switch (geoObj.getGeoType())
89 {
91 {
92 std::function<GeoLib::Point(MeshNodesOnPoint const&)>
93 get_cached_item_function = &MeshNodesOnPoint::getPoint;
95 _mesh_nodes_on_points, get_cached_item_function,
96 *static_cast<const GeoLib::Point*>(&geoObj), _mesh, _mesh_grid,
98 }
100 {
101 std::function<GeoLib::Polyline(MeshNodesAlongPolyline const&)>
102 get_cached_item_function = &MeshNodesAlongPolyline::getPolyline;
104 _mesh_nodes_along_polylines, get_cached_item_function,
105 *static_cast<const GeoLib::Polyline*>(&geoObj), _mesh,
106 _mesh_grid, _search_length_algorithm->getSearchLength(),
108 }
110 {
111 std::function<GeoLib::Surface(MeshNodesAlongSurface const&)>
112 get_cached_item_function = &MeshNodesAlongSurface::getSurface;
114 _mesh_nodes_along_surfaces, get_cached_item_function,
115 *static_cast<const GeoLib::Surface*>(&geoObj), _mesh,
116 _mesh_grid, _search_length_algorithm->getSearchLength(),
118 }
119 default:
120 break;
121 }
122 return vec_nodes;
123}
124
125std::vector<std::size_t> MeshNodeSearcher::getMeshNodeIDs(
126 std::vector<MathLib::Point3dWithID*> const& points) const
127{
128 double const epsilon_radius = _search_length_algorithm->getSearchLength();
129
130 std::vector<std::size_t> node_ids(points.size());
131
132 auto const number_of_points = std::ssize(points);
133#pragma omp for
134 for (std::ptrdiff_t i = 0; i < number_of_points; ++i)
135 {
136 auto const& p = *points[i];
137 std::vector<std::size_t> const ids =
138 _mesh_grid.getPointsInEpsilonEnvironment(p, epsilon_radius);
139 if (ids.empty())
140 {
141 OGS_FATAL(
142 "No nodes could be found in the mesh for point {:d} : ({:g}, "
143 "{:g}, {:g}) in {:g} epsilon radius in the mesh '{:s}'",
144 p.getID(), p[0], p[1], p[2], epsilon_radius, _mesh.getName());
145 }
146 if (ids.size() != 1)
147 {
148 std::stringstream ss;
149 auto const& bulk_nodes = _mesh.getNodes();
150 for (auto const id : ids)
151 {
152 ss << "- bulk node: " << (*bulk_nodes[id])[0] << ", "
153 << (*bulk_nodes[id])[1] << ", " << (*bulk_nodes[id])[2]
154 << ", distance: "
155 << std::sqrt(MathLib::sqrDist(*bulk_nodes[id], p)) << "\n";
156 }
157 OGS_FATAL(
158 "Found {:d} nodes in the mesh for point {:d} : ({:g}, {:g}, "
159 "{:g}) in {:g} epsilon radius in the mesh '{:s}'. Expected to "
160 "find exactly one node.\n{:s}",
161 ids.size(), p.getID(), p[0], p[1], p[2], epsilon_radius,
162 _mesh.getName(), ss.str());
163 }
164 node_ids[i] = ids.front();
165 }
166 return node_ids;
167}
168
170 MeshLib::Mesh const& mesh,
171 std::unique_ptr<MeshGeoToolsLib::SearchLength>&& search_length_algorithm)
172{
173 std::size_t const mesh_id = mesh.getID();
174 if (_mesh_node_searchers.size() < mesh_id + 1)
175 {
176 _mesh_node_searchers.resize(mesh_id + 1);
177 }
178
179 if (_mesh_node_searchers[mesh_id])
180 {
181 auto const& m = *_mesh_node_searchers[mesh_id];
182 // return searcher if search length algorithm and the returned search
183 // length are the same, else recreate the searcher
184 if (typeid(m._search_length_algorithm) ==
185 typeid(search_length_algorithm) &&
186 m._search_length_algorithm->getSearchLength() ==
187 search_length_algorithm->getSearchLength())
188 {
189 return m;
190 }
191 }
192
193 _mesh_node_searchers[mesh_id] =
194 std::make_unique<MeshGeoToolsLib::MeshNodeSearcher>(
195 mesh, std::move(search_length_algorithm), SearchAllNodes::Yes);
196
197 return *_mesh_node_searchers[mesh_id];
198}
199
200} // end namespace MeshGeoToolsLib
#define OGS_FATAL(...)
Definition Error.h:19
std::vector< std::size_t > getNodes(GeoLib::Point const &pnt, std::vector< MeshLib::Node * > const &nodes, MeshLib::PropertyVector< int > const &mat_ids, std::pair< int, int > const &mat_limits, std::pair< double, double > const &elevation_limits, MeshLib::Mesh const &mesh)
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition Polyline.h:29
A Surface is represented by Triangles. It consists of a reference to a vector of (pointers to) points...
std::vector< MeshNodesOnPoint * > _mesh_nodes_on_points
std::vector< std::size_t > getMeshNodeIDs(GeoLib::GeoObject const &geoObj) const
GeoLib::Grid< MeshLib::Node > _mesh_grid
static std::vector< std::unique_ptr< MeshNodeSearcher > > _mesh_node_searchers
Mesh node searcher for the meshes indexed by the meshs' ids.
std::unique_ptr< MeshGeoToolsLib::SearchLength > _search_length_algorithm
std::vector< MeshNodesAlongSurface * > _mesh_nodes_along_surfaces
static OGS_NO_DANGLING MeshNodeSearcher const & getMeshNodeSearcher(MeshLib::Mesh const &mesh, std::unique_ptr< MeshGeoToolsLib::SearchLength > &&search_length_algorithm)
std::vector< MeshNodesAlongPolyline * > _mesh_nodes_along_polylines
MeshNodeSearcher(MeshLib::Mesh const &mesh, std::unique_ptr< MeshGeoToolsLib::SearchLength > &&search_length_algorithm, SearchAllNodes search_all_nodes)
GeoLib::Polyline const & getPolyline() const
GeoLib::Surface const & getSurface() const
GeoLib::Point const & getPoint() const
std::size_t getID() const
Get id of the mesh.
Definition Mesh.h:112
double sqrDist(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.cpp:19
std::vector< std::size_t > const & getMeshNodeIDs(std::vector< CacheType * > &cached_elements, std::function< GeometryType(CacheType const &)> getCachedItem, GeometryType const &item, MeshLib::Mesh const &mesh, GeoLib::Grid< MeshLib::Node > const &mesh_grid, double const search_length, SearchAllNodes const search_all_nodes)
virtual GEOTYPE getGeoType() const =0
return a geometry type