3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
intersectingentities.hh
Go to the documentation of this file.
1/*****************************************************************************
2 * See the file COPYING for full copying permissions. *
3 * *
4 * This program is free software: you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation, either version 3 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 *****************************************************************************/
22#ifndef DUMUX_INTERSECTING_ENTITIES_HH
23#define DUMUX_INTERSECTING_ENTITIES_HH
24
25#include <cmath>
26#include <type_traits>
27
28#include <dune/common/fvector.hh>
29
30#include <dumux/common/math.hh>
36
37namespace Dumux {
38
43template<class EntitySet, class ctype, int dimworld>
44inline std::vector<std::size_t>
45intersectingEntities(const Dune::FieldVector<ctype, dimworld>& point,
47 bool isCartesianGrid = false)
48{
49 // Call the recursive find function to find candidates
50 std::vector<std::size_t> entities;
51 intersectingEntities(point, tree, tree.numBoundingBoxes() - 1, entities, isCartesianGrid);
52 return entities;
53}
54
59template<class EntitySet, class ctype, int dimworld>
60void intersectingEntities(const Dune::FieldVector<ctype, dimworld>& point,
62 std::size_t node,
63 std::vector<std::size_t>& entities,
64 bool isCartesianGrid = false)
65{
66 // Get the bounding box for the current node
67 const auto& bBox = tree.getBoundingBoxNode(node);
68
69 // if the point is not in the bounding box we can stop
70 if (!intersectsPointBoundingBox(point, tree.getBoundingBoxCoordinates(node))) return;
71
72 // now we know it's inside
73 // if the box is a leaf do the primitive test.
74 else if (tree.isLeaf(bBox, node))
75 {
76 const std::size_t entityIdx = bBox.child1;
77 // for structured cube grids skip the primitive test
78 if (isCartesianGrid)
79 entities.push_back(entityIdx);
80 else
81 {
82 const auto geometry = tree.entitySet().entity(entityIdx).geometry();
83 // if the primitive is positive it intersects the actual geometry, add the entity to the list
84 if (intersectsPointGeometry(point, geometry))
85 entities.push_back(entityIdx);
86 }
87 }
88
89 // No leaf. Check both children nodes.
90 else
91 {
92 intersectingEntities(point, tree, bBox.child0, entities, isCartesianGrid);
93 intersectingEntities(point, tree, bBox.child1, entities, isCartesianGrid);
94 }
95}
96
101template<class EntitySet0, class EntitySet1>
102inline std::vector<BoundingBoxTreeIntersection<EntitySet0, EntitySet1>>
104 const BoundingBoxTree<EntitySet1>& treeB)
105{
106 // check if the world dimensions match
107 static_assert(int(EntitySet0::dimensionworld) == int(EntitySet1::dimensionworld),
108 "Can only intersect bounding box trees of same world dimension");
109
110 // Create data structure for return type
111 std::vector<BoundingBoxTreeIntersection<EntitySet0, EntitySet1>> intersections;
112
113 // Call the recursive find function to find candidates
114 intersectingEntities(treeA, treeB,
115 treeA.numBoundingBoxes() - 1,
116 treeB.numBoundingBoxes() - 1,
118
119 return intersections;
120}
121
126template<class EntitySet0, class EntitySet1>
128 const BoundingBoxTree<EntitySet1>& treeB,
129 std::size_t nodeA, std::size_t nodeB,
131{
132 // Get the bounding box for the current node
133 const auto& bBoxA = treeA.getBoundingBoxNode(nodeA);
134 const auto& bBoxB = treeB.getBoundingBoxNode(nodeB);
135
136 // if the two bounding boxes of the current nodes don't intersect we can stop searching
137 static constexpr int dimworld = EntitySet0::dimensionworld;
138 if (!intersectsBoundingBoxBoundingBox<dimworld>(treeA.getBoundingBoxCoordinates(nodeA),
139 treeB.getBoundingBoxCoordinates(nodeB)))
140 return;
141
142 // Check if we have a leaf in treeA or treeB
143 const bool isLeafA = treeA.isLeaf(bBoxA, nodeA);
144 const bool isLeafB = treeB.isLeaf(bBoxB, nodeB);
145
146 // If both boxes are leaves do the primitive test
147 if (isLeafA && isLeafB)
148 {
149 const auto eIdxA = bBoxA.child1;
150 const auto eIdxB = bBoxB.child1;
151
152 const auto geometryA = treeA.entitySet().entity(eIdxA).geometry();
153 const auto geometryB = treeB.entitySet().entity(eIdxB).geometry();
154
155 using GeometryA = std::decay_t<decltype(geometryA)>;
156 using GeometryB = std::decay_t<decltype(geometryB)>;
158 using IntersectionAlgorithm = GeometryIntersection<GeometryA, GeometryB, Policy>;
159 using Intersection = typename IntersectionAlgorithm::Intersection;
160 Intersection intersection;
161
162 if (IntersectionAlgorithm::intersection(geometryA, geometryB, intersection))
163 {
164 static constexpr int dimIntersection = Policy::dimIntersection;
165
166 if (dimIntersection >= 2)
167 {
168 const auto triangulation = triangulate<dimIntersection, dimworld>(intersection);
169 for (unsigned int i = 0; i < triangulation.size(); ++i)
170 intersections.emplace_back(eIdxA, eIdxB, std::move(triangulation[i]));
171 }
172 else
173 intersections.emplace_back(eIdxA, eIdxB, intersection);
174 }
175 }
176
177 // if we reached the leaf in treeA, just continue in treeB
178 else if (isLeafA)
179 {
180 intersectingEntities(treeA, treeB, nodeA, bBoxB.child0, intersections);
181 intersectingEntities(treeA, treeB, nodeA, bBoxB.child1, intersections);
182 }
183
184 // if we reached the leaf in treeB, just continue in treeA
185 else if (isLeafB)
186 {
187 intersectingEntities(treeA, treeB, bBoxA.child0, nodeB, intersections);
188 intersectingEntities(treeA, treeB, bBoxA.child1, nodeB, intersections);
189 }
190
191 // we know now that both trees didn't reach the leaf yet so
192 // we continue with the larger tree first (bigger node number)
193 else if (nodeA > nodeB)
194 {
195 intersectingEntities(treeA, treeB, bBoxA.child0, nodeB, intersections);
196 intersectingEntities(treeA, treeB, bBoxA.child1, nodeB, intersections);
197 }
198 else
199 {
200 intersectingEntities(treeA, treeB, nodeA, bBoxB.child0, intersections);
201 intersectingEntities(treeA, treeB, nodeA, bBoxB.child1, intersections);
202 }
203}
204
205} // end namespace Dumux
206
207#endif
A class storing intersections from intersecting two bounding box trees.
A class for collision detection of two geometries and computation of intersection corners.
Detect if a point intersects a geometry.
Functionality to triangulate point clouds.
Define some often used mathematical functions.
bool intersectsPointGeometry(const Dune::FieldVector< ctype, dimworld > &point, const Geometry &g)
Find out whether a point is inside a three-dimensional geometry.
Definition: intersectspointgeometry.hh:38
std::vector< std::size_t > intersectingEntities(const Dune::FieldVector< ctype, dimworld > &point, const BoundingBoxTree< EntitySet > &tree, bool isCartesianGrid=false)
Compute all intersections between entities and a point.
Definition: intersectingentities.hh:45
Dune::IteratorRange< typename MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper >::Intersections::const_iterator > intersections(const MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper > &glue)
Range generator to iterate with range-based for loops over all intersections as follows: for (const a...
Definition: glue.hh:62
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
bool intersectsPointBoundingBox(const Dune::FieldVector< ctype, dimworld > &point, const ctype *b)
Check whether a point is intersectin a bounding box (dimworld == 3)
Definition: geometry/boundingboxtree.hh:304
typename DefaultPolicyChooser< Geometry1, Geometry2 >::type DefaultPolicy
Helper alias to define the default intersection policy.
Definition: geometryintersection.hh:94
An axis-aligned bounding box volume tree implementation.
Definition: geometry/boundingboxtree.hh:66
const ctype * getBoundingBoxCoordinates(std::size_t nodeIdx) const
Get an existing bounding box for a given node.
Definition: geometry/boundingboxtree.hh:145
bool isLeaf(const BoundingBoxNode &node, std::size_t nodeIdx) const
Definition: geometry/boundingboxtree.hh:154
const EntitySet & entitySet() const
the entity set this tree was built with
Definition: geometry/boundingboxtree.hh:133
std::size_t numBoundingBoxes() const
Get the number of bounding boxes currently in the tree.
Definition: geometry/boundingboxtree.hh:149
const BoundingBoxNode & getBoundingBoxNode(std::size_t nodeIdx) const
Interface to be used by other bounding box trees.
Definition: geometry/boundingboxtree.hh:141
An intersection object resulting from the intersection of two bounding box tree primitives.
Definition: boundingboxtreeintersection.hh:41
A class for geometry collision detection and intersection calculation The class can be specialized fo...
Definition: geometryintersection.hh:197
An axis-aligned bounding box volume hierarchy for dune grids.