Loading [MathJax]/extensions/tex2jax.js

DUNE MultiDomainGrid (unstable)

indexsets.hh
1#ifndef DUNE_MULTIDOMAINGRID_INDEXSETS_HH
2#define DUNE_MULTIDOMAINGRID_INDEXSETS_HH
3
4#include <map>
5#include <unordered_map>
6#include <vector>
7#include <array>
8#include <algorithm>
9#include <memory>
10#include <type_traits>
11#include <tuple>
12#include <optional>
13#include <utility>
14
15#include <dune/common/hybridutilities.hh>
16
17#include <dune/geometry/typeindex.hh>
18
19#include <dune/grid/common/exceptions.hh>
20#include <dune/grid/common/indexidset.hh>
21
22#include <dune/grid/multidomaingrid/utility.hh>
23#include <dune/grid/multidomaingrid/subdomaingrid/indexsets.hh>
24
25namespace Dune {
26
27namespace mdgrid {
28
29template<typename HostGrid, typename MDGridTraits>
30class MultiDomainGrid;
31
33
35namespace detail {
36
37template<template<int> class StructForCodim, typename Codims>
38struct _buildMap;
39
41template<template<int> class StructForCodim, std::size_t... codim>
42struct _buildMap<StructForCodim,std::index_sequence<codim...> > {
43
44 typedef std::tuple<StructForCodim<codim>... > type;
45
46};
47
48template<template<int> class StructForCodim, int dimension>
49struct buildMap {
50
51 typedef typename _buildMap<
52 StructForCodim,
53 decltype(std::make_index_sequence<dimension+1>())
54 >::type type;
55
56};
57
58}
59
61
113template<typename GridImp, typename HostGridViewType>
115 public Dune::IndexSet<GridImp,IndexSetWrapper<GridImp,HostGridViewType>,
116 typename HostGridViewType::IndexSet::IndexType,
117 typename HostGridViewType::IndexSet::Types>
118{
119
120 using Grid = std::remove_const_t<GridImp>;
121
122 template<typename, typename>
123 friend class IndexSetWrapper;
124
125 template<typename, typename>
126 friend class MultiDomainGrid;
127
128 template<typename, typename>
129 friend class subdomain::IndexSetWrapper;
130
131 template<typename, typename, typename, typename>
132 friend class SubDomainInterface;
133
134 template<typename>
135 friend class SubDomainToSubDomainController;
136
137 template<typename>
138 friend class AllInterfacesController;
139
141
142 using HostGrid = typename Grid::HostGrid;
143 typedef HostGridViewType HostGridView;
144 typedef typename HostGridView::IndexSet HostIndexSet;
145 using ctype = typename Grid::ctype;
146 using CellReferenceElement = Dune::ReferenceElement<typename HostGrid::template Codim<0>::Entity::Geometry>;
147
148 typedef Dune::IndexSet<
149 GridImp,
151 GridImp,
152 HostGridViewType
153 >,
154 typename HostGridViewType::IndexSet::IndexType,
155 typename HostGridViewType::IndexSet::Types
156 > BaseT;
157
158public:
159
160 typedef typename BaseT::Types Types;
161
162 using MDGridTraits = typename Grid::MDGridTraits;
163 typedef typename MDGridTraits::template Codim<0>::SubDomainSet SubDomainSet;
164 typedef typename MDGridTraits::SubDomainIndex SubDomainIndex;
165
166
167 typedef typename HostIndexSet::IndexType IndexType;
168 static const int dimension = Grid::dimension;
169 static const std::size_t maxSubDomains = SubDomainSet::maxSize;
170
171private:
172
173 typedef typename HostGridView::template Codim<0>::Iterator HostEntityIterator;
174 typedef typename HostGridView::template Codim<0>::Entity HostEntity;
175 using Codim0Entity = typename Grid::Traits::template Codim<0>::Entity;
176
177 template<int cc>
178 struct MapEntry {
179
180 typedef typename MDGridTraits::template Codim<cc>::SubDomainSet SubDomainSet;
181
182 SubDomainSet domains;
183 IndexType index;
184 };
185
187 struct NotSupported {};
188
189 template<int c>
190 struct Containers {
191 inline static const int codim = c;
192
193 inline static const bool supported = Grid::MDGridTraits::template Codim<codim>::supported;
194
195 static_assert((codim > 0 || supported), "index mapping of codimension 0 must be supported!");
196
197 using IndexMap = std::conditional_t<
198 supported,
199 std::vector<std::vector<MapEntry<codim> > >,
200 NotSupported
201 >;
202
203 using SizeMap = std::conditional_t<
204 supported,
205 std::vector<typename Grid::MDGridTraits::template Codim<codim>::SizeContainer>,
206 NotSupported
207 >;
208
209 using CodimSizeMap = std::conditional_t<
210 supported,
211 typename Grid::MDGridTraits::template Codim<codim>::SizeContainer,
212 NotSupported
213 >;
214
215 using MultiIndexMap = std::conditional_t<
216 supported,
217 std::vector<typename Grid::MDGridTraits::template Codim<codim>::MultiIndexContainer>,
218 NotSupported
219 >;
220
221 IndexMap indexMap;
222 SizeMap sizeMap;
223 CodimSizeMap codimSizeMap;
224 MultiIndexMap multiIndexMap;
225
226 // containers should not be assignable...
227 Containers& operator=(const Containers&) = delete;
228
229 // ...but must be movable
230 Containers& operator=(Containers&&) = default;
231
232 // make sure the compiler generates all necessary constructors...
233 Containers(const Containers&) = default;
234 Containers(Containers&&) = default;
235 Containers() = default;
236
237 };
238
239 typedef typename detail::buildMap<Containers,dimension>::type ContainerMap;
240
241 typedef std::vector<std::shared_ptr<IndexSetWrapper<GridImp, typename HostGridView::Grid::LevelGridView> > > LevelIndexSets;
242
243public:
244
246 template<int codim>
247 IndexType index(const typename Grid::Traits::template Codim<codim>::Entity& e) const {
248 return _hostGridView.indexSet().index(_grid.hostEntity(e));
249 }
250
252 template<typename Entity>
253 IndexType index(const Entity& e) const {
254 return _hostGridView.indexSet().index(_grid.hostEntity(e));
255 }
256
258 template<int codim>
259 IndexType subIndex(const typename Grid::Traits::template Codim<codim>::Entity& e, int i, unsigned int cd) const {
260 return _hostGridView.indexSet().template subIndex<codim>(_grid.hostEntity(e),i,cd);
261 }
262
264 template<typename Entity>
265 IndexType subIndex(const Entity& e, int i, unsigned int cd) const {
266 return _hostGridView.indexSet().subIndex(_grid.hostEntity(e),i,cd);
267 }
268
270 Types types(int codim) const {
271 return _hostGridView.indexSet().types(codim);
272 }
273
275 IndexType size(GeometryType type) const {
276 return _hostGridView.indexSet().size(type);
277 }
278
280 IndexType size(int codim) const {
281 return _hostGridView.indexSet().size(codim);
282 }
283
285 template<typename EntityType>
286 bool contains(const EntityType& e) const {
287 return _hostGridView.indexSet().contains(_grid.hostEntity(e));
288 }
289
291 template<typename EntityType>
292 const typename MapEntry<EntityType::codimension>::SubDomainSet& subDomains(const EntityType& e) const {
293 return subDomainsForHostEntity(_grid.hostEntity(e));
294 }
295
298 template<int cc>
299 const typename MapEntry<cc>::SubDomainSet& subDomains(const typename Grid::Traits::template Codim<cc>::Entity& e) const {
300 return subDomainsForHostEntity<cc>(_grid.hostEntity(e));
301 }
302
304 template<class EntityType>
305 IndexType index(SubDomainIndex subDomain, const EntityType& e) const {
306 return index<EntityType::codimension>(subDomain,e);
307 }
308
311 template<int cc>
312 IndexType index(SubDomainIndex subDomain, const typename Grid::Traits::template Codim<cc>::Entity& e) const {
313 GeometryType gt = e.type();
314 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
315 const MapEntry<cc>& me = indexMap<cc>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
316 assert(me.domains.contains(subDomain));
317 if (me.domains.simple()) {
318 return me.index;
319 } else {
320 return multiIndexMap<cc>()[me.index][me.domains.domainOffset(subDomain)];
321 }
322 }
323
324private:
325
327 template<typename EntityType>
328 typename MapEntry<EntityType::codimension>::SubDomainSet& subDomains(const EntityType& e) {
329 return subDomainsForHostEntity(_grid.hostEntity(e));
330 }
331
334 template<int cc>
335 typename MapEntry<cc>::SubDomainSet& subDomains(const typename Grid::Traits::template Codim<cc>::Entity& e) {
336 return subDomainsForHostEntity<cc>(_grid.hostEntity(e));
337 }
338
340 template<typename HostEntity>
341 typename MapEntry<HostEntity::codimension>::SubDomainSet& subDomainsForHostEntity(const HostEntity& e) {
342 return subDomainsForHostEntity<HostEntity::codimension>(e);
343 }
344
347 template<int cc>
348 typename MapEntry<cc>::SubDomainSet& subDomainsForHostEntity(const typename Grid::HostGrid::Traits::template Codim<cc>::Entity& he) {
349 return indexMap<cc>()[LocalGeometryTypeIndex::index(he.type())][_hostGridView.indexSet().index(he)].domains;
350 }
351
353 template<typename HostEntity>
354 const typename MapEntry<HostEntity::codimension>::SubDomainSet& subDomainsForHostEntity(const HostEntity& e) const {
355 return subDomainsForHostEntity<HostEntity::codimension>(e);
356 }
357
360 template<int cc>
361 const typename MapEntry<cc>::SubDomainSet& subDomainsForHostEntity(const typename Grid::HostGrid::Traits::template Codim<cc>::Entity& he) const {
362 return indexMap<cc>()[LocalGeometryTypeIndex::index(he.type())][_hostGridView.indexSet().index(he)].domains;
363 }
364
365 template<int cc>
366 IndexType indexForSubDomain(SubDomainIndex subDomain, const typename Grid::HostGrid::Traits::template Codim<cc>::Entity& he) const {
367 const GeometryType gt = he.type();
368 const IndexType hostIndex = _hostGridView.indexSet().index(he);
369 const MapEntry<cc>& me = indexMap<cc>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
370 assert(me.domains.contains(subDomain));
371 if (me.domains.simple()) {
372 return me.index;
373 } else {
374 return multiIndexMap<cc>()[me.index][me.domains.domainOffset(subDomain)];
375 }
376 }
377
378 template<typename HostEntity>
379 IndexType subIndexForSubDomain(SubDomainIndex subDomain, const HostEntity& he, int i, int codim) const {
380 std::optional<IndexType> index;
381 auto gt = referenceElement(he.geometry()).type(i,codim - he.codimension);
382 auto hostIndex = _hostGridView.indexSet().subIndex(he,i,codim);
383 Dune::Hybrid::switchCases(std::make_index_sequence<dimension+1>{}, codim, [&](auto icodim){
384 if constexpr (MDGridTraits::template Codim<icodim>::supported) {
385 const MapEntry<icodim>& me = this->indexMap<icodim>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
386 assert(me.domains.contains(subDomain));
387 if (me.domains.simple()) {
388 index = me.index;
389 } else {
390 index = this->multiIndexMap<icodim>()[me.index][me.domains.domainOffset(subDomain)];
391 }
392 } else
393 DUNE_THROW(GridError,"invalid codimension specified");
394 });
395 assert(index.has_value());
396 return *index;
397 }
398
399 Types typesForSubDomain(SubDomainIndex subDomain, int codim) const {
400 return types(codim);
401 }
402
403 IndexType sizeForSubDomain(SubDomainIndex subDomain, GeometryType type) const {
404 std::optional<IndexType> index;
405 Dune::Hybrid::switchCases(Dune::range(index_constant<dimension+1>{}), dimension-type.dim(), [&](auto icodim){
406 if constexpr (MDGridTraits::template Codim<icodim>::supported)
407 index = this->sizeMap<icodim>()[LocalGeometryTypeIndex::index(type)][subDomain];
408 });
409 return index.value_or(0);
410 }
411
412 IndexType sizeForSubDomain(SubDomainIndex subDomain, int codim) const {
413 std::optional<IndexType> index;
414 Dune::Hybrid::switchCases(Dune::range(index_constant<dimension+1>{}), codim, [&](auto icodim){
415 if constexpr (MDGridTraits::template Codim<icodim>::supported)
416 index = this->codimSizes<icodim>()[subDomain];
417 });
418 return index.value_or(0);
419 }
420
421 template<typename EntityType>
422 bool containsForSubDomain(SubDomainIndex subDomain, const EntityType& he) const {
423 const GeometryType gt = he.type();
424 const IndexType hostIndex = _hostGridView.indexSet().index(he);
425 const MapEntry<EntityType::codimension>& me = indexMap<EntityType::codimension>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
426 return me.domains.contains(subDomain);
427 }
428
429public:
430
431 template<typename SubDomainEntity>
432 IndexType subIndex(SubDomainIndex subDomain, const SubDomainEntity& e, int i, int codim) const {
433 return subIndexForSubDomain(subDomain,_grid.hostEntity(e),i,codim);
434 }
435
436 Types types(SubDomainIndex subDomain, int codim) const {
437 return types(codim);
438 }
439
440 IndexType size(SubDomainIndex subDomain, GeometryType type) const {
441 return sizeForSubDomain(subDomain,type);
442 }
443
444 IndexType size(SubDomainIndex subDomain, int codim) const {
445 return sizeForSubDomain(subDomain,codim);
446 }
447
449 template<typename EntityType>
450 bool contains(SubDomainIndex subDomain, const EntityType& e) const {
451 const GeometryType gt = e.type();
452 const IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
453 const MapEntry<EntityType::codimension>& me = indexMap<EntityType::codimension>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
454 return me.domains.contains(subDomain);
455 }
456
457private:
458
459 const GridImp& _grid;
460 HostGridView _hostGridView;
461 ContainerMap _containers;
462
463 void swap(ThisType& rhs) {
464 assert(&_grid == &rhs._grid);
465 std::swap(_containers,rhs._containers);
466 }
467
468 void addToSubDomain(SubDomainIndex subDomain, const Codim0Entity& e) {
469 GeometryType gt = e.type();
470 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
471 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.add(subDomain);
472 }
473
474 void removeFromSubDomain(SubDomainIndex subDomain, const Codim0Entity& e) {
475 GeometryType gt = e.type();
476 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
477 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.remove(subDomain);
478 }
479
480 void removeFromAllSubDomains(const Codim0Entity& e) {
481 GeometryType gt = e.type();
482 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
483 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.clear();
484 }
485
486 void assignToSubDomain(SubDomainIndex subDomain, const Codim0Entity& e) {
487 GeometryType gt = e.type();
488 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
489 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.set(subDomain);
490 }
491
492 void addToSubDomains(const typename MDGridTraits::template Codim<0>::SubDomainSet& subDomains, const Codim0Entity& e) {
493 GeometryType gt = e.type();
494 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
495 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.addAll(subDomains);
496 }
497
498public:
499
500 // just make these public for std::make_shared() access
501
502 IndexSetWrapper(const GridImp& grid, HostGridView hostGridView) :
503 _grid(grid),
504 _hostGridView(hostGridView)
505 {}
506
507private:
508
509 explicit IndexSetWrapper(const ThisType& rhs) :
510 _grid(rhs._grid),
511 _hostGridView(rhs._hostGridView),
512 _containers(rhs._containers)
513 {}
514
515
518 template<int cc>
519 typename Containers<cc>::IndexMap& indexMap() {
520 return std::get<cc>(_containers).indexMap;
521 }
522
523 template<int cc>
524 typename Containers<cc>::SizeMap& sizeMap() {
525 return std::get<cc>(_containers).sizeMap;
526 }
527
528 template<int cc>
529 typename Containers<cc>::CodimSizeMap& codimSizes() {
530 return std::get<cc>(_containers).codimSizeMap;
531 }
532
533 template<int cc>
534 typename Containers<cc>::MultiIndexMap& multiIndexMap() {
535 return std::get<cc>(_containers).multiIndexMap;
536 }
537
538 template<int cc>
539 const typename Containers<cc>::IndexMap& indexMap() const {
540 return std::get<cc>(_containers).indexMap;
541 }
542
543 template<int cc>
544 const typename Containers<cc>::SizeMap& sizeMap() const {
545 return std::get<cc>(_containers).sizeMap;
546 }
547
548 template<int cc>
549 const typename Containers<cc>::CodimSizeMap& codimSizes() const {
550 return std::get<cc>(_containers).codimSizeMap;
551 }
552
553 template<int cc>
554 const typename Containers<cc>::MultiIndexMap& multiIndexMap() const {
555 return std::get<cc>(_containers).multiIndexMap;
556 }
557
558 template<typename Functor>
559 void forEachContainer(Functor func) const {
560 // static loop over container tuple
561 Hybrid::forEach(Dune::range(std::tuple_size<ContainerMap>{}),
562 [&](auto codim){
563 if constexpr (MDGridTraits::template Codim<codim>::supported)
564 func(std::get<codim>(_containers));
565 });
566 }
567
568 template<typename Functor>
569 void forEachContainer(Functor func) {
570 // static loop over container tuple
571 Hybrid::forEach(Dune::range(std::tuple_size<ContainerMap>{}),
572 [&](auto codim){
573 if constexpr (MDGridTraits::template Codim<codim>::supported)
574 func(std::get<codim>(_containers));
575 });
576 }
577
578 void reset(bool full) {
579 const HostIndexSet& his = _hostGridView.indexSet();
580 if (full) {
581 ContainerMap cm = ContainerMap();
582 std::swap(_containers,cm);
583 }
584 forEachContainer([&](auto& c){
585 // setup per-codim sizemap
586 constexpr int codim = std::decay_t<decltype(c)>::codim;
587 _grid._traits.template setupSizeContainer<codim>(c.codimSizeMap);
588 c.indexMap.resize(LocalGeometryTypeIndex::size(dimension-codim));
589 c.sizeMap.resize(LocalGeometryTypeIndex::size(dimension-codim));
590 for (auto gt : his.types(codim)) {
591 const auto gt_index = LocalGeometryTypeIndex::index(gt);
592 if (full) {
593 // resize index map
594 c.indexMap[gt_index].resize(his.size(gt));
595 } else if (codim > 0) {
596 // clear out marked state for codim > 0 (we cannot keep the old
597 // state for subentities, as doing so will leave stale entries if
598 // elements are removed from a subdomain
599 for (auto& mapEntry : c.indexMap[gt_index])
600 mapEntry.domains.clear();
601 }
602 // setup / reset SizeMap counter
603 auto& size_map = c.sizeMap[gt_index];
604 _grid._traits.template setupSizeContainer<codim>(size_map);
605 std::fill(size_map.begin(),size_map.end(),0);
606 }
607 // clear MultiIndexMap
608 c.multiIndexMap.clear();
609 });
610 }
611
612 struct updatePerCodimSizes {
613
614 template<int codim>
615 void operator()(Containers<codim>& c) const {
616 // reset size for this codim to zero
617 std::fill(c.codimSizeMap.begin(),c.codimSizeMap.end(),0);
618 // collect per-geometrytype sizes into codim size structure
619 std::for_each(c.sizeMap.begin(),
620 c.sizeMap.end(),
621 util::collect_elementwise<std::plus<IndexType> >(c.codimSizeMap));
622 }
623
624 };
625
626 void update(LevelIndexSets& levelIndexSets, bool full) {
627 const HostIndexSet& his = _hostGridView.indexSet();
628 // reset(full);
629 for (auto& levelIndexSet : levelIndexSets) {
630 levelIndexSet->reset(full);
631 }
632
633 this->communicateSubDomainSelection();
634
635 auto& im = indexMap<0>();
636 auto& sm = sizeMap<0>();
637 for (const auto& he : elements(_hostGridView)) {
638 // get map entry for host entity
639 auto geo = he.geometry();
640 auto hgt = geo.type();
641 const auto hgt_index = LocalGeometryTypeIndex::index(hgt);
642 IndexType hostIndex = his.index(he);
643 MapEntry<0>& me = im[hgt_index][hostIndex];
644
645 if (_grid.supportLevelIndexSets()) {
646 // include subdomain in entity lvl
647 IndexType hostLvlIndex = levelIndexSets[he.level()]->_hostGridView.indexSet().index(he);
648 levelIndexSets[he.level()]->template indexMap<0>()[hgt_index][hostLvlIndex].domains.addAll(me.domains);
649 // propagate subdomain to all ancestors
650 markAncestors(levelIndexSets,he,me.domains);
651 }
652 updateMapEntry(me,sm[hgt_index],multiIndexMap<0>());
653 forEachContainer(markSubIndices(he,me.domains,his,geo));
654 }
655
656 propagateBorderEntitySubDomains();
657
658 forEachContainer(updateSubIndices(*this));
659 forEachContainer(updatePerCodimSizes());
660 for(auto& levelIndexSet : levelIndexSets) {
661 levelIndexSet->updateLevelIndexSet();
662 }
663 }
664
665
666 void updateLevelIndexSet() {
667 const HostIndexSet& his = _hostGridView.indexSet();
668 typename Containers<0>::IndexMap& im = indexMap<0>();
669 typename Containers<0>::SizeMap& sm = sizeMap<0>();
670
671 communicateSubDomainSelection();
672
673 for (const auto& he : elements(_hostGridView)) {
674 auto geo = he.geometry();
675 const GeometryType hgt = geo.type();
676 const auto hgt_index = LocalGeometryTypeIndex::index(hgt);
677 IndexType hostIndex = his.index(he);
678 MapEntry<0>& me = im[hgt_index][hostIndex];
679 updateMapEntry(me,sm[hgt_index],multiIndexMap<0>());
680 forEachContainer(markSubIndices(he,me.domains,his,geo));
681 }
682
683 propagateBorderEntitySubDomains();
684
685 forEachContainer(updateSubIndices(*this));
686 forEachContainer(updatePerCodimSizes());
687 }
688
689 template<int codim, typename SizeContainer, typename MultiIndexContainer, typename Alloc>
690 void updateMapEntry(MapEntry<codim>& me, SizeContainer& sizes, std::vector<MultiIndexContainer, Alloc>& multiIndexMap) {
691 switch (me.domains.state()) {
692 case MapEntry<codim>::SubDomainSet::emptySet:
693 break;
694 case MapEntry<codim>::SubDomainSet::simpleSet:
695 me.index = sizes[*me.domains.begin()]++;
696 break;
697 case MapEntry<codim>::SubDomainSet::multipleSet:
698 me.index = multiIndexMap.size();
699 MultiIndexContainer mic;
700 for (const auto& subdomain : me.domains)
701 mic[me.domains.domainOffset(subdomain)] = sizes[subdomain]++;
702 multiIndexMap.push_back(std::move(mic));
703 }
704 }
705
706 template<typename SubDomainSet>
707 void markAncestors(LevelIndexSets& levelIndexSets, HostEntity he, const SubDomainSet& domains) {
708 while (he.level() > 0) {
709 he = he.father();
710 SubDomainSet& fatherDomains =
711 levelIndexSets[he.level()]->template indexMap<0>()[LocalGeometryTypeIndex::index(he.type())][levelIndexSets[he.level()]->_hostGridView.indexSet().index(he)].domains;
712 if (fatherDomains.containsAll(domains))
713 break;
714 fatherDomains.addAll(domains);
715 }
716 }
717
718 struct markSubIndices {
719
720 template<int codim>
721 void operator()(Containers<codim>& c) const {
722 if (codim == 0)
723 return;
724 const int size = _refEl.size(codim);
725 for (int i = 0; i < size; ++i) {
726 IndexType hostIndex = _his.subIndex(_he,i,codim);
727 GeometryType gt = _refEl.type(i,codim);
728 c.indexMap[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.addAll(_domains);
729 }
730 }
731
732 typedef typename MapEntry<0>::SubDomainSet& DomainSet;
733
734 const HostEntity& _he;
735 DomainSet& _domains;
736 const HostIndexSet& _his;
737 CellReferenceElement _refEl;
738
739 markSubIndices(const HostEntity& he, DomainSet& domains, const HostIndexSet& his, const typename HostEntity::Geometry& geo) :
740 _he(he),
741 _domains(domains),
742 _his(his),
743 _refEl(referenceElement(geo))
744 {}
745
746 };
747
748 struct updateSubIndices {
749
750 template<int codim>
751 void operator()(Containers<codim>& c) const {
752 if (codim == 0)
753 return;
754 for (std::size_t gt_index = 0,
755 gt_end = c.indexMap.size();
756 gt_index != gt_end;
757 ++gt_index)
758 for (auto& im_entry : c.indexMap[gt_index])
759 _indexSet.updateMapEntry(im_entry,c.sizeMap[gt_index],c.multiIndexMap);
760 }
761
762 ThisType& _indexSet;
763
764 updateSubIndices(ThisType& indexSet) :
765 _indexSet(indexSet)
766 {}
767 };
768
769 bool supportsCodim(int codim) const
770 {
771 auto codim_seq = std::make_index_sequence<dimension + 1>{};
772 return Dune::Hybrid::switchCases(codim_seq, codim, [&](auto icodim) {
773 return MDGridTraits::template Codim<icodim>::supported && Dune::Capabilities::hasEntity<HostGrid, icodim>::v;
774 }, []{
775 return false;
776 });
777 }
778
779 template<typename Impl>
780 struct SubDomainSetDataHandleBase
781 : public Dune::CommDataHandleIF<Impl,
782 typename MapEntry<0>::SubDomainSet::DataHandle::DataType
783 >
784 {
785 typedef typename MapEntry<0>::SubDomainSet SubDomainSet;
786 typedef typename SubDomainSet::DataHandle DataHandle;
787
788 bool fixedSize(int dim, int codim) const
789 {
790 return DataHandle::fixedSize(dim,codim);
791 }
792
793 template<typename Entity>
794 std::size_t size(const Entity& e) const
795 {
796 return MapEntry<Entity::codimension>::SubDomainSet::DataHandle::size(_indexSet.subDomainsForHostEntity(e));
797 }
798
799 template<typename MessageBufferImp, typename Entity>
800 void gather(MessageBufferImp& buf, const Entity& e) const
801 {
802 MapEntry<Entity::codimension>::SubDomainSet::DataHandle::gather(buf,_indexSet.subDomainsForHostEntity(e));
803 }
804
805 template<typename MessageBufferImp, typename Entity>
806 void scatter(MessageBufferImp& buf, const Entity& e, std::size_t n)
807 {
808 MapEntry<Entity::codimension>::SubDomainSet::DataHandle::scatter(buf,_indexSet.subDomainsForHostEntity(e),n);
809 }
810
811 SubDomainSetDataHandleBase(ThisType& indexSet)
812 : _indexSet(indexSet)
813 {}
814
815 ThisType& _indexSet;
816
817 };
818
819 struct SelectionDataHandle
820 : public SubDomainSetDataHandleBase<SelectionDataHandle>
821 {
822
823 bool contains(int dim, int codim) const
824 {
825 return codim == 0;
826 }
827
828 SelectionDataHandle(ThisType& indexSet)
829 : SubDomainSetDataHandleBase<SelectionDataHandle>(indexSet)
830 {}
831
832 };
833
834 struct BorderPropagationDataHandle
835 : public SubDomainSetDataHandleBase<BorderPropagationDataHandle>
836 {
837
838 bool contains(int dim, int codim) const
839 {
840 return codim > 0 && this->_indexSet.supportsCodim(codim);
841 }
842
843 BorderPropagationDataHandle(ThisType& indexSet)
844 : SubDomainSetDataHandleBase<BorderPropagationDataHandle>(indexSet)
845 {}
846
847 };
848
849
850 void communicateSubDomainSelection()
851 {
852 SelectionDataHandle dh(*this);
853 _hostGridView.template communicate<SelectionDataHandle>(dh,Dune::InteriorBorder_All_Interface,Dune::ForwardCommunication);
854 }
855
856 void propagateBorderEntitySubDomains()
857 {
858 BorderPropagationDataHandle dh(*this);
859 _hostGridView.communicate(dh,Dune::InteriorBorder_All_Interface,Dune::ForwardCommunication);
860 }
861
862};
863
864} // namespace mdgrid
865
866} // namespace Dune
867
868#endif // DUNE_MULTIDOMAINGRID_INDEXSETS_HH
Definition: indexsets.hh:118
IndexType size(GeometryType type) const
Returns the number of entities with GeometryType type in the grid.
Definition: indexsets.hh:275
const MapEntry< EntityType::codimension >::SubDomainSet & subDomains(const EntityType &e) const
Returns a constant reference to the SubDomainSet of the given entity.
Definition: indexsets.hh:292
IndexType index(const typename Grid::Traits::template Codim< codim >::Entity &e) const
Returns the index of the entity with codimension codim.
Definition: indexsets.hh:247
IndexType index(const Entity &e) const
Returns the index of the entity.
Definition: indexsets.hh:253
IndexType index(SubDomainIndex subDomain, const typename Grid::Traits::template Codim< cc >::Entity &e) const
Definition: indexsets.hh:312
IndexType index(SubDomainIndex subDomain, const EntityType &e) const
Returns the index of the entity in a specific subdomain.
Definition: indexsets.hh:305
Types types(int codim) const
Returns a list of all geometry types with codimension codim contained in the grid.
Definition: indexsets.hh:270
const MapEntry< cc >::SubDomainSet & subDomains(const typename Grid::Traits::template Codim< cc >::Entity &e) const
Definition: indexsets.hh:299
bool contains(const EntityType &e) const
Returns true if the entity is contained in the grid.
Definition: indexsets.hh:286
IndexType size(int codim) const
Returns the number of entities with codimension codim in the grid.
Definition: indexsets.hh:280
IndexType subIndex(const typename Grid::Traits::template Codim< codim >::Entity &e, int i, unsigned int cd) const
Returns the subdindex of the i-th subentity of e with codimension codim.
Definition: indexsets.hh:259
IndexType subIndex(const Entity &e, int i, unsigned int cd) const
Returns the subdindex of the i-th subentity of e with codimension codim.
Definition: indexsets.hh:265
bool contains(SubDomainIndex subDomain, const EntityType &e) const
Returns true if the entity is contained in a specific subdomain.
Definition: indexsets.hh:450
A meta grid for dividing an existing DUNE grid into subdomains that can be accessed as a grid in thei...
Definition: multidomaingrid.hh:243
An intersection that forms part of the interface between two subdomains.
Definition: subdomaininterfaceiterator.hh:32
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Apr 6, 22:49, 2025)