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-FileCopyrightText: 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 |
24/40✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✓ Branch 14 taken 2 times.
✓ Branch 15 taken 2 times.
✓ Branch 20 taken 2 times.
✓ Branch 21 taken 2 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 2 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 2 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 2 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 2 times.
✓ Branch 50 taken 2 times.
✓ Branch 51 taken 2 times.
✓ Branch 56 taken 2 times.
✓ Branch 57 taken 2 times.
✗ Branch 62 not taken.
✓ Branch 63 taken 2 times.
✗ Branch 68 not taken.
✓ Branch 69 taken 2 times.
✗ Branch 74 not taken.
✓ Branch 75 taken 1 times.
✗ Branch 80 not taken.
✓ Branch 81 taken 1 times.
✗ Branch 86 not taken.
✓ Branch 87 taken 1 times.
✗ Branch 92 not taken.
✓ Branch 93 taken 1 times.
✗ Branch 98 not taken.
✓ Branch 99 taken 1 times.
✗ Branch 104 not taken.
✓ Branch 105 taken 1 times.
✗ Branch 110 not taken.
✓ Branch 111 taken 1 times.
✗ Branch 116 not taken.
✓ Branch 117 taken 1 times.
|
790 | 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 | 27744 | PointGeometry(Point&& point) : point_(std::move(point)) {} | |
47 | 3108638 | 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 | 1530 | explicit AABBDistanceField(const std::vector<Geometry>& geometries) | |
62 |
2/4✓ Branch 1 taken 790 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 790 times.
✗ Branch 5 not taken.
|
3060 | : tree_(std::make_unique<AABBTree>(std::make_shared<GeoSet>(geometries))) |
63 | { | ||
64 |
1/2✓ Branch 1 taken 790 times.
✗ Branch 2 not taken.
|
1530 | std::vector<PointGeometry> points; |
65 |
1/2✓ Branch 1 taken 790 times.
✗ Branch 2 not taken.
|
1530 | points.reserve(geometries.size()); |
66 |
5/5✓ Branch 1 taken 26664 times.
✓ Branch 2 taken 360 times.
✓ Branch 3 taken 24864 times.
✓ Branch 4 taken 70 times.
✓ Branch 0 taken 1440 times.
|
56378 | for (const auto& geo : geometries) |
67 | { | ||
68 | 54848 | auto center = geo.center(); | |
69 |
1/2✓ Branch 1 taken 27744 times.
✗ Branch 2 not taken.
|
54848 | points.emplace_back(std::move(center)); |
70 | } | ||
71 | |||
72 |
2/4✓ Branch 1 taken 790 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 790 times.
|
1530 | pointTree_ = std::make_unique<AABBTreeMidPoints>( |
73 | std::make_shared<PointGeoSet>(std::move(points)) | ||
74 | ); | ||
75 | 1530 | } | |
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 | 34788 | 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.
|
34788 | { 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 | 34788 | 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 | 34788 | 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 | 34788 | const auto [squaredDistance, index] = closestEntity(p, *tree_, minSquaredDistanceEstimate*1.00001); | |
101 | |||
102 | using std::sqrt; | ||
103 | 34788 | 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 |