1#ifndef DUNE_MULTIDOMAINGRID_INDEXSETS_HH
2#define DUNE_MULTIDOMAINGRID_INDEXSETS_HH
5#include <unordered_map>
14#include <dune/common/hybridutilities.hh>
16#include <dune/geometry/typeindex.hh>
18#include <dune/grid/common/exceptions.hh>
19#include <dune/grid/common/indexidset.hh>
21#include <dune/grid/multidomaingrid/utility.hh>
22#include <dune/grid/multidomaingrid/subdomaingrid/indexsets.hh>
28template<
typename HostGr
id,
typename MDGr
idTraits>
36template<
template<
int>
class StructForCodim,
typename Codims>
40template<
template<
int>
class StructForCodim, std::size_t... codim>
41struct _buildMap<StructForCodim,std::index_sequence<codim...> > {
43 typedef std::tuple<StructForCodim<codim>... > type;
47template<
template<
int>
class StructForCodim,
int dimension>
50 typedef typename _buildMap<
52 decltype(std::make_index_sequence<dimension+1>())
65template<
bool doDispatch,
typename Impl,
typename resulttype,
bool alternate_dispatch>
68template<
typename Impl,
typename resulttype,
bool alternate_dispatch>
69struct invokeIf<true,Impl,resulttype,alternate_dispatch> {
71 typedef resulttype result_type;
74 result_type invoke() {
75 return _impl.template invoke<codim>();
80 invokeIf(Impl& impl) :
87template<
typename Impl,
typename resulttype>
88struct invokeIf<false,Impl, resulttype,false> {
90 typedef resulttype result_type;
93 result_type invoke() {
94 DUNE_THROW(GridError,
"codim not supported");
99 invokeIf(Impl& impl) :
105template<
typename Impl,
typename resulttype>
106struct invokeIf<false,Impl, resulttype,true> {
108 typedef resulttype result_type;
111 result_type invoke() {
112 return _impl.template invoke_unsupported<codim>();
117 invokeIf(Impl& impl) :
124template<
typename Impl,
typename resulttype,
typename MDGr
idTraits,
int codim,
bool protect = true,
bool alternate_dispatch = false>
125struct dispatchToCodim
126 :
public dispatchToCodim<Impl,resulttype,MDGridTraits,codim-1,protect,alternate_dispatch> {
128 typedef resulttype result_type;
130 result_type dispatch(
int cc) {
132 return invokeIf<MDGridTraits::template Codim<codim>::supported,Impl,result_type,alternate_dispatch>(
static_cast<Impl&
>(*this)).
template invoke<codim>();
133 return static_cast<dispatchToCodim<Impl,result_type,MDGridTraits,codim-1,protect,alternate_dispatch
>&>(*this).dispatch(cc);
139template<
typename Impl,
typename resulttype,
typename MDGr
idTraits,
bool alternate_dispatch>
140struct dispatchToCodim<Impl,resulttype,MDGridTraits,0,true,alternate_dispatch> {
142 typedef resulttype result_type;
144 result_type dispatch(
int cc) {
146 return invokeIf<MDGridTraits::template Codim<0>::supported,Impl,result_type,alternate_dispatch>(
static_cast<Impl&
>(*this)).
template invoke<0>();
147 DUNE_THROW(GridError,
"invalid codimension specified");
153template<
typename Impl,
typename resulttype,
typename MDGr
idTraits,
int codim,
bool alternate_dispatch>
154struct dispatchToCodim<Impl,resulttype,MDGridTraits,codim,false,alternate_dispatch>
155 :
public dispatchToCodim<Impl,resulttype,MDGridTraits,codim-1,false,alternate_dispatch> {
157 typedef resulttype result_type;
159 result_type dispatch(
int cc) {
161 return static_cast<Impl&
>(*this).template invoke<codim>();
162 return static_cast<dispatchToCodim<Impl,result_type,MDGridTraits,codim-1,false,alternate_dispatch
>&>(*this).dispatch(cc);
168template<
typename Impl,
typename resulttype,
typename MDGr
idTraits,
bool alternate_dispatch>
169struct dispatchToCodim<Impl,resulttype,MDGridTraits,0,false,alternate_dispatch> {
171 typedef resulttype result_type;
173 result_type dispatch(
int cc) {
175 return static_cast<Impl&
>(*this).template invoke<0>();
176 DUNE_THROW(GridError,
"invalid codimension specified");
186template<
bool doApply,
typename Impl>
189 template<
int codim,
typename T>
190 void apply(T& t)
const {
191 _impl.template apply<codim>(t);
196 applyIf(Impl& impl) :
203template<
typename Impl>
204struct applyIf<false,Impl> {
206 template<
int codim,
typename T>
207 void apply(T& t)
const {
212 applyIf(Impl& impl) :
221 return const_cast<T&
>(t);
231template<
typename Gr
idImp,
typename HostGr
idViewType>
233 public Dune::IndexSet<GridImp,IndexSetWrapper<GridImp,HostGridViewType>,
234 typename HostGridViewType::IndexSet::IndexType,
235 typename HostGridViewType::IndexSet::Types>
238 using Grid = std::remove_const_t<GridImp>;
240 template<
typename,
typename>
243 template<
typename,
typename>
246 template<
typename,
typename>
247 friend class subdomain::IndexSetWrapper;
249 template<
typename,
typename,
typename,
typename>
253 friend class SubDomainToSubDomainController;
256 friend class AllInterfacesController;
260 using HostGrid =
typename Grid::HostGrid;
261 typedef HostGridViewType HostGridView;
262 typedef typename HostGridView::IndexSet HostIndexSet;
263 using ctype =
typename Grid::ctype;
264 using CellReferenceElement = Dune::ReferenceElement<typename HostGrid::template Codim<0>::Entity::Geometry>;
266 typedef Dune::IndexSet<
272 typename HostGridViewType::IndexSet::IndexType,
273 typename HostGridViewType::IndexSet::Types
278 typedef typename BaseT::Types Types;
280 using MDGridTraits =
typename Grid::MDGridTraits;
281 typedef typename MDGridTraits::template Codim<0>::SubDomainSet SubDomainSet;
282 typedef typename MDGridTraits::SubDomainIndex SubDomainIndex;
285 typedef typename HostIndexSet::IndexType IndexType;
286 static const int dimension = Grid::dimension;
287 static const std::size_t maxSubDomains = SubDomainSet::maxSize;
291 typedef typename HostGridView::template Codim<0>::Iterator HostEntityIterator;
292 typedef typename HostGridView::template Codim<0>::Entity HostEntity;
293 using Codim0Entity =
typename Grid::Traits::template Codim<0>::Entity;
298 typedef typename MDGridTraits::template Codim<cc>::SubDomainSet SubDomainSet;
300 SubDomainSet domains;
305 struct NotSupported {};
310 static const bool supported = Grid::MDGridTraits::template Codim<codim>::supported;
312 static_assert((codim > 0 || supported),
"index mapping of codimension 0 must be supported!");
314 using IndexMap = std::conditional_t<
316 std::vector<std::vector<MapEntry<codim> > >,
320 using SizeMap = std::conditional_t<
322 std::vector<typename Grid::MDGridTraits::template Codim<codim>::SizeContainer>,
326 using CodimSizeMap = std::conditional_t<
328 typename Grid::MDGridTraits::template Codim<codim>::SizeContainer,
332 using MultiIndexMap = std::conditional_t<
334 std::vector<typename Grid::MDGridTraits::template Codim<codim>::MultiIndexContainer>,
340 CodimSizeMap codimSizeMap;
341 MultiIndexMap multiIndexMap;
344 Containers& operator=(
const Containers&) =
delete;
347 Containers& operator=(Containers&&) =
default;
350 Containers(
const Containers&) =
default;
351 Containers(Containers&&) =
default;
352 Containers() =
default;
356 typedef typename detail::buildMap<Containers,dimension>::type ContainerMap;
358 typedef std::vector<std::shared_ptr<IndexSetWrapper<GridImp, typename HostGridView::Grid::LevelGridView> > > LevelIndexSets;
361 template<
typename Impl,
typename result_type,
bool protect = true,
bool alternate_dispatch = false>
362 struct dispatchToCodim :
public detail::dispatchToCodim<Impl,result_type,MDGridTraits,dimension,protect,alternate_dispatch> {};
368 IndexType
index(
const typename Grid::Traits::template Codim<codim>::Entity& e)
const {
369 return _hostGridView.indexSet().index(_grid.hostEntity(e));
373 template<
typename Entity>
374 IndexType
index(
const Entity& e)
const {
375 return _hostGridView.indexSet().index(_grid.hostEntity(e));
379 template<
int codim,
typename Entity>
381 return _hostGridView.indexSet().subIndex(_grid.hostEntity(e),i,codim);
385 template<
typename Entity>
386 IndexType
subIndex(
const Entity& e,
int i,
unsigned int codim)
const {
387 IndexType r = _hostGridView.indexSet().subIndex(_grid.hostEntity(e),i,codim);
393 return _hostGridView.indexSet().types(codim);
397 IndexType
size(GeometryType type)
const {
398 return _hostGridView.indexSet().size(type);
402 IndexType
size(
int codim)
const {
403 return _hostGridView.indexSet().size(codim);
407 template<
typename EntityType>
409 return _hostGridView.indexSet().contains(_grid.hostEntity(e));
413 template<
typename EntityType>
414 const typename MapEntry<EntityType::codimension>::SubDomainSet&
subDomains(
const EntityType& e)
const {
415 return subDomainsForHostEntity(_grid.hostEntity(e));
421 const typename MapEntry<cc>::SubDomainSet&
subDomains(
const typename Grid::Traits::template Codim<cc>::Entity& e)
const {
422 return subDomainsForHostEntity<cc>(_grid.hostEntity(e));
426 template<
class EntityType>
427 IndexType
index(SubDomainIndex subDomain,
const EntityType& e)
const {
428 return index<EntityType::codimension>(subDomain,e);
434 IndexType
index(SubDomainIndex subDomain,
const typename Grid::Traits::template Codim<cc>::Entity& e)
const {
435 GeometryType gt = e.type();
436 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
437 const MapEntry<cc>& me = indexMap<cc>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
438 assert(me.domains.contains(subDomain));
439 if (me.domains.simple()) {
442 return multiIndexMap<cc>()[me.index][me.domains.domainOffset(subDomain)];
449 template<
typename EntityType>
450 typename MapEntry<EntityType::codimension>::SubDomainSet&
subDomains(
const EntityType& e) {
451 return subDomainsForHostEntity(_grid.hostEntity(e));
457 typename MapEntry<cc>::SubDomainSet&
subDomains(
const typename Grid::Traits::template Codim<cc>::Entity& e) {
458 return subDomainsForHostEntity<cc>(_grid.hostEntity(e));
462 template<
typename HostEntity>
463 typename MapEntry<HostEntity::codimension>::SubDomainSet& subDomainsForHostEntity(
const HostEntity& e) {
464 return subDomainsForHostEntity<HostEntity::codimension>(e);
470 typename MapEntry<cc>::SubDomainSet& subDomainsForHostEntity(
const typename Grid::HostGrid::Traits::template Codim<cc>::Entity& he) {
471 return indexMap<cc>()[LocalGeometryTypeIndex::index(he.type())][_hostGridView.indexSet().index(he)].domains;
475 template<
typename HostEntity>
476 const typename MapEntry<HostEntity::codimension>::SubDomainSet& subDomainsForHostEntity(
const HostEntity& e)
const {
477 return subDomainsForHostEntity<HostEntity::codimension>(e);
483 const typename MapEntry<cc>::SubDomainSet& subDomainsForHostEntity(
const typename Grid::HostGrid::Traits::template Codim<cc>::Entity& he)
const {
484 return indexMap<cc>()[LocalGeometryTypeIndex::index(he.type())][_hostGridView.indexSet().index(he)].domains;
488 IndexType indexForSubDomain(SubDomainIndex subDomain,
const typename Grid::HostGrid::Traits::template Codim<cc>::Entity& he)
const {
489 const GeometryType gt = he.type();
490 const IndexType hostIndex = _hostGridView.indexSet().index(he);
491 const MapEntry<cc>& me = indexMap<cc>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
492 assert(me.domains.contains(subDomain));
493 if (me.domains.simple()) {
496 return multiIndexMap<cc>()[me.index][me.domains.domainOffset(subDomain)];
501 struct getSubIndexForSubDomain :
public dispatchToCodim<getSubIndexForSubDomain,IndexType> {
504 IndexType invoke()
const {
505 const MapEntry<codim>& me = _indexSet.indexMap<codim>()[LocalGeometryTypeIndex::index(_gt)][_hostIndex];
506 assert(me.domains.contains(_subDomain));
507 if (me.domains.simple()) {
510 return _indexSet.multiIndexMap<codim>()[me.index][me.domains.domainOffset(_subDomain)];
514 SubDomainIndex _subDomain;
516 IndexType _hostIndex;
517 const ThisType& _indexSet;
519 getSubIndexForSubDomain(SubDomainIndex subDomain, GeometryType gt, IndexType hostIndex,
const ThisType& indexSet) :
520 _subDomain(subDomain),
522 _hostIndex(hostIndex),
528 template<
typename HostEntity>
529 IndexType subIndexForSubDomain(SubDomainIndex subDomain,
const HostEntity& he,
int i,
int codim)
const {
530 return getSubIndexForSubDomain(subDomain,
531 referenceElement(he.geometry()).type(i,codim - he.codimension),
532 _hostGridView.indexSet().subIndex(he,i,codim),
533 *
this).dispatch(codim);
536 Types typesForSubDomain(SubDomainIndex subDomain,
int codim)
const {
540 struct getGeometryTypeSizeForSubDomain :
public dispatchToCodim<getGeometryTypeSizeForSubDomain,IndexType,true,true> {
543 IndexType invoke()
const {
544 return _indexSet.sizeMap<codim>()[LocalGeometryTypeIndex::index(_gt)][_subDomain];
548 IndexType invoke_unsupported()
const {
552 SubDomainIndex _subDomain;
554 const ThisType& _indexSet;
556 getGeometryTypeSizeForSubDomain(SubDomainIndex subDomain, GeometryType gt,
const ThisType& indexSet) :
557 _subDomain(subDomain),
564 IndexType sizeForSubDomain(SubDomainIndex subDomain, GeometryType type)
const {
565 return getGeometryTypeSizeForSubDomain(subDomain,type,*
this).dispatch(dimension-type.dim());
568 struct getCodimSizeForSubDomain :
public dispatchToCodim<getCodimSizeForSubDomain,IndexType,true,true> {
571 IndexType invoke()
const {
572 return _indexSet.codimSizes<codim>()[_subDomain];
576 IndexType invoke_unsupported()
const {
580 SubDomainIndex _subDomain;
581 const ThisType& _indexSet;
583 getCodimSizeForSubDomain(SubDomainIndex subDomain,
const ThisType& indexSet) :
584 _subDomain(subDomain),
590 IndexType sizeForSubDomain(SubDomainIndex subDomain,
int codim)
const {
591 return getCodimSizeForSubDomain(subDomain,*
this).dispatch(codim);
594 template<
typename EntityType>
595 bool containsForSubDomain(SubDomainIndex subDomain,
const EntityType& he)
const {
596 const GeometryType gt = he.type();
597 const IndexType hostIndex = _hostGridView.indexSet().index(he);
598 const MapEntry<EntityType::codimension>& me = indexMap<EntityType::codimension>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
599 return me.domains.contains(subDomain);
604 template<
typename SubDomainEntity>
605 IndexType
subIndex(SubDomainIndex subDomain,
const SubDomainEntity& e,
int i,
int codim)
const {
606 return subIndexForSubDomain(subDomain,_grid.hostEntity(e),i,codim);
609 Types
types(SubDomainIndex subDomain,
int codim)
const {
613 IndexType
size(SubDomainIndex subDomain, GeometryType type)
const {
614 return sizeForSubDomain(subDomain,type);
617 IndexType
size(SubDomainIndex subDomain,
int codim)
const {
618 return sizeForSubDomain(subDomain,codim);
622 template<
typename EntityType>
623 bool contains(SubDomainIndex subDomain,
const EntityType& e)
const {
624 const GeometryType gt = e.type();
625 const IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
626 const MapEntry<EntityType::codimension>& me = indexMap<EntityType::codimension>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
627 return me.domains.contains(subDomain);
632 const GridImp& _grid;
633 HostGridView _hostGridView;
634 ContainerMap _containers;
636 void swap(ThisType& rhs) {
637 assert(&_grid == &rhs._grid);
638 std::swap(_containers,rhs._containers);
641 void addToSubDomain(SubDomainIndex subDomain,
const Codim0Entity& e) {
642 GeometryType gt = e.type();
643 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
644 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.add(subDomain);
647 void removeFromSubDomain(SubDomainIndex subDomain,
const Codim0Entity& e) {
648 GeometryType gt = e.type();
649 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
650 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.remove(subDomain);
653 void removeFromAllSubDomains(
const Codim0Entity& e) {
654 GeometryType gt = e.type();
655 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
656 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.clear();
659 void assignToSubDomain(SubDomainIndex subDomain,
const Codim0Entity& e) {
660 GeometryType gt = e.type();
661 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
662 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.set(subDomain);
665 void addToSubDomains(
const typename MDGridTraits::template Codim<0>::SubDomainSet&
subDomains,
const Codim0Entity& e) {
666 GeometryType gt = e.type();
667 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
668 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.addAll(
subDomains);
675 IndexSetWrapper(
const GridImp& grid, HostGridView hostGridView) :
677 _hostGridView(hostGridView)
680 explicit IndexSetWrapper(
const ThisType& rhs) :
682 _hostGridView(rhs._hostGridView),
683 _containers(rhs._containers)
691 typename Containers<cc>::IndexMap& indexMap() {
692 return std::get<cc>(_containers).indexMap;
696 typename Containers<cc>::SizeMap& sizeMap() {
697 return std::get<cc>(_containers).sizeMap;
701 typename Containers<cc>::CodimSizeMap& codimSizes() {
702 return std::get<cc>(_containers).codimSizeMap;
706 typename Containers<cc>::MultiIndexMap& multiIndexMap() {
707 return std::get<cc>(_containers).multiIndexMap;
711 const typename Containers<cc>::IndexMap& indexMap()
const {
712 return std::get<cc>(_containers).indexMap;
716 const typename Containers<cc>::SizeMap& sizeMap()
const {
717 return std::get<cc>(_containers).sizeMap;
721 const typename Containers<cc>::CodimSizeMap& codimSizes()
const {
722 return std::get<cc>(_containers).codimSizeMap;
726 const typename Containers<cc>::MultiIndexMap& multiIndexMap()
const {
727 return std::get<cc>(_containers).multiIndexMap;
730 template<
typename Functor>
731 void applyToCodims(Functor func)
const {
733 Hybrid::forEach(Dune::range(std::tuple_size<ContainerMap>{}),
734 [&](
auto i){func(i, std::get<i>(_containers));}
738 template<
typename Functor>
739 void applyToCodims(Functor func) {
741 Hybrid::forEach(Dune::range(std::tuple_size<ContainerMap>{}),
742 [&](
auto i){func(i, std::get<i>(_containers));}
746 template<
typename Impl>
747 struct applyToCodim {
749 template<
typename I,
typename T>
750 void operator()(I i, T&& t)
const {
751 const int codim = I::value;
752 detail::applyIf<MDGridTraits::template Codim<codim>::supported,
const Impl>(
static_cast<const Impl&
>(*this)).
template apply<codim>(std::forward<T>(t));
757 struct resetPerCodim :
public applyToCodim<resetPerCodim> {
760 void apply(Containers<codim>& c)
const {
762 _traits.template setupSizeContainer<codim>(c.codimSizeMap);
763 c.indexMap.resize(LocalGeometryTypeIndex::size(dimension-codim));
764 c.sizeMap.resize(LocalGeometryTypeIndex::size(dimension-codim));
765 for (
auto gt : _his.types(codim)) {
766 const auto gt_index = LocalGeometryTypeIndex::index(gt);
769 c.indexMap[gt_index].resize(_his.size(gt));
770 }
else if (codim > 0) {
774 for (
auto& mapEntry : c.indexMap[gt_index])
775 mapEntry.domains.clear();
778 auto& size_map = c.sizeMap[gt_index];
779 _traits.template setupSizeContainer<codim>(size_map);
780 std::fill(size_map.begin(),size_map.end(),0);
783 c.multiIndexMap.clear();
786 resetPerCodim(
bool full,
const HostIndexSet& his,
const MDGridTraits& traits) :
793 const HostIndexSet& _his;
794 const MDGridTraits& _traits;
797 void reset(
bool full) {
798 const HostIndexSet& his = _hostGridView.indexSet();
800 ContainerMap cm = ContainerMap();
801 std::swap(_containers,cm);
803 applyToCodims(resetPerCodim(full,his,_grid._traits));
806 struct updatePerCodimSizes :
public applyToCodim<updatePerCodimSizes> {
809 void apply(Containers<codim>& c)
const {
811 std::fill(c.codimSizeMap.begin(),c.codimSizeMap.end(),0);
813 std::for_each(c.sizeMap.begin(),
815 util::collect_elementwise<std::plus<IndexType> >(c.codimSizeMap));
820 void update(LevelIndexSets& levelIndexSets,
bool full) {
821 const HostIndexSet& his = _hostGridView.indexSet();
823 for (
typename LevelIndexSets::iterator it = levelIndexSets.begin(); it != levelIndexSets.end(); ++it) {
827 this->communicateSubDomainSelection();
829 typename Containers<0>::IndexMap& im = indexMap<0>();
830 typename Containers<0>::SizeMap& sm = sizeMap<0>();
831 for (
const auto& he : elements(_hostGridView)) {
832 auto geo = he.geometry();
833 auto hgt = geo.type();
834 const auto hgt_index = LocalGeometryTypeIndex::index(hgt);
835 IndexType hostIndex = his.index(he);
836 MapEntry<0>& me = im[hgt_index][hostIndex];
838 if (_grid.supportLevelIndexSets()) {
839 levelIndexSets[he.level()]->template indexMap<0>()[hgt_index][levelIndexSets[he.level()]->_hostGridView.indexSet().index(he)].domains.addAll(me.domains);
840 markAncestors(levelIndexSets,he,me.domains);
842 updateMapEntry(me,sm[hgt_index],multiIndexMap<0>());
843 applyToCodims(markSubIndices(he,me.domains,his,geo));
846 propagateBorderEntitySubDomains();
848 applyToCodims(updateSubIndices(*
this));
849 applyToCodims(updatePerCodimSizes());
850 for(
typename LevelIndexSets::iterator it = levelIndexSets.begin(); it != levelIndexSets.end(); ++it) {
851 (*it)->updateLevelIndexSet();
856 void updateLevelIndexSet() {
857 const HostIndexSet& his = _hostGridView.indexSet();
858 typename Containers<0>::IndexMap& im = indexMap<0>();
859 typename Containers<0>::SizeMap& sm = sizeMap<0>();
861 communicateSubDomainSelection();
863 for (
const auto& he : elements(_hostGridView)) {
864 auto geo = he.geometry();
865 const GeometryType hgt = geo.type();
866 const auto hgt_index = LocalGeometryTypeIndex::index(hgt);
867 IndexType hostIndex = his.index(he);
868 MapEntry<0>& me = im[hgt_index][hostIndex];
869 updateMapEntry(me,sm[hgt_index],multiIndexMap<0>());
870 applyToCodims(markSubIndices(he,me.domains,his,geo));
873 propagateBorderEntitySubDomains();
875 applyToCodims(updateSubIndices(*
this));
876 applyToCodims(updatePerCodimSizes());
879 template<
int codim,
typename SizeContainer,
typename MultiIndexContainer>
880 void updateMapEntry(MapEntry<codim>& me, SizeContainer& sizes, std::vector<MultiIndexContainer>& multiIndexMap) {
881 switch (me.domains.state()) {
882 case MapEntry<codim>::SubDomainSet::emptySet:
884 case MapEntry<codim>::SubDomainSet::simpleSet:
885 me.index = sizes[*me.domains.begin()]++;
887 case MapEntry<codim>::SubDomainSet::multipleSet:
888 me.index = multiIndexMap.size();
889 multiIndexMap.push_back(MultiIndexContainer());
890 MultiIndexContainer& mic = multiIndexMap.back();
891 for (
typename SubDomainSet::Iterator it = me.domains.begin(); it != me.domains.end(); ++it) {
892 mic[me.domains.domainOffset(*it)] = sizes[*it]++;
897 template<
typename SubDomainSet>
898 void markAncestors(LevelIndexSets& levelIndexSets, HostEntity he,
const SubDomainSet& domains) {
899 while (he.level() > 0) {
901 SubDomainSet& fatherDomains =
902 levelIndexSets[he.level()]->template indexMap<0>()[LocalGeometryTypeIndex::index(he.type())][levelIndexSets[he.level()]->_hostGridView.indexSet().index(he)].domains;
903 if (fatherDomains.containsAll(domains))
905 fatherDomains.addAll(domains);
909 struct markSubIndices :
public applyToCodim<const markSubIndices> {
912 void apply(Containers<codim>& c)
const {
915 const int size = _refEl.size(codim);
916 for (
int i = 0; i <
size; ++i) {
917 IndexType hostIndex = _his.subIndex(_he,i,codim);
918 GeometryType gt = _refEl.type(i,codim);
919 c.indexMap[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.addAll(_domains);
923 typedef typename MapEntry<0>::SubDomainSet& DomainSet;
925 const HostEntity& _he;
927 const HostIndexSet& _his;
928 CellReferenceElement _refEl;
930 markSubIndices(
const HostEntity& he, DomainSet& domains,
const HostIndexSet& his,
const typename HostEntity::Geometry& geo) :
934 _refEl(referenceElement(geo))
939 struct updateSubIndices :
public applyToCodim<const updateSubIndices> {
942 void apply(Containers<codim>& c)
const {
945 for (std::size_t gt_index = 0,
946 gt_end = c.indexMap.size();
949 for (
auto& im_entry : c.indexMap[gt_index])
950 _indexSet.updateMapEntry(im_entry,c.sizeMap[gt_index],c.multiIndexMap);
955 updateSubIndices(ThisType& indexSet) :
961 struct getSupportsCodim :
public dispatchToCodim<getSupportsCodim,bool,false> {
964 bool invoke()
const {
965 return MDGridTraits::template Codim<codim>::supported && Dune::Capabilities::hasEntity<HostGrid,codim>::v;
970 bool supportsCodim(
int codim)
const
972 return getSupportsCodim().dispatch(codim);
975 template<
typename Impl>
976 struct SubDomainSetDataHandleBase
977 :
public Dune::CommDataHandleIF<Impl,
978 typename MapEntry<0>::SubDomainSet::DataHandle::DataType
981 typedef typename MapEntry<0>::SubDomainSet SubDomainSet;
982 typedef typename SubDomainSet::DataHandle DataHandle;
984 bool fixedSize(
int dim,
int codim)
const
986 return DataHandle::fixedSize(dim,codim);
989 template<
typename Entity>
990 std::size_t
size(
const Entity& e)
const
992 return MapEntry<Entity::codimension>::SubDomainSet::DataHandle::size(_indexSet.subDomainsForHostEntity(e));
995 template<
typename MessageBufferImp,
typename Entity>
996 void gather(MessageBufferImp& buf,
const Entity& e)
const
998 MapEntry<Entity::codimension>::SubDomainSet::DataHandle::gather(buf,_indexSet.subDomainsForHostEntity(e));
1001 template<
typename MessageBufferImp,
typename Entity>
1002 void scatter(MessageBufferImp& buf,
const Entity& e, std::size_t n)
1004 MapEntry<Entity::codimension>::SubDomainSet::DataHandle::scatter(buf,_indexSet.subDomainsForHostEntity(e),n);
1007 SubDomainSetDataHandleBase(ThisType& indexSet)
1008 : _indexSet(indexSet)
1011 ThisType& _indexSet;
1015 struct SelectionDataHandle
1016 :
public SubDomainSetDataHandleBase<SelectionDataHandle>
1019 bool contains(
int dim,
int codim)
const
1024 SelectionDataHandle(ThisType& indexSet)
1025 : SubDomainSetDataHandleBase<SelectionDataHandle>(indexSet)
1030 struct BorderPropagationDataHandle
1031 :
public SubDomainSetDataHandleBase<BorderPropagationDataHandle>
1034 bool contains(
int dim,
int codim)
const
1036 return codim > 0 && this->_indexSet.supportsCodim(codim);
1039 BorderPropagationDataHandle(ThisType& indexSet)
1040 : SubDomainSetDataHandleBase<BorderPropagationDataHandle>(indexSet)
1046 void communicateSubDomainSelection()
1048 SelectionDataHandle dh(*
this);
1049 _hostGridView.template communicate<SelectionDataHandle>(dh,Dune::InteriorBorder_All_Interface,Dune::ForwardCommunication);
1052 void propagateBorderEntitySubDomains()
1054 BorderPropagationDataHandle dh(*
this);
1055 _hostGridView.communicate(dh,Dune::InteriorBorder_All_Interface,Dune::ForwardCommunication);
Definition: indexsets.hh:236
IndexType size(GeometryType type) const
Returns the number of entities with GeometryType type in the grid.
Definition: indexsets.hh:397
const MapEntry< EntityType::codimension >::SubDomainSet & subDomains(const EntityType &e) const
Returns a constant reference to the SubDomainSet of the given entity.
Definition: indexsets.hh:414
IndexType index(const typename Grid::Traits::template Codim< codim >::Entity &e) const
Returns the index of the entity with codimension codim.
Definition: indexsets.hh:368
IndexType index(const Entity &e) const
Returns the index of the entity.
Definition: indexsets.hh:374
IndexType index(SubDomainIndex subDomain, const typename Grid::Traits::template Codim< cc >::Entity &e) const
Definition: indexsets.hh:434
IndexType subIndex(const Entity &e, int i, unsigned int codim) const
Returns the subdindex of the i-th subentity of e with codimension codim.
Definition: indexsets.hh:386
IndexType index(SubDomainIndex subDomain, const EntityType &e) const
Returns the index of the entity in a specific subdomain.
Definition: indexsets.hh:427
Types types(int codim) const
Returns a list of all geometry types with codimension codim contained in the grid.
Definition: indexsets.hh:392
const MapEntry< cc >::SubDomainSet & subDomains(const typename Grid::Traits::template Codim< cc >::Entity &e) const
Definition: indexsets.hh:421
bool contains(const EntityType &e) const
Returns true if the entity is contained in the grid.
Definition: indexsets.hh:408
IndexType size(int codim) const
Returns the number of entities with codimension codim in the grid.
Definition: indexsets.hh:402
IndexType subIndex(const Entity &e, int i) const
Returns the subdindex of the i-th subentity of e with codimension codim.
Definition: indexsets.hh:380
bool contains(SubDomainIndex subDomain, const EntityType &e) const
Returns true if the entity is contained in a specific subdomain.
Definition: indexsets.hh:623
A meta grid for dividing an existing DUNE grid into subdomains that can be accessed as a grid in thei...
Definition: multidomaingrid.hh:241
An intersection that forms part of the interface between two subdomains.
Definition: subdomaininterfaceiterator.hh:32