Loading [MathJax]/extensions/tex2jax.js

DUNE MultiDomainGrid (2.10)

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 Communication = typename HostGrid::Communication;
175
176 using LeafSubDomainInterfaceIterator = Dune::mdgrid::LeafSubDomainInterfaceIterator<const Grid>;
177 using LevelSubDomainInterfaceIterator = Dune::mdgrid::LevelSubDomainInterfaceIterator<const Grid>;
178
179 using LeafAllSubDomainInterfacesIterator = Dune::mdgrid::LeafAllSubDomainInterfacesIterator<const Grid>;
180 using LevelAllSubDomainInterfacesIterator = Dune::mdgrid::LevelAllSubDomainInterfacesIterator<const Grid>;
181
182 };
183
184};
185
186namespace Impl {
187
188 template<typename Grid, typename SI, bool max_subdomain_index_is_static>
189 struct MaxSubDomainIndexProvider
190 {
191
192 typedef SI SubDomainIndex;
193
194 const SubDomainIndex maxSubDomainIndex() const
195 {
196 return static_cast<const Grid*>(this)->traits().maxSubDomainIndex();
197 }
198
199 };
200
201 template<typename Grid, typename SI>
202 struct MaxSubDomainIndexProvider<Grid,SI,true>
203 {
204
205 typedef SI SubDomainIndex;
206
207 static constexpr SubDomainIndex maxSubDomainIndex()
208 {
209 return Grid::MDGridTraits::maxSubDomainIndex();
210 }
211
212 };
213
214}
215
216
218
223template<
224 typename HostGrid_,
225 typename MDGridTraitsType
226 >
228 : public GridDefaultImplementation<HostGrid_::dimension,
229 HostGrid_::dimensionworld,
230 typename HostGrid_::ctype,
231 MultiDomainGridFamily<
232 HostGrid_,
233 MDGridTraitsType
234 >
235 >,
236 public Impl::MaxSubDomainIndexProvider<MultiDomainGrid<
237 HostGrid_,
238 MDGridTraitsType
239 >,
240 typename MDGridTraitsType::SubDomainIndex,
241 MDGridTraitsType::maxSubDomainIndexIsStatic()
242 >
243{
244
245public:
246
247 using HostGrid = HostGrid_;
248
249private:
250
251
252 template<int codim, int dim, typename GridImp>
253 friend class EntityWrapper;
254
255 template<typename,int,PartitionIteratorType,typename>
256 friend class IteratorWrapper;
257
258 template<typename GridImp>
259 friend class HierarchicIteratorWrapper;
260
261 template<int mydim, int coorddim, typename GridImp>
262 friend class GeometryWrapper;
263
264 template<int mydim, int coorddim, typename GridImp>
265 friend class LocalGeometryWrapper;
266
267 template<typename GridImp, typename WrappedIndexSet>
268 friend class IndexSetWrapper;
269
270 template<typename GridImp, typename WrappedIdSet>
271 friend class IdSetWrapper;
272
273 template<typename GridImp>
274 friend struct detail::HostGridAccessor;
275
276 template<typename,typename>
277 friend class IntersectionIteratorWrapper;
278
279 template<typename,typename>
280 friend class IntersectionWrapper;
281
282 template<typename>
283 friend class subdomain::SubDomainGrid;
284
285 template<typename>
286 friend struct subdomain::SubDomainGridFamily;
287
288 template<int,int,typename>
289 friend class subdomain::EntityWrapperBase;
290
291 template<int,int,typename>
292 friend class subdomain::EntityWrapper;
293
294 template <typename>
296
297 template <typename>
299
300 template <typename>
302
303 template <typename>
305
306 template<typename,typename,typename,typename>
307 friend class SubDomainInterface;
308
309 template<typename,typename,typename>
310 friend class subdomain::IntersectionIteratorWrapper;
311
312 template<typename,typename,typename>
313 friend class subdomain::IntersectionWrapper;
314
315 template<typename>
316 friend class LeafGridView;
317
318 template<typename>
319 friend class LevelGridView;
320
321 typedef GridDefaultImplementation<HostGrid::dimension,
322 HostGrid::dimensionworld,
323 typename HostGrid::ctype,
324 MultiDomainGridFamily<HostGrid,MDGridTraitsType>
325 > BaseT;
326
328
330
332
333 typedef IdSetWrapper<const GridImp, typename HostGrid::Traits::GlobalIdSet> GlobalIdSetImp;
334
335 typedef IdSetWrapper<const GridImp, typename HostGrid::Traits::LocalIdSet> LocalIdSetImp;
336
337 enum State { stateFixed, stateMarking, statePreUpdate, statePostUpdate, statePreAdapt, statePostAdapt };
338
339 typedef GridImp ThisType;
340
341 using Base = GridDefaultImplementation<
342 HostGrid::dimension,
343 HostGrid::dimensionworld,
344 typename HostGrid::ctype,
345 MultiDomainGridFamily<
346 HostGrid,
347 MDGridTraitsType
348 >
349 >;
350
351public:
352
353 using Base::dimension;
354 using Base::dimensionworld;
355
356 typedef MultiDomainGridFamily<HostGrid,MDGridTraitsType> GridFamily;
357 typedef typename GridFamily::Traits Traits;
358 typedef MDGridTraitsType MDGridTraits;
359 typedef typename HostGrid::ctype ctype;
360
361private:
362
363 typedef std::map<typename Traits::LocalIdSet::IdType,typename MDGridTraits::template Codim<0>::SubDomainSet> AdaptationStateMap;
364
365 typedef std::map<typename Traits::GlobalIdSet::IdType,typename MDGridTraits::template Codim<0>::SubDomainSet> LoadBalanceStateMap;
366
367 // typedefs for extracting the host entity types from our own entities
368
369 template<typename Entity>
370 struct HostEntity {
371 typedef typename HostGrid::Traits::template Codim<Entity::codimension>::Entity type;
372 };
373
374 // typedefs for extracting the multidomain entity types from subdomain entities
375
376 template<typename Entity>
377 struct MultiDomainEntity {
378 typedef typename Traits::template Codim<Entity::codimension>::Entity type;
379 };
380
381public:
382
384 typedef typename MDGridTraits::SubDomainIndex SubDomainIndex;
385
387 static const std::size_t maxNumberOfSubDomains = MDGridTraits::maxSubDomainsPerCell;
388
389#ifdef DOXYGEN
391
396 {
397 return _traits.maxSubDomainIndex();
398 }
399#endif
400
401 static constexpr bool maxSubDomainIndexIsStatic()
402 {
403 return MDGridTraits::maxSubDomainIndexIsStatic();
404 }
405
407 typedef subdomain::SubDomainGrid<ThisType> SubDomainGrid;
408
409
411 typedef typename Traits::LeafSubDomainInterfaceIterator LeafSubDomainInterfaceIterator;
412
414 typedef typename Traits::LevelSubDomainInterfaceIterator LevelSubDomainInterfaceIterator;
415
417 typedef typename Traits::LeafAllSubDomainInterfacesIterator LeafAllSubDomainInterfacesIterator;
418
420 typedef typename Traits::LevelAllSubDomainInterfacesIterator LevelAllSubDomainInterfacesIterator;
421
425
430 explicit MultiDomainGrid(const std::shared_ptr<HostGrid>& hostGridPtr, bool supportLevelIndexSets = true) :
431 _hostGridPtr(hostGridPtr),
432 _traits(),
433 _leafIndexSet(*this,hostGrid().leafGridView()),
434 _globalIdSet(*this),
435 _localIdSet(*this),
436 _state(stateFixed),
437 _adaptState(stateFixed),
438 _supportLevelIndexSets(supportLevelIndexSets),
439 _maxAssignedSubDomainIndex(0)
440 {
441 updateIndexSets();
442 }
443
445
451 explicit MultiDomainGrid(const std::shared_ptr<HostGrid>& hostGridPtr, const MDGridTraitsType& traits, bool supportLevelIndexSets = true) :
452 _hostGridPtr(hostGridPtr),
453 _traits(traits),
454 _leafIndexSet(*this,hostGrid().leafGridView()),
455 _globalIdSet(*this),
456 _localIdSet(*this),
457 _state(stateFixed),
458 _adaptState(stateFixed),
459 _supportLevelIndexSets(supportLevelIndexSets),
460 _maxAssignedSubDomainIndex(0)
461 {
462 updateIndexSets();
463 }
464
465
469
474 explicit MultiDomainGrid(HostGrid& hostGrid, bool supportLevelIndexSets = true)
475 : MultiDomainGrid(stackobject_to_shared_ptr(hostGrid), supportLevelIndexSets)
476 {}
477
479
485 explicit MultiDomainGrid(HostGrid& hostGrid, const MDGridTraitsType& traits, bool supportLevelIndexSets = true)
486 : MultiDomainGrid{stackobject_to_shared_ptr(hostGrid), traits, supportLevelIndexSets}
487 {}
488
493
494 template<typename EntitySeed>
495 typename Traits::template Codim<EntitySeed::codimension>::Entity
496 entity(const EntitySeed& entitySeed) const
497 {
498 return {EntityWrapper<EntitySeed::codimension,dimension,const GridImp>(hostGrid().entity(entitySeed.hostEntitySeed()))};
499 }
500
502 int maxLevel() const {
503 return hostGrid().maxLevel();
504 }
505
506 template<int codim>
507 typename Traits::template Codim<codim>::LevelIterator lbegin(int level) const {
508 return {
509 IteratorWrapper<
510 typename HostGrid::LevelGridView,
511 codim,
512 All_Partition,
513 const GridImp
514 >(hostGrid().levelGridView(level).template begin<codim>())
515 };
516 }
517
518 template<int codim>
519 typename Traits::template Codim<codim>::LevelIterator lend(int level) const {
520 return {
521 IteratorWrapper<
522 typename HostGrid::LevelGridView,
523 codim,
524 All_Partition,
525 const GridImp
526 >(hostGrid().levelGridView(level).template end<codim>())
527 };
528 }
529
530 template<int codim, PartitionIteratorType pitype>
531 typename Traits::template Codim<codim>::template Partition<pitype>::LevelIterator lbegin(int level) const {
532 return {
533 IteratorWrapper<
534 typename HostGrid::LevelGridView,
535 codim,
536 pitype,
537 const GridImp
538 >(hostGrid().levelGridView(level).template begin<codim,pitype>())
539 };
540 }
541
542 template<int codim, PartitionIteratorType pitype>
543 typename Traits::template Codim<codim>::template Partition<pitype>::LevelIterator lend(int level) const {
544 return {
545 IteratorWrapper<
546 typename HostGrid::LevelGridView,
547 codim,
548 pitype,
549 const GridImp
550 >(hostGrid().levelGridView(level).template end<codim,pitype>())
551 };
552 }
553
554 template<int codim>
555 typename Traits::template Codim<codim>::LeafIterator leafbegin() const {
556 return {
557 IteratorWrapper<
558 typename HostGrid::LeafGridView,
559 codim,
560 All_Partition,
561 const GridImp
562 >(hostGrid().leafGridView().template begin<codim>())
563 };
564 }
565
566 template<int codim>
567 typename Traits::template Codim<codim>::LeafIterator leafend() const {
568 return {
569 IteratorWrapper<
570 typename HostGrid::LeafGridView,
571 codim,
572 All_Partition,
573 const GridImp
574 >(hostGrid().leafGridView().template end<codim>())
575 };
576 }
577
578 template<int codim, PartitionIteratorType pitype>
579 typename Traits::template Codim<codim>::template Partition<pitype>::LeafIterator leafbegin() const {
580 return {
581 IteratorWrapper<
582 typename HostGrid::LeafGridView,
583 codim,
584 pitype,
585 const GridImp
586 >(hostGrid().leafGridView().template begin<codim,pitype>())
587 };
588 }
589
590 template<int codim, PartitionIteratorType pitype>
591 typename Traits::template Codim<codim>::template Partition<pitype>::LeafIterator leafend() const {
592 return {
593 IteratorWrapper<
594 typename HostGrid::LeafGridView,
595 codim,
596 pitype,
597 const GridImp
598 >(hostGrid().leafGridView().template end<codim,pitype>())
599 };
600 }
606
616 return LeafSubDomainInterfaceIterator(*this,subDomain1,subDomain2);
617 }
618
621 return LeafSubDomainInterfaceIterator(*this,subDomain1,subDomain2,true);
622 }
623
625
636 return LevelSubDomainInterfaceIterator(*this,subDomain1,subDomain2,level);
637 }
638
640
644 return LevelSubDomainInterfaceIterator(*this,subDomain1,subDomain2,level,true);
645 }
646
648
664 }
665
668 return LeafAllSubDomainInterfacesIterator(*this,true);
669 }
670
672
689 return LevelAllSubDomainInterfacesIterator(*this,level);
690 }
691
693
697 return LevelAllSubDomainInterfacesIterator(*this,level,true);
698 }
703 int size(int level, int codim) const {
704 return hostGrid().size(level,codim);
705 }
706
707 int size(int codim) const {
708 return hostGrid().size(codim);
709 }
710
711 int size(int level, GeometryType type) const {
712 return hostGrid().size(level,type);
713 }
714
715 int size(GeometryType type) const {
716 return hostGrid().size(type);
717 }
718
719 const typename Traits::GlobalIdSet& globalIdSet() const {
720 return _globalIdSet;
721 }
722
723 const typename Traits::LocalIdSet& localIdSet() const {
724 return _localIdSet;
725 }
726
727 const typename Traits::LevelIndexSet& levelIndexSet(int level) const {
728 if (!_supportLevelIndexSets) {
729 DUNE_THROW(GridError,"level index set support not enabled for this grid");
730 }
731 assert(level <= maxLevel());
732 return *_levelIndexSets[level];
733 }
734
735 const typename Traits::LeafIndexSet& leafIndexSet() const {
736 return _leafIndexSet;
737 }
738
739 void globalRefine(int refCount) {
740 saveMultiDomainState();
741 hostGrid().globalRefine(refCount);
742 updateIndexSets();
743 restoreMultiDomainState();
744 }
745
746 bool mark(int refCount, const typename Traits::template Codim<0>::Entity& e) {
747 assert(_state == stateFixed);
748 return hostGrid().mark(refCount, hostEntity(e));
749 }
750
751 int getMark(const typename Traits::template Codim<0>::Entity& e) {
752 assert(_state == stateFixed);
753 return hostGrid().getMark(hostEntity(e));
754 }
755
756 bool preAdapt() {
757 assert(_state == stateFixed && _adaptState == stateFixed);
758 _adaptState = statePreAdapt;
759 bool result = hostGrid().preAdapt();
760 return result;
761 }
762
763 bool adapt() {
764 assert(_state == stateFixed && _adaptState == statePreAdapt);
765 _adaptState = statePostAdapt;
766 saveMultiDomainState();
767 bool result = hostGrid().adapt();
768 updateIndexSets();
769 restoreMultiDomainState();
770 return result;
771 }
772
773 void postAdapt() {
774 assert(_state == stateFixed && _adaptState == statePostAdapt);
775 _adaptState = stateFixed;
776 hostGrid().postAdapt();
777 }
778
779 int overlapSize(int level, int codim) const {
780 return hostGrid().overlapSize(level,codim);
781 }
782
783 int overlapSize(int codim) const {
784 return hostGrid().overlapSize(codim);
785 }
786
787 int ghostSize(int level, int codim) const {
788 return hostGrid().ghostSize(level,codim);
789 }
790
791 int ghostSize(int codim) const {
792 return hostGrid().ghostSize(codim);
793 }
794
795 const typename Traits::Communication& comm() const {
796 return hostGrid().comm();
797 }
798
799 template<typename DataHandleImp, typename DataTypeImp>
800 void communicate (CommDataHandleIF<DataHandleImp,DataTypeImp> &data,
801 InterfaceType iftype,
802 CommunicationDirection dir,
803 int level) const
804 {
805 DataHandleWrapper<CommDataHandleIF<DataHandleImp,DataTypeImp> > datahandle(data,*this);
806 hostGrid().levelGridView(level).communicate(datahandle,iftype,dir);
807 }
808
809 template<typename DataHandleImp, typename DataTypeImp>
810 void communicate (CommDataHandleIF<DataHandleImp,DataTypeImp> &data,
811 InterfaceType iftype,
812 CommunicationDirection dir) const
813 {
814 DataHandleWrapper<CommDataHandleIF<DataHandleImp,DataTypeImp> > datahandle(data,*this);
815 hostGrid().leafGridView().communicate(datahandle,iftype,dir);
816 }
817
818 template<typename DataHandle>
819 bool loadBalance(DataHandle& dataHandle)
820 {
821 typedef typename MultiDomainGrid::LeafGridView GV;
822 GV gv = this->leafGridView();
823 typedef typename GV::template Codim<0>::Iterator Iterator;
824 typedef typename GV::template Codim<0>::Entity Entity;
825 typedef typename MDGridTraits::template Codim<0>::SubDomainSet SubDomainSet;
826 for (Iterator it = gv.template begin<0>(); it != gv.template end<0>(); ++it) {
827 const Entity& e = *it;
828 const SubDomainSet& subDomains = gv.indexSet().subDomains(e);
829 _loadBalanceStateMap[globalIdSet().id(e)] = subDomains;
830 }
831
832 LoadBalancingDataHandle<DataHandle> dataHandleWrapper(*this,dataHandle);
833 if (!hostGrid().loadBalance(dataHandleWrapper))
834 return false;
835
836 this->startSubDomainMarking();
837
838 for (Iterator it = gv.template begin<0>(); it != gv.template end<0>(); ++it) {
839 _leafIndexSet.addToSubDomains(_loadBalanceStateMap[globalIdSet().id(*it)],*it);
840 }
841
842 this->preUpdateSubDomains();
843 this->updateSubDomains();
844 this->postUpdateSubDomains();
845
846 _loadBalanceStateMap.clear();
847
848 return true;
849 }
850
851 bool loadBalance()
852 {
853 EmptyDataHandle emptyDataHandle;
854 return loadBalance(emptyDataHandle);
855 }
856
857 size_t numBoundarySegments() const
858 {
859 return hostGrid().numBoundarySegments();
860 }
861
867
876 assert(_state == stateFixed && _adaptState == stateFixed);
877 _tmpLeafIndexSet.reset(new LeafIndexSetImp(_leafIndexSet));
878 _tmpLeafIndexSet->reset(false);
879 _state = stateMarking;
880 }
881
883
891 assert(_state == stateMarking && _adaptState == stateFixed);
892 if (_supportLevelIndexSets) {
893 for (int l = 0; l <= maxLevel(); ++l) {
894 _tmpLevelIndexSets.push_back(std::make_shared<LevelIndexSetImp>(*this,hostGrid().levelGridView(l)));
895 }
896 }
897 _tmpLeafIndexSet->update(_tmpLevelIndexSets,true);
898 _state = statePreUpdate;
899 }
900
902
906 assert(_state == statePreUpdate && _adaptState == stateFixed);
907 _leafIndexSet.swap(*_tmpLeafIndexSet);
908 if (_supportLevelIndexSets) {
909 for (int l = 0; l <= maxLevel(); ++l) {
910 _levelIndexSets[l]->swap(*_tmpLevelIndexSets[l]);
911 }
912 }
913 _state = statePostUpdate;
914 }
915
918 assert(_state == statePostUpdate && _adaptState == stateFixed);
919 _tmpLevelIndexSets.clear();
920 _tmpLeafIndexSet.reset(nullptr);
921 _state = stateFixed;
922 }
923
925 void addToSubDomain(SubDomainIndex subDomain, const typename Traits::template Codim<0>::Entity& e) {
926 assert(_state == stateMarking);
927 assert(e.isLeaf());
928 assert(e.partitionType() == Dune::InteriorEntity);
929 _maxAssignedSubDomainIndex = std::max(_maxAssignedSubDomainIndex,subDomain);
930 _tmpLeafIndexSet->addToSubDomain(subDomain,e);
931 }
932
934 void removeFromSubDomain(SubDomainIndex subDomain, const typename Traits::template Codim<0>::Entity& e) {
935 assert(_state == stateMarking);
936 assert(e.isLeaf());
937 assert(e.partitionType() == Dune::InteriorEntity);
938 _tmpLeafIndexSet->removeFromSubDomain(subDomain,e);
939 }
940
942 void assignToSubDomain(SubDomainIndex subDomain, const typename Traits::template Codim<0>::Entity& e) {
943 assert(_state == stateMarking);
944 assert(e.isLeaf());
945 assert(e.partitionType() == Dune::InteriorEntity);
946 _maxAssignedSubDomainIndex = std::max(_maxAssignedSubDomainIndex,subDomain);
947 _tmpLeafIndexSet->assignToSubDomain(subDomain,e);
948 }
949
951 void removeFromAllSubDomains(const typename Traits::template Codim<0>::Entity& e) {
952 assert(_state == stateMarking);
953 assert(e.isLeaf());
954 assert(e.partitionType() == Dune::InteriorEntity);
955 _tmpLeafIndexSet->removeFromAllSubDomains(e);
956 }
963 std::shared_ptr<SubDomainGrid>& subGridPointer = _subDomainGrids[subDomain];
964 if (!subGridPointer) {
965 subGridPointer.reset(new SubDomainGrid(const_cast<MultiDomainGrid&>(*this),subDomain));
966 }
967 return *subGridPointer;
968 }
969
972 std::shared_ptr<SubDomainGrid>& subGridPointer = _subDomainGrids[subDomain];
973 if (!subGridPointer) {
974 subGridPointer.reset(new SubDomainGrid(*this,subDomain));
975 }
976 return *subGridPointer;
977 }
978
980
987 {
988 return _maxAssignedSubDomainIndex;
989 }
990
993 return _supportLevelIndexSets;
994 }
1000
1004 template<typename EntityType>
1005 static const typename HostEntity<EntityType>::type& hostEntity(const EntityType& e)
1006 {
1007 return e.impl().hostEntity();
1008 }
1009
1010 template<typename EntityType>
1011 static const typename MultiDomainEntity<EntityType>::type& multiDomainEntity(const EntityType& e)
1012 {
1013 return e.impl().multiDomainEntity();
1014 }
1015
1016 template<typename IntersectionType>
1017 static const auto& multiDomainIntersection(const IntersectionType& is) {
1018 return SubDomainGrid::multiDomainIntersection(is);
1019 }
1022 const MDGridTraits& traits() const
1023 {
1024 return _traits;
1025 }
1026
1027 const HostGrid& hostGrid() const
1028 {
1029 return *_hostGridPtr;
1030 }
1031
1032 HostGrid& hostGrid()
1033 {
1034 return *_hostGridPtr;
1035 }
1036
1037private:
1038
1039 std::shared_ptr<HostGrid> _hostGridPtr;
1040 const MDGridTraitsType _traits;
1041
1042 std::vector<std::shared_ptr<LevelIndexSetImp> > _levelIndexSets;
1043 LeafIndexSetImp _leafIndexSet;
1044
1045 std::vector<std::shared_ptr<LevelIndexSetImp> > _tmpLevelIndexSets;
1046 std::unique_ptr<LeafIndexSetImp> _tmpLeafIndexSet;
1047
1048 GlobalIdSetImp _globalIdSet;
1049 LocalIdSetImp _localIdSet;
1050
1051 State _state;
1052 State _adaptState;
1053 const bool _supportLevelIndexSets;
1054
1055 mutable std::map<SubDomainIndex,std::shared_ptr<SubDomainGrid> > _subDomainGrids;
1056 SubDomainIndex _maxAssignedSubDomainIndex;
1057
1058 AdaptationStateMap _adaptationStateMap;
1059 LoadBalanceStateMap _loadBalanceStateMap;
1060
1061 void updateIndexSets() {
1062 // make sure we have enough LevelIndexSets
1063 if (_supportLevelIndexSets) {
1064 while (static_cast<int>(_levelIndexSets.size()) <= maxLevel()) {
1065 _levelIndexSets.push_back(std::make_shared<LevelIndexSetImp>(*this,hostGrid().levelGridView(_levelIndexSets.size())));
1066 }
1067 // and make sure we don't have too many...
1068 if (static_cast<int>(_levelIndexSets.size()) > maxLevel() + 1)
1069 {
1070 _levelIndexSets.resize(maxLevel() + 1);
1071 }
1072 }
1073
1074 _leafIndexSet.reset(true);
1075 _leafIndexSet.update(_levelIndexSets,true);
1076
1077 _globalIdSet.update(hostGrid().globalIdSet());
1078 _localIdSet.update(hostGrid().localIdSet());
1079
1080 // rebuild level index sets on subgrids
1081 for (auto& subGridPair : _subDomainGrids)
1082 subGridPair.second->update();
1083 }
1084
1085 void saveMultiDomainState() {
1086 typedef typename ThisType::LeafGridView GV;
1087 GV gv = this->leafGridView();
1088 typedef typename GV::template Codim<0>::Entity Entity;
1089 typedef typename MDGridTraits::template Codim<0>::SubDomainSet SubDomainSet;
1090 for (const auto& e : elements(gv)) {
1091 const SubDomainSet& subDomains = gv.indexSet().subDomains(e);
1092 _adaptationStateMap[localIdSet().id(e)] = subDomains;
1093 Entity he(e);
1094 while (he.mightVanish()) {
1095 he = he.father();
1096 typename Traits::LocalIdSet::IdType id = localIdSet().id(he);
1097 // if the entity has not been added to the set, create a new entry
1098 // (entity returns false and does not change the map if there is already an entry for "id")
1099 if (!_adaptationStateMap.insert(typename AdaptationStateMap::value_type(id,subDomains)).second) {
1100 // otherwise add the leaf entity's subdomains to the existing set of subdomains
1101 _adaptationStateMap[id].addAll(subDomains);
1102 }
1103 }
1104 }
1105 }
1106
1107 void restoreMultiDomainState() {
1108 typedef typename ThisType::LeafGridView GV;
1109 GV gv = this->leafGridView();
1110 typedef typename GV::template Codim<0>::Entity Entity;
1111 for (const auto& e : elements(gv)) {
1112 Entity he(e);
1113 // First try to exploit the information in the underlying grid
1114 while (he.isNew()) {
1115 he = he.father();
1116 }
1117 // This might not work, as there are no isNew() marks for globalrefine()
1118 // We thus have to look up the former leaf entity in our adaptation map
1119 typename AdaptationStateMap::iterator asmit = _adaptationStateMap.find(localIdSet().id(he));
1120 while(asmit == _adaptationStateMap.end()) {
1121 he = he.father();
1122 asmit = _adaptationStateMap.find(localIdSet().id(he));
1123 }
1124 _leafIndexSet.addToSubDomains(asmit->second, e);
1125 }
1126 _leafIndexSet.update(_levelIndexSets,false);
1127 _adaptationStateMap.clear();
1128 }
1129
1130 template<typename GridView, typename HostGridView>
1131 static typename GridView::IntersectionIterator multiDomainIntersectionIterator(typename HostGridView::IntersectionIterator iit) {
1132 typedef decltype(std::declval<typename GridView::IntersectionIterator>().impl()) Implementation;
1133 return Implementation(iit);
1134 }
1135
1136public:
1137
1138 template<typename Entity>
1139 typename Traits::template Codim<Entity::codimension>::Entity wrapHostEntity(const Entity& e) const {
1140 return wrapHostEntity<Entity::codimension>(e);
1141 }
1142
1143 template<int codim>
1144 typename Traits::template Codim<codim>::Entity wrapHostEntity(const typename HostGrid::template Codim<codim>::Entity& e) const
1145 {
1146 return {EntityWrapper<codim,dimension,const GridImp>(e)};
1147 }
1148
1149private:
1150
1151
1152 template<typename Impl>
1153 struct DataHandleWrapper
1154 : public Dune::CommDataHandleIF<DataHandleWrapper<Impl>,
1155 typename Impl::DataType
1156 >
1157 {
1158
1159 bool contains(int dim, int codim) const
1160 {
1161 return _impl.contains(dim,codim); // TODO: check if codim supported
1162 }
1163
1164 bool fixedSize(int dim, int codim) const
1165 {
1166 return _impl.fixedSize(dim,codim);
1167 }
1168
1169 template<typename Entity>
1170 std::size_t size(const Entity& e) const
1171 {
1172 return _impl.size(_grid.wrapHostEntity(e));
1173 }
1174
1175 template<typename MessageBufferImp, typename Entity>
1176 void gather(MessageBufferImp& buf, const Entity& e) const
1177 {
1178 _impl.gather(buf,_grid.wrapHostEntity(e));
1179 }
1180
1181 template<typename MessageBufferImp, typename Entity>
1182 void scatter(MessageBufferImp& buf, const Entity& e, std::size_t n)
1183 {
1184 _impl.scatter(buf,_grid.wrapHostEntity(e),n);
1185 }
1186
1187 DataHandleWrapper(Impl& impl, const MultiDomainGrid<HostGrid,MDGridTraitsType>& grid)
1188 : _impl(impl)
1189 , _grid(grid)
1190 {}
1191
1192 Impl& _impl;
1193 const MultiDomainGrid<HostGrid,MDGridTraitsType>& _grid;
1194
1195 };
1196
1197
1198 template<typename WrappedDataHandle>
1199 struct LoadBalancingDataHandle
1200 : public Dune::CommDataHandleIF<LoadBalancingDataHandle<WrappedDataHandle>,
1201 typename WrappedDataHandle::DataType
1202 >
1203 {
1204
1205 union Data
1206 {
1207 SubDomainIndex data;
1208 typename WrappedDataHandle::DataType buffer;
1209 };
1210
1211 static_assert(sizeof(Data) >= sizeof(SubDomainIndex),
1212 "During load balancing, the data type has to be large enough to contain MultiDomaingrid::SubDomainIndex");
1213
1214 bool contains(int dim, int codim) const
1215 {
1216 return (codim == 0)
1217 || _wrappedDataHandle.contains(dim,codim);
1218 }
1219
1220 bool fixedSize(int dim, int codim) const
1221 {
1222 return false;
1223 }
1224
1225 template<typename Entity>
1226 std::size_t size(const Entity& e) const
1227 {
1228 if (_grid.leafGridView().indexSet().contains(e) && e.partitionType() == Dune::InteriorEntity)
1229 return _grid.leafGridView().indexSet().subDomains(e).size() + 1 + _wrappedDataHandle.size(e);
1230 else
1231 return _wrappedDataHandle.size(e);
1232 }
1233
1234 template<typename MessageBufferImp, typename Entity>
1235 void gather(MessageBufferImp& buf, const Entity& e) const
1236 {
1237 assert(Entity::codimension == 0);
1238 if (e.partitionType() == Dune::InteriorEntity && _grid.leafGridView().indexSet().contains(e))
1239 {
1240 const auto& subDomains = _grid.leafGridView().indexSet().subDomains(e);
1241 Data size = { subDomains.size() };
1242 buf.write(size.buffer);
1243 for (auto& sub_domain : subDomains)
1244 {
1245 Data subDomain = { sub_domain };
1246 buf.write(subDomain.buffer);
1247 }
1248 }
1249 _wrappedDataHandle.gather(buf,e);
1250 }
1251
1252 template<typename MessageBufferImp, typename Entity>
1253 void scatter(MessageBufferImp& buf, const Entity& e, std::size_t n)
1254 {
1255 if (e.partitionType() != Dune::InteriorEntity && _grid.leafGridView().indexSet().contains(e))
1256 {
1257 Data subDomains = { 0 };
1258 buf.read(subDomains.buffer);
1259 for (int i = 0; i < subDomains.data; ++i)
1260 {
1261 Data subDomain = { 0 };
1262 buf.read(subDomain.buffer);
1263 _grid._loadBalanceStateMap[_grid.globalIdSet().id(multiDomainEntity(e))].add(subDomain.data);
1264 }
1265 _wrappedDataHandle.scatter(buf,e,n - (subDomains.data + 1));
1266 }
1267 else
1268 _wrappedDataHandle.scatter(buf,e,n);
1269 }
1270
1271 LoadBalancingDataHandle(MultiDomainGrid& grid, WrappedDataHandle& wrappedDataHandle)
1272 : _grid(grid)
1273 , _wrappedDataHandle(wrappedDataHandle)
1274 {}
1275
1276 MultiDomainGrid& _grid;
1277 WrappedDataHandle& _wrappedDataHandle;
1278
1279 };
1280
1281 struct EmptyDataHandle
1282 : public Dune::CommDataHandleIF<EmptyDataHandle,
1283 SubDomainIndex
1284 >
1285 {
1286
1287 bool contains(int dim, int codim) const
1288 {
1289 return false;
1290 }
1291
1292 bool fixedSize(int dim, int codim) const
1293 {
1294 return true;
1295 }
1296
1297 template<typename Entity>
1298 std::size_t size(const Entity& e) const
1299 {
1300 return 0;
1301 }
1302
1303 template<typename MessageBufferImp, typename Entity>
1304 void gather(MessageBufferImp& buf, const Entity& e) const
1305 {
1306 }
1307
1308 template<typename MessageBufferImp, typename Entity>
1309 void scatter(MessageBufferImp& buf, const Entity& e, std::size_t n)
1310 {
1311 }
1312
1313 };
1314
1315};
1316
1317enum MultiDomainGridType { multiDomainGrid, subDomainGrid, other };
1318
1319template<typename T>
1320struct GridType {
1321 static const MultiDomainGridType v = other;
1322};
1323
1324template<class HostGrid, typename MDGridTraits>
1325struct GridType<MultiDomainGrid<HostGrid,MDGridTraits> > {
1326 static const MultiDomainGridType v = multiDomainGrid;
1327};
1328
1329template<class MDGrid>
1330struct GridType<subdomain::SubDomainGrid<MDGrid> > {
1331 static const MultiDomainGridType v = subDomainGrid;
1332};
1333
1334} // namespace mdgrid
1335
1336} // namespace Dune
1337
1338#endif // DUNE_MULTIDOMAINGRID_MULTIDOMAINGRID_HH
Definition: indexsets.hh:118
A meta grid for dividing an existing DUNE grid into subdomains that can be accessed as a grid in thei...
Definition: multidomaingrid.hh:243
Traits::LeafAllSubDomainInterfacesIterator LeafAllSubDomainInterfacesIterator
The type of the iterators over the codim 1 interfaces between all subdomains on the leaf view.
Definition: multidomaingrid.hh:417
Traits::LevelAllSubDomainInterfacesIterator LevelAllSubDomainInterfacesIterator
The type of the iterators over the codim 1 interfaces between all subdomains on a level view.
Definition: multidomaingrid.hh:420
LevelAllSubDomainInterfacesIterator levelAllSubDomainInterfacesBegin(int level) const
Returns an iterator over all subdomain interfaces on the requested level view.
Definition: multidomaingrid.hh:688
MultiDomainGrid(HostGrid &hostGrid, const MDGridTraitsType &traits, bool supportLevelIndexSets=true)
Constructs a new MultiDomainGrid from the given host grid.
Definition: multidomaingrid.hh:485
Traits::LevelSubDomainInterfaceIterator LevelSubDomainInterfaceIterator
The type of the iterators over the codim 1 interface between two subdomains on a level view.
Definition: multidomaingrid.hh:414
static const HostEntity< EntityType >::type & hostEntity(const EntityType &e)
Returns a reference to the corresponding host entity.
Definition: multidomaingrid.hh:1005
void startSubDomainMarking()
Prepares the grid for (re-)assigning cells to subdomains.
Definition: multidomaingrid.hh:875
void updateSubDomains()
Switches the subdomain layout over to the new layout.
Definition: multidomaingrid.hh:905
const SubDomainIndex maxSubDomainIndex() const
The largest allowed index for a subdomain.
Definition: multidomaingrid.hh:395
void postUpdateSubDomains()
clears the saved state of the subdomain layout that was active before the last call to updateSubDomai...
Definition: multidomaingrid.hh:917
int maxLevel() const
The current maximum level of the grid.
Definition: multidomaingrid.hh:502
MDGridTraits::SubDomainIndex SubDomainIndex
The (integer) type used to identify subdomains.
Definition: multidomaingrid.hh:384
bool supportLevelIndexSets() const
Indicates whether this MultiDomainGrid instance supports level index sets on its SubDomainGrids.
Definition: multidomaingrid.hh:992
LeafSubDomainInterfaceIterator leafSubDomainInterfaceEnd(SubDomainIndex subDomain1, SubDomainIndex subDomain2) const
Returns the corresponding end iterator for leafSubDomainInterfaceBegin().
Definition: multidomaingrid.hh:620
LevelAllSubDomainInterfacesIterator levelAllSubDomainInterfacesEnd(int level) const
Returns the corresponding end iterator for levelAllSubDomainInterfacesBegin().
Definition: multidomaingrid.hh:696
MultiDomainGrid(const std::shared_ptr< HostGrid > &hostGridPtr, bool supportLevelIndexSets=true)
Constructs a new MultiDomainGrid from the given host grid.
Definition: multidomaingrid.hh:430
SubDomainIndex maxAssignedSubDomainIndex() const
Returns the largest subdomain index that was ever assigned to a cell in this grid.
Definition: multidomaingrid.hh:986
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:942
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:635
LeafSubDomainInterfaceIterator leafSubDomainInterfaceBegin(SubDomainIndex subDomain1, SubDomainIndex subDomain2) const
Returns an iterator over the leaf interface of two subdomains.
Definition: multidomaingrid.hh:615
void removeFromSubDomain(SubDomainIndex subDomain, const typename Traits::template Codim< 0 >::Entity &e)
Removes the given leaf entity from the specified subdomain.
Definition: multidomaingrid.hh:934
SubDomainGrid & subDomain(SubDomainIndex subDomain)
Returns a reference to the SubDomainGrid associated with the given subdomain.
Definition: multidomaingrid.hh:971
static const std::size_t maxNumberOfSubDomains
The largest number of subdomains any given grid cell may belong to.
Definition: multidomaingrid.hh:387
subdomain::SubDomainGrid< ThisType > SubDomainGrid
The type used for representing the grid of a subdomain, always a specialization of Dune::mdgrid::subd...
Definition: multidomaingrid.hh:407
void addToSubDomain(SubDomainIndex subDomain, const typename Traits::template Codim< 0 >::Entity &e)
Adds the given leaf entity to the specified subdomain.
Definition: multidomaingrid.hh:925
Traits::LeafSubDomainInterfaceIterator LeafSubDomainInterfaceIterator
The type of the iterators over the codim 1 interface between two subdomains on the leaf view.
Definition: multidomaingrid.hh:411
LeafAllSubDomainInterfacesIterator leafAllSubDomainInterfacesEnd() const
Returns the corresponding end iterator for leafAllSubDomainInterfacesBegin().
Definition: multidomaingrid.hh:667
void preUpdateSubDomains()
Calculates the new subdomain layout, but does not update the current subdomains yet.
Definition: multidomaingrid.hh:890
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:951
const SubDomainGrid & subDomain(SubDomainIndex subDomain) const
Returns a reference to the SubDomainGrid associated with the given subdomain.
Definition: multidomaingrid.hh:962
MultiDomainGrid(const std::shared_ptr< HostGrid > &hostGridPtr, const MDGridTraitsType &traits, bool supportLevelIndexSets=true)
Constructs a new MultiDomainGrid from the given host grid.
Definition: multidomaingrid.hh:451
LevelSubDomainInterfaceIterator levelSubDomainInterfaceEnd(SubDomainIndex subDomain1, SubDomainIndex subDomain2, int level) const
Returns the corresponding end iterator for levelSubDomainInterfaceBegin().
Definition: multidomaingrid.hh:643
MultiDomainGrid(HostGrid &hostGrid, bool supportLevelIndexSets=true)
Constructs a new MultiDomainGrid from the given host grid.
Definition: multidomaingrid.hh:474
LeafAllSubDomainInterfacesIterator leafAllSubDomainInterfacesBegin() const
Returns an iterator over all subdomain interfaces on the leaf view.
Definition: multidomaingrid.hh:662
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)