DUNE MultiDomainGrid (2.8)

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