3#include <boost/iterator/function_output_iterator.hpp>
4#include <boost/range/irange.hpp>
15precice::logging::Logger
Index::_log{
"query::Index"};
17namespace bg = boost::geometry;
18namespace bgi = boost::geometry::index;
58 auto tree = std::make_shared<VertexTraits::RTree>(
59 boost::irange<std::size_t>(0lu,
mesh.nVertices()), params, ind);
61 indices.vertexRTree = std::move(tree);
79 auto tree = std::make_shared<EdgeTraits::RTree>(
80 boost::irange<std::size_t>(0lu,
mesh.edges().size()), params, ind);
82 indices.edgeRTree = std::move(tree);
97 std::vector<TriangleTraits::IndexType> elements;
98 elements.reserve(
mesh.triangles().size());
99 for (
size_t i = 0; i <
mesh.triangles().size(); ++i) {
100 auto box = bg::return_envelope<RTreeBox>(
mesh.triangles()[i]);
101 elements.emplace_back(std::move(box), i);
109 auto tree = std::make_shared<TriangleTraits::RTree>(elements, params, ind);
110 indices.triangleRTree = std::move(tree);
125 std::vector<TetrahedronTraits::IndexType> elements;
126 elements.reserve(
mesh.tetrahedra().size());
127 for (
size_t i = 0; i <
mesh.tetrahedra().size(); ++i) {
131 elements.emplace_back(std::move(box), i);
139 auto tree = std::make_shared<TetrahedronTraits::RTree>(elements, params, ind);
140 indices.tetraRTree = std::move(tree);
177 const auto &rtree =
_pimpl->getVertexRTree(*
_mesh);
178 rtree->query(bgi::nearest(sourceCoord, 1), boost::make_function_output_iterator([&](
size_t matchID) {
188 std::vector<VertexID> matches;
189 const auto &rtree =
_pimpl->getVertexRTree(*
_mesh);
191 rtree->query(bgi::nearest(sourceCoord, n), boost::make_function_output_iterator([&](
size_t matchID) {
192 matches.emplace_back(matchID);
203 std::vector<EdgeMatch> matches;
205 rtree->query(bgi::nearest(sourceCoord, n), boost::make_function_output_iterator([&](
size_t matchID) {
206 matches.emplace_back(matchID);
214 const auto &rtree =
_pimpl->getTriangleRTree(*
_mesh);
216 std::vector<TriangleMatch> matches;
218 rtree->query(bgi::nearest(sourceCoord, n),
220 matches.emplace_back(match.second);
231 auto searchBox =
query::makeBox(coords.array() - radius, coords.array() + radius);
233 const auto &rtree =
_pimpl->getVertexRTree(*
_mesh);
234 std::vector<VertexID> matches;
235 rtree->query(bgi::intersects(searchBox) and bg::index::satisfies([&](
size_t const i) {
return bg::distance(centerVertex,
_mesh->vertex(i)) < radius; }),
236 std::back_inserter(matches));
246 auto searchBox =
query::makeBox(coords.array() - radius, coords.array() + radius);
248 const auto &rtree =
_pimpl->getVertexRTree(*
_mesh);
250 auto queryIter = rtree->qbegin(bgi::intersects(searchBox) and bg::index::satisfies([&](
size_t const i) {
return bg::distance(centerVertex,
_mesh->vertex(i)) < radius; }));
251 bool hasMatch = queryIter != rtree->qend();
259 const auto &rtree =
_pimpl->getVertexRTree(*
_mesh);
260 std::vector<VertexID> matches;
270 std::vector<TetrahedronID> matches;
272 matches.emplace_back(match.second);
279 if (
_mesh->getDimensions() == 2) {
288 if (
_mesh->getDimensions() == 2) {
290 for (
const auto &match : matchedTriangles) {
292 if (polation.isInterpolation()) {
293 return {std::move(polation)};
303 for (
const auto &match : matchedTetra) {
306 if (polation.isInterpolation()) {
307 return {std::move(polation)};
322 std::vector<ProjectionMatch> candidates;
323 candidates.reserve(n);
326 if (polation.isInterpolation()) {
327 candidates.emplace_back(std::move(polation));
332 if (candidates.empty()) {
333 return closestVertex;
337 auto min = std::min_element(candidates.begin(), candidates.end());
339 return closestVertex;
346 std::vector<ProjectionMatch> candidates;
347 candidates.reserve(n);
350 if (polation.isInterpolation()) {
351 candidates.emplace_back(std::move(polation));
356 if (candidates.empty()) {
361 auto min = std::min_element(candidates.begin(), candidates.end());
377 auto rtreeBox =
_pimpl->getVertexRTree(*_mesh)->bounds();
378 int dim =
_mesh->getDimensions();
379 Eigen::VectorXd min(dim), max(dim);
381 min[0] = rtreeBox.min_corner().get<0>();
382 min[1] = rtreeBox.min_corner().get<1>();
383 max[0] = rtreeBox.max_corner().get<0>();
384 max[1] = rtreeBox.max_corner().get<1>();
387 min[2] = rtreeBox.min_corner().get<2>();
388 max[2] = rtreeBox.max_corner().get<2>();
#define PRECICE_TRACE(...)
#define PRECICE_ASSERT(...)
Calculates the barycentric coordinates of a coordinate on the given vertex/edge/triangle and stores t...
double distance() const
Returns the projection distance.
An axis-aligned bounding box around a (partition of a) mesh.
Eigen::VectorXd maxCorner() const
the max corner of the bounding box
Eigen::VectorXd minCorner() const
the min corner of the bounding box
Container and creator for meshes.
Eigen::VectorXd getCoords() const
Returns the coordinates of the vertex.
VertexTraits::Ptr getVertexRTree(const mesh::Mesh &mesh)
TetrahedronTraits::Ptr getTetraRTree(const mesh::Mesh &mesh)
TriangleTraits::Ptr getTriangleRTree(const mesh::Mesh &mesh)
EdgeTraits::Ptr getEdgeRTree(const mesh::Mesh &mesh)
mesh::BoundingBox getRtreeBounds()
std::vector< TetrahedronID > getEnclosingTetrahedra(const Eigen::VectorXd &location)
Return all the tetrahedra whose axis-aligned bounding box contains a vertex.
mesh::Mesh * _mesh
The indexed Mesh.
ProjectionMatch findCellOrProjection(const Eigen::VectorXd &location, int n)
VertexMatch getClosestVertex(const Eigen::VectorXd &sourceCoord)
Get the closest vertex to the given vertex.
ProjectionMatch findNearestProjection(const Eigen::VectorXd &location, int n)
Find the closest interpolation element to the given location. If exists, triangle or edge projection ...
bool isAnyVertexInsideBox(const mesh::Vertex ¢erVertex, double radius)
Returns.
std::unique_ptr< IndexImpl > _pimpl
std::vector< TriangleMatch > getClosestTriangles(const Eigen::VectorXd &sourceCoord, int n)
Get n number of closest triangles to the given vertex.
std::vector< VertexID > getVerticesInsideBox(const mesh::Vertex ¢erVertex, double radius)
Return all the vertices inside the box formed by vertex and radius (boundary exclusive)
void clear()
Clear the index.
ProjectionMatch findEdgeProjection(const Eigen::VectorXd &location, int n, ProjectionMatch closestVertex)
Find closest edge interpolation element. If cannot be found, it falls back to vertex projection.
ProjectionMatch findVertexProjection(const Eigen::VectorXd &location)
Closest vertex projection element is always the nearest neighbor.
Index(mesh::PtrMesh mesh)
std::vector< VertexID > getClosestVertices(const Eigen::VectorXd &sourceCoord, int n)
Get n number of closest vertices to the given vertex.
ProjectionMatch findTriangleProjection(const Eigen::VectorXd &location, int n, ProjectionMatch closestVertex)
Find closest face interpolation element. If cannot be found, it falls back to first edge interpolatio...
std::vector< EdgeMatch > getClosestEdges(const Eigen::VectorXd &sourceCoord, int n)
Get n number of closest edges to the given vertex.
static precice::logging::Logger _log
provides Mesh, Data and primitives.
std::shared_ptr< Mesh > PtrMesh
boost::geometry::index::rstar< 16 > RTreeParameters
The general rtree parameter type used in precice.
contains geometrical queries.
impl::RTreeTraits< mesh::Edge > EdgeTraits
RTreeBox makeBox(const pm::Vertex::RawCoords &min, const pm::Vertex::RawCoords &max)
impl::RTreeTraits< mesh::Vertex > VertexTraits
impl::RTreeTraits< mesh::Triangle > TriangleTraits
impl::RTreeTraits< mesh::Tetrahedron > TetrahedronTraits
MatchType< struct VertexMatchTag > VertexMatch
constexpr auto get(span< E, S > s) -> decltype(s[N])
VertexTraits::Ptr vertexRTree
EdgeTraits::Ptr edgeRTree
TetrahedronTraits::Ptr tetraRTree
TriangleTraits::Ptr triangleRTree
Struct representing a projection match.
mapping::Polation polation
The type traits of a rtree based on a Primitive.
typename std::conditional< IsDirectIndexable< mesh::Triangle >::value, MeshContainerIndex, std::pair< RTreeBox, MeshContainerIndex > >::type IndexType
typename std::conditional< IsDirectIndexable< mesh::Vertex >::value, impl::VectorIndexable< MeshContainer >, boost::geometry::index::indexable< IndexType > >::type IndexGetter
std::shared_ptr< RTree > Ptr