Line | Branch | Exec | Source |
---|---|---|---|
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 | // | ||
7 | /*! | ||
8 | * \file | ||
9 | * \ingroup Geometry | ||
10 | * \copydoc Dumux::DistanceField | ||
11 | */ | ||
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 | |||
19 | #include <dumux/geometry/distance.hh> | ||
20 | #include <dumux/geometry/boundingboxtree.hh> | ||
21 | #include <dumux/geometry/geometricentityset.hh> | ||
22 | |||
23 | namespace Dumux { | ||
24 | |||
25 | /*! | ||
26 | * \ingroup Geometry | ||
27 | * \brief Class to calculate the closest distance from a point to a given set of geometries describing the domain's boundaries. | ||
28 | * Internally uses an AABB tree representation of the geometries for logarithmic distance queries | ||
29 | * \tparam Geometry The (dune) geometry type. | ||
30 | */ | ||
31 | template<class Geometry> | ||
32 | class AABBDistanceField | ||
33 | { | ||
34 | using Point = typename Geometry::GlobalCoordinate; | ||
35 | using Scalar = typename Geometry::ctype; | ||
36 | using GeoSet = GeometriesEntitySet<Geometry>; | ||
37 | using AABBTree = BoundingBoxTree<GeoSet>; | ||
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 | 27634 | PointGeometry(Point&& point) : point_(std::move(point)) {} | |
47 | 3105778 | 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 | |||
53 | using PointGeoSet = GeometriesEntitySet<PointGeometry>; | ||
54 | using AABBTreeMidPoints = BoundingBoxTree<PointGeoSet>; | ||
55 | |||
56 | public: | ||
57 | /*! | ||
58 | * \brief The constructor. | ||
59 | * \param geometries A vector of geometries describing the boundaries of the spatial domain. | ||
60 | */ | ||
61 | 1509 | AABBDistanceField(const std::vector<Geometry>& geometries) | |
62 |
3/12✓ Branch 2 taken 769 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 769 times.
✓ Branch 7 taken 769 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
1509 | : tree_(std::make_unique<AABBTree>(std::make_shared<GeoSet>(geometries))) |
63 | { | ||
64 |
1/2✓ Branch 1 taken 769 times.
✗ Branch 2 not taken.
|
1509 | std::vector<PointGeometry> points; |
65 |
2/4✓ Branch 1 taken 769 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 769 times.
✗ Branch 5 not taken.
|
3018 | points.reserve(geometries.size()); |
66 |
4/4✓ Branch 0 taken 27634 times.
✓ Branch 1 taken 769 times.
✓ Branch 2 taken 27634 times.
✓ Branch 3 taken 769 times.
|
59265 | for (const auto& geo : geometries) |
67 | { | ||
68 | 54738 | auto center = geo.center(); | |
69 |
1/2✓ Branch 1 taken 27634 times.
✗ Branch 2 not taken.
|
54738 | points.emplace_back(std::move(center)); |
70 | } | ||
71 | |||
72 |
5/14✓ Branch 1 taken 769 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 769 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 769 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 769 times.
✓ Branch 9 taken 769 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
1509 | pointTree_ = std::make_unique<AABBTreeMidPoints>( |
73 |
1/2✓ Branch 1 taken 769 times.
✗ Branch 2 not taken.
|
1509 | std::make_shared<PointGeoSet>(std::move(points)) |
74 | ); | ||
75 | 1509 | } | |
76 | |||
77 | /*! | ||
78 | * \brief Returns the distance from a point to the closest geometry on the domain's boundary, as well as the index | ||
79 | * of the closest geometry. | ||
80 | * \param p The location at which the closest distance is evaluated. | ||
81 | */ | ||
82 | std::pair<Scalar, std::size_t> distanceAndIndex(const Point& p) const | ||
83 |
4/8✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 120 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 120 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 120 times.
✗ Branch 11 not taken.
|
34088 | { return distanceAndIndex_(p); } |
84 | |||
85 | /*! | ||
86 | * \brief Returns the distance from a point to the closest geometry on the domain's boundary. | ||
87 | * \param p The location at which the closest distance is evaluated. | ||
88 | */ | ||
89 | Scalar distance(const Point& p) const | ||
90 | { return distanceAndIndex_(p).first; } | ||
91 | |||
92 | private: | ||
93 | 34088 | 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 | 68176 | 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 | 68176 | const auto [squaredDistance, index] = closestEntity(p, *tree_, minSquaredDistanceEstimate*1.00001); | |
101 | |||
102 | using std::sqrt; | ||
103 | 68176 | return { sqrt(squaredDistance), index }; | |
104 | } | ||
105 | |||
106 | std::unique_ptr<AABBTree> tree_; | ||
107 | std::unique_ptr<AABBTreeMidPoints> pointTree_; | ||
108 | }; | ||
109 | |||
110 | /*! | ||
111 | * \ingroup Geometry | ||
112 | * \brief Class to calculate the closest distance from a point to a given set of geometries describing the domain's boundaries. | ||
113 | * \tparam Geometry The (dune) geometry type. | ||
114 | * \note Defaults to Dumux::AABBDistanceField | ||
115 | */ | ||
116 | template<class Geometry> | ||
117 | using DistanceField = AABBDistanceField<Geometry>; | ||
118 | |||
119 | } // end namespace Dumux | ||
120 | |||
121 | #endif | ||
122 |