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