// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- // vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_MULTIMESH_GRID_HH #define DUNE_MULTIMESH_GRID_HH #include #include #include #include #include #include #include // The components of the MultiMesh interface #include "mmentity.hh" #include "mmentityseed.hh" #include "mmgridview.hh" #include "mmiterator.hh" namespace Dune { // Forward declaration template class MultiMesh; template struct MultiMeshFamily { struct Traits : HostGrid::GridFamily::Traits { /// The type that implements the grid. using Grid = Dune::MultiMesh; /// Traits associated with a specific codim. template struct Codim : public HostGrid::GridFamily::Traits::template Codim { /// The type of the entity seed of this codim. using EntitySeed = Dune::EntitySeed >; /// Traits associated with a specific grid partition type. template struct Partition { /// The type of the iterator over the level entities of this codim on this partition. // using LevelIterator = Dune::EntityIterator >; using LevelIterator = MultiMeshIterator; /// The type of the iterator over the leaf entities of this codim on this partition. // using LeafIterator = Dune::EntityIterator >; using LeafIterator = MultiMeshIterator; }; /// The type of the iterator over all leaf entities of this codim. using LeafIterator = typename Partition::LeafIterator; /// The type of the entity pointer for entities of this codim. using LevelIterator = typename Partition::LevelIterator; private: friend class HostGrid::GridFamily::Traits::template Codim::Entity; }; /// The type of view for leaf grid using LeafGridView = Dune::GridView >; /// The type of view for level grid using LevelGridView = Dune::GridView >; }; }; /// \brief Provides a meta grid that encapsulates n versions of its host grid /** * \ingroup GridImplementations * \ingroup MultiMesh * * \tparam HostGrid The host grid type wrapped by the MultiMesh */ template class MultiMesh : public GridDefaultImplementation > { template friend class MultiMeshIterator; template friend class MultiMeshLevelGridView; template friend class MultiMeshLeafGridView; template friend class MultiEntity; friend class GridFactory >; using Super = GridDefaultImplementation >; public: using HostGridType = HostGrid; /// Type of the used GridFamily for this grid using GridFamily = MultiMeshFamily; /// The Traits using Traits = typename MultiMeshFamily::Traits; /// The type used to store coordinates, inherited from the HostGrid using ctype = typename HostGrid::ctype; /// \brief Constructor, stores n copies of the hostgrid /** * \param n The number of host grids to handle by the MultiMesh */ template explicit MultiMesh (std::size_t n, Args&&... args) { grids_.reserve(n); for (std::size_t i = 0; i < n; ++i) grids_.emplace_back(std::make_unique(std::forward(args)...)); } // Initialize an empty MultiMesh MultiMesh () = default; /// Return the number of grids handled by this MultiMesh std::size_t size() const { return grids_.size(); } /// Returns the i'th grid managed by this MultiMesh HostGridType& operator[] (std::size_t i) { assert(i < grids_.size()); return *grids_[i]; } /// Returns the i'th grid managed by this MultiMesh HostGridType const& operator[] (std::size_t i) const { assert(i < grids_.size()); return *grids_[i]; } /// \brief Return maximum level defined in all grid. /** * Levels are numbered 0 ... maxlevel with 0 the coarsest level. */ int maxLevel () const { return std::accumulate(grids_.begin(), grids_.end(), 0, [](int level, auto const& grid) { return std::max(level, grid->maxLevel()); }); } /// Iterator to first entity of given codim on level template typename Traits::template Codim::template Partition::LevelIterator lbegin (int level) const { return MultiMeshIterator(this, level); } /// one past the end on this level template typename Traits::template Codim::template Partition::LevelIterator lend (int level) const { return MultiMeshIterator(this, level, true); } /// Iterator to first leaf entity of given codim template typename Traits::template Codim::template Partition::LeafIterator leafbegin () const { return MultiMeshIterator(this); } /// one past the end of the sequence of leaf entities template typename Traits::template Codim::template Partition::LeafIterator leafend () const { return MultiMeshIterator(this, true); } /// Number of grid entities per level and codim of the first grid int size (int level, int codim) const { assert(false && "Should be called on the i'th grid: grid(i).size(level,codim)"); return grids_[0]->size(level, codim); } /// Returns the number of boundary segments within the macro grid std::size_t numBoundarySegments () const { assert(false && "Should be called on the i'th grid: grid(i).numBoundarySegments()"); return grids_[0]->numBoundarySegments(); } /// Number of leaf entities per codim in this process int size (int codim) const { assert(false && "Should be called on the i'th grid: grid(i).size(codim)"); return leafIndexSet().size(codim); } /// Number of entities per level, codim and geometry type in this process int size (std::size_t idx, int level, GeometryType type) const { return levelIndexSet(level).size(type); } /// Number of leaf entities per codim and geometry type in this process int size (std::size_t idx, GeometryType type) const { return leafIndexSet().size(type); } /// Access to the GlobalIdSet const typename HostGrid::GlobalIdSet& globalIdSet (std::size_t idx) const { return grids_[idx]->globalIdSet(); } /// Return the globalIdSet for grid 0 const typename HostGrid::GlobalIdSet& globalIdSet () const { assert(false && "Should be called on the i'th grid: globalIdSet(i)"); return globalIdSet(0); } /// Access to the LocalIdSet const typename HostGrid::LocalIdSet& localIdSet (std::size_t idx) const { return grids_[idx]->localIdSet(); } /// Return the localIdSet for grid 0 const typename HostGrid::LocalIdSet& localIdSet () const { assert(false && "Should be called on the i'th grid: localIdSet(i)"); return localIdSet(0); } /// Access to the LevelIndexSets const typename HostGrid::LevelIndexSet& levelIndexSet (std::size_t idx, int level) const { if (level < 0 || level > grids_[idx].maxLevel()) { DUNE_THROW(GridError, "levelIndexSet of nonexisting level " << level << " requested!"); } return grids_[idx]->levelIndexSet(level); } /// Return the levelIndexSet for grid 0 const typename HostGrid::LevelIndexSet& levelIndexSet (int level) const { assert(false && "Should be called on the i'th grid: levelIndexSet(i,level)"); return levelIndexSet(0, level); } /// Access to the LeafIndexSet const typename HostGrid::LeafIndexSet& leafIndexSet(std::size_t idx) const { return grids_[idx]->leafIndexSet(); } /// Return the leafIndexSet for grid 0 const typename HostGrid::LeafIndexSet& leafIndexSet() const { assert(false && "Should be called on the i'th grid: leafIndexSet(i)"); return leafIndexSet(0); } /// View for a grid level for All_Partition of the idx'th grid typename HostGrid::LevelGridView levelGridView(std::size_t idx, int level) const { return grids_[idx]->levelGridView(level); } /// Return \ref MultiMeshLevelGridView, i.e. a view on the combined /// level of all grids using Super::levelGridView; /// View for the leaf grid for All_Partition of the idx'th grid typename HostGrid::LeafGridView leafGridView(std::size_t idx) const { return grids_[idx]->leafGridView(); } /// Return \ref MultiMeshLeafGridView, i.e. a view on the combined /// leaf-level of all grids using Super::leafGridView; /// Create Entity from EntitySeed template typename Traits::template Codim::Entity entity(const EntitySeed& seed) const { std::size_t gridIdx = this->getRealImplementation(seed).gridIndex(); return grids_[gridIdx]->entity(this->getRealImplementation(seed).hostEntitySeed()); } /** @name Grid Refinement Methods */ /** @{ */ /// Global refinement of all handled grids void globalRefine (int refCount) { for (auto& grid : grids_) grid->globalRefine(refCount); } /// Returns true, if at least one entity is marked for adaption in any of the /// handled grids bool preAdapt() { return std::accumulate(grids_.begin(), grids_.end(), false, [](bool b, auto& grid) { return grid->preAdapt() || b; }); } /// Triggers the grid refinement process on all handled grids bool adapt() { return std::accumulate(grids_.begin(), grids_.end(), false, [](bool b, auto& grid) { return grid->adapt() || b; }); } /// Clean up refinement markers on all handled grids void postAdapt() { for (auto& grid : grids_) grid->postAdapt(); } /** @} */ /// Size of the overlap on the leaf level unsigned int overlapSize (int codim) const { return 0u; // TODO: implement } /// Size of the ghost cell layer on the leaf level unsigned int ghostSize (int codim) const { return 0u; // TODO: implement } /// Size of the overlap on a given level unsigned int overlapSize (int level, int codim) const { return 0u; // TODO: implement } /// Size of the ghost cell layer on a given level unsigned int ghostSize (int level, int codim) const { return 0u; // TODO: implement } /// dummy collective communication const auto& comm () const { assert(false && "Should be called on the i'th grid: grid(i).comm()"); return comm(0); } public: // implementation details /// Returns the hostgrid entity encapsulated in given MultiMesh entity template const typename HostGrid::Traits::template Codim::Entity& getHostEntity (const typename Traits::template Codim::Entity& e) const { return this->getRealImplementation(e).hostEntity_; } protected: /// The grids to handle by this MultiMesh std::vector> grids_; }; // end Class MultiMesh namespace Capabilities { /** \brief has entities for some codimensions as host grid * \ingroup MultiMesh */ template struct hasEntity, codim> { static const bool v = hasEntity::v; }; /** \brief has entity-iterator for some codimensions as host grid * \ingroup MultiMesh */ template struct hasEntityIterator, codim> { static const bool v = hasEntityIterator::v; }; /** \brief has conforming level grids when host grid has * \ingroup MultiMesh */ template struct isLevelwiseConforming > { static const bool v = isLevelwiseConforming::v; }; /** \brief has conforming leaf grids when host grid has * \ingroup MultiMesh */ template struct isLeafwiseConforming > { static const bool v = isLeafwiseConforming::v; }; } // end namespace Capabilities } // end namespace Dune #endif // DUNE_MULTIMESH_GRID_HH