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