GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/geometry/boundingboxtree.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 116 118 98.3%
Functions: 336 526 63.9%
Branches: 399 480 83.1%

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 An axis-aligned bounding box volume hierarchy for dune grids
11 *
12 * Dumux implementation of an AABB tree
13 * Inspired by the AABB tree implementation in DOLFIN by Anders Logg which has the
14 * following license info: DOLFIN is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 */
19 #ifndef DUMUX_GEOMETRY_BOUNDINGBOXTREE_HH
20 #define DUMUX_GEOMETRY_BOUNDINGBOXTREE_HH
21
22 #include <vector>
23 #include <array>
24 #include <algorithm>
25 #include <memory>
26 #include <numeric>
27 #include <type_traits>
28 #include <iostream>
29
30 #include <dune/common/promotiontraits.hh>
31 #include <dune/common/timer.hh>
32 #include <dune/common/fvector.hh>
33
34 namespace Dumux {
35
36 /*!
37 * \ingroup Geometry
38 * \brief An axis-aligned bounding box volume tree implementation
39 *
40 * The class constructs a hierarchical structure of bounding box volumes around
41 * grid entities. This class can be used to efficiently compute intersections
42 * between a grid and other geometrical object. It only implements the intersection
43 * of two of such bounding box trees, so that two independent grids can be intersected.
44 * \tparam GeometricEntitySet has the following requirements
45 * * export dimensionworld, ctype
46 * * a size() member function returning the number of entities
47 * * begin() and end() member function returning at least forward iterators to entities
48 * * an index() method returning a consecutive index given an entity
49 * * an entity() method returning an entity given the consecutive index
50 * * entities have the following requirements:
51 * * a member function geometry() returning a geometry with the member functions
52 * * corner() and corners() returning global coordinates and number of corners
53 */
54 template <class GeometricEntitySet>
55 class BoundingBoxTree
56 {
57 enum { dimworld = GeometricEntitySet::dimensionworld };
58 using ctype = typename GeometricEntitySet::ctype;
59
60 /*!
61 * \brief Bounding box node data structure
62 * leaf nodes are indicated by setting child0 to
63 * the node itself and child1 to the index of the entity in the bounding box.
64 */
65 struct BoundingBoxNode
66 {
67 std::size_t child0;
68 std::size_t child1;
69 };
70
71 public:
72 //! the type of entity set this tree was built with
73 using EntitySet = GeometricEntitySet;
74
75 //! Default Constructor
76
8/16
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 4 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
72 BoundingBoxTree() = default;
77
78 //! Constructor with gridView
79 4517 BoundingBoxTree(std::shared_ptr<const GeometricEntitySet> set)
80
2/12
✓ Branch 5 taken 2508 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2508 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
22585 { build(set); }
81
82 //! Build up bounding box tree for a grid with leafGridView
83 4589 void build(std::shared_ptr<const GeometricEntitySet> set)
84 {
85 // set the pointer to the entity set
86 4589 entitySet_ = set;
87
88 // clear all internal data
89
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2542 times.
4589 boundingBoxNodes_.clear();
90
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2542 times.
4589 boundingBoxCoordinates_.clear();
91
92 // start the timer
93 4589 Dune::Timer timer;
94
95 // Create bounding boxes for all elements
96 9178 const auto numLeaves = set->size();
97
98 // reserve enough space for the nodes and the coordinates
99 4589 const auto numNodes = 2*numLeaves - 1;
100 4589 boundingBoxNodes_.reserve(numNodes);
101 4589 boundingBoxCoordinates_.reserve(numNodes*2*dimworld);
102
103 // create a vector for leaf boxes (min and max for all dims)
104 9178 std::vector<ctype> leafBoxes(2*dimworld*numLeaves);
105
106
16/18
✓ Branch 0 taken 56039 times.
✓ Branch 1 taken 2381 times.
✓ Branch 2 taken 56039 times.
✓ Branch 3 taken 124184 times.
✓ Branch 4 taken 877 times.
✓ Branch 5 taken 122515 times.
✓ Branch 6 taken 165 times.
✓ Branch 7 taken 721 times.
✓ Branch 8 taken 3751 times.
✓ Branch 9 taken 3155947 times.
✓ Branch 10 taken 220 times.
✓ Branch 11 taken 648659 times.
✓ Branch 12 taken 220 times.
✓ Branch 13 taken 11160 times.
✓ Branch 14 taken 648659 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 648659 times.
✗ Branch 18 not taken.
9689156 for (const auto& geometricEntity : *set)
107
4/8
✓ Branch 1 taken 665748 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 743894 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 665748 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 654588 times.
✗ Branch 11 not taken.
16102447 computeEntityBoundingBox_(leafBoxes.data() + 2*dimworld*set->index(geometricEntity), geometricEntity);
108
109 // create the leaf partition, the set of available indices (to be sorted)
110
3/8
✓ Branch 1 taken 2546 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2546 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2546 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
13767 std::vector<std::size_t> leafPartition(numLeaves);
111 13767 std::iota(leafPartition.begin(), leafPartition.end(), 0);
112
113 // Recursively build the bounding box tree
114
3/8
✓ Branch 1 taken 2546 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2546 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2546 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
13767 build_(leafBoxes, leafPartition.begin(), leafPartition.end());
115
116 // We are done, log output
117
1/2
✓ Branch 2 taken 2546 times.
✗ Branch 3 not taken.
9178 std::cout << "Computed bounding box tree with " << numBoundingBoxes()
118
1/2
✓ Branch 2 taken 2546 times.
✗ Branch 3 not taken.
9178 << " nodes for " << numLeaves << " grid entities in "
119
3/6
✓ Branch 2 taken 2546 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2546 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2546 times.
✗ Branch 9 not taken.
9178 << timer.stop() << " seconds." << std::endl;
120 4589 }
121
122 //! the entity set this tree was built with
123 const EntitySet& entitySet() const
124
30/43
✓ Branch 1 taken 16404 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 453 times.
✓ Branch 4 taken 16404 times.
✓ Branch 5 taken 314256 times.
✓ Branch 6 taken 453 times.
✓ Branch 7 taken 11396 times.
✓ Branch 8 taken 314256 times.
✓ Branch 9 taken 24502 times.
✓ Branch 10 taken 11396 times.
✓ Branch 11 taken 316422 times.
✓ Branch 12 taken 24502 times.
✓ Branch 13 taken 11408 times.
✓ Branch 14 taken 316422 times.
✓ Branch 15 taken 4640 times.
✓ Branch 16 taken 11408 times.
✓ Branch 17 taken 314662 times.
✓ Branch 18 taken 4640 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 314662 times.
✓ Branch 21 taken 1968 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 779344 times.
✓ Branch 24 taken 1968 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 779344 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 7056 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 7056 times.
✗ Branch 33 not taken.
✓ Branch 35 taken 7056 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 7056 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 7056 times.
✗ Branch 42 not taken.
✓ Branch 44 taken 7056 times.
✗ Branch 45 not taken.
✓ Branch 47 taken 28224 times.
✗ Branch 48 not taken.
✓ Branch 50 taken 28224 times.
✗ Branch 51 not taken.
13167644 { return *entitySet_; }
125
126 /////////////////////////////////////////////////////
127 //! Interface to be used by other bounding box trees
128 /////////////////////////////////////////////////////
129
130 //! Get an existing bounding box for a given node
131 const BoundingBoxNode& getBoundingBoxNode(std::size_t nodeIdx) const
132
48/48
✓ Branch 0 taken 2764020 times.
✓ Branch 1 taken 2154111 times.
✓ Branch 2 taken 2764020 times.
✓ Branch 3 taken 2154111 times.
✓ Branch 4 taken 1687539 times.
✓ Branch 5 taken 1214453 times.
✓ Branch 6 taken 1687539 times.
✓ Branch 7 taken 1214453 times.
✓ Branch 8 taken 5640342 times.
✓ Branch 9 taken 5541430 times.
✓ Branch 10 taken 5640342 times.
✓ Branch 11 taken 5541430 times.
✓ Branch 12 taken 198631 times.
✓ Branch 13 taken 265226 times.
✓ Branch 14 taken 198631 times.
✓ Branch 15 taken 265226 times.
✓ Branch 16 taken 1807786 times.
✓ Branch 17 taken 4359807 times.
✓ Branch 18 taken 1807786 times.
✓ Branch 19 taken 4359807 times.
✓ Branch 20 taken 926876 times.
✓ Branch 21 taken 2381898 times.
✓ Branch 22 taken 926876 times.
✓ Branch 23 taken 2381898 times.
✓ Branch 24 taken 2892 times.
✓ Branch 25 taken 1325 times.
✓ Branch 26 taken 2892 times.
✓ Branch 27 taken 1325 times.
✓ Branch 28 taken 2136 times.
✓ Branch 29 taken 1091 times.
✓ Branch 30 taken 2136 times.
✓ Branch 31 taken 1091 times.
✓ Branch 32 taken 517677 times.
✓ Branch 33 taken 204664 times.
✓ Branch 34 taken 517677 times.
✓ Branch 35 taken 204664 times.
✓ Branch 36 taken 496492 times.
✓ Branch 37 taken 191807 times.
✓ Branch 38 taken 496492 times.
✓ Branch 39 taken 191807 times.
✓ Branch 40 taken 1259897 times.
✓ Branch 41 taken 692793 times.
✓ Branch 42 taken 1259897 times.
✓ Branch 43 taken 692793 times.
✓ Branch 44 taken 893741 times.
✓ Branch 45 taken 477679 times.
✓ Branch 46 taken 893741 times.
✓ Branch 47 taken 477679 times.
67368626 { return boundingBoxNodes_[nodeIdx]; }
133
134 //! Get an existing bounding box for a given node
135 const ctype* getBoundingBoxCoordinates(std::size_t nodeIdx) const
136
48/48
✓ Branch 0 taken 2767915 times.
✓ Branch 1 taken 2074690 times.
✓ Branch 2 taken 2767915 times.
✓ Branch 3 taken 2074690 times.
✓ Branch 4 taken 1687787 times.
✓ Branch 5 taken 1212459 times.
✓ Branch 6 taken 1687787 times.
✓ Branch 7 taken 1212459 times.
✓ Branch 8 taken 5743241 times.
✓ Branch 9 taken 5203175 times.
✓ Branch 10 taken 5743241 times.
✓ Branch 11 taken 5203175 times.
✓ Branch 12 taken 247696 times.
✓ Branch 13 taken 107380 times.
✓ Branch 14 taken 247696 times.
✓ Branch 15 taken 107380 times.
✓ Branch 16 taken 3085030 times.
✓ Branch 17 taken 1311211 times.
✓ Branch 18 taken 3085030 times.
✓ Branch 19 taken 1311211 times.
✓ Branch 20 taken 1653644 times.
✓ Branch 21 taken 742169 times.
✓ Branch 22 taken 1653644 times.
✓ Branch 23 taken 742169 times.
✓ Branch 24 taken 2892 times.
✓ Branch 25 taken 1325 times.
✓ Branch 26 taken 2892 times.
✓ Branch 27 taken 1325 times.
✓ Branch 28 taken 2136 times.
✓ Branch 29 taken 1091 times.
✓ Branch 30 taken 2136 times.
✓ Branch 31 taken 1091 times.
✓ Branch 32 taken 517677 times.
✓ Branch 33 taken 204664 times.
✓ Branch 34 taken 517677 times.
✓ Branch 35 taken 204664 times.
✓ Branch 36 taken 496492 times.
✓ Branch 37 taken 191807 times.
✓ Branch 38 taken 496492 times.
✓ Branch 39 taken 191807 times.
✓ Branch 40 taken 1268157 times.
✓ Branch 41 taken 688441 times.
✓ Branch 42 taken 1268157 times.
✓ Branch 43 taken 688441 times.
✓ Branch 44 taken 893741 times.
✓ Branch 45 taken 477679 times.
✓ Branch 46 taken 893741 times.
✓ Branch 47 taken 477679 times.
61164998 { return boundingBoxCoordinates_.data() + 2*dimworld*nodeIdx; }
137
138 //! Get the number of bounding boxes currently in the tree
139 std::size_t numBoundingBoxes() const
140
35/50
✓ Branch 1 taken 765 times.
✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 910 times.
✓ Branch 5 taken 149 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 59308 times.
✓ Branch 8 taken 29 times.
✓ Branch 9 taken 120 times.
✓ Branch 10 taken 4789 times.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 120 times.
✓ Branch 13 taken 277359 times.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 124 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 2 times.
✓ Branch 19 taken 142 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 2 times.
✓ Branch 22 taken 4 times.
✓ Branch 23 taken 120 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 10 times.
✓ Branch 26 taken 120 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 22 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 120 times.
✓ Branch 31 taken 8 times.
✓ Branch 32 taken 6 times.
✓ Branch 33 taken 120 times.
✓ Branch 34 taken 4 times.
✓ Branch 35 taken 6 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 124 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 2 times.
✓ Branch 40 taken 124 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 2 times.
✓ Branch 43 taken 16 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 18 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 6 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 8 times.
✗ Branch 53 not taken.
412959 { return boundingBoxNodes_.size(); }
141
142 //! Check whether a bounding box node is a leaf node
143 //! Leaf nodes have itself as child0
144 bool isLeaf(const BoundingBoxNode& node, std::size_t nodeIdx) const
145
20/20
✓ Branch 0 taken 234935 times.
✓ Branch 1 taken 1398482 times.
✓ Branch 2 taken 234935 times.
✓ Branch 3 taken 1398482 times.
✓ Branch 4 taken 17267 times.
✓ Branch 5 taken 72536 times.
✓ Branch 6 taken 17267 times.
✓ Branch 7 taken 72536 times.
✓ Branch 8 taken 4580 times.
✓ Branch 9 taken 9335 times.
✓ Branch 10 taken 4580 times.
✓ Branch 11 taken 9335 times.
✓ Branch 12 taken 256 times.
✓ Branch 13 taken 308 times.
✓ Branch 14 taken 256 times.
✓ Branch 15 taken 308 times.
✓ Branch 16 taken 143776 times.
✓ Branch 17 taken 287492 times.
✓ Branch 18 taken 143776 times.
✓ Branch 19 taken 287492 times.
4337934 { return node.child0 == nodeIdx; }
146
147 private:
148
149 //! vector of bounding box nodes
150 std::vector<BoundingBoxNode> boundingBoxNodes_;
151
152 //! vector of bounding box coordinates
153 std::vector<ctype> boundingBoxCoordinates_;
154
155 //! a pointer to the entity set
156 std::shared_ptr<const EntitySet> entitySet_;
157
158 //! Compute the bounding box of a grid entity
159 template <class Entity>
160 5291449 void computeEntityBoundingBox_(ctype* b, const Entity& entity) const
161 {
162 // get the bounding box coordinates
163 5319083 ctype* xMin = b;
164 5319083 ctype* xMax = b + dimworld;
165
166 // get mesh entity data
167
1/2
✓ Branch 2 taken 2178 times.
✗ Branch 3 not taken.
5862445 auto geometry = entity.geometry();
168
169 // Get coordinates of first vertex
170 5319083 auto corner = geometry.corner(0);
171
12/12
✓ Branch 0 taken 3512814 times.
✓ Branch 1 taken 7525616 times.
✓ Branch 2 taken 216546 times.
✓ Branch 3 taken 528 times.
✓ Branch 4 taken 24000 times.
✓ Branch 5 taken 8160 times.
✓ Branch 6 taken 7200 times.
✓ Branch 7 taken 2400 times.
✓ Branch 8 taken 34020 times.
✓ Branch 9 taken 11340 times.
✓ Branch 10 taken 11820 times.
✓ Branch 11 taken 4100 times.
18568208 for (std::size_t dimIdx = 0; dimIdx < dimworld; ++dimIdx)
172 26483638 xMin[dimIdx] = xMax[dimIdx] = corner[dimIdx];
173
174 // Compute the min and max over the remaining vertices
175
4/4
✓ Branch 0 taken 14160371 times.
✓ Branch 1 taken 3306366 times.
✓ Branch 2 taken 14160304 times.
✓ Branch 3 taken 3306333 times.
35230086 for (std::size_t cornerIdx = 1; cornerIdx < geometry.corners(); ++cornerIdx)
176 {
177 24605008 corner = geometry.corner(cornerIdx);
178
3/3
✓ Branch 0 taken 36530644 times.
✓ Branch 1 taken 14288673 times.
✓ Branch 2 taken 125558 times.
90552823 for (std::size_t dimIdx = 0; dimIdx < dimworld; ++dimIdx)
179 {
180 using std::max;
181 using std::min;
182
4/4
✓ Branch 0 taken 1026621 times.
✓ Branch 1 taken 35757883 times.
✓ Branch 2 taken 1026621 times.
✓ Branch 3 taken 35743291 times.
131881018 xMin[dimIdx] = min(xMin[dimIdx], corner[dimIdx]);
183
4/4
✓ Branch 0 taken 7876033 times.
✓ Branch 1 taken 28908471 times.
✓ Branch 2 taken 7861441 times.
✓ Branch 3 taken 28908471 times.
145042463 xMax[dimIdx] = max(xMax[dimIdx], corner[dimIdx]);
184 }
185 }
186 5291449 }
187
188 //! Build bounding box tree for all entities recursively
189 10688845 std::size_t build_(const std::vector<ctype>& leafBoxes,
190 const std::vector<std::size_t>::iterator& begin,
191 const std::vector<std::size_t>::iterator& end)
192 {
193
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6665454 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6665454 times.
21377690 assert(begin < end);
194
195 // If we reached the end of the recursion, i.e. only a leaf box is left
196
4/4
✓ Branch 0 taken 3334000 times.
✓ Branch 1 taken 3331454 times.
✓ Branch 2 taken 3334000 times.
✓ Branch 3 taken 3331454 times.
21377690 if (end - begin == 1)
197 {
198 // Get the bounding box coordinates for the leaf
199 5346717 const std::size_t leafNodeIdx = *begin;
200 10693434 const auto beginCoords = leafBoxes.begin() + 2*dimworld*leafNodeIdx;
201 5346717 const auto endCoords = beginCoords + 2*dimworld;
202
203 // Store the data in the bounding box
204 // leaf nodes are indicated by setting child0 to
205 // the node itself and child1 to the index of the entity in the bounding box.
206 10693434 return addBoundingBox_(BoundingBoxNode{numBoundingBoxes(), leafNodeIdx}, beginCoords, endCoords);
207 }
208
209 // Compute the bounding box of all bounding boxes in the range [begin, end]
210 5342128 const auto bCoords = computeBBoxOfBBoxes_(leafBoxes, begin, end);
211
212 // sort bounding boxes along the longest axis
213 5356694 const auto axis = computeLongestAxis_(bCoords);
214
215 // nth_element sorts the range to make sure that middle points to the coordinate median in axis direction
216 // this is the most expensive part of the algorithm
217 5342128 auto middle = begin + (end - begin)/2;
218 173759594 std::nth_element(begin, middle, end, [&leafBoxes, axis](std::size_t i, std::size_t j)
219 {
220 265475454 const ctype* bi = leafBoxes.data() + 2*dimworld*i;
221 265475454 const ctype* bj = leafBoxes.data() + 2*dimworld*j;
222 132737727 return bi[axis] + bi[axis + dimworld] < bj[axis] + bj[axis + dimworld];
223 });
224
225 // split the bounding boxes into two at the middle iterator and call build recursively, each
226 // call resulting in a new node of this bounding box, i.e. the root will be added at the end of the process.
227 return addBoundingBox_(BoundingBoxNode{build_(leafBoxes, begin, middle), build_(leafBoxes, middle, end)},
228
5/10
✓ Branch 1 taken 3331454 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3331454 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3331454 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3331454 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3331454 times.
✗ Branch 14 not taken.
16026384 bCoords.begin(), bCoords.end());
229 }
230
231 //! Add a new bounding box to the tree
232 template <class Iterator>
233 6662908 std::size_t addBoundingBox_(BoundingBoxNode&& node,
234 const Iterator& coordBegin,
235 const Iterator& coordEnd)
236 {
237 // Add the bounding box
238 6662908 boundingBoxNodes_.emplace_back(node);
239
240 // Add the bounding box's coordinates
241
0/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
19988724 boundingBoxCoordinates_.insert(boundingBoxCoordinates_.end(), coordBegin, coordEnd);
242
243 // return the index of the new node
244 13325816 return boundingBoxNodes_.size() - 1;
245 }
246
247 //! Compute the bounding box of a vector of bounding boxes
248 std::array<ctype, 2*dimworld>
249 5342128 computeBBoxOfBBoxes_(const std::vector<ctype>& leafBoxes,
250 const std::vector<std::size_t>::iterator& begin,
251 const std::vector<std::size_t>::iterator& end)
252 {
253 std::array<ctype, 2*dimworld> bBoxCoords;
254
255 // copy the iterator and get coordinates of first box
256 5342128 auto it = begin;
257 5342128 const auto* bFirst = leafBoxes.data() + 2*dimworld*(*it);
258
259
2/2
✓ Branch 0 taken 3331454 times.
✓ Branch 1 taken 16036380 times.
31979548 for (int coordIdx = 0; coordIdx < 2*dimworld; ++coordIdx)
260 53274840 bBoxCoords[coordIdx] = bFirst[coordIdx];
261
262 // Compute min and max with the remaining boxes
263
4/4
✓ Branch 0 taken 48452029 times.
✓ Branch 1 taken 3331454 times.
✓ Branch 2 taken 48452029 times.
✓ Branch 3 taken 3331454 times.
89642595 for (; it != end; ++it)
264 {
265 78958339 const auto* b = leafBoxes.data() + 2*dimworld*(*it);
266
2/2
✓ Branch 0 taken 48452029 times.
✓ Branch 1 taken 118476794 times.
279198802 for (int coordIdx = 0; coordIdx < dimworld; ++coordIdx)
267
4/4
✓ Branch 0 taken 3895068 times.
✓ Branch 1 taken 114581726 times.
✓ Branch 2 taken 3895068 times.
✓ Branch 3 taken 114581726 times.
400208126 if (b[coordIdx] < bBoxCoords[coordIdx])
268 12214160 bBoxCoords[coordIdx] = b[coordIdx];
269
2/2
✓ Branch 0 taken 118476794 times.
✓ Branch 1 taken 48452029 times.
279062402 for (int coordIdx = dimworld; coordIdx < 2*dimworld; ++coordIdx)
270
4/4
✓ Branch 0 taken 6188268 times.
✓ Branch 1 taken 112288526 times.
✓ Branch 2 taken 6188268 times.
✓ Branch 3 taken 112288526 times.
400208126 if (b[coordIdx] > bBoxCoords[coordIdx])
271 19644202 bBoxCoords[coordIdx] = b[coordIdx];
272 }
273
274 5342128 return bBoxCoords;
275 }
276
277 //! Compute the bounding box of a vector of bounding boxes
278 std::size_t computeLongestAxis_(const std::array<ctype, 2*dimworld>& bCoords)
279 {
280 std::array<ctype, dimworld> axisLength;
281
30/30
✓ Branch 0 taken 422208 times.
✓ Branch 1 taken 901512 times.
✓ Branch 2 taken 2662093 times.
✓ Branch 3 taken 6410892 times.
✓ Branch 4 taken 20781 times.
✓ Branch 5 taken 61838 times.
✓ Branch 6 taken 160538 times.
✓ Branch 7 taken 477168 times.
✓ Branch 8 taken 498 times.
✓ Branch 9 taken 1040 times.
✓ Branch 10 taken 454 times.
✓ Branch 11 taken 956 times.
✓ Branch 12 taken 406 times.
✓ Branch 13 taken 1172 times.
✓ Branch 14 taken 8034 times.
✓ Branch 15 taken 24102 times.
✓ Branch 16 taken 8034 times.
✓ Branch 17 taken 24102 times.
✓ Branch 18 taken 2274 times.
✓ Branch 19 taken 6822 times.
✓ Branch 20 taken 2274 times.
✓ Branch 21 taken 6462 times.
✓ Branch 22 taken 11218 times.
✓ Branch 23 taken 33294 times.
✓ Branch 24 taken 10858 times.
✓ Branch 25 taken 32574 times.
✓ Branch 26 taken 3618 times.
✓ Branch 27 taken 10854 times.
✓ Branch 28 taken 3618 times.
✓ Branch 29 taken 10854 times.
11335096 for (int coordIdx = 0; coordIdx < dimworld; ++coordIdx)
282 32014568 axisLength[coordIdx] = bCoords[dimworld + coordIdx] - bCoords[coordIdx];
283
284 9950718 return std::distance(axisLength.begin(), std::max_element(axisLength.begin(), axisLength.end()));
285 }
286 };
287
288 /*!
289 * \brief Check whether a point is intersectin a bounding box (dimworld == 3)
290 * \param point The point
291 * \param b Pointer to bounding box coordinates
292 */
293 template<class ctype, int dimworld, typename std::enable_if_t<dimworld == 3, int> = 0>
294 24638475 inline bool intersectsPointBoundingBox(const Dune::FieldVector<ctype, dimworld>& point, const ctype* b)
295 {
296 static constexpr ctype eps_ = 1.0e-7;
297
298 using std::max;
299 24638475 const auto dx = b[3] - b[0];
300 24638475 const auto dy = b[4] - b[1];
301 24638475 const auto dz = b[5] - b[2];
302 24638475 const ctype eps = max({dx, dy, dz})*eps_;
303
6/6
✓ Branch 0 taken 23489212 times.
✓ Branch 1 taken 1149263 times.
✓ Branch 2 taken 22331060 times.
✓ Branch 3 taken 1158152 times.
✓ Branch 4 taken 22331060 times.
✓ Branch 5 taken 1158152 times.
24638475 return (b[0] - eps <= point[0] && point[0] <= b[3] + eps &&
304
8/8
✓ Branch 0 taken 21377072 times.
✓ Branch 1 taken 953988 times.
✓ Branch 2 taken 21377072 times.
✓ Branch 3 taken 953988 times.
✓ Branch 4 taken 20394470 times.
✓ Branch 5 taken 982602 times.
✓ Branch 6 taken 20394470 times.
✓ Branch 7 taken 982602 times.
44662120 b[1] - eps <= point[1] && point[1] <= b[4] + eps &&
305
10/10
✓ Branch 0 taken 23489212 times.
✓ Branch 1 taken 1149263 times.
✓ Branch 2 taken 19588205 times.
✓ Branch 3 taken 806265 times.
✓ Branch 4 taken 19588205 times.
✓ Branch 5 taken 806265 times.
✓ Branch 6 taken 873660 times.
✓ Branch 7 taken 18714545 times.
✓ Branch 8 taken 873660 times.
✓ Branch 9 taken 18714545 times.
65427415 b[2] - eps <= point[2] && point[2] <= b[5] + eps);
306 }
307
308 /*!
309 * \brief Check whether a point is intersectin a bounding box (dimworld == 2)
310 * \param point The point
311 * \param b Pointer to bounding box coordinates
312 */
313 template<class ctype, int dimworld, typename std::enable_if_t<dimworld == 2, int> = 0>
314 757997 inline bool intersectsPointBoundingBox(const Dune::FieldVector<ctype, dimworld>& point, const ctype* b)
315 {
316 static constexpr ctype eps_ = 1.0e-7;
317
318 using std::max;
319 757997 const auto dx = b[2] - b[0];
320 757997 const auto dy = b[3] - b[1];
321
2/2
✓ Branch 0 taken 370536 times.
✓ Branch 1 taken 387461 times.
757997 const ctype eps = max(dx, dy)*eps_;
322
6/6
✓ Branch 0 taken 659671 times.
✓ Branch 1 taken 98326 times.
✓ Branch 2 taken 560653 times.
✓ Branch 3 taken 99018 times.
✓ Branch 4 taken 560653 times.
✓ Branch 5 taken 99018 times.
757997 return (b[0] - eps <= point[0] && point[0] <= b[2] + eps &&
323
10/10
✓ Branch 0 taken 659671 times.
✓ Branch 1 taken 98326 times.
✓ Branch 2 taken 462236 times.
✓ Branch 3 taken 98417 times.
✓ Branch 4 taken 462236 times.
✓ Branch 5 taken 98417 times.
✓ Branch 6 taken 105636 times.
✓ Branch 7 taken 356600 times.
✓ Branch 8 taken 105636 times.
✓ Branch 9 taken 356600 times.
1879303 b[1] - eps <= point[1] && point[1] <= b[3] + eps);
324 }
325
326 /*!
327 * \brief Check whether a point is intersectin a bounding box (dimworld == 1)
328 * \param point The point
329 * \param b Pointer to bounding box coordinates
330 */
331 template<class ctype, int dimworld, typename std::enable_if_t<dimworld == 1, int> = 0>
332 inline bool intersectsPointBoundingBox(const Dune::FieldVector<ctype, dimworld>& point, const ctype* b)
333 {
334 static constexpr ctype eps_ = 1.0e-7;
335 214 const ctype eps0 = eps_*(b[1] - b[0]);
336
4/4
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 86 times.
✓ Branch 2 taken 104 times.
✓ Branch 3 taken 24 times.
214 return b[0] - eps0 <= point[0] && point[0] <= b[1] + eps0;
337 }
338
339 /*!
340 * \ingroup Geometry
341 * \brief Determine if a point intersects an axis-aligned bounding box
342 * The bounding box is given by the lower left corner (min) and the upper right corner (max)
343 */
344 template<class ctype, int dimworld>
345 12357291 inline bool intersectsPointBoundingBox(const Dune::FieldVector<ctype, dimworld>& point,
346 const Dune::FieldVector<ctype, dimworld>& min,
347 const Dune::FieldVector<ctype, dimworld>& max)
348 {
349 std::array<ctype, 2*dimworld> bBox;
350 49429164 std::copy(min.begin(), min.end(), bBox.begin());
351 49429164 std::copy(max.begin(), max.end(), bBox.begin()+dimworld);
352 24714582 return intersectsPointBoundingBox(point, bBox.data());
353 }
354
355 /*!
356 * \brief Check whether a bounding box is intersecting another bounding box (dimworld == 3)
357 * \param a Pointer to first bounding box coordinates
358 * \param b Pointer to second bounding box coordinates
359 */
360 template<int dimworld, class ctypea, class ctypeb, typename std::enable_if_t<dimworld == 3, int> = 0>
361 1415281 inline bool intersectsBoundingBoxBoundingBox(const ctypea* a, const ctypeb* b)
362 {
363 using ctype = typename Dune::PromotionTraits<ctypea, ctypeb>::PromotedType;
364 static constexpr ctype eps_ = 1.0e-7;
365
2/2
✓ Branch 0 taken 639414 times.
✓ Branch 1 taken 775867 times.
1415281 const ctype eps0 = eps_*std::max(b[3]-b[0], a[3]-a[0]);
366
2/2
✓ Branch 0 taken 637925 times.
✓ Branch 1 taken 777356 times.
1415281 const ctype eps1 = eps_*std::max(b[4]-b[1], a[4]-a[1]);
367
2/2
✓ Branch 0 taken 764277 times.
✓ Branch 1 taken 651004 times.
1415281 const ctype eps2 = eps_*std::max(b[5]-b[2], a[5]-a[2]);
368
2/2
✓ Branch 0 taken 1140100 times.
✓ Branch 1 taken 128838 times.
1268938 return (b[0] - eps0 <= a[3] && a[0] <= b[3] + eps0 &&
369
4/4
✓ Branch 0 taken 1080269 times.
✓ Branch 1 taken 59831 times.
✓ Branch 2 taken 1019371 times.
✓ Branch 3 taken 60898 times.
1140100 b[1] - eps1 <= a[4] && a[1] <= b[4] + eps1 &&
370
6/6
✓ Branch 0 taken 1268938 times.
✓ Branch 1 taken 146343 times.
✓ Branch 2 taken 968029 times.
✓ Branch 3 taken 51342 times.
✓ Branch 4 taken 55945 times.
✓ Branch 5 taken 912084 times.
2434652 b[2] - eps2 <= a[5] && a[2] <= b[5] + eps2);
371
372 }
373
374 /*!
375 * \brief Check whether a bounding box is intersecting another bounding box (dimworld == 2)
376 * \param a Pointer to first bounding box coordinates
377 * \param b Pointer to second bounding box coordinates
378 */
379 template<int dimworld, class ctypea, class ctypeb, typename std::enable_if_t<dimworld == 2, int> = 0>
380 2137844 inline bool intersectsBoundingBoxBoundingBox(const ctypea* a, const ctypeb* b)
381 {
382 using ctype = typename Dune::PromotionTraits<ctypea, ctypeb>::PromotedType;
383 static constexpr ctype eps_ = 1.0e-7;
384
2/2
✓ Branch 0 taken 2111163 times.
✓ Branch 1 taken 26681 times.
2137844 const ctype eps0 = eps_*std::max(b[2]-b[0], a[2]-a[0]);
385
2/2
✓ Branch 0 taken 2116201 times.
✓ Branch 1 taken 21643 times.
2137844 const ctype eps1 = eps_*std::max(b[3]-b[1], a[3]-a[1]);
386
2/2
✓ Branch 0 taken 1691074 times.
✓ Branch 1 taken 203897 times.
1894971 return (b[0] - eps0 <= a[2] && a[0] <= b[2] + eps0 &&
387
6/6
✓ Branch 0 taken 1894971 times.
✓ Branch 1 taken 242873 times.
✓ Branch 2 taken 1471988 times.
✓ Branch 3 taken 219086 times.
✓ Branch 4 taken 202393 times.
✓ Branch 5 taken 1269595 times.
3828918 b[1] - eps1 <= a[3] && a[1] <= b[3] + eps1);
388 }
389
390 /*!
391 * \brief Check whether a bounding box is intersecting another bounding box (dimworld == 1)
392 * \param a Pointer to first bounding box coordinates
393 * \param b Pointer to second bounding box coordinates
394 */
395 template<int dimworld, class ctypea, class ctypeb, typename std::enable_if_t<dimworld == 1, int> = 0>
396 inline bool intersectsBoundingBoxBoundingBox(const ctypea* a, const ctypeb* b)
397 {
398 using ctype = typename Dune::PromotionTraits<ctypea, ctypeb>::PromotedType;
399 static constexpr ctype eps_ = 1.0e-7;
400 const ctype eps0 = eps_*std::max(b[1]-b[0], a[1]-a[0]);
401 return b[0] - eps0 <= a[1] && a[0] <= b[1] + eps0;
402 }
403
404 /*!
405 * \brief Compute squared distance between point and bounding box
406 * \param point The point
407 * \param b Pointer to bounding box coordinates
408 */
409 template<int dimworld, class ctype>
410 11097934 inline ctype squaredDistancePointBoundingBox(const Dune::FieldVector<ctype, dimworld>& point, const ctype* b)
411 {
412 11097934 ctype squaredDistance = 0.0;
413
2/2
✓ Branch 0 taken 293084 times.
✓ Branch 1 taken 146542 times.
44232996 for (int d = 0; d < dimworld; ++d)
414 {
415
4/4
✓ Branch 0 taken 25456 times.
✓ Branch 1 taken 267628 times.
✓ Branch 2 taken 25456 times.
✓ Branch 3 taken 267628 times.
66270124 if (point[d] < b[d])
416 22474146 squaredDistance += (point[d] - b[d])*(point[d] - b[d]);
417
4/4
✓ Branch 0 taken 103484 times.
✓ Branch 1 taken 189600 times.
✓ Branch 2 taken 103484 times.
✓ Branch 3 taken 189600 times.
66270124 if (point[d] > b[d+dimworld])
418 56468778 squaredDistance += (point[d] - b[d+dimworld])*(point[d] - b[d+dimworld]);
419 }
420 11097934 return squaredDistance;
421 }
422
423 } // end namespace Dumux
424
425 #endif
426