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 
29 namespace Dune {
30 
31 namespace mdgrid {
32 
33 template<typename HostGrid, typename MDGridTraits>
34 class MultiDomainGrid;
35 
36 template<typename HostGrid, typename MDGridTraits>
37 struct MultiDomainGridFamily {
38 
39 private:
40 
41   static const int dim  = HostGrid::dimension;
42   static const int dimw = HostGrid::dimensionworld;
43 
44 public:
45 
46   struct Traits
47   {
48     /** \brief The type that implementing the grid. */
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 
184 namespace Impl {
185 
186   template<typename Grid, typename SI, bool max_subdomain_index_is_static>
187   struct MaxSubDomainIndexProvider
188   {
189 
190     typedef SI SubDomainIndex;
191 
maxSubDomainIndexDune::mdgrid::Impl::MaxSubDomainIndexProvider192     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 
maxSubDomainIndexDune::mdgrid::Impl::MaxSubDomainIndexProvider205     static constexpr SubDomainIndex maxSubDomainIndex()
206     {
207       return Grid::MDGridTraits::maxSubDomainIndex();
208     }
209 
210   };
211 
212 }
213 
214 
215 //! A meta grid for dividing an existing DUNE grid into subdomains that can be accessed as a grid in their own right.
216 /**
217  * \tparam HostGrid             The type of the underlying grid implementation.
218  * \tparam MDGridTraitsType     A traits type for customizing how the MultiDomainGrid manages the partitioning information.
219  */
220 
221 template<
222   typename HostGrid_,
223   typename MDGridTraitsType
224   >
225 class MultiDomainGrid
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 
243 public:
244 
245   using HostGrid = HostGrid_;
246 
247 private:
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>
293   friend class LeafSubDomainInterfaceIterator;
294 
295   template <typename>
296   friend class LevelSubDomainInterfaceIterator;
297 
298   template <typename>
299   friend class LeafAllSubDomainInterfacesIterator;
300 
301   template <typename>
302   friend class LevelAllSubDomainInterfacesIterator;
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 
325   typedef MultiDomainGrid<HostGrid,MDGridTraitsType> GridImp;
326 
327   typedef IndexSetWrapper<const GridImp, typename HostGrid::LevelGridView> LevelIndexSetImp;
328 
329   typedef IndexSetWrapper<const GridImp, typename HostGrid::LeafGridView> LeafIndexSetImp;
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 
349 public:
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 
359 private:
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 
379 public:
380 
381   //! The (integer) type used to identify subdomains.
382   typedef typename MDGridTraits::SubDomainIndex SubDomainIndex;
383 
384   //! The largest number of subdomains any given grid cell may belong to.
385   static const std::size_t maxNumberOfSubDomains = MDGridTraits::maxSubDomainsPerCell;
386 
387 #ifdef DOXYGEN
388   //! The largest allowed index for a subdomain.
389   /**
390    * \note As subdomain indices always start at 0, this also determines the maximum
391    * number of possible subdomains.
392    */
maxSubDomainIndex() const393   const SubDomainIndex maxSubDomainIndex() const
394   {
395     return _traits.maxSubDomainIndex();
396   }
397 #endif
398 
maxSubDomainIndexIsStatic()399   static constexpr bool maxSubDomainIndexIsStatic()
400   {
401     return MDGridTraits::maxSubDomainIndexIsStatic();
402   }
403 
404   //! The type used for representing the grid of a subdomain, always a specialization of Dune::mdgrid::subdomain::SubDomainGrid.
405   typedef subdomain::SubDomainGrid<ThisType> SubDomainGrid;
406 
407 
408   //! The type of the iterators over the codim 1 interface between two subdomains on the leaf view.
409   typedef typename Traits::LeafSubDomainInterfaceIterator LeafSubDomainInterfaceIterator;
410 
411   //! The type of the iterators over the codim 1 interface between two subdomains on a level view.
412   typedef typename Traits::LevelSubDomainInterfaceIterator LevelSubDomainInterfaceIterator;
413 
414   //! The type of the iterators over the codim 1 interfaces between all subdomains on the leaf view.
415   typedef typename Traits::LeafAllSubDomainInterfacesIterator LeafAllSubDomainInterfacesIterator;
416 
417   //! The type of the iterators over the codim 1 interfaces between all subdomains on a level view.
418   typedef typename Traits::LevelAllSubDomainInterfacesIterator LevelAllSubDomainInterfacesIterator;
419 
420   /** @name Constructors */
421   /*@{*/
422   //! Constructs a new MultiDomainGrid from the given host grid.
423   /**
424    *
425    * \param hostGrid                the host grid that will be wrapped by the MultiDomainGrid
426    * \param supportLevelIndexSets   flag indicating support for level index sets on subdomains
427    */
MultiDomainGrid(HostGrid & hostGrid,bool supportLevelIndexSets=true)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 
442   //! Constructs a new MultiDomainGrid from the given host grid.
443   /**
444    *
445    * \param hostGrid                the host grid that will be wrapped by the MultiDomainGrid
446    * \param traits                  an instance of the grid traits, which might contain runtime information
447    * \param supportLevelIndexSets   flag indicating support for level index sets on subdomains
448    */
MultiDomainGrid(HostGrid & hostGrid,const MDGridTraitsType & traits,bool supportLevelIndexSets=true)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 
463   /*@}*/
464 
465   /** @name Dune grid interface methods */
466   /*@{*/
467 
468   template<typename EntitySeed>
469   typename Traits::template Codim<EntitySeed::codimension>::Entity
entity(const EntitySeed & entitySeed) const470   entity(const EntitySeed& entitySeed) const
471   {
472     return {EntityWrapper<EntitySeed::codimension,dimension,const GridImp>(_hostGrid.entity(entitySeed.hostEntitySeed()))};
473   }
474 
475   //! The current maximum level of the grid.
maxLevel() const476   int maxLevel() const {
477     return _hostGrid.maxLevel();
478   }
479 
480   template<int codim>
lbegin(int level) const481   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>
lend(int level) const493   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>
lbegin(int level) const505   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>
lend(int level) const517   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>
leafbegin() const529   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>
leafend() const541   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>
leafbegin() const553   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>
leafend() const565   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   }
575   /*@}*/
576 
577   /** @name Methods for iterating over subdomain interfaces */
578   /*@{*/
579   //! Returns an iterator over the leaf interface of two subdomains.
580   /**
581    * The resulting iterator will visit all cell intersections that are part of both subdomains.
582    *
583    * \attention The iterator assumes the two subdomains to be non-overlapping! If there is an overlap,
584    * some intersections will be iterated over twice!
585    *
586    * \param subDomain1 the first subdomain
587    * \param subDomain2 the second subdomain
588    */
leafSubDomainInterfaceBegin(SubDomainIndex subDomain1,SubDomainIndex subDomain2) const589   LeafSubDomainInterfaceIterator leafSubDomainInterfaceBegin(SubDomainIndex subDomain1, SubDomainIndex subDomain2) const {
590     return LeafSubDomainInterfaceIterator(*this,subDomain1,subDomain2);
591   }
592 
593   //! Returns the corresponding end iterator for leafSubDomainInterfaceBegin().
leafSubDomainInterfaceEnd(SubDomainIndex subDomain1,SubDomainIndex subDomain2) const594   LeafSubDomainInterfaceIterator leafSubDomainInterfaceEnd(SubDomainIndex subDomain1, SubDomainIndex subDomain2) const {
595     return LeafSubDomainInterfaceIterator(*this,subDomain1,subDomain2,true);
596   }
597 
598   //! Returns an iterator over the interface of two subdomains at the given level.
599   /**
600    * The resulting iterator will visit all cell intersections that are part of both subdomains.
601    *
602    * \attention The iterator assumes the two subdomains to be non-overlapping! If there is an overlap,
603    * some intersections will be iterated over twice!
604    *
605    * \param subDomain1 the first subdomain
606    * \param subDomain2 the second subdomain
607    * \param level      the grid level over which to iterate
608    */
levelSubDomainInterfaceBegin(SubDomainIndex subDomain1,SubDomainIndex subDomain2,int level) const609   LevelSubDomainInterfaceIterator levelSubDomainInterfaceBegin(SubDomainIndex subDomain1, SubDomainIndex subDomain2, int level) const {
610     return LevelSubDomainInterfaceIterator(*this,subDomain1,subDomain2,level);
611   }
612 
613   //! Returns the corresponding end iterator for levelSubDomainInterfaceBegin().
614   /**
615    * \param level the grid level to be iterated over.
616    */
levelSubDomainInterfaceEnd(SubDomainIndex subDomain1,SubDomainIndex subDomain2,int level) const617   LevelSubDomainInterfaceIterator levelSubDomainInterfaceEnd(SubDomainIndex subDomain1, SubDomainIndex subDomain2, int level) const {
618     return LevelSubDomainInterfaceIterator(*this,subDomain1,subDomain2,level,true);
619   }
620 
621   //! Returns an iterator over all subdomain interfaces on the leaf view.
622   /**
623    * This method returns an iterator that will visit all pairwise surface interfaces
624    * between subdomains on the leaf view. In particular, given to adjacent cells
625    * \f$e_1\f$ and \f$e_2\f$ and two subdomains \f$s_1\f$ and \f$s_2\f$, this iterator
626    * will visit the intersection between \f$e_1\f$ and \f$e_2\f$ iff all of the following hold:
627    * \f{eqnarray*} e_1 \in s_1,\ e_1 \not\in s_2,\\ e_2 \not\in s_1,\ e_1 \in s_2.\f}
628    * In essence, the two subdomains have to be locally disjoint on \f$e_1\f$ and \f$e_2\f$.
629    *
630    * The iterator will only traverse the host grid once for visiting all subdomain interfaces.
631    * Incrementing the iterator might thus result in an iterator pointing to the same grid
632    * intersection, but to a different pair of subdomains. The subdomains pointed to by ther
633    * iterator can be retrieved by calling LeafAllSubDomainInterfacesIterator::subDomain1()
634    * and LeafAllSubDomainInterfacesIterator::subDomain2(), respectively.
635    */
leafAllSubDomainInterfacesBegin() const636   LeafAllSubDomainInterfacesIterator leafAllSubDomainInterfacesBegin() const {
637     return LeafAllSubDomainInterfacesIterator(*this);
638   }
639 
640   //! Returns the corresponding end iterator for leafAllSubDomainInterfacesBegin().
leafAllSubDomainInterfacesEnd() const641   LeafAllSubDomainInterfacesIterator leafAllSubDomainInterfacesEnd() const {
642     return LeafAllSubDomainInterfacesIterator(*this,true);
643   }
644 
645   //! Returns an iterator over all subdomain interfaces on the requested level view.
646   /**
647    * This method returns an iterator that will visit all pairwise surface interfaces
648    * between subdomains on the requested level view. In particular, given to adjacent cells
649    * \f$e_1\f$ and \f$e_2\f$ and two subdomains \f$s_1\f$ and \f$s_2\f$, this iterator
650    * will visit the intersection between \f$e_1\f$ and \f$e_2\f$ iff all of the following hold:
651    * \f{eqnarray*} e_1 \in s_1,\ e_1 \not\in s_2,\\ e_2 \not\in s_1,\ e_1 \in s_2.\f}
652    * In essence, the two subdomains have to be locally disjoint on \f$e_1\f$ and \f$e_2\f$.
653    *
654    * The iterator will only traverse the host grid once for visiting all subdomain interfaces.
655    * Incrementing the iterator might thus result in an iterator pointing to the same grid
656    * intersection, but to a different pair of subdomains. The subdomains pointed to by ther
657    * iterator can be retrieved by calling LevelAllSubDomainInterfacesIterator::subDomain1()
658    * and LevelAllSubDomainInterfacesIterator::subDomain2(), respectively.
659    *
660    * \param level the grid level to be iterated over.
661    */
levelAllSubDomainInterfacesBegin(int level) const662   LevelAllSubDomainInterfacesIterator levelAllSubDomainInterfacesBegin(int level) const {
663     return LevelAllSubDomainInterfacesIterator(*this,level);
664   }
665 
666   //! Returns the corresponding end iterator for levelAllSubDomainInterfacesBegin().
667   /**
668    * \param level the grid level to be iterated over.
669    */
levelAllSubDomainInterfacesEnd(int level) const670   LevelAllSubDomainInterfacesIterator levelAllSubDomainInterfacesEnd(int level) const {
671     return LevelAllSubDomainInterfacesIterator(*this,level,true);
672   }
673   /*@}*/
674 
675   /** @name Dune grid interface methods */
676   /*@{*/
size(int level,int codim) const677   int size(int level, int codim) const {
678     return _hostGrid.size(level,codim);
679   }
680 
size(int codim) const681   int size(int codim) const {
682     return _hostGrid.size(codim);
683   }
684 
size(int level,GeometryType type) const685   int size(int level, GeometryType type) const {
686     return _hostGrid.size(level,type);
687   }
688 
size(GeometryType type) const689   int size(GeometryType type) const {
690     return _hostGrid.size(type);
691   }
692 
globalIdSet() const693   const typename Traits::GlobalIdSet& globalIdSet() const {
694     return _globalIdSet;
695   }
696 
localIdSet() const697   const typename Traits::LocalIdSet& localIdSet() const {
698     return _localIdSet;
699   }
700 
levelIndexSet(int level) const701   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 
leafIndexSet() const709   const typename Traits::LeafIndexSet& leafIndexSet() const {
710     return _leafIndexSet;
711   }
712 
globalRefine(int refCount)713   void globalRefine(int refCount) {
714     saveMultiDomainState();
715     _hostGrid.globalRefine(refCount);
716     updateIndexSets();
717     restoreMultiDomainState();
718   }
719 
mark(int refCount,const typename Traits::template Codim<0>::Entity & e)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 
getMark(const typename Traits::template Codim<0>::Entity & e)725   int getMark(const typename Traits::template Codim<0>::Entity& e) {
726     assert(_state == stateFixed);
727     return _hostGrid.getMark(hostEntity(e));
728   }
729 
preAdapt()730   bool preAdapt() {
731     assert(_state == stateFixed && _adaptState == stateFixed);
732     _adaptState = statePreAdapt;
733     bool result = _hostGrid.preAdapt();
734     return result;
735   }
736 
adapt()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 
postAdapt()747   void postAdapt() {
748     assert(_state == stateFixed && _adaptState == statePostAdapt);
749     _adaptState = stateFixed;
750     _hostGrid.postAdapt();
751   }
752 
overlapSize(int level,int codim) const753   int overlapSize(int level, int codim) const {
754     return _hostGrid.overlapSize(level,codim);
755   }
756 
overlapSize(int codim) const757   int overlapSize(int codim) const {
758     return _hostGrid.overlapSize(codim);
759   }
760 
ghostSize(int level,int codim) const761   int ghostSize(int level, int codim) const {
762     return _hostGrid.ghostSize(level,codim);
763   }
764 
ghostSize(int codim) const765   int ghostSize(int codim) const {
766     return _hostGrid.ghostSize(codim);
767   }
768 
comm() const769   const typename Traits::CollectiveCommunication& comm() const {
770     return _hostGrid.comm();
771   }
772 
773   template<typename DataHandleImp, typename DataTypeImp>
communicate(CommDataHandleIF<DataHandleImp,DataTypeImp> & data,InterfaceType iftype,CommunicationDirection dir,int level) const774   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>
communicate(CommDataHandleIF<DataHandleImp,DataTypeImp> & data,InterfaceType iftype,CommunicationDirection dir) const784   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>
loadBalance(DataHandle & 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 
loadBalance()825   bool loadBalance()
826   {
827     EmptyDataHandle emptyDataHandle;
828     return loadBalance(emptyDataHandle);
829   }
830 
numBoundarySegments() const831   size_t numBoundarySegments() const
832   {
833     return _hostGrid.numBoundarySegments();
834   }
835 
836   /*@}*/
837 
838   /** @name Subdomain creation- and adaptation methods */
839   /*@{*/
840   //! Prepares the grid for (re-)assigning cells to subdomains.
841   /**
842    * After calling this method, it becomes possible to invoke the various methods
843    * for cell assignment to subdomains. When you are done marking, call preUpdateSubDomains().
844    *
845    * IMPORTANT: Reassigning subdomains and grid adaptation are mutually exclusive,
846    * it is not possibly to do both at the same time. This restriction is enforced
847    * by the grid.
848    */
startSubDomainMarking()849   void startSubDomainMarking() {
850     assert(_state == stateFixed && _adaptState == stateFixed);
851     _tmpLeafIndexSet.reset(new LeafIndexSetImp(_leafIndexSet));
852     _tmpLeafIndexSet->reset(false);
853     _state = stateMarking;
854   }
855 
856   //! Calculates the new subdomain layout, but does not update the current subdomains yet.
857   /**
858    * After calling this method, you can query the grid for the changes that will occur when the
859    * new subdomain layout becomes active. This includes the possibility to obtain the new indices
860    * entities will be assigned in the modified subdomains.
861    *
862    * To switch the grid over to the new layout, call updateSubDomains().
863    */
preUpdateSubDomains()864   void preUpdateSubDomains() {
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 
875   //! Switches the subdomain layout over to the new layout.
876   /**
877    *
878    */
updateSubDomains()879   void updateSubDomains() {
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 
890   //! clears the saved state of the subdomain layout that was active before the last call to updateSubDomains().
postUpdateSubDomains()891   void postUpdateSubDomains() {
892     assert(_state == statePostUpdate && _adaptState == stateFixed);
893     _tmpLevelIndexSets.clear();
894     _tmpLeafIndexSet.reset(nullptr);
895     _state = stateFixed;
896   }
897 
898   //! Adds the given leaf entity to the specified subdomain.
addToSubDomain(SubDomainIndex subDomain,const typename Traits::template Codim<0>::Entity & e)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 
907   //! Removes the given leaf entity from the specified subdomain.
removeFromSubDomain(SubDomainIndex subDomain,const typename Traits::template Codim<0>::Entity & e)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 
915   //! Assigns the given leaf entity to the specified subdomain, clearing any previous subdomain assignments.
assignToSubDomain(SubDomainIndex subDomain,const typename Traits::template Codim<0>::Entity & e)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 
924   //! Removes the given leaf entity from all subdomains it currently belongs to.
removeFromAllSubDomains(const typename Traits::template Codim<0>::Entity & e)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   }
931   /*@}*/
932 
933   /** @name Access to the subdomain grids */
934   /*@{*/
935   //! Returns a reference to the SubDomainGrid associated with the given subdomain.
subDomain(SubDomainIndex subDomain) const936   const SubDomainGrid& subDomain(SubDomainIndex subDomain) const {
937     std::shared_ptr<SubDomainGrid>& subGridPointer = _subDomainGrids[subDomain];
938     if (!subGridPointer) {
939       subGridPointer.reset(new SubDomainGrid(const_cast<MultiDomainGrid&>(*this),subDomain));
940       // subGridPointer->update();
941     }
942     return *subGridPointer;
943   }
944 
945   //! Returns a reference to the SubDomainGrid associated with the given subdomain.
subDomain(SubDomainIndex subDomain)946   SubDomainGrid& subDomain(SubDomainIndex subDomain) {
947     std::shared_ptr<SubDomainGrid>& subGridPointer = _subDomainGrids[subDomain];
948     if (!subGridPointer) {
949       subGridPointer.reset(new SubDomainGrid(*this,subDomain));
950       // subGridPointer->update();
951     }
952     return *subGridPointer;
953   }
954 
955   //! Returns the largest subdomain index that was ever assigned to a cell in this grid.
956   /**
957    * This method returns the largest subdomain index that was passed to addToSubDomain() or
958    * assignToSubDomain() since this MultiDomainGrid was created. Keep in mind that the subdomain
959    * belonging to that index might not contain any entities anymore if all entities have been
960    * removed from it at a later point.
961    */
maxAssignedSubDomainIndex() const962   SubDomainIndex maxAssignedSubDomainIndex() const
963   {
964     return _maxAssignedSubDomainIndex;
965   }
966 
967   //! Indicates whether this MultiDomainGrid instance supports level index sets on its SubDomainGrids.
supportLevelIndexSets() const968   bool supportLevelIndexSets() const {
969     return _supportLevelIndexSets;
970   }
971   /*@}*/
972 
973   /** @name Entity conversion methods */
974   /*@{*/
975   //! Returns a reference to the corresponding host entity.
976   /**
977    * \warning The returned reference will only be valid as long as the passed-in reference to the
978    * MultiDomainGrid entity! If you need a persistent host entity object , copy the returned reference.
979    */
980   template<typename EntityType>
hostEntity(const EntityType & e)981   static const typename HostEntity<EntityType>::type& hostEntity(const EntityType& e)
982   {
983     return e.impl().hostEntity();
984   }
985 
986   template<typename EntityType>
multiDomainEntity(const EntityType & e)987   static const typename MultiDomainEntity<EntityType>::type& multiDomainEntity(const EntityType& e)
988   {
989     return e.impl().multiDomainEntity();
990   }
991 
992   template<typename IntersectionType>
multiDomainIntersection(const IntersectionType & is)993   static const typename SubDomainGrid::template MultiDomainIntersection<IntersectionType>::Type& multiDomainIntersection(const IntersectionType& is) {
994     return SubDomainGrid::multiDomainIntersection(is);
995   }
996  /*@}*/
997 
traits() const998   const MDGridTraits& traits() const
999   {
1000     return _traits;
1001   }
1002 
1003 private:
1004 
hostGrid() const1005   const HostGrid& hostGrid() const
1006   {
1007     return _hostGrid;
1008   }
1009 
hostGrid()1010   HostGrid& hostGrid()
1011   {
1012     return _hostGrid;
1013   }
1014 
1015   HostGrid& _hostGrid;
1016   const MDGridTraitsType _traits;
1017 
1018   std::vector<std::shared_ptr<LevelIndexSetImp> > _levelIndexSets;
1019   LeafIndexSetImp _leafIndexSet;
1020 
1021   std::vector<std::shared_ptr<LevelIndexSetImp> > _tmpLevelIndexSets;
1022   std::unique_ptr<LeafIndexSetImp> _tmpLeafIndexSet;
1023 
1024   GlobalIdSetImp _globalIdSet;
1025   LocalIdSetImp _localIdSet;
1026 
1027   State _state;
1028   State _adaptState;
1029   const bool _supportLevelIndexSets;
1030 
1031   mutable std::map<SubDomainIndex,std::shared_ptr<SubDomainGrid> > _subDomainGrids;
1032   SubDomainIndex _maxAssignedSubDomainIndex;
1033 
1034   AdaptationStateMap _adaptationStateMap;
1035   LoadBalanceStateMap _loadBalanceStateMap;
1036 
updateIndexSets()1037   void updateIndexSets() {
1038     // make sure we have enough LevelIndexSets
1039     if (_supportLevelIndexSets) {
1040       while (static_cast<int>(_levelIndexSets.size()) <= maxLevel()) {
1041         _levelIndexSets.push_back(std::make_shared<LevelIndexSetImp>(*this,_hostGrid.levelGridView(_levelIndexSets.size())));
1042       }
1043       // and make sure we don't have too many...
1044       if (static_cast<int>(_levelIndexSets.size()) > maxLevel() + 1)
1045         {
1046           _levelIndexSets.resize(maxLevel() + 1);
1047         }
1048     }
1049 
1050     _leafIndexSet.reset(true);
1051     _leafIndexSet.update(_levelIndexSets,true);
1052 
1053     _globalIdSet.update(_hostGrid.globalIdSet());
1054     _localIdSet.update(_hostGrid.localIdSet());
1055   }
1056 
saveMultiDomainState()1057   void saveMultiDomainState() {
1058     typedef typename ThisType::LeafGridView GV;
1059     GV gv = this->leafGridView();
1060     typedef typename GV::template Codim<0>::Entity Entity;
1061     typedef typename MDGridTraits::template Codim<0>::SubDomainSet SubDomainSet;
1062     for (const auto& e : elements(gv)) {
1063       const SubDomainSet& subDomains = gv.indexSet().subDomains(e);
1064       _adaptationStateMap[localIdSet().id(e)] = subDomains;
1065       Entity he(e);
1066       while (he.mightVanish()) {
1067         he = he.father();
1068         typename Traits::LocalIdSet::IdType id = localIdSet().id(he);
1069         // if the entity has not been added to the set, create a new entry
1070         // (entity returns false and does not change the map if there is already an entry for "id")
1071         if (!_adaptationStateMap.insert(typename AdaptationStateMap::value_type(id,subDomains)).second) {
1072           // otherwise add the leaf entity's subdomains to the existing set of subdomains
1073           _adaptationStateMap[id].addAll(subDomains);
1074         }
1075       }
1076     }
1077   }
1078 
restoreMultiDomainState()1079   void restoreMultiDomainState() {
1080     typedef typename ThisType::LeafGridView GV;
1081     GV gv = this->leafGridView();
1082     typedef typename GV::template Codim<0>::Entity Entity;
1083     for (const auto& e : elements(gv)) {
1084       Entity he(e);
1085       // First try to exploit the information in the underlying grid
1086       while (he.isNew()) {
1087         he = he.father();
1088       }
1089       // This might not work, as there are no isNew() marks for globalrefine()
1090       // We thus have to look up the former leaf entity in our adaptation map
1091       typename AdaptationStateMap::iterator asmit = _adaptationStateMap.find(localIdSet().id(he));
1092       while(asmit == _adaptationStateMap.end()) {
1093         he = he.father();
1094         asmit = _adaptationStateMap.find(localIdSet().id(he));
1095       }
1096       _leafIndexSet.addToSubDomains(asmit->second, e);
1097     }
1098     _leafIndexSet.update(_levelIndexSets,false);
1099     _adaptationStateMap.clear();
1100   }
1101 
1102   template<typename GridView, typename HostGridView>
multiDomainIntersectionIterator(typename HostGridView::IntersectionIterator iit)1103   static typename GridView::IntersectionIterator multiDomainIntersectionIterator(typename HostGridView::IntersectionIterator iit) {
1104     typedef decltype(std::declval<typename GridView::IntersectionIterator>().impl()) Implementation;
1105     return Implementation(iit);
1106   }
1107 
1108 public:
1109 
1110   template<typename Entity>
wrapHostEntity(const Entity & e) const1111   typename Traits::template Codim<Entity::codimension>::Entity wrapHostEntity(const Entity& e) const {
1112     return wrapHostEntity<Entity::codimension>(e);
1113   }
1114 
1115   template<int codim>
wrapHostEntity(const typename HostGrid::template Codim<codim>::Entity & e) const1116   typename Traits::template Codim<codim>::Entity wrapHostEntity(const typename HostGrid::template Codim<codim>::Entity& e) const
1117   {
1118     return {EntityWrapper<codim,dimension,const GridImp>(e)};
1119   }
1120 
1121 private:
1122 
1123 
1124   template<typename Impl>
1125   struct DataHandleWrapper
1126     : public Dune::CommDataHandleIF<DataHandleWrapper<Impl>,
1127                                     typename Impl::DataType
1128                                     >
1129   {
1130 
containsDune::mdgrid::MultiDomainGrid::DataHandleWrapper1131     bool contains(int dim, int codim) const
1132     {
1133       return _impl.contains(dim,codim); // TODO: check if codim supported
1134     }
1135 
fixedSizeDune::mdgrid::MultiDomainGrid::DataHandleWrapper1136     bool fixedSize(int dim, int codim) const
1137     {
1138       return _impl.fixedSize(dim,codim);
1139     }
1140 
1141     template<typename Entity>
sizeDune::mdgrid::MultiDomainGrid::DataHandleWrapper1142     std::size_t size(const Entity& e) const
1143     {
1144       return _impl.size(_grid.wrapHostEntity(e));
1145     }
1146 
1147     template<typename MessageBufferImp, typename Entity>
gatherDune::mdgrid::MultiDomainGrid::DataHandleWrapper1148     void gather(MessageBufferImp& buf, const Entity& e) const
1149     {
1150       _impl.gather(buf,_grid.wrapHostEntity(e));
1151     }
1152 
1153     template<typename MessageBufferImp, typename Entity>
scatterDune::mdgrid::MultiDomainGrid::DataHandleWrapper1154     void scatter(MessageBufferImp& buf, const Entity& e, std::size_t n)
1155     {
1156       _impl.scatter(buf,_grid.wrapHostEntity(e),n);
1157     }
1158 
DataHandleWrapperDune::mdgrid::MultiDomainGrid::DataHandleWrapper1159     DataHandleWrapper(Impl& impl, const MultiDomainGrid<HostGrid,MDGridTraitsType>& grid)
1160       : _impl(impl)
1161       , _grid(grid)
1162     {}
1163 
1164     Impl& _impl;
1165     const MultiDomainGrid<HostGrid,MDGridTraitsType>& _grid;
1166 
1167   };
1168 
1169 
1170   template<typename WrappedDataHandle>
1171   struct LoadBalancingDataHandle
1172     : public Dune::CommDataHandleIF<LoadBalancingDataHandle<WrappedDataHandle>,
1173                                     typename WrappedDataHandle::DataType
1174                                     >
1175   {
1176 
1177     union Data
1178     {
1179       SubDomainIndex data;
1180       typename WrappedDataHandle::DataType buffer;
1181     };
1182 
1183     static_assert(sizeof(WrappedDataHandle::DataType) >= sizeof(SubDomainIndex),
1184                   "During load balancing, the data type has to be large enough to contain MultiDomaingrid::SubDomainIndex");
1185 
containsDune::mdgrid::MultiDomainGrid::LoadBalancingDataHandle1186     bool contains(int dim, int codim) const
1187     {
1188       return (codim == 0)
1189         || _wrappedDataHandle.contains(dim,codim);
1190     }
1191 
fixedSizeDune::mdgrid::MultiDomainGrid::LoadBalancingDataHandle1192     bool fixedSize(int dim, int codim) const
1193     {
1194       return false;
1195     }
1196 
1197     template<typename Entity>
sizeDune::mdgrid::MultiDomainGrid::LoadBalancingDataHandle1198     std::size_t size(const Entity& e) const
1199     {
1200       if (_grid.leafGridView().indexSet().contains(e) && e.partitionType() == Dune::InteriorEntity)
1201         return _grid.leafGridView().indexSet().subDomains(e).size() + 1 + _wrappedDataHandle.size(e);
1202       else
1203         return _wrappedDataHandle.size(e);
1204     }
1205 
1206     template<typename MessageBufferImp, typename Entity>
gatherDune::mdgrid::MultiDomainGrid::LoadBalancingDataHandle1207     void gather(MessageBufferImp& buf, const Entity& e) const
1208     {
1209       assert(Entity::codimension == 0);
1210       if (e.partitionType() == Dune::InteriorEntity && _grid.leafGridView().indexSet().contains(e))
1211         {
1212           typedef typename MDGridTraits::template Codim<0>::SubDomainSet SubDomainSet;
1213           const SubDomainSet& subDomains = _grid.leafGridView().indexSet().subDomains(e);
1214           Data size = { subDomains.size() };
1215           buf.write(size.buffer);
1216           for (typename SubDomainSet::const_iterator it = subDomains.begin(); it != subDomains.end(); ++it)
1217             {
1218               Data subDomain = { *it };
1219               buf.write(subDomain.buffer);
1220             }
1221         }
1222       _wrappedDataHandle.gather(buf,e);
1223     }
1224 
1225     template<typename MessageBufferImp, typename Entity>
scatterDune::mdgrid::MultiDomainGrid::LoadBalancingDataHandle1226     void scatter(MessageBufferImp& buf, const Entity& e, std::size_t n)
1227     {
1228       if (e.partitionType() != Dune::InteriorEntity && _grid.leafGridView().indexSet().contains(e))
1229         {
1230           Data subDomains = { 0 };
1231           buf.read(subDomains.buffer);
1232           for (int i = 0; i < subDomains.data; ++i)
1233             {
1234               Data subDomain = { 0 };
1235               buf.read(subDomain.buffer);
1236               _grid._loadBalanceStateMap[_grid.globalIdSet().id(e)].add(subDomain.data);
1237             }
1238           _wrappedDataHandle.scatter(buf,e,n - (subDomains.data + 1));
1239         }
1240       else
1241         _wrappedDataHandle.scatter(buf,e,n);
1242     }
1243 
LoadBalancingDataHandleDune::mdgrid::MultiDomainGrid::LoadBalancingDataHandle1244     LoadBalancingDataHandle(const MultiDomainGrid& grid, WrappedDataHandle& wrappedDataHandle)
1245       : _grid(grid)
1246       , _wrappedDataHandle(wrappedDataHandle)
1247     {}
1248 
1249     const MultiDomainGrid& _grid;
1250     WrappedDataHandle& _wrappedDataHandle;
1251 
1252   };
1253 
1254   struct EmptyDataHandle
1255     : public Dune::CommDataHandleIF<EmptyDataHandle,
1256                                     SubDomainIndex
1257                                     >
1258   {
1259 
containsDune::mdgrid::MultiDomainGrid::EmptyDataHandle1260     bool contains(int dim, int codim) const
1261     {
1262       return false;
1263     }
1264 
fixedSizeDune::mdgrid::MultiDomainGrid::EmptyDataHandle1265     bool fixedSize(int dim, int codim) const
1266     {
1267       return true;
1268     }
1269 
1270     template<typename Entity>
sizeDune::mdgrid::MultiDomainGrid::EmptyDataHandle1271     std::size_t size(const Entity& e) const
1272     {
1273       return 0;
1274     }
1275 
1276     template<typename MessageBufferImp, typename Entity>
gatherDune::mdgrid::MultiDomainGrid::EmptyDataHandle1277     void gather(MessageBufferImp& buf, const Entity& e) const
1278     {
1279     }
1280 
1281     template<typename MessageBufferImp, typename Entity>
scatterDune::mdgrid::MultiDomainGrid::EmptyDataHandle1282     void scatter(MessageBufferImp& buf, const Entity& e, std::size_t n)
1283     {
1284     }
1285 
1286   };
1287 
1288 };
1289 
1290 enum MultiDomainGridType { multiDomainGrid, subDomainGrid, other };
1291 
1292 template<typename T>
1293 struct GridType {
1294   static const MultiDomainGridType v = other;
1295 };
1296 
1297 template<class HostGrid, typename MDGridTraits>
1298 struct GridType<MultiDomainGrid<HostGrid,MDGridTraits> > {
1299   static const MultiDomainGridType v = multiDomainGrid;
1300 };
1301 
1302 template<class MDGrid>
1303 struct GridType<subdomain::SubDomainGrid<MDGrid> > {
1304   static const MultiDomainGridType v = subDomainGrid;
1305 };
1306 
1307 } // namespace mdgrid
1308 
1309 } // namespace Dune
1310 
1311 #endif // DUNE_MULTIDOMAINGRID_MULTIDOMAINGRID_HH
1312