version 3.8
distancefield.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_GEOMETRY_DISTANCE_FIELD_HH
13#define DUMUX_GEOMETRY_DISTANCE_FIELD_HH
14
15#include <memory>
16#include <vector>
17#include <utility>
18
22
23namespace Dumux {
24
31template<class Geometry>
33{
34 using Point = typename Geometry::GlobalCoordinate;
35 using Scalar = typename Geometry::ctype;
38
39 class PointGeometry
40 {
41 public:
42 static constexpr int mydimension = 0;
43 static constexpr int coorddimension = Geometry::coorddimension;
44 using ctype = typename Geometry::ctype;
45
46 PointGeometry(Point&& point) : point_(std::move(point)) {}
47 const Point& corner(std::size_t i) const { assert(i == 0); return point_; }
48 std::size_t corners() const { return 1; }
49 private:
50 Point point_;
51 };
52
55
56public:
61 AABBDistanceField(const std::vector<Geometry>& geometries)
62 : tree_(std::make_unique<AABBTree>(std::make_shared<GeoSet>(geometries)))
63 {
64 std::vector<PointGeometry> points;
65 points.reserve(geometries.size());
66 for (const auto& geo : geometries)
67 {
68 auto center = geo.center();
69 points.emplace_back(std::move(center));
70 }
71
72 pointTree_ = std::make_unique<AABBTreeMidPoints>(
73 std::make_shared<PointGeoSet>(std::move(points))
74 );
75 }
76
82 std::pair<Scalar, std::size_t> distanceAndIndex(const Point& p) const
83 { return distanceAndIndex_(p); }
84
89 Scalar distance(const Point& p) const
90 { return distanceAndIndex_(p).first; }
91
92private:
93 std::pair<Scalar, std::size_t> distanceAndIndex_(const Point& p) const
94 {
95 // find a good first guess by checking the mid point tree
96 const auto minSquaredDistanceEstimate = squaredDistance(p, *pointTree_);
97
98 // find actual entity and distance to the entity's geometry
99 // we choose the distance estimate a bit larger in case it actually is already the minimum distance
100 const auto [squaredDistance, index] = closestEntity(p, *tree_, minSquaredDistanceEstimate*1.00001);
101
102 using std::sqrt;
103 return { sqrt(squaredDistance), index };
104 }
105
106 std::unique_ptr<AABBTree> tree_;
107 std::unique_ptr<AABBTreeMidPoints> pointTree_;
108};
109
116template<class Geometry>
118
119} // end namespace Dumux
120
121#endif
An axis-aligned bounding box volume hierarchy for dune grids.
Class to calculate the closest distance from a point to a given set of geometries describing the doma...
Definition: distancefield.hh:33
std::pair< Scalar, std::size_t > distanceAndIndex(const Point &p) const
Returns the distance from a point to the closest geometry on the domain's boundary,...
Definition: distancefield.hh:82
Scalar distance(const Point &p) const
Returns the distance from a point to the closest geometry on the domain's boundary.
Definition: distancefield.hh:89
AABBDistanceField(const std::vector< Geometry > &geometries)
The constructor.
Definition: distancefield.hh:61
An axis-aligned bounding box volume tree implementation.
Definition: boundingboxtree.hh:56
An interface for a set of geometric entities.
Definition: geometricentityset.hh:109
Helper functions for distance queries.
An interface for a set of geometric entities.
static ctype squaredDistance(const Dune::FieldVector< ctype, dimWorld > &a, const Dune::FieldVector< ctype, dimWorld > &b)
Compute the shortest squared distance between two points.
Definition: distance.hh:291
std::pair< ctype, std::size_t > closestEntity(const Dune::FieldVector< ctype, dimworld > &point, const BoundingBoxTree< EntitySet > &tree, ctype minSquaredDistance=std::numeric_limits< ctype >::max())
Compute the closest entity in an AABB tree to a point (index and shortest squared distance)
Definition: distance.hh:494
Corners::value_type center(const Corners &corners)
The center of a given list of corners.
Definition: center.hh:24
Definition: adapt.hh:17