diff --git a/dumux/io/grid/gridmanager_sub.hh b/dumux/io/grid/gridmanager_sub.hh index 16f884e86fdbd2e3a3f0f4a4466e9210db45cc7e..cf18c0bb848ffe93732876667b8a01fe69435ed7 100644 --- a/dumux/io/grid/gridmanager_sub.hh +++ b/dumux/io/grid/gridmanager_sub.hh @@ -70,6 +70,7 @@ class SubGridManagerBase { static constexpr int dim = HostGrid::dimension; using HostElement = typename HostGrid::template Codim<0>::Entity; + using GlobalPosition = typename HostElement::Geometry::GlobalCoordinate; public: using Grid = Dune::SubGrid<dim, HostGrid>; @@ -153,6 +154,16 @@ protected: hostGridManager_->init(paramGroup); } + void initHostGrid_(const GlobalPosition& lowerLeft, + const GlobalPosition& upperRight, + const std::array<int, dim>& cells, + const std::string& paramGroup, + const int overlap = 1) + { + hostGridManager_ = std::make_unique<HostGridManager>(); + hostGridManager_->init(lowerLeft, upperRight, cells, paramGroup, overlap); + } + /*! * \brief Returns a reference to the host grid. */ @@ -230,20 +241,16 @@ private: template<class Img> void createGridFromImage_(const Img& img, const std::string& paramGroup) { - // check if the number of cells matches - std::array<int, dim> cells; cells.fill(1); - cells = getParamFromGroup<std::array<int, dim>>(paramGroup, "Grid.Cells", cells); - - if (img.header().nCols != cells[0]) - DUNE_THROW(Dune::GridError, "Host grid has wrong number of cells in x-direction. Expected " - << img.header().nCols << ", got " << cells[0]); - if (img.header().nRows != cells[1]) - DUNE_THROW(Dune::GridError, "Host grid has wrong number of cells in y-direction. Expected " - << img.header().nRows << ", got " << cells[1]); + // get the corner coordinates + using GlobalPosition = typename ParentType::Grid::template Codim<0>::Geometry::GlobalCoordinate; + const auto upperRight = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.UpperRight"); + const auto lowerLeft = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.LowerLeft", GlobalPosition(0.0)); + // get the number of cells + const std::array<int, dim> cells{static_cast<int>(img.header().nCols), static_cast<int>(img.header().nRows)}; // construct the host grid - this->initHostGrid_(paramGroup); + this->initHostGrid_(lowerLeft, upperRight, cells, paramGroup); // check if the marker is customized, per default // we mark all cells that are encoded as 0 @@ -252,12 +259,26 @@ private: // Create the selector auto elementSelector = [this, &img, &marked](const auto& element) { - const auto eIdx = this->hostGrid_().leafGridView().indexSet().index(element); + auto eIdx = this->hostGrid_().leafGridView().indexSet().index(element); + + // if the hostgrid was refined, get the index of the original, un-refined + // host grid element which fits with the image's indices + if (element.hasFather()) + { + auto level0Element = element.father(); + while (level0Element.hasFather()) + level0Element = level0Element.father(); + + assert(level0Element.level() == 0); + eIdx = this->hostGrid_().levelGridView(0).indexSet().index(level0Element); + } + return img[eIdx] == marked; }; // create the grid this->gridPtr() = this->createGrid_(this->hostGrid_(), elementSelector, paramGroup); + this->loadBalance(); } }; diff --git a/dumux/io/grid/gridmanager_yasp.hh b/dumux/io/grid/gridmanager_yasp.hh index 6ecb00067e5b62781070e78a5bb0f70abf07374b..d98c73d279aebb191e04726c5fd07fe66c1915c8 100644 --- a/dumux/io/grid/gridmanager_yasp.hh +++ b/dumux/io/grid/gridmanager_yasp.hh @@ -94,10 +94,13 @@ public: // get the overlap const int overlap = getParamFromGroup<int>(modelParamGroup, "Grid.Overlap", 1); - // make the grid - ParentType::gridPtr() = createGrid_(modelParamGroup, upperRight, cells, periodic, overlap, Coordinates{}); - - postProcessing_(modelParamGroup); + if constexpr (std::is_same_v<Dune::EquidistantCoordinates<ct, dim>, Coordinates>) + init(upperRight, cells, modelParamGroup, overlap, periodic); + else + { + const auto lowerLeft = getParamFromGroup<GlobalPosition>(modelParamGroup, "Grid.LowerLeft", GlobalPosition(0.0)); + init(lowerLeft, upperRight, cells, modelParamGroup, overlap, periodic); + } } // Didn't find a way to construct the grid @@ -111,57 +114,67 @@ public: } } -private: /*! - * \brief Create a grid with zero offset + * \brief Make the grid using input data not read from the input file. + * \note Use this function for EquidistantCoordinates where lowerLeft is always zero. */ - std::unique_ptr<Grid> createGrid_(const std::string& modelParamGroup, - const GlobalPosition& upperRight, - const std::array<int, dim>& cells, - const std::bitset<dim>& periodic, - const int overlap, - Dune::EquidistantCoordinates<ct, dim>) const + void init(const GlobalPosition& upperRight, + const std::array<int, dim>& cells, + const std::string& modelParamGroup = "", + const int overlap = 1, + const std::bitset<dim> periodic = std::bitset<dim>{}) { + static_assert(std::is_same_v<Dune::EquidistantCoordinates<ct, dim>, Coordinates>, + "Use init function taking lowerLeft as argument when working with EquidistantOffsetCoordinates"); + if (!hasParamInGroup(modelParamGroup, "Grid.Partitioning")) { // construct using default load balancing - return std::make_unique<Grid>(upperRight, cells, periodic, overlap); + ParentType::gridPtr() = std::make_unique<Grid>(upperRight, cells, periodic, overlap); } else { // construct using user defined partitioning const auto partitioning = getParamFromGroup<std::array<int, dim>>(modelParamGroup, "Grid.Partitioning"); Dune::YaspFixedSizePartitioner<dim> lb(partitioning); - return std::make_unique<Grid>(upperRight, cells, periodic, overlap, typename Grid::CollectiveCommunicationType(), &lb); + ParentType::gridPtr() = std::make_unique<Grid>(upperRight, cells, periodic, overlap, typename Grid::CollectiveCommunicationType(), &lb); } + + postProcessing_(modelParamGroup); } /*! - * \brief Create a grid with non-zero offset + * \brief Make the grid using input data not read from the input file. + * \note Use this function for EquidistantOffsetCoordinates. */ - std::unique_ptr<Grid> createGrid_(const std::string& modelParamGroup, - const GlobalPosition& upperRight, - const std::array<int, dim>& cells, - const std::bitset<dim>& periodic, - const int overlap, - Dune::EquidistantOffsetCoordinates<ct, dim>) const + void init(const GlobalPosition& lowerLeft, + const GlobalPosition& upperRight, + const std::array<int, dim>& cells, + const std::string& modelParamGroup = "", + const int overlap = 1, + const std::bitset<dim> periodic = std::bitset<dim>{}) { - const auto lowerLeft = getParamFromGroup<GlobalPosition>(modelParamGroup, "Grid.LowerLeft", GlobalPosition(0.0)); + static_assert(std::is_same_v<Dune::EquidistantOffsetCoordinates<ct, dim>, Coordinates>, + "LowerLeft can only be specified with EquidistantOffsetCoordinates"); if (!hasParamInGroup(modelParamGroup, "Grid.Partitioning")) { // construct using default load balancing - return std::make_unique<Grid>(lowerLeft, upperRight, cells, periodic, overlap); + ParentType::gridPtr() = std::make_unique<Grid>(lowerLeft, upperRight, cells, periodic, overlap); } else { // construct using user defined partitioning const auto partitioning = getParamFromGroup<std::array<int, dim>>(modelParamGroup, "Grid.Partitioning"); Dune::YaspFixedSizePartitioner<dim> lb(partitioning); - return std::make_unique<Grid>(lowerLeft, upperRight, cells, periodic, overlap, typename Grid::CollectiveCommunicationType(), &lb); + ParentType::gridPtr() = std::make_unique<Grid>(lowerLeft, upperRight, cells, periodic, overlap, typename Grid::CollectiveCommunicationType(), &lb); } + + postProcessing_(modelParamGroup); } +private: + /*! * \brief Postprocessing for YaspGrid */ @@ -252,9 +265,7 @@ public: const std::array<std::vector<ctype>, dim>& grading, const std::string& modelParamGroup = "") { - - - // Additional arameters (they have a default) + // Additional parameters (they have a default) const int overlap = getParamFromGroup<int>(modelParamGroup, "Grid.Overlap", 1); const bool verbose = getParamFromGroup<bool>(modelParamGroup, "Grid.Verbosity", false); // \todo TODO periodic boundaries with yasp (the periodicity concept of yasp grid is currently not supported, use dune-spgrid)