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_);
205 void build(
const DomainTree& domainTree,
const TargetTree& 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_;