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 if (gt.dim() <= dimension)
240 return sizePerGT_[Dune::GlobalGeometryTypeIndex::index(gt)];
245 IndexType size(
int codim)
const
247 return sizePerCodim_[codim];
250 template<
class Entity>
251 IndexType index(
const Entity& entity)
const
253 auto index = indices_[allEntityMapper_.index(entity)];
254 if (index==unusesIndex)
255 DUNE_THROW(Dune::InvalidStateException,
"Accessing nonexisting entry using SubDomainIndexSet::index()!");
260 IndexType index(
const typename Codim<cc>::Entity& entity)
const
262 return index<typename Codim<cc>::Entity>(entity);
265 template<
class Entity>
266 IndexType subIndex(
const Entity& entity,
int subEntity,
unsigned int codim)
const
268 auto index = indices_[allEntityMapper_.subIndex(entity, subEntity, codim)];
269 if (index==unusesIndex)
270 DUNE_THROW(Dune::InvalidStateException,
"Accessing nonexisting entry using SubDomainIndexSet::subIndex()!");
275 IndexType subIndex(
const typename Codim<cc>::Entity& entity,
int subEntity,
unsigned int codim)
const
277 return subIndex<typename Codim<cc>::Entity>(entity, subEntity, codim);
280 template<
class Entity >
281 bool contains(
const Entity& entity)
const
283 return (indices_[allEntityMapper_.index(entity)] != unusesIndex);
286 Types types(
int codim)
const
288 return typesPerCodim_[codim];
298 return hostGridView_;
304 const auto& re = referenceElement(element);
305 for (
auto codim : Dune::range(0, dimension+1))
307 for (
auto subEntity : Dune::range(re.size(codim)))
309 auto& index = indices_[allEntityMapper_.subIndex(element, subEntity, codim)];
310 if (index==unusesIndex)
312 const auto& type = re.type(subEntity, codim);
313 const auto typeIndex = Dune::GlobalGeometryTypeIndex::index(type);
314 index = sizePerGT_[typeIndex];
315 if (sizePerGT_[typeIndex]==0)
316 typesPerCodim_[codim].push_back(type);
317 sizePerGT_[typeIndex]++;
318 sizePerCodim_[codim]++;
329 for(
auto& size : sizePerGT_)
331 for(
auto& size : sizePerCodim_)
333 for(
auto& types : typesPerCodim_)
336 indices_.resize(allEntityMapper_.size(), unusesIndex);
339 HostGridView hostGridView_;
342 std::array<std::size_t, typeIndexSize> sizePerGT_;
343 std::array<std::size_t, dimension+1> sizePerCodim_;
344 std::array<Types, dimension+1> typesPerCodim_;
346 AllEntityMapper allEntityMapper_;
349 std::vector<IndexType> indices_;
371 class NonImplementedIterator
374 NonImplementedIterator()
376 static_assert(codim==0,
"SubDomainGridView::Codim::Iterator<codim> is only implemented for codim=0");
380 template<PartitionIteratorType pit>
381 class ElementIterator
386 using HostElementIterator =
typename HGV::template
Codim<0>::template Partition<pit>::Iterator;
388 ElementIterator(
const SubDomainIndexSet<HGV>& indexSet, HostElementIterator&& it, HostElementIterator&& endIt)
389 : indexSet_(&indexSet)
390 , hostIt_(std::move(it))
391 , hostEndIt_(std::move(endIt))
393 while ((hostIt_!= hostEndIt_) and (not indexSet_->contains(*hostIt_)))
397 ElementIterator& operator++()
400 while ((hostIt_!= hostEndIt_) and (not indexSet_->contains(*hostIt_)))
405 const Element& operator*()
const
410 friend bool operator==(
const ElementIterator& a,
const ElementIterator& b)
412 return a.hostIt_==b.hostIt_;
416 HostElementIterator hostIt_;
417 HostElementIterator hostEndIt_;
423 using HostGridView = HGV;
425 using Grid =
typename HostGridView::Grid;
426 using ctype =
typename Grid::ctype;
428 using Intersection =
typename HostGridView::Intersection;
429 using IntersectionIterator =
typename HostGridView::IntersectionIterator;
435 using Entity =
typename Grid::template Codim<codim>::Entity;
436 using EntitySeed =
typename Grid::template Codim<codim>::EntitySeed;
437 using Geometry =
typename Grid::template Codim<codim>::Geometry;
438 using LocalGeometry =
typename Grid::template Codim<codim>::LocalGeometry;
439 using Iterator = std::conditional_t<codim==0, ElementIterator<All_Partition>, NonImplementedIterator<codim>>;
441 template<PartitionIteratorType pit>
444 using Iterator = std::conditional_t<codim==0, ElementIterator<pit>, NonImplementedIterator<codim>>;
448 enum {dimension = Grid::dimension};
449 enum {dimensionworld = Grid::dimensionworld};
451 SubDomainGridView(
const IndexSet& indexSet)
452 : indexSet_(&indexSet)
455 SubDomainGridView(
const SubDomainGridView& other) =
default;
457 const Grid& grid()
const
462 const IndexSet& indexSet()
const
467 int size(
int codim)
const
469 return indexSet_->size(codim);
472 int size(Dune::GeometryType gt)
const
474 return indexSet_->size(gt);
477 template<
class Entity>
478 bool contains(
const Entity& entity)
const
480 return indexSet_->contains(entity);
484 template<
int codim, PartitionIteratorType pit = All_Partition>
487 static_assert(codim==0,
"SubDomainGridView::begin<codim> is only implemented for codim=0");
492 template<
int codim, PartitionIteratorType pit = All_Partition>
495 static_assert(codim==0,
"SubDomainGridView::end<codim> is only implemented for codim=0");
499 decltype(
auto) comm()
const
504 decltype(
auto) ibegin(
const typename Codim<0>::Entity& element)
const
509 decltype(
auto) iend(
const typename Codim<0>::Entity& element)
const
521 const IndexSet* indexSet_;
531 template<
class HostGr
idView>
534 return Dune::IteratorRange(subDomainGridView.template begin<0>(), subDomainGridView.template end<0>());
542 template<
class HostGr
idView,
unsigned int partitions>
545 constexpr auto pit = partitionSet.partitionIterator();
546 return Dune::IteratorRange(subDomainGridView.template begin<0, pit>(), subDomainGridView.template end<0, pit>());
554 template<
class HostGr
idView,
class Element>
557 return Dune::IteratorRange(subDomainGridView.ibegin(element), subDomainGridView.iend(element));
582 using HostGridView = HGV;
583 using Grid =
typename HostGridView::Grid;
591 using Entity =
typename Grid::template Codim<codim>::Entity;
592 using EntitySeed =
typename Grid::template Codim<codim>::EntitySeed;
593 using Geometry =
typename Grid::template Codim<codim>::Geometry;
594 using LocalGeometry =
typename Grid::template Codim<codim>::LocalGeometry;
597 enum {dimension = Grid::dimension};
604 const IndexSet& indexSet()
const
630 return indexSet_.contains(element);
644 template<
class SubDomainA,
class SubDomainB>
648 std::is_same_v<typename SubDomainA::GridView::Intersection, typename SubDomainB::GridView::Intersection>,
649 "SubDomainInterface requires that both SubDomain types have the same Intersection type");
653 using Intersection =
typename SubDomainA::GridView::Intersection;
663 : subDomainA_(subDomainA)
664 , subDomainB_(subDomainB)
678 if (is.boundary() or not(is.neighbor()))
680 return (subDomainA_.contains(is.inside()) && subDomainB_.contains(is.outside()))
681 || (subDomainA_.contains(is.outside()) && subDomainB_.contains(is.inside()));
694 if (is.boundary() or not(is.neighbor()))
696 return (subDomainA_.contains(is.inside()) && subDomainB_.contains(is.outside()));
707 return Impl::GlobalIntersectionIt(subDomainA_.gridView(), [&](
const auto& is) {
708 if (is.boundary() or not(is.neighbor()))
710 return subDomainB_.indexSet().contains(is.outside());
717 return typename decltype(
begin())::SentinelIterator();
721 const SubDomainA& subDomainA_;
722 const SubDomainB& subDomainB_;
732 template<
class SubDomain>
737 using Intersection =
typename SubDomain::GridView::Intersection;
741 : subDomain_(subDomain)
747 if (is.boundary() or not(is.neighbor()))
749 return subDomain_.
contains(is.inside()) and subDomain_.
contains(is.outside());
A GridView for a sub-domain.
Definition: subdomain.hh:368
Codim< codim >::template Partition< pit >::Iterator end() const
Create an iterator pointing to the end of the range.
Definition: subdomain.hh:493
const HostGridView & hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:515
Codim< codim >::template Partition< pit >::Iterator begin() const
Create an iterator pointing to the begin of the range.
Definition: subdomain.hh:485
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:302
const HostGridView & hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:296
Class representing the intersection between two subdomains.
Definition: subdomain.hh:646
const auto end() const
End iterator (sentinel)
Definition: subdomain.hh:715
bool contains(const Intersection &is) const
Check if intersection is contained in the interface between the subdomains.
Definition: subdomain.hh:676
const auto begin() const
Begin iterator over all intersection between the subdomains.
Definition: subdomain.hh:705
SubDomainInterface(const SubDomainA &subDomainA, const SubDomainB &subDomainB)
Create interface between two subdomains.
Definition: subdomain.hh:662
bool isOriented(const Intersection &is) const
Check if intersection is oriented.
Definition: subdomain.hh:692
Class representing the skeleton of a subdomain.
Definition: subdomain.hh:734
SubDomainSkeleton(const SubDomain &subDomain)
Create skeleton of a subdomain.
Definition: subdomain.hh:740
bool contains(const Intersection &is) const
Check if intersection is contained in the skeleton of the subdomain.
Definition: subdomain.hh:745
Class representing a sub-domain of a GridView.
Definition: subdomain.hh:579
void insertElement(const typename Codim< 0 >::Entity &element)
Insert element and all its sub-entities into SubDomain.
Definition: subdomain.hh:622
GridView gridView() const
Create grid view representing the SubDomain.
Definition: subdomain.hh:610
HostGridView hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:616
SubDomain(const HostGridView &hostGridView)
Construct SubDomain for underlying host grid view.
Definition: subdomain.hh:600
bool contains(const typename Codim< 0 >::Entity &element) const
Check if element is contained in SubDomain.
Definition: subdomain.hh:628
auto elements(const SubDomainGridView< HostGridView > &subDomainGridView, Dune::PartitionSet< partitions > partitionSet)
ADL findable access to element range for a SubDomainGridView.
Definition: subdomain.hh:543
auto intersections(const SubDomainGridView< HostGridView > &subDomainGridView, const Element &element)
ADL findable access to intersection range for an element of a SubDomainGridView.
Definition: subdomain.hh:555
Codim specific typedefs.
Definition: subdomain.hh:434
Codim specific typedefs.
Definition: subdomain.hh:202
Codim specific typedefs.
Definition: subdomain.hh:590