13#ifndef DUMUX_GEOMETRY_INTERSECTION_ENTITY_SET_HH
14#define DUMUX_GEOMETRY_INTERSECTION_ENTITY_SET_HH
24#include <dune/common/indices.hh>
25#include <dune/common/timer.hh>
26#include <dune/common/iteratorrange.hh>
27#include <dune/common/promotiontraits.hh>
28#include <dune/common/reservedvector.hh>
29#include <dune/geometry/affinegeometry.hh>
30#include <dune/geometry/type.hh>
40template<
class DomainEntitySet,
class TargetEntitySet>
43 static constexpr int dimDomain = DomainEntitySet::Entity::Geometry::mydimension;
44 static constexpr int dimTarget = TargetEntitySet::Entity::Geometry::mydimension;
45 using ctype =
typename Dune::PromotionTraits<typename DomainEntitySet::ctype, typename TargetEntitySet::ctype>::PromotedType;
47 static constexpr int dimWorld = DomainEntitySet::dimensionworld;
48 static_assert(dimWorld == int(TargetEntitySet::dimensionworld),
"Entity sets must have the same world dimension");
50 static constexpr int dimIs = std::min(dimDomain, dimTarget);
52 using GlobalPosition = Dune::FieldVector<ctype, dimWorld>;
53 using Geometry = Dune::AffineGeometry<ctype, dimIs, dimWorld>;
56 using IndexStorage = std::pair<std::conditional_t<dimDomain <= dimTarget, Dune::ReservedVector<std::size_t, 1>, std::vector<std::size_t>>,
57 std::conditional_t<dimTarget <= dimDomain, Dune::ReservedVector<std::size_t, 1>, std::vector<std::size_t>>>;
59 static constexpr auto domainIdx = Dune::index_constant<0>{};
60 static constexpr auto targetIdx = Dune::index_constant<1>{};
63 IntersectionEntity(
const DomainEntitySet& domainEntitySet,
const TargetEntitySet& targetEntitySet)
64 : domainEntitySet_(domainEntitySet)
65 , targetEntitySet_(targetEntitySet)
69 void setCorners(
const std::vector<GlobalPosition>& corners)
72 assert(corners.size() == dimIs + 1);
80 std::get<domainIdx>(neighbors_).push_back(domain);
81 std::get<targetIdx>(neighbors_).push_back(target);
83 else if (dimDomain > dimTarget)
84 std::get<domainIdx>(neighbors_).push_back(domain);
86 else if (dimTarget > dimDomain)
87 std::get<targetIdx>(neighbors_).push_back(target);
90 DUNE_THROW(Dune::InvalidStateException,
"Cannot add more than one neighbor per side for equidimensional intersection!");
95 {
return Geometry(Dune::GeometryTypes::simplex(dimIs), corners_); }
99 {
return std::get<domainIdx>(neighbors_).size(); }
103 {
return std::get<targetIdx>(neighbors_).size(); }
106 typename DomainEntitySet::Entity
domainEntity(
unsigned int n = 0)
const
107 {
return domainEntitySet_.entity(std::get<domainIdx>(neighbors_)[n]); }
110 typename TargetEntitySet::Entity
targetEntity(
unsigned int n = 0)
const
111 {
return targetEntitySet_.entity(std::get<targetIdx>(neighbors_)[n]); }
114 IndexStorage neighbors_;
115 std::vector<GlobalPosition> corners_;
117 const DomainEntitySet& domainEntitySet_;
118 const TargetEntitySet& targetEntitySet_;
129template<
class DomainEntitySet,
class TargetEntitySet>
135 using ctype =
typename Dune::PromotionTraits<typename DomainEntitySet::ctype, typename TargetEntitySet::ctype>::PromotedType;
137 static constexpr int dimWorld = DomainEntitySet::dimensionworld;
138 static_assert(dimWorld == int(TargetEntitySet::dimensionworld),
"Entity sets must have the same world dimension");
140 using GlobalPosition = Dune::FieldVector<ctype, dimWorld>;
142 static constexpr int dimDomain = DomainEntitySet::Entity::Geometry::mydimension;
143 static constexpr int dimTarget = TargetEntitySet::Entity::Geometry::mydimension;
144 static constexpr bool isMixedDimensional = dimDomain != dimTarget;
147 using Intersections = std::vector<IntersectionEntity>;
149 using DomainGeometry =
typename DomainEntitySet::Entity::Geometry;
150 using TargetGeometry =
typename TargetEntitySet::Entity::Geometry;
166 void build(std::shared_ptr<const DomainEntitySet> domainSet, std::shared_ptr<const TargetEntitySet> targetSet)
169 if (targetSet->size() == 1)
171 domainTree_ = std::make_shared<DomainTree>(domainSet);
172 targetEntitySet_ = targetSet;
173 build_(*domainTree_, targetEntitySet_->entity(0).geometry());
176 else if (domainSet->size() == 1)
178 domainEntitySet_ = domainSet;
179 targetTree_ = std::make_shared<TargetTree>(targetSet);
180 build_(domainEntitySet_->entity(0).geometry(), *targetTree_);
184 domainTree_ = std::make_shared<DomainTree>(domainSet);
185 targetTree_ = std::make_shared<TargetTree>(targetSet);
186 build(*domainTree_, *targetTree_);
193 void build(std::shared_ptr<const DomainTree> domainTree, std::shared_ptr<const TargetTree> targetTree)
196 domainTree_ = domainTree;
197 targetTree_ = targetTree;
198 build(*domainTree_, *targetTree_);
212 std::cout <<
"Computed " <<
size() <<
" intersection entities in " << timer.elapsed() << std::endl;
216 typename Intersections::const_iterator
ibegin()
const
217 {
return intersections_.begin(); }
220 typename Intersections::const_iterator
iend()
const
221 {
return intersections_.end(); }
225 {
return intersections_.size(); }
236 void build_(
const DomainTree& domainTree,
const TargetGeometry& targetGeometry)
244 const bool flipNeighborIndices =
true;
245 build_(domainTree.entitySet(), *targetEntitySet_, rawIntersections, flipNeighborIndices);
247 std::cout <<
"Computed " <<
size() <<
" intersection entities in " << timer.elapsed() << std::endl;
250 void build_(
const DomainGeometry& domainGeometry,
const TargetTree& targetTree)
255 build_(*domainEntitySet_, targetTree.entitySet(), rawIntersections);
257 std::cout <<
"Computed " <<
size() <<
" intersection entities in " << timer.elapsed() << std::endl;
260 template<
class RawIntersections>
261 void build_(
const DomainEntitySet& domainEntitySet,
const TargetEntitySet& targetEntitySet,
262 const RawIntersections& rawIntersections,
263 bool flipNeighborIndices =
false)
269 std::vector<std::vector<std::vector<GlobalPosition>>> intersectionMap;
270 std::vector<std::vector<std::size_t>> intersectionIndex;
271 if constexpr (isMixedDimensional)
273 const auto numLowDimEntities = dimTarget < dimDomain ? targetEntitySet.size() : domainEntitySet.size();
274 intersectionMap.resize(numLowDimEntities);
275 intersectionIndex.resize(numLowDimEntities);
281 intersections_.clear();
282 intersections_.reserve(rawIntersections.size());
284 for (
const auto& rawIntersection : rawIntersections)
290 if constexpr (isMixedDimensional)
292 const auto lowDimNeighborIdx = getLowDimNeighborIndex_(rawIntersection, flipNeighborIndices);
293 for (
int i = 0; i < intersectionMap[lowDimNeighborIdx].size(); ++i)
295 if (rawIntersection.cornersMatch(intersectionMap[lowDimNeighborIdx][i]))
299 auto idx = intersectionIndex[lowDimNeighborIdx][i];
300 intersections_[idx].addNeighbors(domainNeighborIndex_(rawIntersection, flipNeighborIndices), targetNeighborIndex_(rawIntersection, flipNeighborIndices));
309 if constexpr (isMixedDimensional)
311 const auto lowDimNeighborIdx = getLowDimNeighborIndex_(rawIntersection, flipNeighborIndices);
312 intersectionMap[lowDimNeighborIdx].push_back(rawIntersection.corners());
313 intersectionIndex[lowDimNeighborIdx].push_back(intersections_.size());
317 intersections_.emplace_back(domainEntitySet, targetEntitySet);
318 intersections_.back().setCorners(rawIntersection.corners());
319 intersections_.back().addNeighbors(domainNeighborIndex_(rawIntersection, flipNeighborIndices), targetNeighborIndex_(rawIntersection, flipNeighborIndices));
323 intersections_.shrink_to_fit();
326 template<
class RawIntersection,
327 bool enable = isMixedDimensional, std::enable_if_t<enable, int> = 0>
328 auto getLowDimNeighborIndex_(
const RawIntersection& is,
bool flipNeighborIndices)
330 if constexpr (dimTarget < dimDomain)
331 return targetNeighborIndex_(is, flipNeighborIndices);
333 return domainNeighborIndex_(is, flipNeighborIndices);
336 template<
class RawIntersection>
337 auto domainNeighborIndex_(
const RawIntersection& is,
bool flipNeighborIndices)
338 {
return flipNeighborIndices ? is.second() : is.first(); }
340 template<
class RawIntersection>
341 auto targetNeighborIndex_(
const RawIntersection& is,
bool flipNeighborIndices)
342 {
return flipNeighborIndices ? is.first() : is.second(); }
344 Intersections intersections_;
346 std::shared_ptr<const DomainTree> domainTree_;
347 std::shared_ptr<const TargetTree> targetTree_;
348 std::shared_ptr<const DomainEntitySet> domainEntitySet_;
349 std::shared_ptr<const TargetEntitySet> targetEntitySet_;
An axis-aligned bounding box volume hierarchy for dune grids.
An axis-aligned bounding box volume tree implementation.
Definition: boundingboxtree.hh:56
const EntitySet & entitySet() const
the entity set this tree was built with
Definition: boundingboxtree.hh:123
A class representing an intersection entity.
Definition: intersectionentityset.hh:42
std::size_t numTargetNeighbors() const
get the number of target neighbors of this intersection
Definition: intersectionentityset.hh:102
void setCorners(const std::vector< GlobalPosition > &corners)
set the intersection geometry corners
Definition: intersectionentityset.hh:69
std::size_t numDomainNeighbors() const
get the number of domain neighbors of this intersection
Definition: intersectionentityset.hh:98
IntersectionEntity(const DomainEntitySet &domainEntitySet, const TargetEntitySet &targetEntitySet)
Definition: intersectionentityset.hh:63
DomainEntitySet::Entity domainEntity(unsigned int n=0) const
get the nth domain neighbor entity
Definition: intersectionentityset.hh:106
TargetEntitySet::Entity targetEntity(unsigned int n=0) const
get the nth target neighbor entity
Definition: intersectionentityset.hh:110
void addNeighbors(std::size_t domain, std::size_t target)
add a pair of neighbor elements
Definition: intersectionentityset.hh:76
Geometry geometry() const
get the intersection geometry
Definition: intersectionentityset.hh:94
A class representing the intersection entities two geometric entity sets.
Definition: intersectionentityset.hh:131
IntersectionEntitySet()=default
Default constructor.
void build(std::shared_ptr< const DomainEntitySet > domainSet, std::shared_ptr< const TargetEntitySet > targetSet)
Build intersections.
Definition: intersectionentityset.hh:166
std::size_t size() const
the number of intersections
Definition: intersectionentityset.hh:224
void build(const DomainTree &domainTree, const TargetTree &targetTree)
Build intersections.
Definition: intersectionentityset.hh:205
void build(std::shared_ptr< const DomainTree > domainTree, std::shared_ptr< const TargetTree > targetTree)
Build intersections.
Definition: intersectionentityset.hh:193
typename Intersections::const_iterator EntityIterator
make entity iterator type available
Definition: intersectionentityset.hh:156
friend Dune::IteratorRange< EntityIterator > intersections(const IntersectionEntitySet &set)
Range generator to iterate with range-based for loops over all intersections as follows: for (const a...
Definition: intersectionentityset.hh:232
Intersections::const_iterator ibegin() const
return begin iterator to intersection container
Definition: intersectionentityset.hh:216
Intersections::const_iterator iend() const
return end iterator to intersection container
Definition: intersectionentityset.hh:220
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:102
Algorithms that finds which geometric entities intersect.
Definition: intersectionentityset.hh:35