1#ifndef DUNE_MULTIDOMAINGRID_SUBDOMAINGRID_HH 
    2#define DUNE_MULTIDOMAINGRID_SUBDOMAINGRID_HH 
    7#include <dune/common/exceptions.hh> 
    9#include <dune/grid/multidomaingrid/hostgridaccessor.hh> 
   10#include <dune/grid/multidomaingrid/subdomainset.hh> 
   12#include <dune/grid/multidomaingrid/subdomaingrid/geometry.hh> 
   13#include <dune/grid/multidomaingrid/subdomaingrid/localgeometry.hh> 
   14#include <dune/grid/multidomaingrid/subdomaingrid/entity.hh> 
   15#include <dune/grid/multidomaingrid/subdomaingrid/iterator.hh> 
   16#include <dune/grid/multidomaingrid/subdomaingrid/hierarchiciterator.hh> 
   17#include <dune/grid/multidomaingrid/subdomaingrid/intersection.hh> 
   18#include <dune/grid/multidomaingrid/subdomaingrid/intersectioniterator.hh> 
   19#include <dune/grid/multidomaingrid/subdomaingrid/idsets.hh> 
   20#include <dune/grid/multidomaingrid/subdomaingrid/indexsets.hh> 
   21#include <dune/grid/multidomaingrid/subdomaingrid/gridview.hh> 
   30template<
typename,
typename>
 
   35template<
typename MDGr
id>
 
   38template<
