DUNE MultiDomainGrid (2.9)

multidomaingrid.hh
1#ifndef DUNE_MULTIDOMAINGRID_MULTIDOMAINGRID_HH
2#define DUNE_MULTIDOMAINGRID_MULTIDOMAINGRID_HH
3
4#include <string>
5#include <memory>
6
7#include <dune/common/shared_ptr.hh>
8
9#include <dune/grid/common/grid.hh>
10
11#include <dune/grid/multidomaingrid/hostgridaccessor.hh>
12#include <dune/grid/multidomaingrid/subdomainset.hh>
13
14#include <dune/grid/multidomaingrid/subdomaingrid/subdomaingrid.hh>
15
16#include <dune/grid/multidomaingrid/geometry.hh>
17#include <dune/grid/multidomaingrid/localgeometry.hh>
18#include <dune/grid/multidomaingrid/entity.hh>
19#include <dune/grid/multidomaingrid/iterator.hh>
20#include <dune/grid/multidomaingrid/hierarchiciterator.hh>
21#include <dune/grid/multidomaingrid/intersection.hh>
22#include <dune/grid/multidomaingrid/intersectioniterator.hh>
23#include <dune/grid/multidomaingrid/idsets.hh>
24#include <dune/grid/multidomaingrid/indexsets.hh>
25#include <dune/grid/multidomaingrid/gridview.hh>
26#include <dune/grid/multidomaingrid/mdgridtraits.hh>
27
28#include <dune/grid/multidomaingrid/subdomaintosubdomaininterfaceiterator.hh>
29#include <dune/grid/multidomaingrid/allsubdomaininterfacesiterator.hh>
30
31namespace Dune {
32
33namespace mdgrid {
34
35template<typename HostGrid, typename MDGridTraits>
36class MultiDomainGrid;
37
38template<typename HostGrid, typename MDGridTraits>
39struct MultiDomainGridFamily {
40
41private:
42
43 static const int dim = HostGrid::dimension;
44 static const int dimw = HostGrid::dimensionworld;
45
46public:
47
48 struct Traits
49 {
51 using Grid = MultiDomainGrid<HostGrid,MDGridTraits>;
52
53
54 using LeafIntersection = Dune::Intersection<
55 const Grid,
56 IntersectionWrapper<
57 const Grid,
58 typename HostGrid::LeafGridView::Intersection
59 >
60 >;
61
62 using LevelIntersection = Dune::Intersection<
63 const Grid,
64 IntersectionWrapper<
65 const Grid,
66 typename HostGrid::LevelGridView::Intersection
67 >
68 >;
69
70 using LeafIntersectionIterator = Dune::IntersectionIterator<
71 const Grid,
72 IntersectionIteratorWrapper<
73 const Grid,
74 typename HostGrid::LeafGridView::IntersectionIterator
75 >,
76 IntersectionWrapper<
77 const Grid,
78 typename HostGrid::LeafGridView::Intersection
79 >
80 >;
81
82 using LevelIntersectionIterator = Dune::IntersectionIterator<
83 const Grid,
84 IntersectionIteratorWrapper<
85 const Grid,
86 typename HostGrid::LevelGridView::IntersectionIterator
87 >,
88 IntersectionWrapper<
89 const Grid,
90 typename HostGrid::LevelGridView::Intersection
91 >
92 >;
93
94
95 using HierarchicIterator = Dune::EntityIterator<
96 0,
97 const Grid,
98 HierarchicIteratorWrapper<
99 const Grid
100 >
101 >;
102
103
104 template <int cd>
105 struct Codim
106 {
107
108 using Geometry = Dune::Geometry<dim-cd, dimw, const Grid, GeometryWrapper>;
109 using LocalGeometry = Dune::Geometry<dim-cd, dimw, const Grid, LocalGeometryWrapper>;
110
111 using Entity = Dune::Entity<cd, dim, const Grid, EntityWrapper>;
112
113 using EntitySeed = EntitySeedWrapper<typename HostGrid::template Codim<cd>::EntitySeed>;
114
115 template <PartitionIteratorType pitype>
116 struct Partition
117 {
118
119 using LevelIterator = Dune::EntityIterator<
120 cd,
121 const Grid,
122 IteratorWrapper<
123 typename HostGrid::LevelGridView,
124 cd,
125 pitype,
126 const Grid
127 >
128 >;
129
130 using LeafIterator = Dune::EntityIterator<
131 cd,
132 const Grid,
133 IteratorWrapper<
134 typename HostGrid::LeafGridView,
135 cd,
136 pitype,
137 const Grid
138 >
139 >;
140 };
141
142 using LeafIterator = typename Partition< All_Partition >::LeafIterator;
143 using LevelIterator = typename Partition< All_Partition >::LevelIterator;
144
145 private:
146 friend class Dune::Entity<cd, dim, const Grid, EntityWrapper>;
147 };
148
149
150 using LevelGridView = Dune::GridView<LevelGridViewTraits<const Grid> >;
151 using LeafGridView = Dune::GridView<LeafGridViewTraits<const Grid> >;
152
153 using LevelIndexSet = IndexSetWrapper<const Grid, typename HostGrid::LevelGridView>;
154 using LeafIndexSet = IndexSetWrapper<const Grid, typename HostGrid::LeafGridView>;
155
156 using GlobalIdSet = IdSet<
157 const Grid,
158 IdSetWrapper<
159 const Grid,
160 typename HostGrid::Traits::GlobalIdSet
161 >,
162 typename HostGrid::Traits::GlobalIdSet::IdType
163 >;
164
165 using LocalIdSet = IdSet<
166 const Grid,
167 IdSetWrapper<
168 const Grid,
169 typename HostGrid::Traits::LocalIdSet
170 >,
171 typename HostGrid::Traits::LocalIdSet::IdType
172 >;
173
174 using CollectiveCommunication
175 [[deprecated("Use CommunicationType. Will be removed after release 2.9")]]
176 = typename HostGrid::CollectiveCommunication;
177
178 using Communication = typename HostGrid::Communication;
179
180 using LeafSubDomainInterfaceIterator = Dune::mdgrid::LeafSubDomainInterfaceIterator<const Grid>;
181 using LevelSubDomainInterfaceIterator = Dune::mdgrid::LevelSubDomainInterfaceIterator<const Grid>;
182
183 using LeafAllSubDomainInterfacesIterator = Dune::mdgrid::LeafAllSubDomainInterfacesIterator<const Grid>;
184 using LevelAllSubDomainInterfacesIterator = Dune::mdgrid::LevelAllSubDomainInterfacesIterator<const Grid>;
185
186 };
187
188};
189
190namespace Impl {
191
192 template<typename Grid, typename SI, bool max_subdomain_index_is_static>
193 struct MaxSubDomainIndexProvider
194 {
195
196 typedef SI SubDomainIndex;
197
198 const SubDomainIndex maxSubDomainIndex() const
199 {
200 return static_cast<const Grid*>(this)->traits().maxSubDomainIndex();
201 }
202
203 };
204
205 template<typename Grid, typename SI>
206 struct MaxSubDomainIndexProvider<Grid,SI,true>
207 {
208
209 typedef SI SubDomainIndex;
210
211 static constexpr SubDomainIndex maxSubDomainIndex()
212 {
213 return Grid::MDGridTraits::maxSubDomainIndex();
214 }
215
216 };
217
218}
219
220
222
227template<
228 typename HostGrid_,
229 typename MDGridTraitsType
230 >
232 : public GridDefaultImplementation<HostGrid_::dimension,
233 HostGrid_::dimensionworld,
234 typename HostGrid_::ctype,
235 MultiDomainGridFamily<
236 HostGrid_,
237 MDGridTraitsType
238 >
239 >,
240 public Impl::MaxSubDomainIndexProvider<MultiDomainGrid<
241 HostGrid_,
242 MDGridTraitsType
243 >,
244 typename MDGridTraitsType::SubDomainIndex,
245 MDGridTraitsType::maxSubDomainIndexIsStatic()
246 >
247{
248
249public:
250
251 using HostGrid = HostGrid_;
252
253private:
254
255
256 template<int codim, int dim, typename GridImp>
257 friend class EntityWrapper;
258
259 template<typename,int,PartitionIteratorType,typename>
260 friend class IteratorWrapper;
261
262 template<typename GridImp>
263 friend class HierarchicIteratorWrapper;
264
265 template<int mydim, int coorddim, typename GridImp>
266 friend class GeometryWrapper;
267
268 template<int mydim, int coorddim, typename GridImp>
269 friend class LocalGeometryWrapper;
270
271 template<typename GridImp, typename WrappedIndexSet>
272 friend class IndexSetWrapper;
273
274 template<typename GridImp, typename WrappedIdSet>
275 friend class IdSetWrapper;
276
277 template<typename GridImp>
278 friend struct detail::HostGridAccessor;
279
280 template<typename,typename>
281 friend class IntersectionIteratorWrapper;
282
283 template<typename,typename>
284 friend class IntersectionWrapper;
285
286 template<typename>
287 friend class subdomain::SubDomainGrid;
288
289 template<typename>
290 friend struct subdomain::SubDomainGridFamily;
291
292 template<int,int,typename>
293 friend class subdomain::EntityWrapperBase;
294
295 template<int,int,typename>
296 friend class subdomain::EntityWrapper;
297
298 template <typename>
300
301 template <typename>
303
304 template <typename>
306
307 template <typename>
309
310 template<typename,typename,typename,typename>
311 friend class SubDomainInterface;
312
313 template<typename,typename,typename>
314 friend class subdomain::IntersectionIteratorWrapper;
315
316 template<typename,typename,typename>
317 friend class subdomain::IntersectionWrapper;
318
319 template<typename>
320 friend class LeafGridView;
321
322 template<typename>
323 friend class LevelGridView;
324
325 typedef GridDefaultImplementation<HostGrid::dimension,
326 HostGrid::dimensionworld,
327 typename HostGrid::ctype,
328 MultiDomainGridFamily<HostGrid,MDGridTraitsType>
329 > BaseT;
330
332
334
336
337 typedef IdSetWrapper<const GridImp, typename HostGrid::Traits::GlobalIdSet> GlobalIdSetImp;
338
339 typedef IdSetWrapper<const GridImp, typename HostGrid::Traits::LocalIdSet> LocalIdSetImp;
340
341 enum State { stateFixed, stateMarking, statePreUpdate, statePostUpdate, statePreAdapt, statePostAdapt };
342
343 typedef GridImp ThisType;
344
345 using Base = GridDefaultImplementation<
346 HostGrid::dimension,
347 HostGrid::dimensionworld,
348 typename HostGrid::ctype,
349 MultiDomainGridFamily<
350 HostGrid,
351 MDGridTraitsType
352 >
353 >;
354
355public:
356
357 using Base::dimension;
358 using Base::dimensionworld;
359
360 typedef MultiDomainGridFamily<HostGrid,MDGridTraitsType> GridFamily;
361 typedef typename GridFamily::Traits Traits;
362 typedef MDGridTraitsType MDGridTraits;
363 typedef typename HostGrid::ctype ctype;
364
365private:
366
367 typedef std::map<typename Traits::LocalIdSet::IdType,typename MDGridTraits::template Codim<0>::SubDomainSet> AdaptationStateMap;
368
369 typedef std::map<typename Traits::GlobalIdSet::IdType,typename MDGridTraits::template Codim<0>::SubDomainSet> LoadBalanceStateMap;
370
371 // typedefs for extracting the host entity types from our own entities
372
373 template<typename Entity>
374 struct HostEntity {
375 typedef typename HostGrid::Traits::template Codim<Entity::codimension>::Entity type;
376 };
377
378 // typedefs for extracting the multidomain entity types from subdomain entities
379
380 template<typename Entity>
381 struct MultiDomainEntity {
382 typedef typename Traits::template Codim<Entity::codimension>::Entity type;
383 };
384
385public:
386
388 typedef typename MDGridTraits::SubDomainIndex SubDomainIndex;
389
391 static const std::size_t maxNumberOfSubDomains = MDGridTraits::maxSubDomainsPerCell;
392
393#ifdef DOXYGEN
395
400 {
401 return _traits.maxSubDomainIndex();
402 }
403#endif
404
405 static constexpr bool maxSubDomainIndexIsStatic()
406 {
407 return MDGridTraits::maxSubDomainIndexIsStatic();
408 }
409
411 typedef subdomain::SubDomainGrid<ThisType> SubDomainGrid;
412
413
415 typedef typename Traits::LeafSubDomainInterfaceIterator LeafSubDomainInterfaceIterator;
416
418 typedef typename Traits::LevelSubDomainInterfaceIterator LevelSubDomainInterfaceIterator;
419
421 typedef typename Traits::LeafAllSubDomainInterfacesIterator LeafAllSubDomainInterfacesIterator;
422
424 typedef typename Traits::LevelAllSubDomainInterfacesIterator LevelAllSubDomainInterfacesIterator;
425
429
434 explicit MultiDomainGrid(const std::shared_ptr<HostGrid>& hostGrid, bool supportLevelIndexSets = true) :
435 _hostGridPtr(hostGrid),
436 _hostGrid(*_hostGridPtr),
437 _traits(),
438 _leafIndexSet(*this,_hostGrid.leafGridView()),
439 _globalIdSet(*this),
440 _localIdSet(*this),
441 _state(stateFixed),
442 _adaptState(stateFixed),
443 _supportLevelIndexSets(supportLevelIndexSets),
444 _maxAssignedSubDomainIndex(0)
445 {
446 updateIndexSets();
447 }
448
450
456 explicit MultiDomainGrid(const std::shared_ptr<HostGrid>& hostGrid, const MDGridTraitsType& traits, bool supportLevelIndexSets = true) :
457 _hostGridPtr(hostGrid),
458 _hostGrid(*_hostGridPtr),
459 _traits(traits),
460 _leafIndexSet(*this,_hostGrid.leafGridView()),
461 _globalIdSet(*this),
462 _localIdSet(*this),
463 _state(stateFixed),
464 _adaptState(stateFixed),
465 _supportLevelIndexSets(supportLevelIndexSets),
466 _maxAssignedSubDomainIndex(0)
467 {
468 updateIndexSets();
469 }
470
471
475
480 explicit MultiDomainGrid(HostGrid& hostGrid, bool supportLevelIndexSets = true)
481 : MultiDomainGrid(stackobject_to_shared_ptr(hostGrid), supportLevelIndexSets)
482 {}
483
485
491 explicit MultiDomainGrid(HostGrid& hostGrid, const MDGridTraitsType& traits, bool supportLevelIndexSets = true)
492 : MultiDomainGrid{stackobject_to_shared_ptr(hostGrid), traits, supportLevelIndexSets}
493 {}
494
499
500 template<typename EntitySeed>
501 typename Traits::template Codim<EntitySeed::codimension>::Entity
502 entity(const EntitySeed& entitySeed) const
503 {
504 return {EntityWrapper<EntitySeed::codimension,dimension,const GridImp>(_hostGrid.entity(entitySeed.hostEntitySeed()))};
505 }
506
508 int maxLevel() const {
509 return _hostGrid.maxLevel();
510 }
511
512 template<int codim>
513 typename Traits::template Codim<codim>::LevelIterator lbegin(int level) const {
514 return {
515 IteratorWrapper<
516 typename HostGrid::LevelGridView,
517 codim,
518 All_Partition,
519 const GridImp
520 >(_hostGrid.levelGridView(level).template begin<codim>())
521 };
522 }
523
524 template<int codim>
525 typename Traits::template Codim<codim>::LevelIterator lend(int level) const {
526 return {
527 IteratorWrapper<
528 typename HostGrid::LevelGridView,
529 codim,
530 All_Partition,
531 const GridImp
532 >(_hostGrid.levelGridView(level).template end<codim>())
533 };
534 }
535
536 template<int codim, PartitionIteratorType pitype>
537 typename Traits::template Codim<codim>::template Partition<pitype>::LevelIterator lbegin(int level) const {
538 return {
539 IteratorWrapper<
540 typename HostGrid::LevelGridView,
541 codim,
542 pitype,
543 const GridImp
544 >(_hostGrid.levelGridView(level).template begin<codim,pitype>())
545 };
546 }
547
548 template<int codim, PartitionIteratorType pitype>
549 typename Traits::template Codim<codim>::template Partition<pitype>::LevelIterator lend(int level) const {
550 return {
551 IteratorWrapper<
552 typename HostGrid::LevelGridView,
553 codim,
554 pitype,
555 const GridImp
556 >(_hostGrid.levelGridView(level).template end<codim,pitype>())
557 };
558 }
559
560 template<int codim>
561 typename Traits::template Codim<codim>::LeafIterator leafbegin() const {
562 return {
563 IteratorWrapper<
564 typename HostGrid::LeafGridView,
565 codim,
566 All_Partition,
567 const GridImp
568 >(_hostGrid.leafGridView().template begin<codim>())
569 };
570 }
571
572 template<int codim>
573 typename Traits::template Codim<codim>::LeafIterator leafend() const {
574 return {
575 IteratorWrapper<
576 typename HostGrid::LeafGridView,
577 codim,
578 All_Partition,
579 const GridImp
580 >(_hostGrid.leafGridView().template end<codim>())
581 };
582 }
583
584 template<int codim, PartitionIteratorType pitype>
585 typename Traits::template Codim<codim>::template Partition<pitype>::LeafIterator leafbegin() const {
586 return {
587 IteratorWrapper<
588 typename HostGrid::LeafGridView,
589 codim,
590 pitype,
591 const GridImp
592 >(_hostGrid.leafGridView().template begin<codim,pitype>())
593 };
594 }
595
596 template<int codim, PartitionIteratorType pitype>
597 typename Traits::template Codim<codim>::template Partition<pitype>::LeafIterator leafend() const {
598 return {
599 IteratorWrapper<
600 typename HostGrid::LeafGridView,
601 codim,
602 pitype,
603 const GridImp
604 >(_hostGrid.leafGridView().template end<codim,pitype>())
605 };
606 }
612
622 return LeafSubDomainInterfaceIterator(*this,subDomain1,subDomain2);
623 }
624
627 return LeafSubDomainInterfaceIterator(*this,subDomain1,subDomain2,true);
628 }
629
631
642 return LevelSubDomainInterfaceIterator(*this,subDomain1,subDomain2,level);
643 }
644
646
650 return LevelSubDomainInterfaceIterator(*this,subDomain1,subDomain2,level,true);
651 }
652
654
670 }
671
674 return LeafAllSubDomainInterfacesIterator(*this,true);
675 }
676
678
695 return LevelAllSubDomainInterfacesIterator(*this,level);
696 }
697
699
703 return LevelAllSubDomainInterfacesIterator(*this,level,true);
704 }
709 int size(int level, int codim) const {
710 return _hostGrid.size(level,codim);
711 }
712
713 int size(int codim) const {
714 return _hostGrid.size(codim);
715 }
716
717 int size(int level, GeometryType type) const {
718 return _hostGrid.size(level,type);
719 }
720
721 int size(GeometryType type) const {
722 return _hostGrid.size(type);
723 }
724
725 const typename Traits::GlobalIdSet& globalIdSet() const {
726 return _globalIdSet;
727 }
728
729 const typename Traits::LocalIdSet& localIdSet() const {
730 return _localIdSet;
731 }
732
733 const typename Traits::LevelIndexSet& levelIndexSet(int level) const {
734 if (!_supportLevelIndexSets) {
735 DUNE_THROW(GridError,"level index set support not enabled for this grid");
736 }
737 assert(level <= maxLevel());
738 return *_levelIndexSets[level];
739 }
740
741 const typename Traits::LeafIndexSet& leafIndexSet() const {
742 return _leafIndexSet;
743 }
744
745 void globalRefine(int refCount) {
746 saveMultiDomainState();
747 _hostGrid.globalRefine(refCount);
748 updateIndexSets();
749 restoreMultiDomainState();
750 }
751
752 bool mark(int refCount, const typename Traits::template Codim<0>::Entity& e) {
753 assert(_state == stateFixed);
754 return _hostGrid.mark(refCount, hostEntity(e));
755 }
756
757 int getMark(const typename Traits::template Codim<0>::Entity& e) {
758 assert(_state == stateFixed);
759 return _hostGrid.getMark(hostEntity(e));
760 }
761
762 bool preAdapt() {
763 assert(_state == stateFixed && _adaptState == stateFixed);
764 _adaptState = statePreAdapt;
765 bool result = _hostGrid.preAdapt();
766 return result;
767 }
768
769 bool adapt() {
770 assert(_state == stateFixed && _adaptState == statePreAdapt);
771 _adaptState = statePostAdapt;
772 saveMultiDomainState();
773 bool result = _hostGrid.adapt();
774 updateIndexSets();
775 restoreMultiDomainState();
776 return result;
777 }
778
779 void postAdapt() {
780 assert(_state == stateFixed && _adaptState == statePostAdapt);
781 _adaptState = stateFixed;
782 _hostGrid.postAdapt();
783 }
784
785 int overlapSize(int level, int codim) const {
786 return _hostGrid.overlapSize(level,codim);
787 }
788
789 int overlapSize(int codim) const {
790 return _hostGrid.overlapSize(codim);
791 }
792
793 int ghostSize(int level, int codim) const {
794 return _hostGrid.ghostSize(level,codim);
795 }
796
797 int ghostSize(int codim) const {
798 return _hostGrid.ghostSize(codim);
799 }
800
801 const typename Traits::Communication& comm() const {
802 return _hostGrid.comm();
803 }
804
805 template<typename DataHandleImp, typename DataTypeImp>
806 void communicate (CommDataHandleIF<DataHandleImp,DataTypeImp> &data,
807 InterfaceType iftype,
808 CommunicationDirection dir,
809 int level) const
810 {
811 DataHandleWrapper<CommDataHandleIF<DataHandleImp,DataTypeImp> > datahandle(data,*this);
812 _hostGrid.levelGridView(level).communicate(datahandle,iftype,dir);
813 }
814
815 template<typename DataHandleImp, typename DataTypeImp>
816 void communicate (CommDataHandleIF<DataHandleImp,DataTypeImp> &data,
817 InterfaceType iftype,
818 CommunicationDirection dir) const
819 {
820 DataHandleWrapper<CommDataHandleIF<DataHandleImp,DataTypeImp> > datahandle(data,*this);
821 _hostGrid.leafGridView().communicate(datahandle,iftype,dir);
822 }
823
824 template<typename DataHandle>
825 bool loadBalance(DataHandle& dataHandle)
826 {
827 typedef typename MultiDomainGrid::LeafGridView GV;
828 GV gv = this->leafGridView();
829 typedef typename GV::template Codim<0>::Iterator Iterator;
830 typedef typename GV::template Codim<0>::Entity Entity;
831 typedef typename MDGridTraits::template Codim<0>::SubDomainSet SubDomainSet;
832 for (Iterator it = gv.template begin<0>(); it != gv.template end<0>(); ++it) {
833 const Entity& e = *it;
834 const SubDomainSet& subDomains = gv.indexSet().subDomains(e);
835 _loadBalanceStateMap[globalIdSet().id(e)] = subDomains;
836 }
837
838 LoadBalancingDataHandle<DataHandle> dataHandleWrapper(*this,dataHandle);
839 if (!_hostGrid.loadBalance(dataHandleWrapper))
840 return false;
841
842 this->startSubDomainMarking();
843
844 for (Iterator it = gv.template begin<0>(); it != gv.template end<0>(); ++it) {
845 _leafIndexSet.addToSubDomains(_loadBalanceStateMap[globalIdSet().id(*it)],*it);
846 }
847
848 this->preUpdateSubDomains();
849 this->updateSubDomains();
850 this->postUpdateSubDomains();
851
852 _loadBalanceStateMap.clear();
853
854 return true;
855 }
856
857 bool loadBalance()
858 {
859 EmptyDataHandle emptyDataHandle;
860 return loadBalance(emptyDataHandle);
861 }
862
863 size_t numBoundarySegments() const
864 {
865 return _hostGrid.numBoundarySegments();
866 }
867
873
882 assert(_state == stateFixed && _adaptState == stateFixed);
883 _tmpLeafIndexSet.reset(new LeafIndexSetImp(_leafIndexSet));
884 _tmpLeafIndexSet->reset(false);
885 _state = stateMarking;
886 }
887
889
897 assert(_state == stateMarking && _adaptState == stateFixed);
898 if (_supportLevelIndexSets) {
899 for (int l = 0; l <= maxLevel(); ++l) {
900 _tmpLevelIndexSets.push_back(std::make_shared<LevelIndexSetImp>(*this,_hostGrid.levelGridView(l)));
901 }
902 }
903 _tmpLeafIndexSet->update(_tmpLevelIndexSets,true);
904 _state = statePreUpdate;
905 }
906
908
912 assert(_state == statePreUpdate && _adaptState == stateFixed);
913 _leafIndexSet.swap(*_tmpLeafIndexSet);
914 if (_supportLevelIndexSets) {
915 for (int l = 0; l <= maxLevel(); ++l) {
916 _levelIndexSets[l]->swap(*_tmpLevelIndexSets[l]);
917 }
918 }
919 _state = statePostUpdate;
920 }
921
924 assert(_state == statePostUpdate && _adaptState == stateFixed);
925 _tmpLevelIndexSets.clear();
926 _tmpLeafIndexSet.reset(nullptr);
927 _state = stateFixed;
928 }
929
931 void addToSubDomain(SubDomainIndex subDomain, const typename Traits::template Codim<0>::Entity& e) {
932 assert(_state == stateMarking);
933 assert(e.isLeaf());
934 assert(e.partitionType() == Dune::InteriorEntity);
935 _maxAssignedSubDomainIndex = std::max(_maxAssignedSubDomainIndex,subDomain);
936 _tmpLeafIndexSet->addToSubDomain(subDomain,e);
937 }
938
940 void removeFromSubDomain(SubDomainIndex subDomain, const typename Traits::template Codim<0>::Entity& e) {
941 assert(_state == stateMarking);
942 assert(e.isLeaf());
943 assert(e.partitionType() == Dune::InteriorEntity);
944 _tmpLeafIndexSet->removeFromSubDomain(subDomain,e);
945 }
946
948 void assignToSubDomain(SubDomainIndex subDomain, const typename Traits::template Codim<0>::Entity& e) {
949 assert(_state == stateMarking);
950 assert(e.isLeaf());
951 assert(e.partitionType() == Dune::InteriorEntity);
952 _maxAssignedSubDomainIndex = std::max(_maxAssignedSubDomainIndex,subDomain);
953 _tmpLeafIndexSet->assignToSubDomain(subDomain,e);
954 }
955
957 void removeFromAllSubDomains(const typename Traits::template Codim<0>::Entity& e) {
958 assert(_state == stateMarking);
959 assert(e.isLeaf());
960 assert(e.partitionType() == Dune::InteriorEntity);
961 _tmpLeafIndexSet->removeFromAllSubDomains(e);
962 }
969 std::shared_ptr<SubDomainGrid>& subGridPointer = _subDomainGrids[subDomain];
970 if (!subGridPointer) {
971 subGridPointer.reset(new SubDomainGrid(const_cast<MultiDomainGrid&>(*this),subDomain));
972 }
973 return *subGridPointer;
974 }
975
978 std::shared_ptr<SubDomainGrid>& subGridPointer = _subDomainGrids[subDomain];
979 if (!subGridPointer) {
980 subGridPointer.reset(new SubDomainGrid(*this,subDomain));
981 }
982 return *subGridPointer;
983 }
984
986
993 {
994 return _maxAssignedSubDomainIndex;
995 }
996
999 return _supportLevelIndexSets;
1000 }
1006
1010 template<typename EntityType>
1011 static const typename HostEntity<EntityType>::type& hostEntity(const EntityType& e)
1012 {
1013 return e.impl().hostEntity();
1014 }
1015
1016 template<typename EntityType>
1017 static const typename MultiDomainEntity<EntityType>::type& multiDomainEntity(const EntityType& e)
1018 {
1019 return e.impl().multiDomainEntity();
1020 }
1021
1022 template<typename IntersectionType>
1023 static const auto& multiDomainIntersection(const IntersectionType& is) {
1024 return SubDomainGrid::multiDomainIntersection(is);
1025 }
1028 const MDGridTraits& traits() const
1029 {
1030 return _traits;
1031 }
1032
1033private:
1034
1035 const HostGrid& hostGrid() const
1036 {
1037 return _hostGrid;
1038 }
1039
1040 HostGrid& hostGrid()
1041 {
1042 return _hostGrid;
1043 }
1044
1045 std::shared_ptr<HostGrid> _hostGridPtr;
1046 HostGrid& _hostGrid;
1047 const MDGridTraitsType _traits;
1048
1049 std::vector<std::shared_ptr<LevelIndexSetImp> > _levelIndexSets;
1050 LeafIndexSetImp _leafIndexSet;
1051
1052 std::vector<std::shared_ptr<LevelIndexSetImp> > _tmpLevelIndexSets;
1053 std::unique_ptr<LeafIndexSetImp> _tmpLeafIndexSet;
1054
1055 GlobalIdSetImp _globalIdSet;
1056 LocalIdSetImp _localIdSet;
1057
1058 State _state;
1059 State _adaptState;
1060 const bool _supportLevelIndexSets;
1061
1062 mutable std::map<SubDomainIndex,std::shared_ptr<SubDomainGrid> > _subDomainGrids;
1063 SubDomainIndex _maxAssignedSubDomainIndex;
1064
1065 AdaptationStateMap _adaptationStateMap;
1066 LoadBalanceStateMap _loadBalanceStateMap;
1067
1068 void updateIndexSets() {
1069 // make sure we have enough LevelIndexSets
1070 if (_supportLevelIndexSets) {
1071 while (static_cast<int>(_levelIndexSets.size()) <= maxLevel()) {
1072 _levelIndexSets.push_back(std::make_shared<LevelIndexSetImp>(*this,_hostGrid.levelGridView(_levelIndexSets.size())));
1073 }
1074 // and make sure we don't have too many...
1075 if (static_cast<int>(_levelIndexSets.size()) > maxLevel() + 1)
1076 {
1077 _levelIndexSets.resize(maxLevel() + 1);
1078 }
1079 }
1080
1081 _leafIndexSet.reset(true);
1082 _leafIndexSet.update(_levelIndexSets,true);
1083
1084 _globalIdSet.update(_hostGrid.globalIdSet());
1085 _localIdSet.update(_hostGrid.localIdSet());
1086
1087 // rebuild level index sets on subgrids
1088 for (auto& subGridPair : _subDomainGrids)
1089 subGridPair.second->update();
1090 }
1091
1092 void saveMultiDomainState() {
1093 typedef typename ThisType::LeafGridView GV;
1094 GV gv = this->leafGridView();
1095 typedef typename GV::template Codim<0>::Entity Entity;
1096 typedef typename MDGridTraits::template Codim<0>::SubDomainSet SubDomainSet;
1097 for (const auto& e : elements(gv)) {
1098 const SubDomainSet& subDomains = gv.indexSet().subDomains(e);
1099 _adaptationStateMap[localIdSet().id(e)] = subDomains;
1100 Entity he(e);
1101 while (he.mightVanish()) {
1102 he = he.father();
1103 typename Traits::LocalIdSet::IdType id = localIdSet().id(he);
1104 // if the entity has not been added to the set, create a new entry
1105 // (entity returns false and does not change the map if there is already an entry for "id")
1106 if (!_adaptationStateMap.insert(typename AdaptationStateMap::value_type(id,subDomains)).second) {
1107 // otherwise add the leaf entity's subdomains to the existing set of subdomains
1108 _adaptationStateMap[id].addAll(subDomains);
1109 }
1110 }
1111 }
1112 }
1113
1114 void restoreMultiDomainState() {
1115 typedef typename ThisType::LeafGridView GV;
1116 GV gv = this->leafGridView();
1117 typedef typename GV::template Codim<0>::Entity Entity;
1118 for (const auto& e : elements(gv)) {
1119 Entity he(e);
1120 // First try to exploit the information in the underlying grid
1121 while (he.isNew()) {
1122 he = he.father();
1123 }
1124 // This might not work, as there are no isNew() marks for globalrefine()
1125 // We thus have to look up the former leaf entity in our adaptation map
1126 typename AdaptationStateMap::iterator asmit = _adaptationStateMap.find(localIdSet().id(he));
1127 while(asmit == _adaptationStateMap.end()) {
1128 he = he.father();
1129 asmit = _adaptationStateMap.find(localIdSet().id(he));
1130 }
1131 _leafIndexSet.addToSubDomains(asmit->second, e);
1132 }
1133 _leafIndexSet.update(_levelIndexSets,false);
1134 _adaptationStateMap.clear();
1135 }
1136
1137 template<typename GridView, typename HostGridView>
1138 static typename GridView::IntersectionIterator multiDomainIntersectionIterator(typename HostGridView::IntersectionIterator iit) {
1139 typedef decltype(std::declval<typename GridView::IntersectionIterator>().impl()) Implementation;
1140 return Implementation(iit);
1141 }
1142
1143public:
1144
1145 template<typename Entity>
1146 typename Traits::template Codim<Entity::codimension>::Entity wrapHostEntity(const Entity& e) const {
1147 return wrapHostEntity<Entity::codimension>(e);
1148 }
1149
1150 template<int codim>
1151 typename Traits::template Codim<codim>::Entity wrapHostEntity(const typename HostGrid::template Codim<codim>::Entity& e) const
1152 {
1153 return {EntityWrapper<codim,dimension,const GridImp>(e)};
1154 }
1155
1156private:
1157
1158
1159 template<typename Impl>
1160 struct DataHandleWrapper
1161 : public Dune::CommDataHandleIF<DataHandleWrapper<Impl>,
1162 typename Impl::DataType
1163 >
1164 {
1165
1166 bool contains(int dim, int codim) const
1167 {
1168 return _impl.contains(dim,codim); // TODO: check if codim supported
1169 }
1170
1171 bool fixedSize(int dim, int codim) const
1172 {
1173 return _impl.fixedSize(dim,codim);
1174 }
1175
1176 template<typename Entity>
1177 std::size_t size(const Entity& e) const
1178 {
1179 return _impl.size(_grid.wrapHostEntity(e));
1180 }
1181
1182 template<typename MessageBufferImp, typename Entity>
1183 void gather(MessageBufferImp& buf, const Entity& e) const
1184 {
1185 _impl.gather(buf,_grid.wrapHostEntity(e));
1186 }
1187
1188 template<typename MessageBufferImp, typename Entity>
1189 void scatter(MessageBufferImp& buf, const Entity& e, std::size_t n)
1190 {
1191 _impl.scatter(buf,_grid.wrapHostEntity(e),n);
1192 }
1193
1194 DataHandleWrapper(Impl& impl, const MultiDomainGrid<HostGrid,MDGridTraitsType>& grid)
1195 : _impl(impl)
1196 , _grid(grid)
1197 {}
1198
1199 Impl& _impl;
1200 const MultiDomainGrid<HostGrid,MDGridTraitsType>& _grid;
1201
1202 };
1203
1204
1205 template<typename WrappedDataHandle>
1206 struct LoadBalancingDataHandle
1207 : public Dune::CommDataHandleIF<LoadBalancingDataHandle<WrappedDataHandle>,
1208 typename WrappedDataHandle::DataType
1209 >
1210 {
1211
1212 union Data
1213 {
1214 SubDomainIndex data;
1215 typename WrappedDataHandle::DataType buffer;
1216 };
1217
1218 static_assert(sizeof(Data) >= sizeof(SubDomainIndex),
1219 "During load balancing, the data type has to be large enough to contain MultiDomaingrid::SubDomainIndex");
1220
1221 bool contains(int dim, int codim) const
1222 {
1223 return (codim == 0)
1224 || _wrappedDataHandle.contains(dim,codim);
1225 }
1226
1227 bool fixedSize(int dim, int codim) const
1228 {
1229 return false;
1230 }
1231
1232 template<typename Entity>
1233 std::size_t size(const Entity& e) const
1234 {
1235 if (_grid.leafGridView().indexSet().contains(e) && e.partitionType() == Dune::InteriorEntity)
1236 return _grid.leafGridView().indexSet().subDomains(e).size() + 1 + _wrappedDataHandle.size(e);
1237 else
1238 return _wrappedDataHandle.size(e);
1239 }
1240
1241 template<typename MessageBufferImp, typename Entity>
1242 void gather(MessageBufferImp& buf, const Entity& e) const
1243 {
1244 assert(Entity::codimension == 0);
1245 if (e.partitionType() == Dune::InteriorEntity && _grid.leafGridView().indexSet().contains(e))
1246 {
1247 const auto& subDomains = _grid.leafGridView().indexSet().subDomains(e);
1248 Data size = { subDomains.size() };
1249 buf.write(size.buffer);
1250 for (auto& sub_domain : subDomains)
1251 {
1252 Data subDomain = { sub_domain };
1253 buf.write(subDomain.buffer);
1254 }
1255 }
1256 _wrappedDataHandle.gather(buf,e);
1257 }
1258
1259 template<typename MessageBufferImp, typename Entity>
1260 void scatter(MessageBufferImp& buf, const Entity& e, std::size_t n)
1261 {
1262 if (e.partitionType() != Dune::InteriorEntity && _grid.leafGridView().indexSet().contains(e))
1263 {
1264 Data subDomains = { 0 };
1265 buf.read(subDomains.buffer);
1266 for (int i = 0; i < subDomains.data; ++i)
1267 {
1268 Data subDomain = { 0 };
1269 buf.read(subDomain.buffer);
1270 _grid._loadBalanceStateMap[_grid.globalIdSet().id(multiDomainEntity(e))].add(subDomain.data);
1271 }
1272 _wrappedDataHandle.scatter(buf,e,n - (subDomains.data + 1));
1273 }
1274 else
1275 _wrappedDataHandle.scatter(buf,e,n);
1276 }
1277
1278 LoadBalancingDataHandle(MultiDomainGrid& grid, WrappedDataHandle& wrappedDataHandle)
1279 : _grid(grid)
1280 , _wrappedDataHandle(wrappedDataHandle)
1281 {}
1282
1283 MultiDomainGrid& _grid;
1284 WrappedDataHandle& _wrappedDataHandle;
1285
1286 };
1287
1288 struct EmptyDataHandle
1289 : public Dune::CommDataHandleIF<EmptyDataHandle,
1290 SubDomainIndex
1291 >
1292 {
1293
1294 bool contains(int dim, int codim) const
1295 {
1296 return false;
1297 }
1298
1299 bool fixedSize(int dim, int codim) const
1300 {
1301 return true;
1302 }
1303
1304 template<typename Entity>
1305 std::size_t size(const Entity& e) const
1306 {
1307 return 0;
1308 }
1309
1310 template<typename MessageBufferImp, typename Entity>
1311 void gather(MessageBufferImp& buf, const Entity& e) const
1312 {
1313 }
1314
1315 template<typename MessageBufferImp, typename Entity>
1316 void scatter(MessageBufferImp& buf, const Entity& e, std::size_t n)
1317 {
1318 }
1319
1320 };
1321
1322};
1323
1324enum MultiDomainGridType { multiDomainGrid, subDomainGrid, other };
1325
1326template<typename T>
1327struct GridType {
1328 static const MultiDomainGridType v = other;
1329};
1330
1331template<class HostGrid, typename MDGridTraits>
1332struct GridType<MultiDomainGrid<HostGrid,MDGridTraits> > {
1333 static const MultiDomainGridType v = multiDomainGrid;
1334};
1335
1336template<class MDGrid>
1337struct GridType<subdomain::SubDomainGrid<MDGrid> > {
1338 static const MultiDomainGridType v = subDomainGrid;
1339};
1340
1341} // namespace mdgrid
1342
1343} // namespace Dune
1344
1345#endif // DUNE_MULTIDOMAINGRID_MULTIDOMAINGRID_HH
Definition: indexsets.hh:236
A meta grid for dividing an existing DUNE grid into subdomains that can be accessed as a grid in thei...
Definition: multidomaingrid.hh:247
Traits::LeafAllSubDomainInterfacesIterator LeafAllSubDomainInterfacesIterator
The type of the iterators over the codim 1 interfaces between all subdomains on the leaf view.
Definition: multidomaingrid.hh:421
Traits::LevelAllSubDomainInterfacesIterator LevelAllSubDomainInterfacesIterator
The type of the iterators over the codim 1 interfaces between all subdomains on a level view.
Definition: multidomaingrid.hh:424
LevelAllSubDomainInterfacesIterator levelAllSubDomainInterfacesBegin(int level) const
Returns an iterator over all subdomain interfaces on the requested level view.
Definition: multidomaingrid.hh:694
MultiDomainGrid(HostGrid &hostGrid, const MDGridTraitsType &traits, bool supportLevelIndexSets=true)
Constructs a new MultiDomainGrid from the given host grid.
Definition: multidomaingrid.hh:491
Traits::LevelSubDomainInterfaceIterator LevelSubDomainInterfaceIterator
The type of the iterators over the codim 1 interface between two subdomains on a level view.
Definition: multidomaingrid.hh:418
static const HostEntity< EntityType >::type & hostEntity(const EntityType &e)
Returns a reference to the corresponding host entity.
Definition: multidomaingrid.hh:1011
void startSubDomainMarking()
Prepares the grid for (re-)assigning cells to subdomains.
Definition: multidomaingrid.hh:881
void updateSubDomains()
Switches the subdomain layout over to the new layout.
Definition: multidomaingrid.hh:911
const SubDomainIndex maxSubDomainIndex() const
The largest allowed index for a subdomain.
Definition: multidomaingrid.hh:399
void postUpdateSubDomains()
clears the saved state of the subdomain layout that was active before the last call to updateSubDomai...
Definition: multidomaingrid.hh:923
int maxLevel() const
The current maximum level of the grid.
Definition: multidomaingrid.hh:508
MDGridTraits::SubDomainIndex SubDomainIndex
The (integer) type used to identify subdomains.
Definition: multidomaingrid.hh:388
bool supportLevelIndexSets() const
Indicates whether this MultiDomainGrid instance supports level index sets on its SubDomainGrids.
Definition: multidomaingrid.hh:998
LeafSubDomainInterfaceIterator leafSubDomainInterfaceEnd(SubDomainIndex subDomain1, SubDomainIndex subDomain2) const
Returns the corresponding end iterator for leafSubDomainInterfaceBegin().
Definition: multidomaingrid.hh:626
LevelAllSubDomainInterfacesIterator levelAllSubDomainInterfacesEnd(int level) const
Returns the corresponding end iterator for levelAllSubDomainInterfacesBegin().
Definition: multidomaingrid.hh:702
MultiDomainGrid(const std::shared_ptr< HostGrid > &hostGrid, const MDGridTraitsType &traits, bool supportLevelIndexSets=true)
Constructs a new MultiDomainGrid from the given host grid.
Definition: multidomaingrid.hh:456
SubDomainIndex maxAssignedSubDomainIndex() const
Returns the largest subdomain index that was ever assigned to a cell in this grid.
Definition: multidomaingrid.hh:992
void assignToSubDomain(SubDomainIndex subDomain, const typename Traits::template Codim< 0 >::Entity &e)
Assigns the given leaf entity to the specified subdomain, clearing any previous subdomain assignments...
Definition: multidomaingrid.hh:948
LevelSubDomainInterfaceIterator levelSubDomainInterfaceBegin(SubDomainIndex subDomain1, SubDomainIndex subDomain2, int level) const
Returns an iterator over the interface of two subdomains at the given level.
Definition: multidomaingrid.hh:641
LeafSubDomainInterfaceIterator leafSubDomainInterfaceBegin(SubDomainIndex subDomain1, SubDomainIndex subDomain2) const
Returns an iterator over the leaf interface of two subdomains.
Definition: multidomaingrid.hh:621
void removeFromSubDomain(SubDomainIndex subDomain, const typename Traits::template Codim< 0 >::Entity &e)
Removes the given leaf entity from the specified subdomain.
Definition: multidomaingrid.hh:940
SubDomainGrid & subDomain(SubDomainIndex subDomain)
Returns a reference to the SubDomainGrid associated with the given subdomain.
Definition: multidomaingrid.hh:977
static const std::size_t maxNumberOfSubDomains
The largest number of subdomains any given grid cell may belong to.
Definition: multidomaingrid.hh:391
subdomain::SubDomainGrid< ThisType > SubDomainGrid
The type used for representing the grid of a subdomain, always a specialization of Dune::mdgrid::subd...
Definition: multidomaingrid.hh:411
void addToSubDomain(SubDomainIndex subDomain, const typename Traits::template Codim< 0 >::Entity &e)
Adds the given leaf entity to the specified subdomain.
Definition: multidomaingrid.hh:931
Traits::LeafSubDomainInterfaceIterator LeafSubDomainInterfaceIterator
The type of the iterators over the codim 1 interface between two subdomains on the leaf view.
Definition: multidomaingrid.hh:415
LeafAllSubDomainInterfacesIterator leafAllSubDomainInterfacesEnd() const
Returns the corresponding end iterator for leafAllSubDomainInterfacesBegin().
Definition: multidomaingrid.hh:673
void preUpdateSubDomains()
Calculates the new subdomain layout, but does not update the current subdomains yet.
Definition: multidomaingrid.hh:896
MultiDomainGrid(const std::shared_ptr< HostGrid > &hostGrid, bool supportLevelIndexSets=true)
Constructs a new MultiDomainGrid from the given host grid.
Definition: multidomaingrid.hh:434
void removeFromAllSubDomains(const typename Traits::template Codim< 0 >::Entity &e)
Removes the given leaf entity from all subdomains it currently belongs to.
Definition: multidomaingrid.hh:957
const SubDomainGrid & subDomain(SubDomainIndex subDomain) const
Returns a reference to the SubDomainGrid associated with the given subdomain.
Definition: multidomaingrid.hh:968
LevelSubDomainInterfaceIterator levelSubDomainInterfaceEnd(SubDomainIndex subDomain1, SubDomainIndex subDomain2, int level) const
Returns the corresponding end iterator for levelSubDomainInterfaceBegin().
Definition: multidomaingrid.hh:649
MultiDomainGrid(HostGrid &hostGrid, bool supportLevelIndexSets=true)
Constructs a new MultiDomainGrid from the given host grid.
Definition: multidomaingrid.hh:480
LeafAllSubDomainInterfacesIterator leafAllSubDomainInterfacesBegin() const
Returns an iterator over all subdomain interfaces on the leaf view.
Definition: multidomaingrid.hh:668
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 7, 22:57, 2025)