Loading [MathJax]/extensions/tex2jax.js

DUNE MultiDomainGrid (2.9)

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 <utility>
13
14#include <dune/common/hybridutilities.hh>
15
16#include <dune/geometry/typeindex.hh>
17
18#include <dune/grid/common/exceptions.hh>
19#include <dune/grid/common/indexidset.hh>
20
21#include <dune/grid/multidomaingrid/utility.hh>
22#include <dune/grid/multidomaingrid/subdomaingrid/indexsets.hh>
23
24namespace Dune {
25
26namespace mdgrid {
27
28template<typename HostGrid, typename MDGridTraits>
29class MultiDomainGrid;
30
32
34namespace detail {
35
36template<template<int> class StructForCodim, typename Codims>
37struct _buildMap;
38
40template<template<int> class StructForCodim, std::size_t... codim>
41struct _buildMap<StructForCodim,std::index_sequence<codim...> > {
42
43 typedef std::tuple<StructForCodim<codim>... > type;
44
45};
46
47template<template<int> class StructForCodim, int dimension>
48struct buildMap {
49
50 typedef typename _buildMap<
51 StructForCodim,
52 decltype(std::make_index_sequence<dimension+1>())
53 >::type type;
54
55};
56
58
65template<bool doDispatch, typename Impl, typename resulttype,bool alternate_dispatch>
66struct invokeIf;
67
68template<typename Impl, typename resulttype, bool alternate_dispatch>
69struct invokeIf<true,Impl,resulttype,alternate_dispatch> {
70
71 typedef resulttype result_type;
72
73 template<int codim>
74 result_type invoke() {
75 return _impl.template invoke<codim>();
76 }
77
78 Impl& _impl;
79
80 invokeIf(Impl& impl) :
81 _impl(impl)
82 {}
83
84};
85
87template<typename Impl, typename resulttype>
88struct invokeIf<false,Impl, resulttype,false> {
89
90 typedef resulttype result_type;
91
92 template<int codim>
93 result_type invoke() {
94 DUNE_THROW(GridError,"codim not supported");
95 }
96
97 Impl& _impl;
98
99 invokeIf(Impl& impl) :
100 _impl(impl)
101 {}
102
103};
104
105template<typename Impl, typename resulttype>
106struct invokeIf<false,Impl, resulttype,true> {
107
108 typedef resulttype result_type;
109
110 template<int codim>
111 result_type invoke() {
112 return _impl.template invoke_unsupported<codim>();
113 }
114
115 Impl& _impl;
116
117 invokeIf(Impl& impl) :
118 _impl(impl)
119 {}
120
121};
122
124template<typename Impl, typename resulttype, typename MDGridTraits, int codim, bool protect = true, bool alternate_dispatch = false>
125struct dispatchToCodim
126 : public dispatchToCodim<Impl,resulttype,MDGridTraits,codim-1,protect,alternate_dispatch> {
127
128 typedef resulttype result_type;
129
130 result_type dispatch(int cc) {
131 if (cc == codim)
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);
134 }
135
136};
137
139template<typename Impl, typename resulttype, typename MDGridTraits, bool alternate_dispatch>
140struct dispatchToCodim<Impl,resulttype,MDGridTraits,0,true,alternate_dispatch> {
141
142 typedef resulttype result_type;
143
144 result_type dispatch(int cc) {
145 if (cc == 0)
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");
148 }
149
150};
151
153template<typename Impl, typename resulttype, typename MDGridTraits, 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> {
156
157 typedef resulttype result_type;
158
159 result_type dispatch(int cc) {
160 if (cc == codim)
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);
163 }
164
165};
166
168template<typename Impl, typename resulttype, typename MDGridTraits, bool alternate_dispatch>
169struct dispatchToCodim<Impl,resulttype,MDGridTraits,0,false,alternate_dispatch> {
170
171 typedef resulttype result_type;
172
173 result_type dispatch(int cc) {
174 if (cc == 0)
175 return static_cast<Impl&>(*this).template invoke<0>();
176 DUNE_THROW(GridError,"invalid codimension specified");
177 }
178
179};
180
186template<bool doApply, typename Impl>
187struct applyIf {
188
189 template<int codim, typename T>
190 void apply(T& t) const {
191 _impl.template apply<codim>(t);
192 }
193
194 Impl& _impl;
195
196 applyIf(Impl& impl) :
197 _impl(impl)
198 {}
199
200};
201
203template<typename Impl>
204struct applyIf<false,Impl> {
205
206 template<int codim, typename T>
207 void apply(T& t) const {
208 }
209
210 Impl& _impl;
211
212 applyIf(Impl& impl) :
213 _impl(impl)
214 {}
215
216};
217
219template<typename T>
220T& rw(const T& t) {
221 return const_cast<T&>(t);
222}
223
224}
225
227
231template<typename GridImp, typename HostGridViewType>
233 public Dune::IndexSet<GridImp,IndexSetWrapper<GridImp,HostGridViewType>,
234 typename HostGridViewType::IndexSet::IndexType,
235 typename HostGridViewType::IndexSet::Types>
236{
237
238 using Grid = std::remove_const_t<GridImp>;
239
240 template<typename, typename>
241 friend class IndexSetWrapper;
242
243 template<typename, typename>
244 friend class MultiDomainGrid;
245
246 template<typename, typename>
247 friend class subdomain::IndexSetWrapper;
248
249 template<typename, typename, typename, typename>
250 friend class SubDomainInterface;
251
252 template<typename>
253 friend class SubDomainToSubDomainController;
254
255 template<typename>
256 friend class AllInterfacesController;
257
259
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>;
265
266 typedef Dune::IndexSet<
267 GridImp,
269 GridImp,
270 HostGridViewType
271 >,
272 typename HostGridViewType::IndexSet::IndexType,
273 typename HostGridViewType::IndexSet::Types
274 > BaseT;
275
276public:
277
278 typedef typename BaseT::Types Types;
279
280 using MDGridTraits = typename Grid::MDGridTraits;
281 typedef typename MDGridTraits::template Codim<0>::SubDomainSet SubDomainSet;
282 typedef typename MDGridTraits::SubDomainIndex SubDomainIndex;
283
284
285 typedef typename HostIndexSet::IndexType IndexType;
286 static const int dimension = Grid::dimension;
287 static const std::size_t maxSubDomains = SubDomainSet::maxSize;
288
289private:
290
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;
294
295 template<int cc>
296 struct MapEntry {
297
298 typedef typename MDGridTraits::template Codim<cc>::SubDomainSet SubDomainSet;
299
300 SubDomainSet domains;
301 IndexType index;
302 };
303
305 struct NotSupported {};
306
307 template<int codim>
308 struct Containers {
309
310 static const bool supported = Grid::MDGridTraits::template Codim<codim>::supported;
311
312 static_assert((codim > 0 || supported), "index mapping of codimension 0 must be supported!");
313
314 using IndexMap = std::conditional_t<
315 supported,
316 std::vector<std::vector<MapEntry<codim> > >,
317 NotSupported
318 >;
319
320 using SizeMap = std::conditional_t<
321 supported,
322 std::vector<typename Grid::MDGridTraits::template Codim<codim>::SizeContainer>,
323 NotSupported
324 >;
325
326 using CodimSizeMap = std::conditional_t<
327 supported,
328 typename Grid::MDGridTraits::template Codim<codim>::SizeContainer,
329 NotSupported
330 >;
331
332 using MultiIndexMap = std::conditional_t<
333 supported,
334 std::vector<typename Grid::MDGridTraits::template Codim<codim>::MultiIndexContainer>,
335 NotSupported
336 >;
337
338 IndexMap indexMap;
339 SizeMap sizeMap;
340 CodimSizeMap codimSizeMap;
341 MultiIndexMap multiIndexMap;
342
343 // containers should not be assignable...
344 Containers& operator=(const Containers&) = delete;
345
346 // ...but must be movable
347 Containers& operator=(Containers&&) = default;
348
349 // make sure the compiler generates all necessary constructors...
350 Containers(const Containers&) = default;
351 Containers(Containers&&) = default;
352 Containers() = default;
353
354 };
355
356 typedef typename detail::buildMap<Containers,dimension>::type ContainerMap;
357
358 typedef std::vector<std::shared_ptr<IndexSetWrapper<GridImp, typename HostGridView::Grid::LevelGridView> > > LevelIndexSets;
359
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> {};
363
364public:
365
367 template<int codim>
368 IndexType index(const typename Grid::Traits::template Codim<codim>::Entity& e) const {
369 return _hostGridView.indexSet().index(_grid.hostEntity(e));
370 }
371
373 template<typename Entity>
374 IndexType index(const Entity& e) const {
375 return _hostGridView.indexSet().index(_grid.hostEntity(e));
376 }
377
379 template<int codim>
380 IndexType subIndex(const typename Grid::Traits::template Codim<codim>::Entity& e, int i, unsigned int cd) const {
381 return _hostGridView.indexSet().template subIndex<codim>(_grid.hostEntity(e),i,cd);
382 }
383
385 template<typename Entity>
386 IndexType subIndex(const Entity& e, int i, unsigned int cd) const {
387 return _hostGridView.indexSet().subIndex(_grid.hostEntity(e),i,cd);
388 }
389
391 Types types(int codim) const {
392 return _hostGridView.indexSet().types(codim);
393 }
394
396 IndexType size(GeometryType type) const {
397 return _hostGridView.indexSet().size(type);
398 }
399
401 IndexType size(int codim) const {
402 return _hostGridView.indexSet().size(codim);
403 }
404
406 template<typename EntityType>
407 bool contains(const EntityType& e) const {
408 return _hostGridView.indexSet().contains(_grid.hostEntity(e));
409 }
410
412 template<typename EntityType>
413 const typename MapEntry<EntityType::codimension>::SubDomainSet& subDomains(const EntityType& e) const {
414 return subDomainsForHostEntity(_grid.hostEntity(e));
415 }
416
419 template<int cc>
420 const typename MapEntry<cc>::SubDomainSet& subDomains(const typename Grid::Traits::template Codim<cc>::Entity& e) const {
421 return subDomainsForHostEntity<cc>(_grid.hostEntity(e));
422 }
423
425 template<class EntityType>
426 IndexType index(SubDomainIndex subDomain, const EntityType& e) const {
427 return index<EntityType::codimension>(subDomain,e);
428 }
429
432 template<int cc>
433 IndexType index(SubDomainIndex subDomain, const typename Grid::Traits::template Codim<cc>::Entity& e) const {
434 GeometryType gt = e.type();
435 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
436 const MapEntry<cc>& me = indexMap<cc>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
437 assert(me.domains.contains(subDomain));
438 if (me.domains.simple()) {
439 return me.index;
440 } else {
441 return multiIndexMap<cc>()[me.index][me.domains.domainOffset(subDomain)];
442 }
443 }
444
445private:
446
448 template<typename EntityType>
449 typename MapEntry<EntityType::codimension>::SubDomainSet& subDomains(const EntityType& e) {
450 return subDomainsForHostEntity(_grid.hostEntity(e));
451 }
452
455 template<int cc>
456 typename MapEntry<cc>::SubDomainSet& subDomains(const typename Grid::Traits::template Codim<cc>::Entity& e) {
457 return subDomainsForHostEntity<cc>(_grid.hostEntity(e));
458 }
459
461 template<typename HostEntity>
462 typename MapEntry<HostEntity::codimension>::SubDomainSet& subDomainsForHostEntity(const HostEntity& e) {
463 return subDomainsForHostEntity<HostEntity::codimension>(e);
464 }
465
468 template<int cc>
469 typename MapEntry<cc>::SubDomainSet& subDomainsForHostEntity(const typename Grid::HostGrid::Traits::template Codim<cc>::Entity& he) {
470 return indexMap<cc>()[LocalGeometryTypeIndex::index(he.type())][_hostGridView.indexSet().index(he)].domains;
471 }
472
474 template<typename HostEntity>
475 const typename MapEntry<HostEntity::codimension>::SubDomainSet& subDomainsForHostEntity(const HostEntity& e) const {
476 return subDomainsForHostEntity<HostEntity::codimension>(e);
477 }
478
481 template<int cc>
482 const typename MapEntry<cc>::SubDomainSet& subDomainsForHostEntity(const typename Grid::HostGrid::Traits::template Codim<cc>::Entity& he) const {
483 return indexMap<cc>()[LocalGeometryTypeIndex::index(he.type())][_hostGridView.indexSet().index(he)].domains;
484 }
485
486 template<int cc>
487 IndexType indexForSubDomain(SubDomainIndex subDomain, const typename Grid::HostGrid::Traits::template Codim<cc>::Entity& he) const {
488 const GeometryType gt = he.type();
489 const IndexType hostIndex = _hostGridView.indexSet().index(he);
490 const MapEntry<cc>& me = indexMap<cc>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
491 assert(me.domains.contains(subDomain));
492 if (me.domains.simple()) {
493 return me.index;
494 } else {
495 return multiIndexMap<cc>()[me.index][me.domains.domainOffset(subDomain)];
496 }
497 }
498
500 struct getSubIndexForSubDomain : public dispatchToCodim<getSubIndexForSubDomain,IndexType> {
501
502 template<int codim>
503 IndexType invoke() const {
504 const MapEntry<codim>& me = _indexSet.indexMap<codim>()[LocalGeometryTypeIndex::index(_gt)][_hostIndex];
505 assert(me.domains.contains(_subDomain));
506 if (me.domains.simple()) {
507 return me.index;
508 } else {
509 return _indexSet.multiIndexMap<codim>()[me.index][me.domains.domainOffset(_subDomain)];
510 }
511 }
512
513 SubDomainIndex _subDomain;
514 GeometryType _gt;
515 IndexType _hostIndex;
516 const ThisType& _indexSet;
517
518 getSubIndexForSubDomain(SubDomainIndex subDomain, GeometryType gt, IndexType hostIndex, const ThisType& indexSet) :
519 _subDomain(subDomain),
520 _gt(gt),
521 _hostIndex(hostIndex),
522 _indexSet(indexSet)
523 {}
524
525 };
526
527 template<typename HostEntity>
528 IndexType subIndexForSubDomain(SubDomainIndex subDomain, const HostEntity& he, int i, int codim) const {
529 return getSubIndexForSubDomain(subDomain,
530 referenceElement(he.geometry()).type(i,codim - he.codimension),
531 _hostGridView.indexSet().subIndex(he,i,codim),
532 *this).dispatch(codim);
533 }
534
535 Types typesForSubDomain(SubDomainIndex subDomain, int codim) const {
536 return types(codim);
537 }
538
539 struct getGeometryTypeSizeForSubDomain : public dispatchToCodim<getGeometryTypeSizeForSubDomain,IndexType,true,true> {
540
541 template<int codim>
542 IndexType invoke() const {
543 return _indexSet.sizeMap<codim>()[LocalGeometryTypeIndex::index(_gt)][_subDomain];
544 }
545
546 template<int codim>
547 IndexType invoke_unsupported() const {
548 return 0;
549 }
550
551 SubDomainIndex _subDomain;
552 GeometryType _gt;
553 const ThisType& _indexSet;
554
555 getGeometryTypeSizeForSubDomain(SubDomainIndex subDomain, GeometryType gt, const ThisType& indexSet) :
556 _subDomain(subDomain),
557 _gt(gt),
558 _indexSet(indexSet)
559 {}
560
561 };
562
563 IndexType sizeForSubDomain(SubDomainIndex subDomain, GeometryType type) const {
564 return getGeometryTypeSizeForSubDomain(subDomain,type,*this).dispatch(dimension-type.dim());
565 }
566
567 struct getCodimSizeForSubDomain : public dispatchToCodim<getCodimSizeForSubDomain,IndexType,true,true> {
568
569 template<int codim>
570 IndexType invoke() const {
571 return _indexSet.codimSizes<codim>()[_subDomain];
572 }
573
574 template<int codim>
575 IndexType invoke_unsupported() const {
576 return 0;
577 }
578
579 SubDomainIndex _subDomain;
580 const ThisType& _indexSet;
581
582 getCodimSizeForSubDomain(SubDomainIndex subDomain, const ThisType& indexSet) :
583 _subDomain(subDomain),
584 _indexSet(indexSet)
585 {}
586
587 };
588
589 IndexType sizeForSubDomain(SubDomainIndex subDomain, int codim) const {
590 return getCodimSizeForSubDomain(subDomain,*this).dispatch(codim);
591 }
592
593 template<typename EntityType>
594 bool containsForSubDomain(SubDomainIndex subDomain, const EntityType& he) const {
595 const GeometryType gt = he.type();
596 const IndexType hostIndex = _hostGridView.indexSet().index(he);
597 const MapEntry<EntityType::codimension>& me = indexMap<EntityType::codimension>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
598 return me.domains.contains(subDomain);
599 }
600
601public:
602
603 template<typename SubDomainEntity>
604 IndexType subIndex(SubDomainIndex subDomain, const SubDomainEntity& e, int i, int codim) const {
605 return subIndexForSubDomain(subDomain,_grid.hostEntity(e),i,codim);
606 }
607
608 Types types(SubDomainIndex subDomain, int codim) const {
609 return types(codim);
610 }
611
612 IndexType size(SubDomainIndex subDomain, GeometryType type) const {
613 return sizeForSubDomain(subDomain,type);
614 }
615
616 IndexType size(SubDomainIndex subDomain, int codim) const {
617 return sizeForSubDomain(subDomain,codim);
618 }
619
621 template<typename EntityType>
622 bool contains(SubDomainIndex subDomain, const EntityType& e) const {
623 const GeometryType gt = e.type();
624 const IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
625 const MapEntry<EntityType::codimension>& me = indexMap<EntityType::codimension>()[LocalGeometryTypeIndex::index(gt)][hostIndex];
626 return me.domains.contains(subDomain);
627 }
628
629private:
630
631 const GridImp& _grid;
632 HostGridView _hostGridView;
633 ContainerMap _containers;
634
635 void swap(ThisType& rhs) {
636 assert(&_grid == &rhs._grid);
637 std::swap(_containers,rhs._containers);
638 }
639
640 void addToSubDomain(SubDomainIndex subDomain, const Codim0Entity& e) {
641 GeometryType gt = e.type();
642 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
643 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.add(subDomain);
644 }
645
646 void removeFromSubDomain(SubDomainIndex subDomain, const Codim0Entity& e) {
647 GeometryType gt = e.type();
648 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
649 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.remove(subDomain);
650 }
651
652 void removeFromAllSubDomains(const Codim0Entity& e) {
653 GeometryType gt = e.type();
654 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
655 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.clear();
656 }
657
658 void assignToSubDomain(SubDomainIndex subDomain, const Codim0Entity& e) {
659 GeometryType gt = e.type();
660 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
661 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.set(subDomain);
662 }
663
664 void addToSubDomains(const typename MDGridTraits::template Codim<0>::SubDomainSet& subDomains, const Codim0Entity& e) {
665 GeometryType gt = e.type();
666 IndexType hostIndex = _hostGridView.indexSet().index(_grid.hostEntity(e));
667 indexMap<0>()[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.addAll(subDomains);
668 }
669
670public:
671
672 // just make these public for std::make_shared() access
673
674 IndexSetWrapper(const GridImp& grid, HostGridView hostGridView) :
675 _grid(grid),
676 _hostGridView(hostGridView)
677 {}
678
679private:
680
681 explicit IndexSetWrapper(const ThisType& rhs) :
682 _grid(rhs._grid),
683 _hostGridView(rhs._hostGridView),
684 _containers(rhs._containers)
685 {}
686
687
690 template<int cc>
691 typename Containers<cc>::IndexMap& indexMap() {
692 return std::get<cc>(_containers).indexMap;
693 }
694
695 template<int cc>
696 typename Containers<cc>::SizeMap& sizeMap() {
697 return std::get<cc>(_containers).sizeMap;
698 }
699
700 template<int cc>
701 typename Containers<cc>::CodimSizeMap& codimSizes() {
702 return std::get<cc>(_containers).codimSizeMap;
703 }
704
705 template<int cc>
706 typename Containers<cc>::MultiIndexMap& multiIndexMap() {
707 return std::get<cc>(_containers).multiIndexMap;
708 }
709
710 template<int cc>
711 const typename Containers<cc>::IndexMap& indexMap() const {
712 return std::get<cc>(_containers).indexMap;
713 }
714
715 template<int cc>
716 const typename Containers<cc>::SizeMap& sizeMap() const {
717 return std::get<cc>(_containers).sizeMap;
718 }
719
720 template<int cc>
721 const typename Containers<cc>::CodimSizeMap& codimSizes() const {
722 return std::get<cc>(_containers).codimSizeMap;
723 }
724
725 template<int cc>
726 const typename Containers<cc>::MultiIndexMap& multiIndexMap() const {
727 return std::get<cc>(_containers).multiIndexMap;
728 }
729
730 template<typename Functor>
731 void applyToCodims(Functor func) const {
732 // static loop over container tuple
733 Hybrid::forEach(Dune::range(std::tuple_size<ContainerMap>{}),
734 [&](auto i){func(i, std::get<i>(_containers));}
735 );
736 }
737
738 template<typename Functor>
739 void applyToCodims(Functor func) {
740 // static loop over container tuple
741 Hybrid::forEach(Dune::range(std::tuple_size<ContainerMap>{}),
742 [&](auto i){func(i, std::get<i>(_containers));}
743 );
744 }
745
746 template<typename Impl>
747 struct applyToCodim {
748
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));
753 }
754
755 };
756
757 struct resetPerCodim : public applyToCodim<resetPerCodim> {
758
759 template<int codim>
760 void apply(Containers<codim>& c) const {
761 // setup per-codim sizemap
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);
767 if (_full) {
768 // resize index map
769 c.indexMap[gt_index].resize(_his.size(gt));
770 } else if (codim > 0) {
771 // clear out marked state for codim > 0 (we cannot keep the old
772 // state for subentities, as doing so will leave stale entries if
773 // elements are removed from a subdomain
774 for (auto& mapEntry : c.indexMap[gt_index])
775 mapEntry.domains.clear();
776 }
777 // setup / reset SizeMap counter
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);
781 }
782 // clear MultiIndexMap
783 c.multiIndexMap.clear();
784 }
785
786 resetPerCodim(bool full, const HostIndexSet& his, const MDGridTraits& traits) :
787 _full(full),
788 _his(his),
789 _traits(traits)
790 {}
791
792 const bool _full;
793 const HostIndexSet& _his;
794 const MDGridTraits& _traits;
795 };
796
797 void reset(bool full) {
798 const HostIndexSet& his = _hostGridView.indexSet();
799 if (full) {
800 ContainerMap cm = ContainerMap();
801 std::swap(_containers,cm);
802 }
803 applyToCodims(resetPerCodim(full,his,_grid._traits));
804 }
805
806 struct updatePerCodimSizes : public applyToCodim<updatePerCodimSizes> {
807
808 template<int codim>
809 void apply(Containers<codim>& c) const {
810 // reset size for this codim to zero
811 std::fill(c.codimSizeMap.begin(),c.codimSizeMap.end(),0);
812 // collect per-geometrytype sizes into codim size structure
813 std::for_each(c.sizeMap.begin(),
814 c.sizeMap.end(),
815 util::collect_elementwise<std::plus<IndexType> >(c.codimSizeMap));
816 }
817
818 };
819
820 void update(LevelIndexSets& levelIndexSets, bool full) {
821 const HostIndexSet& his = _hostGridView.indexSet();
822 //reset(full);
823 for (auto& levelIndexSet : levelIndexSets) {
824 levelIndexSet->reset(full);
825 }
826
827 this->communicateSubDomainSelection();
828
829 auto& im = indexMap<0>();
830 auto& sm = sizeMap<0>();
831 for (const auto& he : elements(_hostGridView)) {
832 // get map entry for host entity
833 auto geo = he.geometry();
834 auto hgt = geo.type();
835 const auto hgt_index = LocalGeometryTypeIndex::index(hgt);
836 IndexType hostIndex = his.index(he);
837 MapEntry<0>& me = im[hgt_index][hostIndex];
838
839 if (_grid.supportLevelIndexSets()) {
840 // include subdomain in entity lvl
841 IndexType hostLvlIndex = levelIndexSets[he.level()]->_hostGridView.indexSet().index(he);
842 levelIndexSets[he.level()]->template indexMap<0>()[hgt_index][hostLvlIndex].domains.addAll(me.domains);
843 // propagate subdomain to all ancestors
844 markAncestors(levelIndexSets,he,me.domains);
845 }
846 updateMapEntry(me,sm[hgt_index],multiIndexMap<0>());
847 applyToCodims(markSubIndices(he,me.domains,his,geo));
848 }
849
850 propagateBorderEntitySubDomains();
851
852 applyToCodims(updateSubIndices(*this));
853 applyToCodims(updatePerCodimSizes());
854 for(auto& levelIndexSet : levelIndexSets) {
855 levelIndexSet->updateLevelIndexSet();
856 }
857 }
858
859
860 void updateLevelIndexSet() {
861 const HostIndexSet& his = _hostGridView.indexSet();
862 typename Containers<0>::IndexMap& im = indexMap<0>();
863 typename Containers<0>::SizeMap& sm = sizeMap<0>();
864
865 communicateSubDomainSelection();
866
867 for (const auto& he : elements(_hostGridView)) {
868 auto geo = he.geometry();
869 const GeometryType hgt = geo.type();
870 const auto hgt_index = LocalGeometryTypeIndex::index(hgt);
871 IndexType hostIndex = his.index(he);
872 MapEntry<0>& me = im[hgt_index][hostIndex];
873 updateMapEntry(me,sm[hgt_index],multiIndexMap<0>());
874 applyToCodims(markSubIndices(he,me.domains,his,geo));
875 }
876
877 propagateBorderEntitySubDomains();
878
879 applyToCodims(updateSubIndices(*this));
880 applyToCodims(updatePerCodimSizes());
881 }
882
883 template<int codim, typename SizeContainer, typename MultiIndexContainer>
884 void updateMapEntry(MapEntry<codim>& me, SizeContainer& sizes, std::vector<MultiIndexContainer>& multiIndexMap) {
885 switch (me.domains.state()) {
886 case MapEntry<codim>::SubDomainSet::emptySet:
887 break;
888 case MapEntry<codim>::SubDomainSet::simpleSet:
889 me.index = sizes[*me.domains.begin()]++;
890 break;
891 case MapEntry<codim>::SubDomainSet::multipleSet:
892 me.index = multiIndexMap.size();
893 MultiIndexContainer mic;
894 for (const auto& subdomain : me.domains)
895 mic[me.domains.domainOffset(subdomain)] = sizes[subdomain]++;
896 multiIndexMap.push_back(std::move(mic));
897 }
898 }
899
900 template<typename SubDomainSet>
901 void markAncestors(LevelIndexSets& levelIndexSets, HostEntity he, const SubDomainSet& domains) {
902 while (he.level() > 0) {
903 he = he.father();
904 SubDomainSet& fatherDomains =
905 levelIndexSets[he.level()]->template indexMap<0>()[LocalGeometryTypeIndex::index(he.type())][levelIndexSets[he.level()]->_hostGridView.indexSet().index(he)].domains;
906 if (fatherDomains.containsAll(domains))
907 break;
908 fatherDomains.addAll(domains);
909 }
910 }
911
912 struct markSubIndices : public applyToCodim<const markSubIndices> {
913
914 template<int codim>
915 void apply(Containers<codim>& c) const {
916 if (codim == 0)
917 return;
918 const int size = _refEl.size(codim);
919 for (int i = 0; i < size; ++i) {
920 IndexType hostIndex = _his.subIndex(_he,i,codim);
921 GeometryType gt = _refEl.type(i,codim);
922 c.indexMap[LocalGeometryTypeIndex::index(gt)][hostIndex].domains.addAll(_domains);
923 }
924 }
925
926 typedef typename MapEntry<0>::SubDomainSet& DomainSet;
927
928 const HostEntity& _he;
929 DomainSet& _domains;
930 const HostIndexSet& _his;
931 CellReferenceElement _refEl;
932
933 markSubIndices(const HostEntity& he, DomainSet& domains, const HostIndexSet& his, const typename HostEntity::Geometry& geo) :
934 _he(he),
935 _domains(domains),
936 _his(his),
937 _refEl(referenceElement(geo))
938 {}
939
940 };
941
942 struct updateSubIndices : public applyToCodim<const updateSubIndices> {
943
944 template<int codim>
945 void apply(Containers<codim>& c) const {
946 if (codim == 0)
947 return;
948 for (std::size_t gt_index = 0,
949 gt_end = c.indexMap.size();
950 gt_index != gt_end;
951 ++gt_index)
952 for (auto& im_entry : c.indexMap[gt_index])
953 _indexSet.updateMapEntry(im_entry,c.sizeMap[gt_index],c.multiIndexMap);
954 }
955
956 ThisType& _indexSet;
957
958 updateSubIndices(ThisType& indexSet) :
959 _indexSet(indexSet)
960 {}
961 };
962
964 struct getSupportsCodim : public dispatchToCodim<getSupportsCodim,bool,false> {
965
966 template<int codim>
967 bool invoke() const {
968 return MDGridTraits::template Codim<codim>::supported && Dune::Capabilities::hasEntity<HostGrid,codim>::v;
969 }
970
971 };
972
973 bool supportsCodim(int codim) const
974 {
975 return getSupportsCodim().dispatch(codim);
976 }
977
978 template<typename Impl>
979 struct SubDomainSetDataHandleBase
980 : public Dune::CommDataHandleIF<Impl,
981 typename MapEntry<0>::SubDomainSet::DataHandle::DataType
982 >
983 {
984 typedef typename MapEntry<0>::SubDomainSet SubDomainSet;
985 typedef typename SubDomainSet::DataHandle DataHandle;
986
987 bool fixedSize(int dim, int codim) const
988 {
989 return DataHandle::fixedSize(dim,codim);
990 }
991
992 template<typename Entity>
993 std::size_t size(const Entity& e) const
994 {
995 return MapEntry<Entity::codimension>::SubDomainSet::DataHandle::size(_indexSet.subDomainsForHostEntity(e));
996 }
997
998 template<typename MessageBufferImp, typename Entity>
999 void gather(MessageBufferImp& buf, const Entity& e) const
1000 {
1001 MapEntry<Entity::codimension>::SubDomainSet::DataHandle::gather(buf,_indexSet.subDomainsForHostEntity(e));
1002 }
1003
1004 template<typename MessageBufferImp, typename Entity>
1005 void scatter(MessageBufferImp& buf, const Entity& e, std::size_t n)
1006 {
1007 MapEntry<Entity::codimension>::SubDomainSet::DataHandle::scatter(buf,_indexSet.subDomainsForHostEntity(e),n);
1008 }
1009
1010 SubDomainSetDataHandleBase(ThisType& indexSet)
1011 : _indexSet(indexSet)
1012 {}
1013
1014 ThisType& _indexSet;
1015
1016 };
1017
1018 struct SelectionDataHandle
1019 : public SubDomainSetDataHandleBase<SelectionDataHandle>
1020 {
1021
1022 bool contains(int dim, int codim) const
1023 {
1024 return codim == 0;
1025 }
1026
1027 SelectionDataHandle(ThisType& indexSet)
1028 : SubDomainSetDataHandleBase<SelectionDataHandle>(indexSet)
1029 {}
1030
1031 };
1032
1033 struct BorderPropagationDataHandle
1034 : public SubDomainSetDataHandleBase<BorderPropagationDataHandle>
1035 {
1036
1037 bool contains(int dim, int codim) const
1038 {
1039 return codim > 0 && this->_indexSet.supportsCodim(codim);
1040 }
1041
1042 BorderPropagationDataHandle(ThisType& indexSet)
1043 : SubDomainSetDataHandleBase<BorderPropagationDataHandle>(indexSet)
1044 {}
1045
1046 };
1047
1048
1049 void communicateSubDomainSelection()
1050 {
1051 SelectionDataHandle dh(*this);
1052 _hostGridView.template communicate<SelectionDataHandle>(dh,Dune::InteriorBorder_All_Interface,Dune::ForwardCommunication);
1053 }
1054
1055 void propagateBorderEntitySubDomains()
1056 {
1057 BorderPropagationDataHandle dh(*this);
1058 _hostGridView.communicate(dh,Dune::InteriorBorder_All_Interface,Dune::ForwardCommunication);
1059 }
1060
1061};
1062
1063} // namespace mdgrid
1064
1065} // namespace Dune
1066
1067#endif // DUNE_MULTIDOMAINGRID_INDEXSETS_HH
Definition: indexsets.hh:236
IndexType size(GeometryType type) const
Returns the number of entities with GeometryType type in the grid.
Definition: indexsets.hh:396
const MapEntry< EntityType::codimension >::SubDomainSet & subDomains(const EntityType &e) const
Returns a constant reference to the SubDomainSet of the given entity.
Definition: indexsets.hh:413
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:433
IndexType index(SubDomainIndex subDomain, const EntityType &e) const
Returns the index of the entity in a specific subdomain.
Definition: indexsets.hh:426
Types types(int codim) const
Returns a list of all geometry types with codimension codim contained in the grid.
Definition: indexsets.hh:391
const MapEntry< cc >::SubDomainSet & subDomains(const typename Grid::Traits::template Codim< cc >::Entity &e) const
Definition: indexsets.hh:420
bool contains(const EntityType &e) const
Returns true if the entity is contained in the grid.
Definition: indexsets.hh:407
IndexType size(int codim) const
Returns the number of entities with codimension codim in the grid.
Definition: indexsets.hh:401
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:380
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:386
bool contains(SubDomainIndex subDomain, const EntityType &e) const
Returns true if the entity is contained in a specific subdomain.
Definition: indexsets.hh:622
A meta grid for dividing an existing DUNE grid into subdomains that can be accessed as a grid in thei...
Definition: multidomaingrid.hh:247
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)