typename MDGr
id>
 
   39struct SubDomainGridFamily {
 
   43  static const int dim  = MDGrid::dimension;
 
   44  static const int dimw = MDGrid::dimensionworld;
 
   51    using Grid = SubDomainGrid<MDGrid>;
 
   54    using LeafIntersection = Dune::Intersection<
 
   60          typename MDGrid::LeafIndexSetImp
 
   62        typename MDGrid::LeafGridView::Intersection
 
   66    using LevelIntersection = Dune::Intersection<
 
   72          typename MDGrid::LevelIndexSetImp
 
   74        typename MDGrid::LevelGridView::Intersection
 
   78    using LeafIntersectionIterator = Dune::IntersectionIterator<
 
   80      IntersectionIteratorWrapper<
 
   84          typename MDGrid::LeafIndexSetImp
 
   86        typename MDGrid::LeafGridView::IntersectionIterator
 
   92          typename MDGrid::LeafIndexSetImp
 
   94        typename MDGrid::LeafGridView::Intersection
 
   98    using LevelIntersectionIterator = Dune::IntersectionIterator<
 
  100      IntersectionIteratorWrapper<
 
  104          typename MDGrid::LevelIndexSetImp
 
  106        typename MDGrid::LevelGridView::IntersectionIterator
 
  112          typename MDGrid::LevelIndexSetImp
 
  114        typename MDGrid::LevelGridView::Intersection
 
  118    using HierarchicIterator = Dune::EntityIterator< 0, const Grid, HierarchicIteratorWrapper< const Grid > >;
 
  120    using LevelGridView = Dune::GridView<LevelGridViewTraits<const Grid>>;
 
  121    using LeafGridView = Dune::GridView<LeafGridViewTraits<const Grid>>;
 
  127      using Geometry      = Dune::Geometry<dim-cd, dimw, 
const Grid, GeometryWrapper>;
 
  128      using LocalGeometry = Dune::Geometry<dim-cd, dim, 
const Grid, LocalGeometryWrapper>;
 
  130      using Entity        = Dune::Entity<cd, dim, const Grid, EntityWrapper>;
 
  132      using EntitySeed    = EntitySeedWrapper<typename MDGrid::HostGrid::template Codim<cd>::EntitySeed>;
 
  134      template <PartitionIteratorType pitype>
 
  138        using LevelIterator = Dune::EntityIterator<
 
  142            typename Traits::LevelGridView,
 
  143            typename MDGrid::LevelGridView::template Codim<cd>::template Partition<pitype>::Iterator,
 
  150        using LeafIterator = Dune::EntityIterator<
 
  154            typename Traits::LeafGridView,
 
  155            typename MDGrid::LeafGridView::template Codim<cd>::template Partition<pitype>::Iterator,
 
  163      using LeafIterator  = 
typename Partition< All_Partition >::LeafIterator;
 
  164      using LevelIterator = 
typename Partition< All_Partition >::LevelIterator;
 
  167      friend class Dune::Entity<cd, dim, const Grid, EntityWrapper>;
 
  171    using LevelIndexSet = IndexSetWrapper<const Grid, typename MDGrid::LevelIndexSetImp>;
 
  172    using LeafIndexSet  = IndexSetWrapper<const Grid, typename MDGrid::LeafIndexSetImp>;
 
  174    using GlobalIdSet = IdSet<
 
  178        typename MDGrid::HostGrid::Traits::GlobalIdSet
 
  180      typename MDGrid::HostGrid::Traits::GlobalIdSet::IdType
 
  183    using LocalIdSet = IdSet<
 
  187        typename MDGrid::HostGrid::Traits::LocalIdSet
 
  189      typename MDGrid::HostGrid::Traits::LocalIdSet::IdType
 
  192    using Communication = 
typename MDGrid::Communication;
 
  198template<
typename MDGr
id>
 
  200    public GridDefaultImplementation<MDGrid::dimension,
 
  201                                     MDGrid::dimensionworld,
 
  202                                     typename MDGrid::ctype,
 
  203                                     SubDomainGridFamily<MDGrid> > {
 
  205  template<
typename,
typename>
 
  206  friend class ::Dune::mdgrid::MultiDomainGrid;
 
  208  template<
int codim, 
int dim, 
typename Gr
idImp>
 
  209  friend class EntityWrapperBase;
 
  211  template<
int codim, 
int dim, 
typename Gr
idImp>
 
  212  friend class EntityWrapper;
 
  214  template<
typename, 
typename, 
int codim, PartitionIteratorType pitype, 
typename Gr
idImp>
 
  215  friend class IteratorWrapper;
 
  217  template<
typename Gr
idImp>
 
  218  friend class HierarchicIteratorWrapper;
 
  220  template<
int mydim, 
int coorddim, 
typename Gr
idImp>
 
  221  friend class GeometryWrapper;
 
  223  template<
int mydim, 
int coorddim, 
typename Gr
idImp>
 
  224  friend class LocalGeometryWrapper;
 
  226  template<
typename Gr
idImp, 
typename WrappedIndexSet>
 
  227  friend class IndexSetWrapper;
 
  229  template<
typename Gr
idImp, 
typename WrappedIdSet>
 
  230  friend class IdSetWrapper;
 
  232  template<
typename Gr
idImp>
 
  233  friend struct ::Dune::mdgrid::detail::HostGridAccessor;
 
  235  template<
typename,
typename,
typename>
 
  236  friend class IntersectionIteratorWrapper;
 
  238  template<
typename,
typename,
typename>
 
  239  friend class IntersectionWrapper;
 
  242  friend class LevelGridView;
 
  245  friend class LeafGridView;
 
  247  typedef GridDefaultImplementation<MDGrid::dimension,
 
  248                                    MDGrid::dimensionworld,
 
  249                                    typename MDGrid::ctype,
 
  250                                    SubDomainGridFamily<MDGrid>
 
  253  using GridImp = SubDomainGrid<MDGrid>;
 
  257  using MultiDomainGrid = MDGrid;
 
  259  using HostGrid = 
typename MDGrid::HostGrid;
 
  263  typedef IndexSetWrapper<const SubDomainGrid<MDGrid>, 
typename MDGrid::LevelIndexSetImp> LevelIndexSetImp;
 
  265  typedef IndexSetWrapper<const SubDomainGrid<MDGrid>, 
typename MDGrid::LeafIndexSetImp> LeafIndexSetImp;
 
  267  typedef IdSetWrapper<const SubDomainGrid<MDGrid>, 
typename HostGrid::Traits::GlobalIdSet> GlobalIdSetImp;
 
  269  typedef IdSetWrapper<const SubDomainGrid<MDGrid>, 
typename HostGrid::Traits::LocalIdSet> LocalIdSetImp;
 
  273  typedef SubDomainGridFamily<MDGrid> GridFamily;
 
  274  typedef typename GridFamily::Traits Traits;
 
  277  typedef typename MDGrid::ctype ctype;
 
  280  typedef typename MDGrid::SubDomainIndex SubDomainIndex;
 
  282  enum IntersectionType { neighbor, foreign, boundary, processor };
 
  284  using BaseT::dimension;
 
  285  using BaseT::dimensionworld;
 
  290  template<
typename EntitySeed>
 
  291  typename Traits::template Codim<EntitySeed::codimension>::Entity
 
  292  entity(
const EntitySeed& entitySeed)
 const 
  295      EntityWrapper<EntitySeed::codimension,dimension,const GridImp>(
 
  297        typename MDGrid::template Codim<EntitySeed::codimension>::Entity(
 
  298          _grid.entity(entitySeed)
 
  303  int maxLevel()
 const {
 
  304    return _grid.maxLevel();
 
  308  typename Traits::template Codim<codim>::LevelIterator lbegin(
int level)
 const {
 
  309    return IteratorWrapper<
 
  310      typename Traits::LevelGridView,
 
  311      typename MultiDomainGrid::LevelGridView::template Codim<codim>::template Partition<All_Partition>::Iterator,
 
  316                     &this->levelGridView(level).indexSet(),
 
  317                     _grid.levelGridView(level).template begin<codim>(),
 
  318                     _grid.levelGridView(level).template end<codim>()
 
  323  typename Traits::template Codim<codim>::LevelIterator lend(
int level)
 const {
 
  324    return IteratorWrapper<
 
  325      typename Traits::LevelGridView,
 
  326      typename MultiDomainGrid::LevelGridView::template Codim<codim>::template Partition<All_Partition>::Iterator,
 
  331                     &this->levelGridView(level).indexSet(),
 
  332                     _grid.levelGridView(level).template end<codim>(),
 
  333                     _grid.levelGridView(level).template end<codim>()
 
  337  template<
int codim, PartitionIteratorType pitype>
 
  338  typename Traits::template Codim<codim>::template Partition<pitype>::LevelIterator lbegin(
int level)
 const {
 
  339    return IteratorWrapper<
 
  340      typename Traits::LevelGridView,
 
  341      typename MultiDomainGrid::LevelGridView::template Codim<codim>::template Partition<pitype>::Iterator,
 
  346                     &this->levelGridView(level).indexSet(),
 
  347                     _grid.levelGridView(level).template begin<codim,pitype>(),
 
  348                     _grid.levelGridView(level).template end<codim,pitype>()
 
  352  template<
int codim, PartitionIteratorType pitype>
 
  353  typename Traits::template Codim<codim>::template Partition<pitype>::LevelIterator lend(
int level)
 const {
 
  354    return IteratorWrapper<
 
  355      typename Traits::LevelGridView,
 
  356      typename MultiDomainGrid::LevelGridView::template Codim<codim>::template Partition<pitype>::Iterator,
 
  361                     &this->levelGridView(level).indexSet(),
 
  362                     _grid.levelGridView(level).template end<codim,pitype>(),
 
  363                     _grid.levelGridView(level).template end<codim,pitype>()
 
  368  typename Traits::template Codim<codim>::LeafIterator leafbegin()
 const {
 
  369    return IteratorWrapper<
 
  370      typename Traits::LeafGridView,
 
  371      typename MultiDomainGrid::LeafGridView::template Codim<codim>::template Partition<All_Partition>::Iterator,
 
  376                     &this->leafGridView().indexSet(),
 
  377                     _grid.leafGridView().template begin<codim>(),
 
  378                     _grid.leafGridView().template end<codim>()
 
  383  typename Traits::template Codim<codim>::LeafIterator leafend()
 const {
 
  384    return IteratorWrapper<
 
  385      typename Traits::LeafGridView,
 
  386      typename MultiDomainGrid::LeafGridView::template Codim<codim>::template Partition<All_Partition>::Iterator,
 
  391                     &this->leafGridView().indexSet(),
 
  392                     _grid.leafGridView().template end<codim>(),
 
  393                     _grid.leafGridView().template end<codim>()
 
  397  template<
int codim, PartitionIteratorType pitype>
 
  398  typename Traits::template Codim<codim>::template Partition<pitype>::LeafIterator leafbegin()
 const {
 
  399    return IteratorWrapper<
 
  400      typename Traits::LeafGridView,
 
  401      typename MultiDomainGrid::LeafGridView::template Codim<codim>::template Partition<pitype>::Iterator,
 
  406                     &this->leafGridView().indexSet(),
 
  407                     _grid.leafGridView().template begin<codim,pitype>(),
 
  408                     _grid.leafGridView().template end<codim,pitype>()
 
  412  template<
int codim, PartitionIteratorType pitype>
 
  413  typename Traits::template Codim<codim>::template Partition<pitype>::LeafIterator leafend()
 const {
 
  414    return IteratorWrapper<
 
  415      typename Traits::LeafGridView,
 
  416      typename MultiDomainGrid::LeafGridView::template Codim<codim>::template Partition<pitype>::Iterator,
 
  421                     &this->leafGridView().indexSet(),
 
  422                     _grid.leafGridView().template end<codim,pitype>(),
 
  423                     _grid.leafGridView().template end<codim,pitype>()
 
  427  int size(
int level, 
int codim)
 const {
 
  428    assert(level <= maxLevel());
 
  429    return _levelIndexSets[level]->size(codim);
 
  432  int size(
int codim)
 const {
 
  433    return _leafIndexSet.size(codim);
 
  436  int size(
int level, GeometryType type)
 const {
 
  437    assert(level <= maxLevel());
 
  438    return _levelIndexSets[level]->size(type);
 
  441  int size(GeometryType type)
 const {
 
  443    return _leafIndexSet.size(type);
 
  446  const typename Traits::GlobalIdSet& globalIdSet()
 const {
 
  450  const typename Traits::LocalIdSet& localIdSet()
 const {
 
  454  const typename Traits::LevelIndexSet& levelIndexSet(
int level)
 const {
 
  455    if (!_grid.supportLevelIndexSets()) {
 
  456      DUNE_THROW(GridError,
"level index set support not enabled for this grid");
 
  458    assert(level <= maxLevel());
 
  459    assert(_levelIndexSets[level]);
 
  460    return *_levelIndexSets[level];
 
  463  const typename Traits::LeafIndexSet& leafIndexSet()
 const {
 
  464    return _leafIndexSet;
 
  474  void globalRefine(
int refCount) {
 
  475    DUNE_THROW(NotImplemented,
"grid modification only allowed on the MultiDomainGrid");
 
  489  bool mark(
int refCount, 
const typename Traits::template Codim<0>::Entity& e) {
 
  490    return _grid.mark(refCount,multiDomainEntity(e));
 
  501  int getMark(
const typename Traits::template Codim<0>::Entity& e) {
 
  502    return _grid.getMark(multiDomainEntity(e));
 
  513    DUNE_THROW(NotImplemented,
"grid modification only allowed on the MultiDomainGrid");
 
  524    DUNE_THROW(NotImplemented,
"grid modification only allowed on the MultiDomainGrid");
 
  535    DUNE_THROW(NotImplemented,
"grid modification only allowed on the MultiDomainGrid");
 
  538  int overlapSize(
int level, 
int codim)
 const {
 
  539    return _grid.overlapSize(level,codim);
 
  542  int overlapSize(
int codim)
 const {
 
  543    return _grid.overlapSize(codim);
 
  546  int ghostSize(
int level, 
int codim)
 const {
 
  547    return _grid.ghostSize(level,codim);
 
  550  int ghostSize(
int codim)
 const {
 
  551    return _grid.ghostSize(codim);
 
  554  const typename Traits::Communication& comm()
 const {
 
  558  template<
typename DataHandleImp, 
typename DataTypeImp>
 
  559  void communicate (CommDataHandleIF<DataHandleImp,DataTypeImp> &data,
 
  560                    InterfaceType iftype,
 
  561                    CommunicationDirection dir,
 
  564    DataHandleWrapper<CommDataHandleIF<DataHandleImp,DataTypeImp> > datahandle(data,*
this);
 
  565    _grid.hostGrid().levelGridView(level).communicate(datahandle,iftype,dir);
 
  568  template<
typename DataHandleImp, 
typename DataTypeImp>
 
  569  void communicate (CommDataHandleIF<DataHandleImp,DataTypeImp> &data,
 
  570                    InterfaceType iftype,
 
  571                    CommunicationDirection dir)
 const 
  573    DataHandleWrapper<CommDataHandleIF<DataHandleImp,DataTypeImp> > datahandle(data,*
this);
 
  574    _grid.hostGrid().leafGridView().communicate(datahandle,iftype,dir);
 
  577  size_t numBoundarySegments()
 const 
  579    return _grid.numBoundarySegments();
 
  585  const MDGrid& multiDomainGrid()
 const {
 
  590  SubDomainIndex domain()
 const {
 
  595    if (_grid.supportLevelIndexSets()) {
 
  596      while (_levelIndexSets.size() <= 
static_cast<std::size_t
>(maxLevel())) {
 
  597        _levelIndexSets.push_back(std::make_shared<LevelIndexSetImp>(*
this,_grid.levelIndexSet(_levelIndexSets.size())));
 
  602  bool operator==(
const SubDomainGrid& rhs)
 const {
 
  603    return (&_grid == &rhs._grid && _subDomain == rhs._subDomain);
 
  611      std::enable_if_t<std::is_same_v<typename MDGrid::Traits::template Codim<EntityType::codimension>::Entity,EntityType>, 
int> = 0>
 
  612  typename Traits::template Codim<EntityType::codimension>::Entity subDomainEntity(
const EntityType& mdEntity)
 const {
 
  613    return EntityWrapper<EntityType::codimension,dimension,const GridImp>(
this,mdEntity);
 
  619      std::enable_if_t<std::is_same_v<typename MDGrid::Traits::template Codim<EntityType::codimension>::Entity,EntityType>, 
int> = 0>
 
  620  static const EntityType&
 
  621  multiDomainEntity(
const EntityType &e) {
 
  627      std::enable_if_t<!std::is_same_v<typename MDGrid::Traits::template Codim<EntityType::codimension>::Entity,EntityType>,
int> = 0>
 
  628  static const typename MDGrid::Traits::template Codim<EntityType::codimension>::Entity &
 
  629  multiDomainEntity(
const EntityType &e) {
 
  630    return e.impl().multiDomainEntity();
 
  633  template<
typename EntityType>
 
  634  static const typename MDGrid::template HostEntity<EntityType>::type& hostEntity(
const EntityType& e) {
 
  635    return e.impl().hostEntity();
 
  638  static const auto& multiDomainIntersection(
const typename Traits::LeafIntersection& is) {
 
  639    return is.impl().multiDomainIntersection();
 
  642  static const auto& multiDomainIntersection(
const typename Traits::LevelIntersection& is) {
 
  643    return is.impl().multiDomainIntersection();
 
  648  typename Traits::LeafIntersectionIterator subDomainIntersectionIterator(
const typename MDGrid::LeafSubDomainInterfaceIterator it)
 const {
 
  649    assert(_subDomain == it->subDomain1() || _subDomain == it->subDomain2());
 
  650    if (_subDomain == it->subDomain1())
 
  651      return IntersectionIteratorWrapper<
 
  653        typename GridImp::LeafGridView::IndexSet,
 
  654        typename MDGrid::LeafGridView::IntersectionIterator
 
  656          &this->leafGridView().indexSet(),
 
  657          it->firstMultiDomainIntersectionIterator()
 
  660      return IntersectionIteratorWrapper<
 
  662        typename GridImp::LeafGridView::IndexSet,
 
  663        typename MDGrid::LeafGridView::IntersectionIterator
 
  665          &this->leafGridView().indexSet(),
 
  666          it->secondMultiDomainIntersectionIterator()
 
  670  typename Traits::LevelIntersectionIterator subDomainIntersectionIterator(
const typename MDGrid::LevelSubDomainInterfaceIterator it)
 const {
 
  671    assert(_subDomain == it->subDomain1() || _subDomain == it->subDomain2());
 
  672    if (_subDomain == it->subDomain1())
 
  673      return IntersectionIteratorWrapper<
 
  675        typename GridImp::LevelGridView::IndexSet,
 
  676        typename MDGrid::LevelGridView::IntersectionIterator
 
  678          &this->levelGridView(it->firstMultiDomainIntersectionIterator()->inside().level()).indexSet(),
 
  679          it->firstMultiDomainIntersectionIterator()
 
  682      return IntersectionIteratorWrapper<
 
  684        typename GridImp::LevelGridView::IndexSet,
 
  685        typename MDGrid::LevelGridView::IntersectionIterator
 
  687          &this->levelGridView(it->secondMultiDomainIntersectionIterator()->inside().level()).indexSet(),
 
  688          it->secondMultiDomainIntersectionIterator()
 
  692  template<
typename Intersection>
 
  693  IntersectionType intersectionType(
const Intersection& intersection)
 const {
 
  694    return intersection.impl().intersectionType();
 
  700  SubDomainIndex _subDomain;
 
  701  GlobalIdSetImp _globalIdSet;
 
  702  LocalIdSetImp _localIdSet;
 
  703  LeafIndexSetImp _leafIndexSet;
 
  704  std::vector<std::shared_ptr<LevelIndexSetImp> > _levelIndexSets;
 
  706  SubDomainGrid(MDGrid& grid, SubDomainIndex subDomain) :
 
  708    _subDomain(subDomain),
 
  709    _globalIdSet(*this,grid.hostGrid().globalIdSet()),
 
  710    _localIdSet(*this,grid.hostGrid().localIdSet()),
 
  711    _leafIndexSet(*this,grid.leafIndexSet())
 
  716  template<
typename EntityType>
 
  717  bool containsMultiDomainEntity(
const EntityType& e)
 const {
 
  718    if (_grid.supportLevelIndexSets())
 
  719      return levelIndexSet(e.level()).containsMultiDomainEntity(e);
 
  721      return leafIndexSet().containsMultiDomainEntity(e);
 
  724  template<
typename EntityType>
 
  725  bool containsHostEntity(
const EntityType& e)
 const {
 
  726    if (_grid.supportLevelIndexSets())
 
  727      return levelIndexSet(e.level()).containsHostEntity(e);
 
  729      return leafIndexSet().containsHostEntity(e);
 
  732  SubDomainGrid(
const SubDomainGrid& rv);
 
  733  SubDomainGrid& operator=(
const SubDomainGrid& rv);
 
  736  template<
typename Impl>
 
  737  struct DataHandleWrapper
 
  738    : 
public Dune::CommDataHandleIF<DataHandleWrapper<Impl>,
 
  739                                    typename Impl::DataType
 
  743    bool contains(
int dim, 
int codim)
 const 
  745      return _impl.contains(dim,codim); 
 
  748    bool fixedSize(
int dim, 
int codim)
 const 
  754    template<
typename Entity>
 
  755    std::size_t size(
const Entity& e)
 const 
  757      if (_grid.containsHostEntity(e))
 
  758        return _impl.size(_grid.subDomainEntity(_grid._grid.wrapHostEntity(e)));
 
  763    template<
typename MessageBufferImp, 
typename Entity>
 
  764    void gather(MessageBufferImp& buf, 
const Entity& e)
 const 
  766      if (_grid.containsHostEntity(e))
 
  767        _impl.gather(buf,_grid.subDomainEntity(_grid._grid.wrapHostEntity(e)));
 
  770    template<
typename MessageBufferImp, 
typename Entity>
 
  771    void scatter(MessageBufferImp& buf, 
const Entity& e, std::size_t n)
 
  773      if (_grid.containsHostEntity(e))
 
  774        _impl.scatter(buf,_grid.subDomainEntity(_grid._grid.wrapHostEntity(e)),n);
 
  777    DataHandleWrapper(Impl& impl, 
const SubDomainGrid<MDGrid>& grid)
 
  783    const SubDomainGrid<MDGrid>& _grid;