7#ifndef DUNE_FUNCTIONS_COMMON_SUBDOMAIN_HH
8#define DUNE_FUNCTIONS_COMMON_SUBDOMAIN_HH
19#include <dune/common/exceptions.hh>
20#include <dune/common/iteratorfacades.hh>
21#include <dune/common/iteratorrange.hh>
22#include <dune/common/rangeutilities.hh>
23#include <dune/common/std/no_unique_address.hh>
25#include <dune/geometry/type.hh>
26#include <dune/geometry/typeindex.hh>
28#include <dune/grid/common/mcmgmapper.hh>
29#include <dune/grid/common/partitionset.hh>
31namespace Dune::Functions::Experimental {
35 template<
class GV,
class ContainsCallback>
36 class GlobalIntersectionIt
37 :
public Dune::IteratorFacade<GlobalIntersectionIt<GV, ContainsCallback>, std::forward_iterator_tag, const typename GV::Intersection>
39 using Facade = Dune::IteratorFacade<GlobalIntersectionIt<GV, ContainsCallback>, std::forward_iterator_tag,
const typename GV::Intersection>;
44 using Element =
typename GridView::template Codim<0>::Entity;
45 using ElementIterator =
typename GridView::template Codim<0>::Iterator;
46 using IntersectionIterator =
typename GridView::IntersectionIterator;
47 using Intersection =
typename GridView::Intersection;
50 static constexpr bool cacheIntersection = not std::is_lvalue_reference_v<decltype(std::declval<IntersectionIterator>().operator*())>;
51 static constexpr bool cacheElement = not std::is_lvalue_reference_v<decltype(std::declval<ElementIterator>().operator*())>;
53 using ElementStorage = std::conditional_t<cacheElement, std::optional<Element>, std::monostate>;
54 using IntersectionStorage = std::conditional_t<cacheIntersection, std::optional<Intersection>, std::monostate>;
56 const Element& element()
const
58 if constexpr (cacheElement)
66 if constexpr (cacheElement)
67 element_ = *elementIt_;
70 const Intersection& intersection()
const
72 if constexpr (cacheIntersection)
73 return *intersection_;
78 void updateIntersection()
80 if constexpr (cacheIntersection)
81 intersection_ = **iIt_;
86 class SentinelIterator
89 GlobalIntersectionIt(
const GridView& gridView,
const ContainsCallback& contains, ElementIterator elementIt, ElementIterator elementEnd)
92 , elementIt_(std::move(elementIt))
93 , elementEnd_(std::move(elementEnd))
95 if (elementIt_ != elementEnd_)
98 iIt_ = gridView_.ibegin(element());
100 if (not contains_(intersection()))
105 GlobalIntersectionIt(
const GridView& gridView,
const ContainsCallback& contains, ElementIterator elementIt)
106 : GlobalIntersectionIt(gridView, contains, elementIt, gridView.template end<0>())
109 GlobalIntersectionIt(
const GridView& gridView,
const ContainsCallback& contains)
110 : GlobalIntersectionIt(gridView, contains, gridView.template begin<0>())
113 using reference =
typename Facade::reference;
115 reference operator*()
const
117 return intersection();
120 GlobalIntersectionIt& operator++()
125 if (*iIt_ == gridView_.iend(element()))
128 if (elementIt_ == elementEnd_)
131 iIt_ = gridView_.ibegin(element());
133 updateIntersection();
134 if (contains_(intersection()))
140 friend bool operator==(
const GlobalIntersectionIt& it1,
const GlobalIntersectionIt& it2)
142 if (it1.elementIt_ != it2.elementIt_)
144 if (it1.elementIt_ == it1.elementEnd_)
146 return (*(it1.iIt_) == *(it2.iIt_));
149 friend bool operator==(
const GlobalIntersectionIt& it1,
const SentinelIterator& it2)
151 return it1.elementIt_ == it1.elementEnd_;
156 ContainsCallback contains_;
157 ElementIterator elementIt_;
158 ElementIterator elementEnd_;
159 std::optional<IntersectionIterator> iIt_;
160 DUNE_NO_UNIQUE_ADDRESS ElementStorage element_;
161 DUNE_NO_UNIQUE_ADDRESS IntersectionStorage intersection_;
191 using HostGridView = HGV;
195 using Grid =
typename HostGridView::Grid;
196 using Types = std::vector<Dune::GeometryType>;
197 using IndexType = std::size_t;
203 using Entity =
typename Grid::template Codim<codim>::Entity;
204 using EntitySeed =
typename Grid::template Codim<codim>::EntitySeed;
205 using Geometry =
typename Grid::template Codim<codim>::Geometry;
206 using LocalGeometry =
typename Grid::template Codim<codim>::LocalGeometry;
209 enum {dimension = Grid::dimension};
213 using AllEntityMapper = Dune::MultipleCodimMultipleGeomTypeMapper<HostGridView>;
215 static auto allCodimLayout()
217 return [](Dune::GeometryType, int) {
return true; };
220 static constexpr auto typeIndexSize = Dune::GlobalGeometryTypeIndex::size(dimension);
221 static constexpr auto unusesIndex = std::numeric_limits<IndexType>::max();
228 , allEntityMapper_(hostGridView_, allCodimLayout())
237 IndexType size(Dune::GeometryType gt)
const
239 return sizePerGT_[Dune::GlobalGeometryTypeIndex::index(gt)];
242 IndexType size(
int codim)
const
244 return sizePerCodim_[codim];
247 template<
class Entity>
248 IndexType index(
const Entity& entity)
const
250 auto index = indices_[allEntityMapper_.index(entity)];
251 if (index==unusesIndex)
252 DUNE_THROW(Dune::InvalidStateException,
"Accessing nonexisting entry using SubDomainIndexSet::index()!");
257 IndexType index(
const typename Codim<cc>::Entity& entity)
const
259 return index<typename Codim<cc>::Entity>(entity);
262 template<
class Entity>
263 IndexType subIndex(
const Entity& entity,
int subEntity,
unsigned int codim)
const
265 auto index = indices_[allEntityMapper_.subIndex(entity, subEntity, codim)];
266 if (index==unusesIndex)
267 DUNE_THROW(Dune::InvalidStateException,
"Accessing nonexisting entry using SubDomainIndexSet::subIndex()!");
272 IndexType subIndex(
const typename Codim<cc>::Entity& entity,
int subEntity,
unsigned int codim)
const
274 return subIndex<typename Codim<cc>::Entity>(entity, subEntity, codim);
277 template<
class Entity >
278 bool contains(
const Entity& entity)
const
280 return (indices_[allEntityMapper_.index(entity)] != unusesIndex);
283 Types types(
int codim)
const
285 return typesPerCodim_[codim];
295 return hostGridView_;
301 const auto& re = referenceElement(element);
302 for (
auto codim : Dune::range(0, dimension+1))
304 for (
auto subEntity : Dune::range(re.size(codim)))
306 auto& index = indices_[allEntityMapper_.subIndex(element, subEntity, codim)];
307 if (index==unusesIndex)
309 const auto& type = re.type(subEntity, codim);
310 const auto typeIndex = Dune::GlobalGeometryTypeIndex::index(type);
311 index = sizePerGT_[typeIndex];
312 if (sizePerGT_[typeIndex]==0)
313 typesPerCodim_[codim].push_back(type);
314 sizePerGT_[typeIndex]++;
315 sizePerCodim_[codim]++;
326 for(
auto& size : sizePerGT_)
328 for(
auto& size : sizePerCodim_)
330 for(
auto& types : typesPerCodim_)
333 indices_.resize(allEntityMapper_.size(), unusesIndex);
336 HostGridView hostGridView_;
339 std::array<std::size_t, typeIndexSize> sizePerGT_;
340 std::array<std::size_t, dimension+1> sizePerCodim_;
341 std::array<Types, dimension+1> typesPerCodim_;
343 AllEntityMapper allEntityMapper_;
346 std::vector<IndexType> indices_;
368 class NonImplementedIterator
371 NonImplementedIterator()
373 static_assert(codim==0,
"SubDomainGridView::Codim::Iterator<codim> is only implemented for codim=0");
377 template<PartitionIteratorType pit>
378 class ElementIterator
383 using HostElementIterator =
typename HGV::template
Codim<0>::template Partition<pit>::Iterator;
385 ElementIterator(
const SubDomainIndexSet<HGV>& indexSet, HostElementIterator&& it, HostElementIterator&& endIt)
386 : indexSet_(&indexSet)
387 , hostIt_(std::move(it))
388 , hostEndIt_(std::move(endIt))
390 while ((hostIt_!= hostEndIt_) and (not indexSet_->contains(*hostIt_)))
394 ElementIterator& operator++()
397 while ((hostIt_!= hostEndIt_) and (not indexSet_->contains(*hostIt_)))
402 const Element& operator*()
const
407 friend bool operator==(
const ElementIterator& a,
const ElementIterator& b)
409 return a.hostIt_==b.hostIt_;
413 HostElementIterator hostIt_;
414 HostElementIterator hostEndIt_;
420 using HostGridView = HGV;
422 using Grid =
typename HostGridView::Grid;
423 using ctype =
typename Grid::ctype;
425 using Intersection =
typename HostGridView::Intersection;
426 using IntersectionIterator =
typename HostGridView::IntersectionIterator;
432 using Entity =
typename Grid::template Codim<codim>::Entity;
433 using EntitySeed =
typename Grid::template Codim<codim>::EntitySeed;
434 using Geometry =
typename Grid::template Codim<codim>::Geometry;
435 using LocalGeometry =
typename Grid::template Codim<codim>::LocalGeometry;
436 using Iterator = std::conditional_t<codim==0, ElementIterator<All_Partition>, NonImplementedIterator<codim>>;
438 template<PartitionIteratorType pit>
441 using Iterator = std::conditional_t<codim==0, ElementIterator<pit>, NonImplementedIterator<codim>>;
445 enum {dimension = Grid::dimension};
446 enum {dimensionworld = Grid::dimensionworld};
448 SubDomainGridView(
const IndexSet& indexSet)
449 : indexSet_(&indexSet)
452 SubDomainGridView(
const SubDomainGridView& other) =
default;
454 const Grid& grid()
const
459 const IndexSet& indexSet()
const
464 int size(
int codim)
const
466 return indexSet_->size(codim);
469 int size(Dune::GeometryType gt)
const
471 return indexSet_->size(gt);
474 template<
class Entity>
475 bool contains(
const Entity& entity)
const
477 return indexSet_->contains(entity);
481 template<
int codim, PartitionIteratorType pit = All_Partition>
484 static_assert(codim==0,
"SubDomainGridView::begin<codim> is only implemented for codim=0");
489 template<
int codim, PartitionIteratorType pit = All_Partition>
492 static_assert(codim==0,
"SubDomainGridView::end<codim> is only implemented for codim=0");
496 decltype(
auto) comm()
const
501 decltype(
auto) ibegin(
const typename Codim<0>::Entity& element)
const
506 decltype(
auto) iend(
const typename Codim<0>::Entity& element)
const
518 const IndexSet* indexSet_;
528 template<
class HostGr
idView>
531 return Dune::IteratorRange(subDomainGridView.template begin<0>(), subDomainGridView.template end<0>());
539 template<
class HostGr
idView,
unsigned int partitions>
542 constexpr auto pit = partitionSet.partitionIterator();
543 return Dune::IteratorRange(subDomainGridView.template begin<0, pit>(), subDomainGridView.template end<0, pit>());
551 template<
class HostGr
idView,
class Element>
554 return Dune::IteratorRange(subDomainGridView.ibegin(element), subDomainGridView.iend(element));
579 using HostGridView = HGV;
580 using Grid =
typename HostGridView::Grid;
588 using Entity =
typename Grid::template Codim<codim>::Entity;
589 using EntitySeed =
typename Grid::template Codim<codim>::EntitySeed;
590 using Geometry =
typename Grid::template Codim<codim>::Geometry;
591 using LocalGeometry =
typename Grid::template Codim<codim>::LocalGeometry;
594 enum {dimension = Grid::dimension};
601 const IndexSet& indexSet()
const
627 return indexSet_.contains(element);
641 template<
class SubDomainA,
class SubDomainB>
645 std::is_same_v<typename SubDomainA::GridView::Intersection, typename SubDomainB::GridView::Intersection>,
646 "SubDomainInterface requires that both SubDomain types have the same Intersection type");
650 using Intersection =
typename SubDomainA::GridView::Intersection;
660 : subDomainA_(subDomainA)
661 , subDomainB_(subDomainB)
675 if (is.boundary() or not(is.neighbor()))
677 return (subDomainA_.contains(is.inside()) && subDomainB_.contains(is.outside()))
678 || (subDomainA_.contains(is.outside()) && subDomainB_.contains(is.inside()));
691 if (is.boundary() or not(is.neighbor()))
693 return (subDomainA_.contains(is.inside()) && subDomainB_.contains(is.outside()));
704 return Impl::GlobalIntersectionIt(subDomainA_.gridView(), [&](
const auto& is) {
705 if (is.boundary() or not(is.neighbor()))
707 return subDomainB_.indexSet().contains(is.outside());
714 return typename decltype(
begin())::SentinelIterator();
718 const SubDomainA& subDomainA_;
719 const SubDomainB& subDomainB_;
729 template<
class SubDomain>
734 using Intersection =
typename SubDomain::GridView::Intersection;
738 : subDomain_(subDomain)
744 if (is.boundary() or not(is.neighbor()))
746 return subDomain_.
contains(is.inside()) and subDomain_.
contains(is.outside());
A GridView for a sub-domain.
Definition: subdomain.hh:365
Codim< codim >::template Partition< pit >::Iterator end() const
Create an iterator pointing to the end of the range.
Definition: subdomain.hh:490
const HostGridView & hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:512
Codim< codim >::template Partition< pit >::Iterator begin() const
Create an iterator pointing to the begin of the range.
Definition: subdomain.hh:482
An IndexSet for a sub-domain.
Definition: subdomain.hh:190
SubDomainIndexSet(const HostGridView &hostGridView)
Construct SubDomainIndexSet for underlying host grid view.
Definition: subdomain.hh:226
void insertElement(const typename Codim< 0 >::Entity &element)
Insert element and all its sub-entities into SubDomainIndexSet.
Definition: subdomain.hh:299
const HostGridView & hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:293
Class representing the intersection between two subdomains.
Definition: subdomain.hh:643
const auto end() const
End iterator (sentinel)
Definition: subdomain.hh:712
bool contains(const Intersection &is) const
Check if intersection is contained in the interface between the subdomains.
Definition: subdomain.hh:673
const auto begin() const
Begin iterator over all intersection between the subdomains.
Definition: subdomain.hh:702
SubDomainInterface(const SubDomainA &subDomainA, const SubDomainB &subDomainB)
Create interface between two subdomains.
Definition: subdomain.hh:659
bool isOriented(const Intersection &is) const
Check if intersection is oriented.
Definition: subdomain.hh:689
Class representing the skeleton of a subdomain.
Definition: subdomain.hh:731
SubDomainSkeleton(const SubDomain &subDomain)
Create skeleton of a subdomain.
Definition: subdomain.hh:737
bool contains(const Intersection &is) const
Check if intersection is contained in the skeleton of the subdomain.
Definition: subdomain.hh:742
Class representing a sub-domain of a GridView.
Definition: subdomain.hh:576
void insertElement(const typename Codim< 0 >::Entity &element)
Insert element and all its sub-entities into SubDomain.
Definition: subdomain.hh:619
GridView gridView() const
Create grid view representing the SubDomain.
Definition: subdomain.hh:607
HostGridView hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:613
SubDomain(const HostGridView &hostGridView)
Construct SubDomain for underlying host grid view.
Definition: subdomain.hh:597
bool contains(const typename Codim< 0 >::Entity &element) const
Check if element is contained in SubDomain.
Definition: subdomain.hh:625
auto elements(const SubDomainGridView< HostGridView > &subDomainGridView, Dune::PartitionSet< partitions > partitionSet)
ADL findable access to element range for a SubDomainGridView.
Definition: subdomain.hh:540
auto intersections(const SubDomainGridView< HostGridView > &subDomainGridView, const Element &element)
ADL findable access to intersection range for an element of a SubDomainGridView.
Definition: subdomain.hh:552
Codim specific typedefs.
Definition: subdomain.hh:431
Codim specific typedefs.
Definition: subdomain.hh:202
Codim specific typedefs.
Definition: subdomain.hh:587