3.2-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
gridmanager_sub.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
24#ifndef DUMUX_IO_GRID_MANAGER_SUB_HH
25#define DUMUX_IO_GRID_MANAGER_SUB_HH
26
27#include <memory>
28
29#include <dune/common/shared_ptr.hh>
30#include <dune/common/concept.hh>
31
32// SubGrid specific includes
33#if HAVE_DUNE_SUBGRID
34#include <dune/subgrid/subgrid.hh>
36#endif
37
38#ifndef DUMUX_IO_GRID_MANAGER_HH
40#endif
41
44
45#if HAVE_DUNE_SUBGRID
46namespace Dumux {
47namespace Concept {
48
53template<class Element>
54struct ElementSelector
55{
56 template<class F>
57 auto require(F&& f) -> decltype(
58 bool(f(std::declval<const Element&>()))
59 );
60};
61} // end namespace Concept
62
67template <class HostGrid, class HostGridManager = GridManager<HostGrid>>
68class SubGridManagerBase
69: public GridManagerBase<Dune::SubGrid<HostGrid::dimension, HostGrid>>
70{
71 static constexpr int dim = HostGrid::dimension;
72 using HostElement = typename HostGrid::template Codim<0>::Entity;
73
74public:
75 using Grid = Dune::SubGrid<dim, HostGrid>;
76
80 template<class ES,
81 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
82 void init(HostGrid& hostGrid,
83 const ES& selector,
84 const std::string& paramGroup = "")
85 {
86 this->gridPtr() = createGrid_(hostGrid, selector, paramGroup);
87 loadBalance();
88 }
89
93 template<class ES,
94 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
95 void init(const ES& selector,
96 const std::string& paramGroup = "")
97 {
98 initHostGrid_(paramGroup);
99 this->gridPtr() = createGrid_(hostGridManager_->grid(), selector, paramGroup);
100 loadBalance();
101 }
102
106 void loadBalance()
107 {
108 if (Dune::MPIHelper::getCollectiveCommunication().size() > 1)
109 this->grid().loadBalance();
110 }
111
112protected:
113
117 template<class ES,
118 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
119 static std::unique_ptr<Grid> createGrid_(HostGrid& hostGrid,
120 const ES& selector,
121 const std::string& paramGroup = "")
122 {
123 // A unique pointer to the subgrid.
124 auto subgridPtr = std::make_unique<Grid>(hostGrid);
125
126 // A container to store the host grid elements' ids.
127 std::set<typename HostGrid::Traits::GlobalIdSet::IdType> elementsForSubgrid;
128 const auto& globalIDset = subgridPtr->getHostGrid().globalIdSet();
129
130 // Construct the subgrid.
131 subgridPtr->createBegin();
132
133 // Loop over all elements of the host grid and use the selector to
134 // choose which elements to add to the subgrid.
135 auto hostGridView = subgridPtr->getHostGrid().leafGridView();
136 for (const auto& e : elements(hostGridView))
137 if (selector(e))
138 elementsForSubgrid.insert(globalIDset.template id<0>(e));
139
140 if (elementsForSubgrid.empty())
141 DUNE_THROW(Dune::GridError, "No elements in subgrid");
142
143 subgridPtr->insertSetPartial(elementsForSubgrid);
144 subgridPtr->createEnd();
145
146 // Return a unique pointer to the subgrid.
147 return subgridPtr;
148 }
149
150 void initHostGrid_(const std::string& paramGroup)
151 {
152 hostGridManager_ = std::make_unique<HostGridManager>();
153 hostGridManager_->init(paramGroup);
154 }
155
159 HostGrid& hostGrid_()
160 {
161 return hostGridManager_->grid();
162 }
163
164 std::unique_ptr<HostGridManager> hostGridManager_;
165};
166
175template<int dim, class HostGrid>
176class GridManager<Dune::SubGrid<dim, HostGrid>>
177: public SubGridManagerBase<HostGrid, GridManager<HostGrid>>
178{};
179
190template<int dim, class Coordinates>
191class GridManager<Dune::SubGrid<dim, Dune::YaspGrid<dim, Coordinates>>>
192: public SubGridManagerBase<Dune::YaspGrid<dim, Coordinates>, GridManager<Dune::YaspGrid<dim, Coordinates>>>
193{
194 using ParentType = SubGridManagerBase<Dune::YaspGrid<dim, Coordinates>,
195 GridManager<Dune::YaspGrid<dim, Coordinates>>>;
196public:
197 using typename ParentType::Grid;
198 using ParentType::init;
199
205 void init(const std::string& paramGroup = "")
206 {
207 // check if there is an image file we can construct the element selector from
208 if (hasParamInGroup(paramGroup, "Grid.Image"))
209 {
210 const auto imgFileName = getParamFromGroup<std::string>(paramGroup, "Grid.Image");
211 const auto ext = this->getFileExtension(imgFileName);
212 if (ext == "pbm")
213 {
214 if (dim != 2)
215 DUNE_THROW(Dune::GridError, "Portable Bitmap Format only supports dim == 2");
216
217 // read image
218 const auto img = NetPBMReader::readPBM(imgFileName);
219 createGridFromImage_(img, paramGroup);
220 }
221 else
222 DUNE_THROW(Dune::IOError, "The SubGridManager doesn't support image files with extension: *." << ext);
223
224 }
225 else
226 DUNE_THROW(Dune::IOError, "SubGridManager couldn't construct element selector. Specify Grid.Image in the input file!");
227 }
228
229private:
230 template<class Img>
231 void createGridFromImage_(const Img& img, const std::string& paramGroup)
232 {
233 // check if the number of cells matches
234 std::array<int, dim> cells; cells.fill(1);
235 cells = getParamFromGroup<std::array<int, dim>>(paramGroup, "Grid.Cells", cells);
236
237 if (img.header().nCols != cells[0])
238 DUNE_THROW(Dune::GridError, "Host grid has wrong number of cells in x-direction. Expected "
239 << img.header().nCols << ", got " << cells[0]);
240 if (img.header().nRows != cells[1])
241 DUNE_THROW(Dune::GridError, "Host grid has wrong number of cells in y-direction. Expected "
242 << img.header().nRows << ", got " << cells[1]);
243
244
245 // construct the host grid
246 this->initHostGrid_(paramGroup);
247
248 // check if the marker is customized, per default
249 // we mark all cells that are encoded as 0
250 const bool marked = getParamFromGroup<bool>(paramGroup, "Grid.Marker", 0);
251
252 // Create the selector
253 auto elementSelector = [this, &img, &marked](const auto& element)
254 {
255 const auto eIdx = this->hostGrid_().leafGridView().indexSet().index(element);
256 return img[eIdx] == marked;
257 };
258
259 // create the grid
260 this->gridPtr() = this->createGrid_(this->hostGrid_(), elementSelector, paramGroup);
261 this->loadBalance();
262 }
263};
264
266template<int dim, class HostGrid>
267class BoundaryFlag<Dune::SubGrid<dim, HostGrid>>
268{
269public:
270 BoundaryFlag() : flag_(-1) {}
271
272 template<class Intersection>
273 BoundaryFlag(const Intersection& i) : flag_(-1) {}
274
275 using value_type = int;
276
277 value_type get() const
278 { DUNE_THROW(Dune::NotImplemented, "Sub-grid doesn't implement boundary segment indices!"); }
279
280private:
281 int flag_;
282};
283
284} // end namespace Dumux
285#endif // HAVE_DUNE_SUBGRID
286#endif
Boundary flag to store e.g. in sub control volume faces.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
A simple reader class for raster images.
bool hasParamInGroup(const std::string &paramGroup, const std::string &param)
Check whether a key exists in the parameter tree with a model group prefix.
Definition: parameters.hh:391
Definition: adapt.hh:29
Definition: common/pdesolver.hh:35
std::size_t value_type
Definition: boundaryflag.hh:51
value_type get() const
Definition: boundaryflag.hh:53
void loadBalance()
Call loadBalance() function of the grid.
Definition: gridmanager_base.hh:103
std::shared_ptr< Grid > & gridPtr()
Returns a reference to the grid pointer (std::shared_ptr<Grid>)
Definition: gridmanager_base.hh:142
void init(const std::string &modelParamGroup="")
Make the grid. Implement this method in the specialization of this class for a grid type.
Definition: gridmanager_base.hh:81
std::string getFileExtension(const std::string &fileName) const
Returns the filename extension of a given filename.
Definition: gridmanager_base.hh:164
static Result< bool > readPBM(const std::string &fileName, const bool useDuneGridOrdering=true)
Reads a *pbm (black and white) in ASCII or binary encoding. Returns a struct that contains both the p...
Definition: rasterimagereader.hh:142
Convience header that includes all grid manager specializations.