GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/geometry/intersectingentities.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 102 113 90.3%
Functions: 66 92 71.7%
Branches: 157 252 62.3%

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 * \brief Algorithms that finds which geometric entities intersect
11 */
12 #ifndef DUMUX_GEOMETRY_INTERSECTING_ENTITIES_HH
13 #define DUMUX_GEOMETRY_INTERSECTING_ENTITIES_HH
14
15 #include <cmath>
16 #include <type_traits>
17 #include <vector>
18 #include <algorithm>
19 #include <limits>
20
21 #include <dune/common/fvector.hh>
22
23 #include <dumux/common/math.hh>
24 #include <dumux/geometry/boundingboxtree.hh>
25 #include <dumux/geometry/intersectspointgeometry.hh>
26 #include <dumux/geometry/geometryintersection.hh>
27 #include <dumux/geometry/triangulation.hh>
28
29 namespace Dumux {
30
31 /*!
32 * \ingroup Geometry
33 * \brief An intersection object resulting from the intersection of two primitives in an entity set
34 * \note this is used as return type for some of the intersectingEntities overloads below
35 */
36 template<int dimworld, class CoordTypeA, class CoordTypeB = CoordTypeA>
37
7/20
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 513082 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1535 times.
✓ Branch 10 taken 387843 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 16380 times.
✓ Branch 14 taken 1746 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 11388 times.
✗ Branch 19 not taken.
2395104 class IntersectionInfo
38 {
39 public:
40 using ctype = typename Dune::PromotionTraits<CoordTypeA, CoordTypeB>::PromotedType;
41 static constexpr int dimensionworld = dimworld;
42 using GlobalPosition = Dune::FieldVector<ctype, dimworld>;
43
44 template<class Corners>
45 400977 explicit IntersectionInfo(std::size_t a, std::size_t b, Corners&& c)
46 : a_(a)
47 , b_(b)
48
26/56
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 13 taken 698 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 698 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 698 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 698 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 215 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 215 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 215 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 215 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 100 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 100 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 138 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 138 times.
✓ Branch 47 taken 13 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 38 times.
✓ Branch 50 taken 13 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 38 times.
✓ Branch 53 taken 13 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 84 times.
✓ Branch 56 taken 13 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 84 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 84 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 84 times.
✗ Branch 65 not taken.
✓ Branch 73 taken 52 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 52 times.
✗ Branch 77 not taken.
✓ Branch 79 taken 52 times.
✗ Branch 80 not taken.
✓ Branch 82 taken 52 times.
✗ Branch 83 not taken.
1603908 , corners_(c.begin(), c.end())
49 {}
50
51 //! Get the index of the intersecting entity belonging to this grid
52 std::size_t first() const
53 { return a_; }
54
55 //! Get the index of the intersecting entity belonging to the other grid
56 std::size_t second() const
57 { return b_; }
58
59 //! Get the corners of the intersection geometry
60 const std::vector<GlobalPosition>& corners() const
61
2/4
✓ Branch 1 taken 382628 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2406 times.
✗ Branch 5 not taken.
385034 { return corners_; }
62
63 /*!
64 * \brief Check if the corners of this intersection match with the given corners
65 * \note This is useful to check if the intersection geometry of two intersections coincide.
66 */
67 511537 bool cornersMatch(const std::vector<GlobalPosition>& otherCorners) const
68 {
69
3/6
✓ Branch 0 taken 511537 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 511537 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 511537 times.
✗ Branch 5 not taken.
1534611 if (otherCorners.size() != corners_.size())
70 return false;
71
72 using std::max;
73 511537 ctype eps2 = std::numeric_limits<ctype>::min();
74
2/2
✓ Branch 0 taken 1017769 times.
✓ Branch 1 taken 511537 times.
1529306 for (int i = 1; i < corners_.size(); ++i)
75
2/2
✓ Branch 0 taken 767879 times.
✓ Branch 1 taken 249890 times.
3821226 eps2 = max(eps2, (corners_[i] - corners_[0]).two_norm2());
76
77 // We use a base epsilon of 1.5e-7 for comparisons of lengths.
78 // Since here we compare squared lengths, we multiply by its square.
79 511537 eps2 *= 1.5e-7*1.5e-7;
80
81
4/4
✓ Branch 0 taken 574164 times.
✓ Branch 1 taken 1261 times.
✓ Branch 2 taken 574164 times.
✓ Branch 3 taken 1261 times.
575425 for (int i = 0; i < corners_.size(); ++i)
82 // early return if none of the other corners are equal to this corner
83
2/2
✓ Branch 3 taken 510276 times.
✓ Branch 4 taken 63888 times.
1722492 if (std::none_of(otherCorners.begin(),
84 otherCorners.end(),
85 3270912 [&] (const auto& other) { return (corners_[i] - other).two_norm2() < eps2; }))
86 510276 return false;
87
88 1261 return true;
89 }
90
91 private:
92 std::size_t a_, b_; //!< Indices of the intersection elements
93 std::vector<GlobalPosition> corners_; //!< the corner points of the intersection geometry
94 };
95
96 /*!
97 * \ingroup Geometry
98 * \brief Compute all intersections between entities and a point
99 */
100 template<class EntitySet, class ctype, int dimworld>
101 inline std::vector<std::size_t>
102 351661 intersectingEntities(const Dune::FieldVector<ctype, dimworld>& point,
103 const BoundingBoxTree<EntitySet>& tree,
104 bool isCartesianGrid = false)
105 {
106 // Call the recursive find function to find candidates
107
1/2
✓ Branch 1 taken 342229 times.
✗ Branch 2 not taken.
351661 std::vector<std::size_t> entities;
108
2/4
✓ Branch 1 taken 342229 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 342229 times.
✗ Branch 5 not taken.
703322 intersectingEntities(point, tree, tree.numBoundingBoxes() - 1, entities, isCartesianGrid);
109 351661 return entities;
110 }
111
112 /*!
113 * \ingroup Geometry
114 * \brief Compute intersections with point for all nodes of the bounding box tree recursively
115 */
116 template<class EntitySet, class ctype, int dimworld>
117 12394991 void intersectingEntities(const Dune::FieldVector<ctype, dimworld>& point,
118 const BoundingBoxTree<EntitySet>& tree,
119 std::size_t node,
120 std::vector<std::size_t>& entities,
121 bool isCartesianGrid = false)
122 {
123 // Get the bounding box for the current node
124
2/2
✓ Branch 0 taken 6375744 times.
✓ Branch 1 taken 5941783 times.
12394991 const auto& bBox = tree.getBoundingBoxNode(node);
125
126 // if the point is not in the bounding box we can stop
127
4/4
✓ Branch 0 taken 6375744 times.
✓ Branch 1 taken 5941783 times.
✓ Branch 2 taken 6375744 times.
✓ Branch 3 taken 5941783 times.
24789982 if (!intersectsPointBoundingBox(point, tree.getBoundingBoxCoordinates(node))) return;
128
129 // now we know it's inside
130 // if the box is a leaf do the primitive test.
131
2/2
✓ Branch 0 taken 383355 times.
✓ Branch 1 taken 5992365 times.
6412180 else if (tree.isLeaf(bBox, node))
132 {
133 385799 const std::size_t entityIdx = bBox.child1;
134 // for structured cube grids skip the primitive test
135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 383355 times.
385799 if (isCartesianGrid)
136 entities.push_back(entityIdx);
137 else
138 {
139
1/2
✓ Branch 3 taken 11 times.
✗ Branch 4 not taken.
771609 const auto geometry = tree.entitySet().entity(entityIdx).geometry();
140 // if the primitive is positive it intersects the actual geometry, add the entity to the list
141
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 330202 times.
✓ Branch 2 taken 53153 times.
✗ Branch 3 not taken.
385819 if (intersectsPointGeometry(point, geometry))
142
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
332666 entities.push_back(entityIdx);
143 }
144 }
145
146 // No leaf. Check both children nodes.
147 else
148 {
149 6026381 intersectingEntities(point, tree, bBox.child0, entities, isCartesianGrid);
150 6026381 intersectingEntities(point, tree, bBox.child1, entities, isCartesianGrid);
151 }
152 }
153
154 /*!
155 * \ingroup Geometry
156 * \brief Compute all intersections between a geometry and a bounding box tree
157 */
158 template<class Geometry, class EntitySet>
159 inline std::vector<IntersectionInfo<Geometry::coorddimension, typename Geometry::ctype, typename EntitySet::ctype>>
160 intersectingEntities(const Geometry& geometry,
161 const BoundingBoxTree<EntitySet>& tree)
162 {
163 using IP = typename IntersectionPolicy::DefaultPolicy<Geometry, typename EntitySet::Entity::Geometry>;
164
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 return intersectingEntities(geometry, tree, IP{});
165 }
166
167 /*!
168 * \ingroup Geometry
169 * \brief Compute all intersections between a geometry and a bounding box tree
170 */
171 template<class Geometry, class EntitySet, class IntersectionPolicy>
172 inline std::vector<IntersectionInfo<Geometry::coorddimension, typename Geometry::ctype, typename EntitySet::ctype>>
173 8 intersectingEntities(const Geometry& geometry,
174 const BoundingBoxTree<EntitySet>& tree,
175 IntersectionPolicy intersectionPolicy)
176 {
177 // check if the world dimensions match
178 static_assert(int(Geometry::coorddimension) == int(EntitySet::dimensionworld),
179 "Can only intersect geometry and bounding box tree of same world dimension");
180
181 // Create data structure for return type
182 8 std::vector<IntersectionInfo<Geometry::coorddimension, typename Geometry::ctype, typename EntitySet::ctype>> intersections;
183 using ctype = typename IntersectionInfo<Geometry::coorddimension, typename Geometry::ctype, typename EntitySet::ctype>::ctype;
184 static constexpr int dimworld = Geometry::coorddimension;
185
186 // compute the bounding box of the given geometry
187 std::array<ctype, 2*Geometry::coorddimension> bBox;
188 8 ctype* xMin = bBox.data(); ctype* xMax = xMin + Geometry::coorddimension;
189
190 // Get coordinates of first vertex
191 8 auto corner = geometry.corner(0);
192
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
28 for (std::size_t dimIdx = 0; dimIdx < dimworld; ++dimIdx)
193 40 xMin[dimIdx] = xMax[dimIdx] = corner[dimIdx];
194
195 // Compute the min and max over the remaining vertices
196
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 4 times.
24 for (std::size_t cornerIdx = 1; cornerIdx < geometry.corners(); ++cornerIdx)
197 {
198 12 corner = geometry.corner(cornerIdx);
199
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 16 times.
44 for (std::size_t dimIdx = 0; dimIdx < dimworld; ++dimIdx)
200 {
201 using std::max;
202 using std::min;
203
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
64 xMin[dimIdx] = min(xMin[dimIdx], corner[dimIdx]);
204
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 20 times.
76 xMax[dimIdx] = max(xMax[dimIdx], corner[dimIdx]);
205 }
206 }
207
208 // Call the recursive find function to find candidates
209 8 intersectingEntities(geometry, tree,
210
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
16 bBox, tree.numBoundingBoxes() - 1,
211 intersections, intersectionPolicy);
212
213 8 return intersections;
214 }
215
216 /*!
217 * \ingroup Geometry
218 * \brief Compute intersections with point for all nodes of the bounding box tree recursively
219 */
220 template<class Geometry, class EntitySet>
221 16668 void intersectingEntities(const Geometry& geometry,
222 const BoundingBoxTree<EntitySet>& tree,
223 const std::array<typename Geometry::ctype, 2*Geometry::coorddimension>& bBox,
224 std::size_t nodeIdx,
225 std::vector<IntersectionInfo<Geometry::coorddimension,
226 typename Geometry::ctype,
227 typename EntitySet::ctype>>& intersections)
228 {
229 using IP = typename IntersectionPolicy::DefaultPolicy<Geometry, typename EntitySet::Entity::Geometry>;
230 16668 intersectingEntities(geometry, tree, bBox, nodeIdx, intersections, IP{});
231 16668 }
232 /*!
233 * \ingroup Geometry
234 * \brief Compute intersections with point for all nodes of the bounding box tree recursively
235 */
236 template<class Geometry, class EntitySet, class IntersectionPolicy>
237 16676 void intersectingEntities(const Geometry& geometry,
238 const BoundingBoxTree<EntitySet>& tree,
239 const std::array<typename Geometry::ctype, 2*Geometry::coorddimension>& bBox,
240 std::size_t nodeIdx,
241 std::vector<IntersectionInfo<Geometry::coorddimension,
242 typename Geometry::ctype,
243 typename EntitySet::ctype>>& intersections,
244 IntersectionPolicy intersectionPolicy)
245 {
246 // if the two bounding boxes don't intersect we can stop searching
247 static constexpr int dimworld = Geometry::coorddimension;
248
6/6
✓ Branch 0 taken 12712 times.
✓ Branch 1 taken 3964 times.
✓ Branch 2 taken 12712 times.
✓ Branch 3 taken 3964 times.
✓ Branch 4 taken 12712 times.
✓ Branch 5 taken 3964 times.
50028 if (!intersectsBoundingBoxBoundingBox<dimworld>(bBox.data(), tree.getBoundingBoxCoordinates(nodeIdx)))
249 return;
250
251 // get node info for current bounding box node
252
2/2
✓ Branch 0 taken 4378 times.
✓ Branch 1 taken 8334 times.
12712 const auto& bBoxNode = tree.getBoundingBoxNode(nodeIdx);
253
254 // if the box is a leaf do the primitive test.
255
2/2
✓ Branch 0 taken 4378 times.
✓ Branch 1 taken 8334 times.
12712 if (tree.isLeaf(bBoxNode, nodeIdx))
256 {
257 // eIdxA is always 0 since we intersect with exactly one geometry
258 4378 const auto eIdxA = 0;
259 4378 const auto eIdxB = bBoxNode.child1;
260
261 8756 const auto geometryTree = tree.entitySet().entity(eIdxB).geometry();
262 using GeometryTree = std::decay_t<decltype(geometryTree)>;
263 using IntersectionAlgorithm = GeometryIntersection<Geometry, GeometryTree, IntersectionPolicy>;
264 using Intersection = typename IntersectionAlgorithm::Intersection;
265
3/6
✓ Branch 1 taken 4356 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2244 times.
✓ Branch 4 taken 2112 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
10978 Intersection intersection;
266
267
4/4
✓ Branch 1 taken 4370 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 2244 times.
✓ Branch 4 taken 2112 times.
4378 if (IntersectionAlgorithm::intersection(geometry, geometryTree, intersection))
268 {
269 static constexpr int dimIntersection = IntersectionPolicy::dimIntersection;
270 if constexpr (dimIntersection >= 2)
271 {
272
2/6
✓ Branch 1 taken 2244 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2244 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
6732 const auto triangulation = triangulate<dimIntersection, dimworld>(intersection);
273
4/4
✓ Branch 0 taken 8580 times.
✓ Branch 1 taken 2244 times.
✓ Branch 2 taken 8580 times.
✓ Branch 3 taken 2244 times.
13068 for (unsigned int i = 0; i < triangulation.size(); ++i)
274
2/4
✓ Branch 1 taken 8580 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8580 times.
✗ Branch 5 not taken.
17160 intersections.emplace_back(eIdxA, eIdxB, std::move(triangulation[i]));
275 }
276 else
277 14 intersections.emplace_back(eIdxA, eIdxB, intersection);
278 }
279 }
280
281 // No leaf. Check both children nodes.
282 else
283 {
284 8334 intersectingEntities(geometry, tree, bBox, bBoxNode.child0, intersections);
285 8334 intersectingEntities(geometry, tree, bBox, bBoxNode.child1, intersections);
286 }
287 }
288
289 /*!
290 * \ingroup Geometry
291 * \brief Compute all intersections between two bounding box trees
292 */
293 template<class EntitySet0, class EntitySet1>
294 inline std::vector<IntersectionInfo<EntitySet0::dimensionworld, typename EntitySet0::ctype, typename EntitySet1::ctype>>
295 intersectingEntities(const BoundingBoxTree<EntitySet0>& treeA,
296 const BoundingBoxTree<EntitySet1>& treeB)
297 {
298 using IP = typename IntersectionPolicy::DefaultPolicy<typename EntitySet0::Entity::Geometry, typename EntitySet1::Entity::Geometry>;
299
2/4
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
144 return intersectingEntities(treeA, treeB, IP{});
300 }
301
302 /*!
303 * \ingroup Geometry
304 * \brief Compute all intersections between two bounding box trees
305 */
306 template<class EntitySet0, class EntitySet1, class IntersectionPolicy>
307 inline std::vector<IntersectionInfo<EntitySet0::dimensionworld, typename EntitySet0::ctype, typename EntitySet1::ctype>>
308 intersectingEntities(const BoundingBoxTree<EntitySet0>& treeA,
309 const BoundingBoxTree<EntitySet1>& treeB,
310 IntersectionPolicy intersectionPolicy)
311 {
312 // check if the world dimensions match
313 static_assert(int(EntitySet0::dimensionworld) == int(EntitySet1::dimensionworld),
314 "Can only intersect bounding box trees of same world dimension");
315
316 // Create data structure for return type
317 std::vector<IntersectionInfo<EntitySet0::dimensionworld, typename EntitySet0::ctype, typename EntitySet1::ctype>> intersections;
318
319 // Call the recursive find function to find candidates
320 intersectingEntities(treeA, treeB,
321 treeA.numBoundingBoxes() - 1,
322 treeB.numBoundingBoxes() - 1,
323 intersections, intersectionPolicy);
324
325 return intersections;
326 }
327
328 /*!
329 * \ingroup Geometry
330 * \brief Compute all intersections between two all bounding box tree nodes recursively
331 */
332 template<class EntitySet0, class EntitySet1>
333 4384068 void intersectingEntities(const BoundingBoxTree<EntitySet0>& treeA,
334 const BoundingBoxTree<EntitySet1>& treeB,
335 std::size_t nodeA, std::size_t nodeB,
336 std::vector<IntersectionInfo<EntitySet0::dimensionworld,
337 typename EntitySet0::ctype,
338 typename EntitySet1::ctype>>& intersections)
339 {
340 using IP = typename IntersectionPolicy::DefaultPolicy<typename EntitySet0::Entity::Geometry, typename EntitySet1::Entity::Geometry>;
341 4384068 intersectingEntities(treeA, treeB, nodeA, nodeB, intersections, IP{});
342 4384068 }
343
344 /*!
345 * \ingroup Geometry
346 * \brief Compute all intersections between two all bounding box tree nodes recursively
347 */
348 template<class EntitySet0, class EntitySet1, class IntersectionPolicy>
349 3565754 void intersectingEntities(const BoundingBoxTree<EntitySet0>& treeA,
350 const BoundingBoxTree<EntitySet1>& treeB,
351 std::size_t nodeA, std::size_t nodeB,
352 std::vector<IntersectionInfo<EntitySet0::dimensionworld,
353 typename EntitySet0::ctype,
354 typename EntitySet1::ctype>>& intersections,
355 IntersectionPolicy intersectionPolicy)
356 {
357 // Get the bounding box for the current node
358
2/2
✓ Branch 0 taken 1603800 times.
✓ Branch 1 taken 1143418 times.
3565754 const auto& bBoxA = treeA.getBoundingBoxNode(nodeA);
359
2/2
✓ Branch 0 taken 1603800 times.
✓ Branch 1 taken 1143418 times.
3565754 const auto& bBoxB = treeB.getBoundingBoxNode(nodeB);
360
361 // if the two bounding boxes of the current nodes don't intersect we can stop searching
362 static constexpr int dimworld = EntitySet0::dimensionworld;
363
6/6
✓ Branch 0 taken 1603800 times.
✓ Branch 1 taken 1143418 times.
✓ Branch 2 taken 1603800 times.
✓ Branch 3 taken 1143418 times.
✓ Branch 4 taken 1603800 times.
✓ Branch 5 taken 1143418 times.
10697262 if (!intersectsBoundingBoxBoundingBox<dimworld>(treeA.getBoundingBoxCoordinates(nodeA),
364 treeB.getBoundingBoxCoordinates(nodeB)))
365 return;
366
367 // Check if we have a leaf in treeA or treeB
368
2/2
✓ Branch 0 taken 230224 times.
✓ Branch 1 taken 1373576 times.
2184965 const bool isLeafA = treeA.isLeaf(bBoxA, nodeA);
369
2/2
✓ Branch 0 taken 230224 times.
✓ Branch 1 taken 1373576 times.
2184965 const bool isLeafB = treeB.isLeaf(bBoxB, nodeB);
370
371 // If both boxes are leaves do the primitive test
372
2/2
✓ Branch 0 taken 230224 times.
✓ Branch 1 taken 1373576 times.
2184965 if (isLeafA && isLeafB)
373 {
374 402160 const auto eIdxA = bBoxA.child1;
375 402160 const auto eIdxB = bBoxB.child1;
376
377 1108701 const auto geometryA = treeA.entitySet().entity(eIdxA).geometry();
378 812038 const auto geometryB = treeB.entitySet().entity(eIdxB).geometry();
379
380 using GeometryA = std::decay_t<decltype(geometryA)>;
381 using GeometryB = std::decay_t<decltype(geometryB)>;
382 using IntersectionAlgorithm = GeometryIntersection<GeometryA, GeometryB, IntersectionPolicy>;
383 using Intersection = typename IntersectionAlgorithm::Intersection;
384
385
7/10
✓ Branch 1 taken 227216 times.
✓ Branch 2 taken 3008 times.
✓ Branch 4 taken 215837 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 88330 times.
✓ Branch 7 taken 127507 times.
✓ Branch 8 taken 88330 times.
✓ Branch 9 taken 127507 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
816280 if (Intersection intersection; IntersectionAlgorithm::intersection(geometryA, geometryB, intersection))
386 {
387 static constexpr int dimIntersection = IntersectionPolicy::dimIntersection;
388
389 // intersection is returned as a point cloud for dim >= 2
390 // so we have to triangulate first
391 if constexpr (dimIntersection >= 2)
392 {
393
2/6
✓ Branch 1 taken 88330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 88330 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
272316 const auto triangulation = triangulate<dimIntersection, dimworld>(intersection);
394
4/4
✓ Branch 0 taken 345906 times.
✓ Branch 1 taken 88330 times.
✓ Branch 2 taken 345906 times.
✓ Branch 3 taken 88330 times.
557381 for (unsigned int i = 0; i < triangulation.size(); ++i)
395
2/4
✓ Branch 1 taken 345906 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 345906 times.
✗ Branch 5 not taken.
751674 intersections.emplace_back(eIdxA, eIdxB, std::move(triangulation[i]));
396 }
397 else
398 16546 intersections.emplace_back(eIdxA, eIdxB, intersection);
399 }
400 }
401
402 // if we reached the leaf in treeA, just continue in treeB
403
2/2
✓ Branch 0 taken 279772 times.
✓ Branch 1 taken 1093804 times.
1782805 else if (isLeafA)
404 {
405 347339 intersectingEntities(treeA, treeB, nodeA, bBoxB.child0, intersections);
406 347339 intersectingEntities(treeA, treeB, nodeA, bBoxB.child1, intersections);
407 }
408
409 // if we reached the leaf in treeB, just continue in treeA
410
2/2
✓ Branch 0 taken 981753 times.
✓ Branch 1 taken 112051 times.
1435466 else if (isLeafB)
411 {
412 1160032 intersectingEntities(treeA, treeB, bBoxA.child0, nodeB, intersections);
413 1160032 intersectingEntities(treeA, treeB, bBoxA.child1, nodeB, intersections);
414 }
415
416 // we know now that both trees didn't reach the leaf yet so
417 // we continue with the larger tree first (bigger node number)
418
2/2
✓ Branch 0 taken 32441 times.
✓ Branch 1 taken 79610 times.
275434 else if (nodeA > nodeB)
419 {
420 44708 intersectingEntities(treeA, treeB, bBoxA.child0, nodeB, intersections);
421 44708 intersectingEntities(treeA, treeB, bBoxA.child1, nodeB, intersections);
422 }
423 else
424 {
425 230726 intersectingEntities(treeA, treeB, nodeA, bBoxB.child0, intersections);
426 230726 intersectingEntities(treeA, treeB, nodeA, bBoxB.child1, intersections);
427 }
428 }
429
430 /*!
431 * \ingroup Geometry
432 * \brief Compute the index of the intersecting element of a Cartesian grid with a point
433 * The grid is given by the lower left corner (min), the upper right corner (max)
434 * and the number of cells in each direction (cells).
435 * \note If there are several options the lowest matching cell index will be returned
436 * \note Returns the index i + I*j + I*J*k for the intersecting element i,j,k of a grid with I,J,K cells
437 */
438 template<class ctype, int dimworld>
439 12767128 inline std::size_t intersectingEntityCartesianGrid(const Dune::FieldVector<ctype, dimworld>& point,
440 const Dune::FieldVector<ctype, dimworld>& min,
441 const Dune::FieldVector<ctype, dimworld>& max,
442 const std::array<int, std::size_t(dimworld)>& cells)
443 {
444 12767128 std::size_t index = 0;
445
2/2
✓ Branch 0 taken 38217594 times.
✓ Branch 1 taken 12739198 times.
51067552 for (int i = 0; i < dimworld; ++i)
446 {
447 using std::clamp; using std::floor;
448
7/14
✓ Branch 0 taken 38217594 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38217594 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 38217594 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 38217594 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 38217594 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 38217594 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 38217594 times.
✗ Branch 13 not taken.
268102848 ctype dimOffset = clamp<ctype>(floor((point[i]-min[i])*cells[i]/(max[i]-min[i])), 0.0, cells[i]-1);
449
2/2
✓ Branch 0 taken 38217594 times.
✓ Branch 1 taken 38217594 times.
76599918 for (int j = 0; j < i; ++j)
450 76598988 dimOffset *= cells[j];
451 38300424 index += static_cast<std::size_t>(dimOffset);
452 }
453 12767128 return index;
454 }
455
456 } // end namespace Dumux
457
458 #endif
459