3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
gridmanager_yasp.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_YASP_HH
25#define DUMUX_IO_GRID_MANAGER_YASP_HH
26
27#include <dune/grid/yaspgrid.hh>
28#include <dune/grid/io/file/dgfparser/dgfyasp.hh>
29
30#ifndef DUMUX_IO_GRID_MANAGER_BASE_HH
32#endif
33
34namespace Dumux {
35
54template<class Coordinates, int dim>
55class GridManager<Dune::YaspGrid<dim, Coordinates>>
56: public GridManagerBase<Dune::YaspGrid<dim, Coordinates>>
57{
58 using ct = typename Dune::YaspGrid<dim, Coordinates>::ctype;
59 using GlobalPosition = Dune::FieldVector<ct, dim>;
60public:
61 using Grid = typename Dune::YaspGrid<dim, Coordinates>;
63
67 void init(const std::string& modelParamGroup = "")
68 {
69 // First try to create it from a DGF file in GridParameterGroup.File
70 if (hasParamInGroup(modelParamGroup, "Grid.File"))
71 {
72 ParentType::makeGridFromDgfFile(getParamFromGroup<std::string>(modelParamGroup, "Grid.File"));
73 postProcessing_(modelParamGroup);
74 return;
75 }
76
77 // Then look for the necessary keys to construct from the input file
78 else if (hasParamInGroup(modelParamGroup, "Grid.UpperRight"))
79 {
80 // get the upper right corner coordinates
81 const auto upperRight = getParamFromGroup<GlobalPosition>(modelParamGroup, "Grid.UpperRight");
82
83 // number of cells in each direction
84 std::array<int, dim> cells; cells.fill(1);
85 cells = getParamFromGroup<std::array<int, dim>>(modelParamGroup, "Grid.Cells", cells);
86
87 // \todo TODO periodic boundaries with yasp (the periodicity concept of yasp grid is currently not supported, use dune-spgrid)
88 // const auto periodic = getParamFromGroup<std::bitset<dim>>(modelParamGroup, "Grid.Periodic", std::bitset<dim>());
89 const std::bitset<dim> periodic;
90
91 // get the overlap
92 const int overlap = getParamFromGroup<int>(modelParamGroup, "Grid.Overlap", 1);
93
94 // make the grid
95 ParentType::gridPtr() = createGrid_(modelParamGroup, upperRight, cells, periodic, overlap, Coordinates{});
96
97 postProcessing_(modelParamGroup);
98 }
99
100 // Didn't find a way to construct the grid
101 else
102 {
103 const auto prefix = modelParamGroup == "" ? modelParamGroup : modelParamGroup + ".";
104 DUNE_THROW(ParameterException, "Please supply one of the parameters "
105 << prefix + "Grid.UpperRight"
106 << ", or a grid file in " << prefix + "Grid.File");
107
108 }
109 }
110
111private:
115 std::unique_ptr<Grid> createGrid_(const std::string& modelParamGroup,
116 const GlobalPosition& upperRight,
117 const std::array<int, dim>& cells,
118 const std::bitset<dim>& periodic,
119 const int overlap,
120 Dune::EquidistantCoordinates<ct, dim>) const
121 {
122 if (!hasParamInGroup(modelParamGroup, "Grid.Partitioning"))
123 {
124 // construct using default load balancing
125 return std::make_unique<Grid>(upperRight, cells, periodic, overlap);
126 }
127 else
128 {
129 // construct using user defined partitioning
130 const auto partitioning = getParamFromGroup<std::array<int, dim>>(modelParamGroup, "Grid.Partitioning");
131 Dune::YaspFixedSizePartitioner<dim> lb(partitioning);
132 return std::make_unique<Grid>(upperRight, cells, periodic, overlap, typename Grid::CollectiveCommunicationType(), &lb);
133 }
134 }
135
139 std::unique_ptr<Grid> createGrid_(const std::string& modelParamGroup,
140 const GlobalPosition& upperRight,
141 const std::array<int, dim>& cells,
142 const std::bitset<dim>& periodic,
143 const int overlap,
144 Dune::EquidistantOffsetCoordinates<ct, dim>) const
145 {
146 const auto lowerLeft = getParamFromGroup<GlobalPosition>(modelParamGroup, "Grid.LowerLeft", GlobalPosition(0.0));
147
148 if (!hasParamInGroup(modelParamGroup, "Grid.Partitioning"))
149 {
150 // construct using default load balancing
151 return std::make_unique<Grid>(lowerLeft, upperRight, cells, periodic, overlap);
152 }
153 else
154 {
155 // construct using user defined partitioning
156 const auto partitioning = getParamFromGroup<std::array<int, dim>>(modelParamGroup, "Grid.Partitioning");
157 Dune::YaspFixedSizePartitioner<dim> lb(partitioning);
158 return std::make_unique<Grid>(lowerLeft, upperRight, cells, periodic, overlap, typename Grid::CollectiveCommunicationType(), &lb);
159 }
160 }
161
165 void postProcessing_(const std::string& modelParamGroup)
166 {
167 // Check if should refine the grid
168 const bool keepPhysicalOverlap = getParamFromGroup<bool>(modelParamGroup, "Grid.KeepPhysicalOverlap", true);
169 ParentType::grid().refineOptions(keepPhysicalOverlap);
170 ParentType::maybeRefineGrid(modelParamGroup);
171 ParentType::loadBalance();
172 }
173};
174
203template<class ctype, int dim>
204class GridManager<Dune::YaspGrid<dim, Dune::TensorProductCoordinates<ctype, dim> >>
205: public GridManagerBase<Dune::YaspGrid<dim, Dune::TensorProductCoordinates<ctype, dim> > >
206{
207public:
208 using Grid = typename Dune::YaspGrid<dim, Dune::TensorProductCoordinates<ctype, dim> >;
210
214 void init(const std::string& modelParamGroup = "")
215 {
216 // Only construction from the input file is possible
217 // Look for the necessary keys to construct from the input file
218 // The positions
219 std::array<std::vector<ctype>, dim> positions;
220 for (int i = 0; i < dim; ++i)
221 positions[i] = getParamFromGroup<std::vector<ctype>>(modelParamGroup, "Grid.Positions" + std::to_string(i));
222
223 // the number of cells (has a default)
224 std::array<std::vector<int>, dim> cells;
225 for (int i = 0; i < dim; ++i)
226 {
227 cells[i].resize(positions[i].size()-1, 1.0);
228 cells[i] = getParamFromGroup<std::vector<int>>(modelParamGroup, "Grid.Cells" + std::to_string(i), cells[i]);
229 }
230
231 // grading factor (has a default)
232 std::array<std::vector<ctype>, dim> grading;
233 for (int i = 0; i < dim; ++i)
234 {
235 grading[i].resize(positions[i].size()-1, 1.0);
236 grading[i] = getParamFromGroup<std::vector<ctype>>(modelParamGroup, "Grid.Grading" + std::to_string(i), grading[i]);
237 }
238
239 // call the generic function
240 init(positions, cells, grading, modelParamGroup);
241 }
242
246 void init(const std::array<std::vector<ctype>, dim>& positions,
247 const std::array<std::vector<int>, dim>& cells,
248 const std::array<std::vector<ctype>, dim>& grading,
249 const std::string& modelParamGroup = "")
250 {
251
252
253 // Additional arameters (they have a default)
254 const int overlap = getParamFromGroup<int>(modelParamGroup, "Grid.Overlap", 1);
255 const bool verbose = getParamFromGroup<bool>(modelParamGroup, "Grid.Verbosity", false);
256 // \todo TODO periodic boundaries with yasp (the periodicity concept of yasp grid is currently not supported, use dune-spgrid)
257 // const auto periodic = getParamFromGroup<std::bitset<dim>>(modelParamGroup, "Grid.Periodic", std::bitset<dim>());
258 const std::bitset<dim> periodic;
259
260 // Some sanity checks
261 for (unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
262 {
263 if (cells[dimIdx].size() + 1 != positions[dimIdx].size())
264 {
265 DUNE_THROW(Dune::RangeError, "Make sure to specify correct \"Cells\" and \"Positions\" arrays");
266 }
267 if (grading[dimIdx].size() + 1 != positions[dimIdx].size())
268 {
269 DUNE_THROW(Dune::RangeError, "Make sure to specify correct \"Grading\" and \"Positions\" arrays");
270 }
271 ctype temp = std::numeric_limits<ctype>::lowest();
272 for (unsigned int posIdx = 0; posIdx < positions[dimIdx].size(); ++posIdx)
273 {
274 if (temp > positions[dimIdx][posIdx])
275 {
276 DUNE_THROW(Dune::RangeError, "Make sure to specify a monotone increasing \"Positions\" array");
277 }
278 temp = positions[dimIdx][posIdx];
279 }
280 }
281
282 const auto globalPositions = computeGlobalPositions_(positions, cells, grading, verbose);
283
284 // make the grid
285 if (!hasParamInGroup(modelParamGroup, "Grid.Partitioning"))
286 {
287 // construct using default load balancing
288 ParentType::gridPtr() = std::make_shared<Grid>(globalPositions, periodic, overlap);
289 }
290 else
291 {
292 // construct using user defined partitioning
293 const auto partitioning = getParamFromGroup<std::array<int, dim>>(modelParamGroup, "Grid.Partitioning");
294 Dune::YaspFixedSizePartitioner<dim> lb(partitioning);
295 ParentType::gridPtr() = std::make_shared<Grid>(globalPositions, periodic, overlap, typename Grid::CollectiveCommunicationType(), &lb);
296 }
297
298 postProcessing_(modelParamGroup);
299 }
300
301private:
305 void postProcessing_(const std::string& modelParamGroup)
306 {
307 // Check if should refine the grid
308 const bool keepPhysicalOverlap = getParamFromGroup<bool>(modelParamGroup, "Grid.KeepPhysicalOverlap", true);
309 ParentType::grid().refineOptions(keepPhysicalOverlap);
310 ParentType::maybeRefineGrid(modelParamGroup);
311 ParentType::loadBalance();
312 }
313
315 std::array<std::vector<ctype>, dim>
316 computeGlobalPositions_(const std::array<std::vector<ctype>, dim>& positions,
317 const std::array<std::vector<int>, dim>& cells,
318 const std::array<std::vector<ctype>, dim>& grading,
319 bool verbose = false)
320 {
321 std::array<std::vector<ctype>, dim> globalPositions;
322 using std::pow;
323 for (int dimIdx = 0; dimIdx < dim; dimIdx++)
324 {
325 for (int zoneIdx = 0; zoneIdx < cells[dimIdx].size(); ++zoneIdx)
326 {
327 ctype lower = positions[dimIdx][zoneIdx];
328 ctype upper = positions[dimIdx][zoneIdx+1];
329 int numCells = cells[dimIdx][zoneIdx];
330 ctype gradingFactor = grading[dimIdx][zoneIdx];
331 ctype length = upper - lower;
332 ctype height = 1.0;
333 bool increasingCellSize = false;
334
335 if (verbose)
336 {
337 std::cout << "dim " << dimIdx
338 << " lower " << lower
339 << " upper " << upper
340 << " numCells " << numCells
341 << " grading " << gradingFactor;
342 }
343
344 if (gradingFactor > 1.0)
345 {
346 increasingCellSize = true;
347 }
348
349 // take absolute values and reverse cell size increment to achieve
350 // reverse behavior for negative values
351 if (gradingFactor < 0.0)
352 {
353 using std::abs;
354 gradingFactor = abs(gradingFactor);
355 if (gradingFactor < 1.0)
356 {
357 increasingCellSize = true;
358 }
359 }
360
361 // if the grading factor is exactly 1.0 do equal spacing
362 if (gradingFactor > 1.0 - 1e-7 && gradingFactor < 1.0 + 1e-7)
363 {
364 height = 1.0 / numCells;
365 if (verbose)
366 {
367 std::cout << " -> h " << height * length << std::endl;
368 }
369 }
370 // if grading factor is not 1.0, do power law spacing
371 else
372 {
373 height = (1.0 - gradingFactor) / (1.0 - pow(gradingFactor, numCells));
374
375 if (verbose)
376 {
377 std::cout << " -> grading_eff " << gradingFactor
378 << " h_min " << height * pow(gradingFactor, 0) * length
379 << " h_max " << height * pow(gradingFactor, numCells-1) * length
380 << std::endl;
381 }
382 }
383
384 std::vector<ctype> localPositions;
385 localPositions.push_back(0);
386 for (int i = 0; i < numCells-1; i++)
387 {
388 ctype hI = height;
389 if (!(gradingFactor < 1.0 + 1e-7 && gradingFactor > 1.0 - 1e-7))
390 {
391 if (increasingCellSize)
392 {
393 hI *= pow(gradingFactor, i);
394 }
395 else
396 {
397 hI *= pow(gradingFactor, numCells-i-1);
398 }
399 }
400 localPositions.push_back(localPositions[i] + hI);
401 }
402
403 for (int i = 0; i < localPositions.size(); i++)
404 {
405 localPositions[i] *= length;
406 localPositions[i] += lower;
407 }
408
409 for (unsigned int i = 0; i < localPositions.size(); ++i)
410 {
411 globalPositions[dimIdx].push_back(localPositions[i]);
412 }
413 }
414 globalPositions[dimIdx].push_back(positions[dimIdx].back());
415 }
416
417 return globalPositions;
418 }
419};
420
421} // end namespace Dumux
422
423#endif
Provides a grid manager for all supported grid managers with input file interfaces....
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition: parameters.hh:438
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:454
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
Definition: common/properties/model.hh:34
Exception thrown if a run-time parameter is not specified correctly.
Definition: exceptions.hh:60
The grid manager (this is the class used by the user) for all supported grid managers that constructs...
Definition: gridmanager_base.hh:312
The grid manager base interface (public) and methods common to most grid manager specializations (pro...
Definition: gridmanager_base.hh:65
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:73
typename Dune::YaspGrid< dim, Coordinates > Grid
Definition: gridmanager_yasp.hh:61
void init(const std::string &modelParamGroup="")
Make the grid. This is implemented by specializations of this method.
Definition: gridmanager_yasp.hh:67
typename Dune::YaspGrid< dim, Dune::TensorProductCoordinates< ctype, dim > > Grid
Definition: gridmanager_yasp.hh:208
void init(const std::array< std::vector< ctype >, dim > &positions, const std::array< std::vector< int >, dim > &cells, const std::array< std::vector< ctype >, dim > &grading, const std::string &modelParamGroup="")
Make the grid using input data not read from the input file.
Definition: gridmanager_yasp.hh:246
void init(const std::string &modelParamGroup="")
Make the grid. This is implemented by specializations of this method.
Definition: gridmanager_yasp.hh:214