7#ifndef DUNE_FUNCTIONS_COMMON_SUBDOMAIN_HH
8#define DUNE_FUNCTIONS_COMMON_SUBDOMAIN_HH
17#include <dune/common/exceptions.hh>
18#include <dune/common/iteratorfacades.hh>
19#include <dune/common/iteratorrange.hh>
20#include <dune/common/rangeutilities.hh>
22#include <dune/geometry/type.hh>
23#include <dune/geometry/typeindex.hh>
25#include <dune/grid/common/mcmgmapper.hh>
26#include <dune/grid/common/partitionset.hh>
28namespace Dune::Functions::Experimental {
32 template<
class Gr
idView>
33 using GlobalIntersectionIteratorTraits = Dune::DefaultIteratorTraits<
34 std::forward_iterator_tag,
35 decltype(*std::declval<typename GridView::IntersectionIterator>())>;
38 template<
class GV,
class ContainsCallback>
39 class GlobalIntersectionIt
40 :
public Dune::IteratorFacadeForTraits<GlobalIntersectionIt<GV, ContainsCallback>, GlobalIntersectionIteratorTraits<GV>>
42 using Facade = Dune::IteratorFacadeForTraits<GlobalIntersectionIt<GV, ContainsCallback>, GlobalIntersectionIteratorTraits<GV>>;
47 using Element =
typename GridView::template Codim<0>::Entity;
48 using ElementIterator =
typename GridView::template Codim<0>::Iterator;
49 using IntersectionIterator =
typename GridView::IntersectionIterator;
51 class SentinelIterator
54 GlobalIntersectionIt(
const GridView& gridView,
const ContainsCallback& contains, ElementIterator elementIt, ElementIterator elementEnd)
57 , elementIt_(std::move(elementIt))
58 , elementEnd_(std::move(elementEnd))
60 if (elementIt_ != elementEnd_)
62 element_ = *elementIt_;
63 iIt_ = gridView_.ibegin(element_);
64 iEnd_ = gridView_.iend(element_);
65 if (not contains_(*iIt_))
70 using reference =
typename Facade::reference;
72 reference operator*()
const
77 GlobalIntersectionIt& operator++()
85 if (elementIt_ == elementEnd_)
87 element_ = *elementIt_;
88 iIt_ = gridView_.ibegin(element_);
89 iIt_ = gridView_.ibegin(element_);
90 iEnd_ = gridView_.iend(element_);
98 friend bool operator==(
const GlobalIntersectionIt& it1,
const GlobalIntersectionIt& it2)
100 if (it1.elementIt_ != it2.elementIt_)
102 if (it1.elementIt_ == it1.elementEnd_)
104 return (it1.iIt_ == it2.iIt_);
107 friend bool operator==(
const GlobalIntersectionIt& it1,
const SentinelIterator& it2)
109 return it1.elementIt_ == it1.elementEnd_;
114 ContainsCallback contains_;
115 ElementIterator elementIt_;
116 ElementIterator elementEnd_;
118 IntersectionIterator iIt_;
119 IntersectionIterator iEnd_;
149 using HostGridView = HGV;
153 using Grid =
typename HostGridView::Grid;
154 using Types = std::vector<Dune::GeometryType>;
155 using IndexType = std::size_t;
161 using Entity =
typename Grid::template Codim<codim>::Entity;
162 using EntitySeed =
typename Grid::template Codim<codim>::EntitySeed;
163 using Geometry =
typename Grid::template Codim<codim>::Geometry;
164 using LocalGeometry =
typename Grid::template Codim<codim>::LocalGeometry;
167 enum {dimension = Grid::dimension};
171 using AllEntityMapper = Dune::MultipleCodimMultipleGeomTypeMapper<HostGridView>;
173 static auto allCodimLayout()
175 return [](Dune::GeometryType, int) {
return true; };
178 static constexpr auto typeIndexSize = Dune::GlobalGeometryTypeIndex::size(dimension);
179 static constexpr auto unusesIndex = std::numeric_limits<IndexType>::max();
186 , allEntityMapper_(hostGridView_, allCodimLayout())
195 IndexType size(Dune::GeometryType gt)
const
197 return sizePerGT_[Dune::GlobalGeometryTypeIndex::index(gt)];
200 IndexType size(
int codim)
const
202 return sizePerCodim_[codim];
205 template<
class Entity>
206 IndexType index(
const Entity& entity)
const
208 auto index = indices_[allEntityMapper_.index(entity)];
209 if (index==unusesIndex)
210 DUNE_THROW(Dune::InvalidStateException,
"Accessing nonexisting entry using SubDomainIndexSet::index()!");
215 IndexType index(
const typename Codim<cc>::Entity& entity)
const
217 return index<typename Codim<cc>::Entity>(entity);
220 template<
class Entity>
221 IndexType subIndex(
const Entity& entity,
int subEntity,
unsigned int codim)
const
223 auto index = indices_[allEntityMapper_.subIndex(entity, subEntity, codim)];
224 if (index==unusesIndex)
225 DUNE_THROW(Dune::InvalidStateException,
"Accessing nonexisting entry using SubDomainIndexSet::subIndex()!");
230 IndexType subIndex(
const typename Codim<cc>::Entity& entity,
int subEntity,
unsigned int codim)
const
232 return subIndex<typename Codim<cc>::Entity>(entity, subEntity, codim);
235 template<
class Entity >
236 bool contains(
const Entity& entity)
const
238 return (indices_[allEntityMapper_.index(entity)] != unusesIndex);
241 Types types(
int codim)
const
243 return typesPerCodim_[codim];
253 return hostGridView_;
259 const auto& re = referenceElement(element);
260 for (
auto codim : Dune::range(0, dimension+1))
262 for (
auto subEntity : Dune::range(re.size(codim)))
264 auto& index = indices_[allEntityMapper_.subIndex(element, subEntity, codim)];
265 if (index==unusesIndex)
267 const auto& type = re.type(subEntity, codim);
268 const auto typeIndex = Dune::GlobalGeometryTypeIndex::index(type);
269 index = sizePerGT_[typeIndex];
270 if (sizePerGT_[typeIndex]==0)
271 typesPerCodim_[codim].push_back(type);
272 sizePerGT_[typeIndex]++;
273 sizePerCodim_[codim]++;
284 for(
auto& size : sizePerGT_)
286 for(
auto& size : sizePerCodim_)
288 for(
auto& types : typesPerCodim_)
291 indices_.resize(allEntityMapper_.size(), unusesIndex);
294 HostGridView hostGridView_;
297 std::array<std::size_t, typeIndexSize> sizePerGT_;
298 std::array<std::size_t, dimension+1> sizePerCodim_;
299 std::array<Types, dimension+1> typesPerCodim_;
301 AllEntityMapper allEntityMapper_;
304 std::vector<IndexType> indices_;
326 class NonImplementedIterator
329 NonImplementedIterator()
331 static_assert(codim==0,
"SubDomainGridView::Codim::Iterator<codim> is only implemented for codim=0");
335 template<PartitionIteratorType pit>
336 class ElementIterator
341 using HostElementIterator =
typename HGV::template
Codim<0>::template Partition<pit>::Iterator;
343 ElementIterator(
const SubDomainIndexSet<HGV>& indexSet, HostElementIterator&& it, HostElementIterator&& endIt)
344 : indexSet_(&indexSet)
345 , hostIt_(std::move(it))
346 , hostEndIt_(std::move(endIt))
348 while ((hostIt_!= hostEndIt_) and (not indexSet_->contains(*hostIt_)))
352 ElementIterator& operator++()
355 while ((hostIt_!= hostEndIt_) and (not indexSet_->contains(*hostIt_)))
360 const Element& operator*()
const
365 friend bool operator==(
const ElementIterator& a,
const ElementIterator& b)
367 return a.hostIt_==b.hostIt_;
371 HostElementIterator hostIt_;
372 HostElementIterator hostEndIt_;
378 using HostGridView = HGV;
380 using Grid =
typename HostGridView::Grid;
381 using ctype =
typename Grid::ctype;
383 using Intersection =
typename HostGridView::Intersection;
384 using IntersectionIterator =
typename HostGridView::IntersectionIterator;
390 using Entity =
typename Grid::template Codim<codim>::Entity;
391 using EntitySeed =
typename Grid::template Codim<codim>::EntitySeed;
392 using Geometry =
typename Grid::template Codim<codim>::Geometry;
393 using LocalGeometry =
typename Grid::template Codim<codim>::LocalGeometry;
394 using Iterator = std::conditional_t<codim==0, ElementIterator<All_Partition>, NonImplementedIterator<codim>>;
396 template<PartitionIteratorType pit>
399 using Iterator = std::conditional_t<codim==0, ElementIterator<pit>, NonImplementedIterator<codim>>;
403 enum {dimension = Grid::dimension};
404 enum {dimensionworld = Grid::dimensionworld};
406 SubDomainGridView(
const IndexSet& indexSet)
407 : indexSet_(&indexSet)
410 SubDomainGridView(
const SubDomainGridView& other) =
default;
412 const Grid& grid()
const
417 const IndexSet& indexSet()
const
422 int size(
int codim)
const
424 return indexSet_->size(codim);
427 int size(Dune::GeometryType gt)
const
429 return indexSet_->size(gt);
432 template<
class Entity>
433 bool contains(
const Entity& entity)
const
435 return indexSet_->contains(entity);
439 template<
int codim, PartitionIteratorType pit = All_Partition>
442 static_assert(codim==0,
"SubDomainGridView::begin<codim> is only implemented for codim=0");
447 template<
int codim, PartitionIteratorType pit = All_Partition>
450 static_assert(codim==0,
"SubDomainGridView::end<codim> is only implemented for codim=0");
454 decltype(
auto) comm()
const
459 decltype(
auto) ibegin(
const typename Codim<0>::Entity& element)
const
464 decltype(
auto) iend(
const typename Codim<0>::Entity& element)
const
476 const IndexSet* indexSet_;
486 template<
class HostGr
idView>
489 return Dune::IteratorRange(subDomainGridView.template begin<0>(), subDomainGridView.template end<0>());
497 template<
class HostGr
idView,
unsigned int partitions>
500 constexpr auto pit = partitionSet.partitionIterator();
501 return Dune::IteratorRange(subDomainGridView.template begin<0, pit>(), subDomainGridView.template end<0, pit>());
509 template<
class HostGr
idView,
class Element>
512 return Dune::IteratorRange(subDomainGridView.ibegin(element), subDomainGridView.iend(element));
537 using HostGridView = HGV;
538 using Grid =
typename HostGridView::Grid;
546 using Entity =
typename Grid::template Codim<codim>::Entity;
547 using EntitySeed =
typename Grid::template Codim<codim>::EntitySeed;
548 using Geometry =
typename Grid::template Codim<codim>::Geometry;
549 using LocalGeometry =
typename Grid::template Codim<codim>::LocalGeometry;
552 enum {dimension = Grid::dimension};
559 const IndexSet& indexSet()
const
585 return indexSet_.contains(element);
599 template<
class SubDomainA,
class SubDomainB>
603 std::is_same_v<typename SubDomainA::GridView::Intersection, typename SubDomainB::GridView::Intersection>,
604 "SubDomainInterface requires that both SubDomain types have the same Intersection type");
608 using Intersection =
typename SubDomainA::GridView::Intersection;
618 : subDomainA_(subDomainA)
619 , subDomainB_(subDomainB)
633 if (is.boundary() or not(is.neighbor()))
635 return (subDomainA_.contains(is.inside()) && subDomainB_.contains(is.outside()))
636 || (subDomainA_.contains(is.outside()) && subDomainB_.contains(is.inside()));
649 if (is.boundary() or not(is.neighbor()))
651 return (subDomainA_.contains(is.inside()) && subDomainB_.contains(is.outside()));
662 return Impl::GlobalIntersectionIt(subDomainA_.gridView(), [&](
const auto& is) {
663 if (is.boundary() or not(is.neighbor()))
665 return subDomainB_.indexSet().contains(is.outside());
666 }, subDomainA_.gridView().template begin<0>(), subDomainA_.gridView().template end<0>());
672 return typename decltype(
begin())::SentinelIterator();
676 const SubDomainA& subDomainA_;
677 const SubDomainB& subDomainB_;
687 template<
class SubDomain>
692 using Intersection =
typename SubDomain::GridView::Intersection;
696 : subDomain_(subDomain)
702 if (is.boundary() or not(is.neighbor()))
704 return subDomain_.
contains(is.inside()) and subDomain_.
contains(is.outside());
A GridView for a sub-domain.
Definition: subdomain.hh:323
Codim< codim >::template Partition< pit >::Iterator end() const
Create an iterator pointing to the end of the range.
Definition: subdomain.hh:448
const HostGridView & hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:470
Codim< codim >::template Partition< pit >::Iterator begin() const
Create an iterator pointing to the begin of the range.
Definition: subdomain.hh:440
An IndexSet for a sub-domain.
Definition: subdomain.hh:148
SubDomainIndexSet(const HostGridView &hostGridView)
Construct SubDomainIndexSet for underlying host grid view.
Definition: subdomain.hh:184
void insertElement(const typename Codim< 0 >::Entity &element)
Insert element and all its sub-entities into SubDomainIndexSet.
Definition: subdomain.hh:257
const HostGridView & hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:251
Class representing the intersection between two subdomains.
Definition: subdomain.hh:601
const auto end() const
End iterator (sentinel)
Definition: subdomain.hh:670
bool contains(const Intersection &is) const
Check if intersection is contained in the interface between the subdomains.
Definition: subdomain.hh:631
const auto begin() const
Begin iterator over all intersection between the subdomains.
Definition: subdomain.hh:660
SubDomainInterface(const SubDomainA &subDomainA, const SubDomainB &subDomainB)
Create interface between two subdomains.
Definition: subdomain.hh:617
bool isOriented(const Intersection &is) const
Check if intersection is oriented.
Definition: subdomain.hh:647
Class representing the skeleton of a subdomain.
Definition: subdomain.hh:689
SubDomainSkeleton(const SubDomain &subDomain)
Create skeleton of a subdomain.
Definition: subdomain.hh:695
bool contains(const Intersection &is) const
Check if intersection is contained in the skeleton of the subdomain.
Definition: subdomain.hh:700
Class representing a sub-domain of a GridView.
Definition: subdomain.hh:534
void insertElement(const typename Codim< 0 >::Entity &element)
Insert element and all its sub-entities into SubDomain.
Definition: subdomain.hh:577
GridView gridView() const
Create grid view representing the SubDomain.
Definition: subdomain.hh:565
HostGridView hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:571
SubDomain(const HostGridView &hostGridView)
Construct SubDomain for underlying host grid view.
Definition: subdomain.hh:555
bool contains(const typename Codim< 0 >::Entity &element) const
Check if element is contained in SubDomain.
Definition: subdomain.hh:583
auto elements(const SubDomainGridView< HostGridView > &subDomainGridView, Dune::PartitionSet< partitions > partitionSet)
ADL findable access to element range for a SubDomainGridView.
Definition: subdomain.hh:498
auto intersections(const SubDomainGridView< HostGridView > &subDomainGridView, const Element &element)
ADL findable access to intersection range for an element of a SubDomainGridView.
Definition: subdomain.hh:510
Codim specific typedefs.
Definition: subdomain.hh:389
Codim specific typedefs.
Definition: subdomain.hh:160
Codim specific typedefs.
Definition: subdomain.hh:545