12#ifndef DUMUX_GEOMETRY_INTERSECTING_ENTITIES_HH
13#define DUMUX_GEOMETRY_INTERSECTING_ENTITIES_HH
21#include <dune/common/fvector.hh>
37template<
int dimworld,
class CoordTypeA,
class CoordTypeB = CoordTypeA>
41 using ctype =
typename Dune::PromotionTraits<CoordTypeA, CoordTypeB>::PromotedType;
45 template<
class Corners>
49 , corners_(c.begin(), c.end())
61 const std::vector<GlobalPosition>&
corners()
const
68 bool cornersMatch(
const std::vector<GlobalPosition>& otherCorners)
const
70 if (otherCorners.size() != corners_.size())
74 ctype eps2 = std::numeric_limits<ctype>::min();
75 for (
int i = 1; i < corners_.size(); ++i)
76 eps2 = max(eps2, (corners_[i] - corners_[0]).two_norm2());
80 eps2 *= 1.5e-7*1.5e-7;
82 for (
int i = 0; i < corners_.size(); ++i)
84 if (std::none_of(otherCorners.begin(),
86 [&] (
const auto& other) { return (corners_[i] - other).two_norm2() < eps2; }))
94 std::vector<GlobalPosition> corners_;
101template<
class EntitySet,
class ctype,
int dimworld>
102inline std::vector<std::size_t>
105 bool isCartesianGrid =
false)
108 std::vector<std::size_t> entities;
117template<
class EntitySet,
class ctype,
int dimworld>
121 std::vector<std::size_t>& entities,
122 bool isCartesianGrid =
false)
132 else if (tree.
isLeaf(bBox, node))
134 const std::size_t entityIdx = bBox.child1;
135 using Geometry =
typename EntitySet::Entity::Geometry;
139 entities.push_back(entityIdx);
142 const auto geometry = tree.
entitySet().entity(entityIdx).geometry();
145 entities.push_back(entityIdx);
166template<
class EntitySet,
class ctype>
170 std::vector<std::size_t>& entities)
173 static constexpr int dimworld = EntitySet::dimensionworld;
179 if (tree.
isLeaf(bBox, node))
180 entities.push_back(bBox.child1);
196template<
class EntitySet,
class ctype>
197inline std::vector<std::size_t>
200 std::vector<std::size_t> entities;
212template<
class EntitySet0,
class EntitySet1>
215 std::size_t nodeA, std::size_t nodeB,
216 std::vector<std::pair<std::size_t, std::size_t>>& pairs)
219 static constexpr int dimworld = EntitySet0::dimensionworld;
226 const bool isLeafA = treeA.
isLeaf(bBoxA, nodeA);
227 const bool isLeafB = treeB.
isLeaf(bBoxB, nodeB);
230 if (isLeafA && isLeafB)
231 pairs.emplace_back(bBoxA.child1, bBoxB.child1);
244 else if (nodeA > nodeB)
261template<
class EntitySet0,
class EntitySet1>
262inline std::vector<std::pair<std::size_t, std::size_t>>
265 static_assert(int(EntitySet0::dimensionworld) == int(EntitySet1::dimensionworld),
266 "Can only intersect bounding box trees of same world dimension");
268 std::vector<std::pair<std::size_t, std::size_t>> pairs;
277template<
class Geometry,
class EntitySet>
278inline std::vector<IntersectionInfo<Geometry::coorddimension, typename Geometry::ctype, typename EntitySet::ctype>>
290template<
class Geometry,
class EntitySet,
class IntersectionPolicy>
291inline std::vector<IntersectionInfo<Geometry::coorddimension, typename Geometry::ctype, typename EntitySet::ctype>>
297 static_assert(int(Geometry::coorddimension) == int(EntitySet::dimensionworld),
298 "Can only intersect geometry and bounding box tree of same world dimension");
301 std::vector<IntersectionInfo<Geometry::coorddimension, typename Geometry::ctype, typename EntitySet::ctype>> intersections;
303 static constexpr int dimworld = Geometry::coorddimension;
306 std::array<ctype, 2*Geometry::coorddimension> bBox;
307 ctype* xMin = bBox.data(); ctype* xMax = xMin + Geometry::coorddimension;
310 auto corner = geometry.corner(0);
311 for (std::size_t dimIdx = 0; dimIdx < dimworld; ++dimIdx)
312 xMin[dimIdx] = xMax[dimIdx] = corner[dimIdx];
315 for (std::size_t cornerIdx = 1; cornerIdx < geometry.corners(); ++cornerIdx)
317 corner = geometry.corner(cornerIdx);
318 for (std::size_t dimIdx = 0; dimIdx < dimworld; ++dimIdx)
322 xMin[dimIdx] = min(xMin[dimIdx], corner[dimIdx]);
323 xMax[dimIdx] = max(xMax[dimIdx], corner[dimIdx]);
330 intersections, intersectionPolicy);
332 return intersections;
339template<
class Geometry,
class EntitySet>
342 const std::array<typename Geometry::ctype, 2*Geometry::coorddimension>& bBox,
345 typename Geometry::ctype,
346 typename EntitySet::ctype>>& intersections)
355template<
class Geometry,
class EntitySet,
class IntersectionPolicy>
358 const std::array<typename Geometry::ctype, 2*Geometry::coorddimension>& bBox,
361 typename Geometry::ctype,
362 typename EntitySet::ctype>>& intersections,
366 static constexpr int dimworld = Geometry::coorddimension;
374 if (tree.
isLeaf(bBoxNode, nodeIdx))
377 const auto eIdxA = 0;
378 const auto eIdxB = bBoxNode.child1;
380 const auto geometryTree = tree.
entitySet().entity(eIdxB).geometry();
381 using GeometryTree = std::decay_t<
decltype(geometryTree)>;
383 using Intersection =
typename IntersectionAlgorithm::Intersection;
384 Intersection intersection;
386 if (IntersectionAlgorithm::intersection(geometry, geometryTree, intersection))
388 static constexpr int dimIntersection = IntersectionPolicy::dimIntersection;
389 if constexpr (dimIntersection >= 2)
392 for (
unsigned int i = 0; i < triangulation.size(); ++i)
393 intersections.emplace_back(eIdxA, eIdxB, std::move(triangulation[i]));
396 intersections.emplace_back(eIdxA, eIdxB, intersection);
412template<
class EntitySet0,
class EntitySet1>
413inline std::vector<IntersectionInfo<EntitySet0::dimensionworld, typename EntitySet0::ctype, typename EntitySet1::ctype>>
425template<
class EntitySet0,
class EntitySet1,
class IntersectionPolicy>
426inline std::vector<IntersectionInfo<EntitySet0::dimensionworld, typename EntitySet0::ctype, typename EntitySet1::ctype>>
432 static_assert(int(EntitySet0::dimensionworld) == int(EntitySet1::dimensionworld),
433 "Can only intersect bounding box trees of same world dimension");
436 std::vector<IntersectionInfo<EntitySet0::dimensionworld, typename EntitySet0::ctype, typename EntitySet1::ctype>> intersections;
442 intersections, intersectionPolicy);
444 return intersections;
451template<
class EntitySet0,
class EntitySet1>
454 std::size_t nodeA, std::size_t nodeB,
456 typename EntitySet0::ctype,
457 typename EntitySet1::ctype>>& intersections)
467template<
class EntitySet0,
class EntitySet1,
class IntersectionPolicy>
470 std::size_t nodeA, std::size_t nodeB,
472 typename EntitySet0::ctype,
473 typename EntitySet1::ctype>>& intersections,
481 static constexpr int dimworld = EntitySet0::dimensionworld;
487 const bool isLeafA = treeA.
isLeaf(bBoxA, nodeA);
488 const bool isLeafB = treeB.
isLeaf(bBoxB, nodeB);
491 if (isLeafA && isLeafB)
493 const auto eIdxA = bBoxA.child1;
494 const auto eIdxB = bBoxB.child1;
496 const auto geometryA = treeA.
entitySet().entity(eIdxA).geometry();
497 const auto geometryB = treeB.
entitySet().entity(eIdxB).geometry();
499 using GeometryA = std::decay_t<
decltype(geometryA)>;
500 using GeometryB = std::decay_t<
decltype(geometryB)>;
502 using Intersection =
typename IntersectionAlgorithm::Intersection;
504 if (Intersection intersection; IntersectionAlgorithm::intersection(geometryA, geometryB, intersection))
506 static constexpr int dimIntersection = IntersectionPolicy::dimIntersection;
510 if constexpr (dimIntersection >= 2)
513 for (
unsigned int i = 0; i < triangulation.size(); ++i)
514 intersections.emplace_back(eIdxA, eIdxB, std::move(triangulation[i]));
517 intersections.emplace_back(eIdxA, eIdxB, intersection);
537 else if (nodeA > nodeB)
557template<
class ctype,
int dimworld>
559 const Dune::FieldVector<ctype, dimworld>& min,
560 const Dune::FieldVector<ctype, dimworld>& max,
561 const std::array<
int, std::size_t(dimworld)>& cells)
563 std::size_t index = 0;
564 for (
int i = 0; i < dimworld; ++i)
566 using std::clamp;
using std::floor;
567 ctype dimOffset = clamp<ctype>(floor((point[i]-min[i])*cells[i]/(max[i]-min[i])), 0.0, cells[i]-1);
568 for (
int j = 0; j < i; ++j)
569 dimOffset *= cells[j];
570 index +=
static_cast<std::size_t
>(dimOffset);
An axis-aligned bounding box volume hierarchy for dune grids.
An axis-aligned bounding box volume tree implementation.
Definition boundingboxtree.hh:105
const ctype * getBoundingBoxCoordinates(std::size_t nodeIdx) const
Get an existing bounding box for a given node.
Definition boundingboxtree.hh:176
bool isLeaf(const BoundingBoxNode &node, std::size_t nodeIdx) const
Definition boundingboxtree.hh:185
const EntitySet & entitySet() const
the entity set this tree was built with
Definition boundingboxtree.hh:164
std::size_t numBoundingBoxes() const
Get the number of bounding boxes currently in the tree.
Definition boundingboxtree.hh:180
const BoundingBoxNode & getBoundingBoxNode(std::size_t nodeIdx) const
Interface to be used by other bounding box trees.
Definition boundingboxtree.hh:172
A class for geometry collision detection and intersection calculation The class can be specialized fo...
Definition geometryintersection.hh:207
An intersection object resulting from the intersection of two primitives in an entity set.
Definition intersectingentities.hh:39
static constexpr int dimensionworld
Definition intersectingentities.hh:42
bool cornersMatch(const std::vector< GlobalPosition > &otherCorners) const
Check if the corners of this intersection match with the given corners.
Definition intersectingentities.hh:68
const std::vector< GlobalPosition > & corners() const
Get the corners of the intersection geometry.
Definition intersectingentities.hh:61
IntersectionInfo(std::size_t a, std::size_t b, Corners &&c)
Definition intersectingentities.hh:46
Dune::FieldVector< ctype, dimworld > GlobalPosition
Definition intersectingentities.hh:43
std::size_t second() const
Get the index of the intersecting entity belonging to the other grid.
Definition intersectingentities.hh:57
std::size_t first() const
Get the index of the intersecting entity belonging to this grid.
Definition intersectingentities.hh:53
typename Dune::PromotionTraits< CoordTypeA, CoordTypeB >::PromotedType ctype
Definition intersectingentities.hh:41
A class for collision detection of two geometries and computation of intersection corners.
Traits telling the bounding box tree algorithms about a leaf geometry.
std::size_t intersectingEntityCartesianGrid(const Dune::FieldVector< ctype, dimworld > &point, const Dune::FieldVector< ctype, dimworld > &min, const Dune::FieldVector< ctype, dimworld > &max, const std::array< int, std::size_t(dimworld)> &cells)
Compute the index of the intersecting element of a Cartesian grid with a point The grid is given by t...
Definition intersectingentities.hh:558
Triangulation< dim, dimWorld, typename RandomAccessContainer::value_type::value_type > triangulate(const RandomAccessContainer &points)
Triangulate area given points of a convex hull (1d).
Definition triangulation.hh:81
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:28
void intersectingBoxes(const ctype *box, const BoundingBoxTree< EntitySet > &tree, std::size_t node, std::vector< std::size_t > &entities)
Compute all entities whose bounding box overlaps the given box.
Definition intersectingentities.hh:167
std::vector< std::pair< int, std::size_t > > intersectingEntities(const Dune::FieldVector< ctype, dimworld > &point, const DistributedBoundingBoxTree< EntitySet > &tree, bool isCartesianGrid=false, bool onlyOwned=true)
Compute all intersections between entities and a point on a distributed tree.
Definition distributedintersectingentities.hh:81
Detect if a point intersects a geometry.
Define some often used mathematical functions.
Definition geometryintersection.hh:29
typename DefaultPolicyChooser< Geometry1, Geometry2 >::type DefaultPolicy
Helper alias to define the default intersection policy.
Definition geometryintersection.hh:104
bool intersectsBoundingBoxBoundingBox(const ctypea *a, const ctypeb *b)
Check whether a bounding box is intersecting another bounding box (dimworld == 3).
Definition boundingboxtree.hh:372
bool intersectsPointBoundingBox(const Dune::FieldVector< ctype, dimworld > &point, const ctype *b)
Check whether a point is intersectin a bounding box (dimworld == 3).
Definition boundingboxtree.hh:305
static constexpr bool axisAligned
Definition geometrytraits.hh:31
Functionality to triangulate point clouds.