Loading [MathJax]/extensions/tex2jax.js
3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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#include <utility>
29
30#include <dune/common/shared_ptr.hh>
31#include <dune/common/concept.hh>
32
33// SubGrid specific includes
34#if HAVE_DUNE_SUBGRID
35#include <dune/subgrid/subgrid.hh>
37#endif
38
39#ifndef DUMUX_IO_GRID_MANAGER_HH
41#endif
42
45
46#if HAVE_DUNE_SUBGRID
47namespace Dumux {
48namespace Concept {
49
54template<class Element>
55struct ElementSelector
56{
57 template<class F>
58 auto require(F&& f) -> decltype(
59 bool(f(std::declval<const Element&>()))
60 );
61};
62} // end namespace Concept
63
68template <class HostGrid, class HostGridManager = GridManager<HostGrid>>
69class SubGridManagerBase
70: public GridManagerBase<Dune::SubGrid<HostGrid::dimension, HostGrid>>
71{
72 static constexpr int dim = HostGrid::dimension;
73 using HostElement = typename HostGrid::template Codim<0>::Entity;
74 using GlobalPosition = typename HostElement::Geometry::GlobalCoordinate;
75
76public:
78
82 template<class ES,
83 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
84 void init(HostGrid& hostGrid,
85 const ES& selector,
86 const std::string& paramGroup = "")
87 {
88 this->gridPtr() = createGrid_(hostGrid, selector, paramGroup);
89 loadBalance();
90 }
91
95 template<class ES,
96 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
97 void init(const ES& selector,
98 const std::string& paramGroup = "")
99 {
100 initHostGrid_(paramGroup);
101 this->gridPtr() = createGrid_(hostGridManager_->grid(), selector, paramGroup);
102 loadBalance();
103 }
104
108 void loadBalance()
109 {
110 if (Dune::MPIHelper::getCommunication().size() > 1)
111 this->grid().loadBalance();
112 }
113
114protected:
115
119 template<class ES,
120 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
121 static std::unique_ptr<Grid> createGrid_(HostGrid& hostGrid,
122 const ES& selector,
123 const std::string& paramGroup = "")
124 {
125 // A unique pointer to the subgrid.
126 auto subgridPtr = std::make_unique<Grid>(hostGrid);
127
128 // A container to store the host grid elements' ids.
129 std::set<typename HostGrid::Traits::GlobalIdSet::IdType> elementsForSubgrid;
130 const auto& globalIDset = subgridPtr->getHostGrid().globalIdSet();
131
132 // Construct the subgrid.
133 subgridPtr->createBegin();
134
135 // Loop over all elements of the host grid and use the selector to
136 // choose which elements to add to the subgrid.
137 auto hostGridView = subgridPtr->getHostGrid().leafGridView();
138 for (const auto& e : elements(hostGridView))
139 if (selector(e))
140 elementsForSubgrid.insert(globalIDset.template id<0>(e));
141
142 if (elementsForSubgrid.empty())
143 DUNE_THROW(Dune::GridError, "No elements in subgrid");
144
145 subgridPtr->insertSetPartial(elementsForSubgrid);
146 subgridPtr->createEnd();
147
148 // Return a unique pointer to the subgrid.
149 return subgridPtr;
150 }
151
152 void initHostGrid_(const std::string& paramGroup)
153 {
154 hostGridManager_ = std::make_unique<HostGridManager>();
155 hostGridManager_->init(paramGroup);
156 }
157
158 void initHostGrid_(const GlobalPosition& lowerLeft,
159 const GlobalPosition& upperRight,
160 const std::array<int, dim>& cells,
161 const std::string& paramGroup,
162 const int overlap = 1)
163 {
164 hostGridManager_ = std::make_unique<HostGridManager>();
165 hostGridManager_->init(lowerLeft, upperRight, cells, paramGroup, overlap);
166 }
167
171 HostGrid& hostGrid_()
172 {
173 return hostGridManager_->grid();
174 }
175
176 std::unique_ptr<HostGridManager> hostGridManager_;
177};
178
187template<int dim, class HostGrid>
188class GridManager<Dune::SubGrid<dim, HostGrid>>
189: public SubGridManagerBase<HostGrid, GridManager<HostGrid>>
190{};
191
202template<int dim, class Coordinates>
203class GridManager<Dune::SubGrid<dim, Dune::YaspGrid<dim, Coordinates>>>
204: public SubGridManagerBase<Dune::YaspGrid<dim, Coordinates>, GridManager<Dune::YaspGrid<dim, Coordinates>>>
205{
206 using ParentType = SubGridManagerBase<Dune::YaspGrid<dim, Coordinates>,
207 GridManager<Dune::YaspGrid<dim, Coordinates>>>;
208public:
209 using typename ParentType::Grid;
210 using ParentType::init;
211
217 void init(const std::string& paramGroup = "")
218 {
219 // check if there is an image file we can construct the element selector from
220 if (hasParamInGroup(paramGroup, "Grid.Image"))
221 {
222 const auto imgFileName = getParamFromGroup<std::string>(paramGroup, "Grid.Image");
223 const auto ext = this->getFileExtension(imgFileName);
224 if (ext == "pbm")
225 {
226 if (dim != 2)
227 DUNE_THROW(Dune::GridError, "Portable Bitmap Format only supports dim == 2");
228
229 // read image
230 const auto img = NetPBMReader::readPBM(imgFileName);
231 createGridFromImage_(img, paramGroup);
232 }
233 else
234 DUNE_THROW(Dune::IOError, "The SubGridManager doesn't support image files with extension: *." << ext);
235
236 }
237 else
238 DUNE_THROW(Dune::IOError, "SubGridManager couldn't construct element selector. Specify Grid.Image in the input file!");
239 }
240
241private:
242 template<class Img>
243 void createGridFromImage_(const Img& img, const std::string& paramGroup)
244 {
245 using GlobalPosition = typename ParentType::Grid::template Codim<0>::Geometry::GlobalCoordinate;
246 const bool repeated = hasParamInGroup(paramGroup,"Grid.Repeat");
247
248 // get the number of cells
249 const std::array<int, dim> imageDimensions{static_cast<int>(img.header().nCols), static_cast<int>(img.header().nRows)};
250 std::array<int, dim> cells{imageDimensions[0], imageDimensions[1]};
251
252 std::array<int, dim> repeatsDefault; repeatsDefault.fill(1);
253 const auto numRepeats = getParamFromGroup<std::array<int, dim>>(paramGroup, "Grid.Repeat", repeatsDefault);
254 for (int i = 0; i < dim; i++)
255 cells[i] = cells[i] * numRepeats[i];
256
257 // get the corner coordinates
258 const auto [lowerLeft, upperRight] = [&]()
259 {
260 const auto lowerLeft = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.LowerLeft", GlobalPosition(0.0));
261 if (hasParamInGroup(paramGroup, "Grid.PixelDimensions"))
262 {
263 auto upperRight = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.PixelDimensions");
264 for (int i = 0; i < upperRight.size(); ++i)
265 upperRight[i] *= cells[i];
266 upperRight += lowerLeft;
267 return std::make_pair(lowerLeft, upperRight);
268 }
269 else
270 return std::make_pair(lowerLeft, getParamFromGroup<GlobalPosition>(paramGroup, "Grid.UpperRight"));
271 }();
272
273 // construct the host grid
274 this->initHostGrid_(lowerLeft, upperRight, cells, paramGroup);
275
276 // check if the marker is customized, per default
277 // we mark all cells that are encoded as 0
278 const bool marked = getParamFromGroup<bool>(paramGroup, "Grid.Marker", false);
279
280 // Create the element selector for a single image
281 const auto elementSelector = [&](const auto& element)
282 {
283 auto eIdx = this->hostGrid_().leafGridView().indexSet().index(element);
284
285 // if the hostgrid was refined, get the index of the original, un-refined
286 // host grid element which fits with the image's indices
287 if (element.hasFather())
288 {
289 auto level0Element = element.father();
290 while (level0Element.hasFather())
291 level0Element = level0Element.father();
292
293 assert(level0Element.level() == 0);
294 eIdx = this->hostGrid_().levelGridView(0).indexSet().index(level0Element);
295 }
296 return img[eIdx] == marked;
297 };
298
299 // Create the element selector for a repeated image
300 const auto repeatedElementSelector = [&](const auto& element)
301 {
302 auto eIdx = this->hostGrid_().leafGridView().indexSet().index(element);
303
304 // if the hostgrid was refined, get the index of the original, un-refined
305 // host grid element which fits with the image's indices
306 if (element.hasFather())
307 {
308 auto level0Element = element.father();
309 while (level0Element.hasFather())
310 level0Element = level0Element.father();
311
312 assert(level0Element.level() == 0);
313 eIdx = this->hostGrid_().levelGridView(0).indexSet().index(level0Element);
314 }
315
316 // figure out the size of the repeat, and the size of the target repeated grid
317 const int numCols = imageDimensions[0];
318 const int numRows = imageDimensions[1];
319
320 // map the eIdx to the original img index
321 const int repeatUnitIndex = eIdx % (numCols * numRepeats[0] * numRows);
322 const int imgI = repeatUnitIndex % numCols;
323 const int imgJ = repeatUnitIndex / (numCols * numRepeats[0]);
324 return img[ (imgJ * numCols + imgI) ] == marked;
325 };
326
327 // create the grid
328 if (repeated)
329 this->gridPtr() = this->createGrid_(this->hostGrid_(), repeatedElementSelector, paramGroup);
330 else
331 this->gridPtr() = this->createGrid_(this->hostGrid_(), elementSelector, paramGroup);
332
333 this->loadBalance();
334 }
335};
336
338template<int dim, class HostGrid>
339class BoundaryFlag<Dune::SubGrid<dim, HostGrid>>
340{
341public:
342 BoundaryFlag() : flag_(-1) {}
343
344 template<class Intersection>
345 BoundaryFlag(const Intersection& i) : flag_(-1) {}
346
347 using value_type = int;
348
349 value_type get() const
350 { DUNE_THROW(Dune::NotImplemented, "Sub-grid doesn't implement boundary segment indices!"); }
351
352private:
353 int flag_;
354};
355
356} // end namespace Dumux
357#endif // HAVE_DUNE_SUBGRID
358#endif
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Boundary flag to store e.g. in sub control volume faces.
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:177
Adaption of the non-isothermal two-phase two-component flow model to problems with CO2.
Definition: adapt.hh:29
Definition: deprecated.hh:149
std::size_t value_type
Definition: boundaryflag.hh:51
value_type get() const
Definition: boundaryflag.hh:53
Definition: consistentlyorientedgrid.hh:35
void loadBalance()
Call loadBalance() function of the grid.
Definition: gridmanager_base.hh:98
std::shared_ptr< Grid > & gridPtr()
Returns a reference to the grid pointer (std::shared_ptr<Grid>)
Definition: gridmanager_base.hh:146
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:75
std::string getFileExtension(const std::string &fileName) const
Returns the filename extension of a given filename.
Definition: gridmanager_base.hh:168
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:145
Convenience header that includes all grid manager specializations.