3.6-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/common/math.hh>
28
29#include <dune/grid/yaspgrid.hh>
30#include <dune/grid/io/file/dgfparser/dgfyasp.hh>
31
32#ifndef DUMUX_IO_GRID_MANAGER_BASE_HH
34#endif
35
37
38namespace Dumux {
39
59template<class Coordinates, int dim>
60class GridManager<Dune::YaspGrid<dim, Coordinates>>
61: public GridManagerBase<Dune::YaspGrid<dim, Coordinates>>
62{
64 using GlobalPosition = Dune::FieldVector<ct, dim>;
65public:
68
72 void init(const std::string& modelParamGroup = "")
73 {
74 // First try to create it from a DGF file in GridParameterGroup.File
75 if (hasParamInGroup(modelParamGroup, "Grid.File"))
76 {
77 ParentType::makeGridFromDgfFile(getParamFromGroup<std::string>(modelParamGroup, "Grid.File"));
78 postProcessing_(modelParamGroup);
79 return;
80 }
81
82 // Then look for the necessary keys to construct from the input file
83 else if (hasParamInGroup(modelParamGroup, "Grid.UpperRight"))
84 {
85 // get the upper right corner coordinates
86 const auto upperRight = getParamFromGroup<GlobalPosition>(modelParamGroup, "Grid.UpperRight");
87
88 // number of cells in each direction
89 std::array<int, dim> cells; cells.fill(1);
90 cells = getParamFromGroup<std::array<int, dim>>(modelParamGroup, "Grid.Cells", cells);
91
92 // \todo TODO periodic boundaries with yasp (the periodicity concept of yasp grid is currently not supported, use dune-spgrid)
93 // const auto periodic = getParamFromGroup<std::bitset<dim>>(modelParamGroup, "Grid.Periodic", std::bitset<dim>{});
94 const std::bitset<dim> periodic;
95
96 // get the overlap
97 const int overlap = getParamFromGroup<int>(modelParamGroup, "Grid.Overlap", 1);
98
99 if constexpr (std::is_same_v<Dune::EquidistantCoordinates<ct, dim>, Coordinates>)
100 init(upperRight, cells, modelParamGroup, overlap, periodic);
101 else
102 {
103 const auto lowerLeft = getParamFromGroup<GlobalPosition>(modelParamGroup, "Grid.LowerLeft", GlobalPosition(0.0));
104 init(lowerLeft, upperRight, cells, modelParamGroup, overlap, periodic);
105 }
106 }
107
108 // Didn't find a way to construct the grid
109 else
110 {
111 const auto prefix = modelParamGroup.empty() ? modelParamGroup : modelParamGroup + ".";
112 DUNE_THROW(ParameterException, "Please supply one of the parameters "
113 << prefix + "Grid.UpperRight"
114 << ", or a grid file in " << prefix + "Grid.File");
115
116 }
117 }
118
123 void init(const GlobalPosition& upperRight,
124 const std::array<int, dim>& cells,
125 const std::string& modelParamGroup = "",
126 const int overlap = 1,
127 const std::bitset<dim> periodic = std::bitset<dim>{})
128 {
129 static_assert(std::is_same_v<Dune::EquidistantCoordinates<ct, dim>, Coordinates>,
130 "Use init function taking lowerLeft as argument when working with EquidistantOffsetCoordinates");
131
132 if (!hasParamInGroup(modelParamGroup, "Grid.Partitioning"))
133 {
134 // construct using default load balancing
135 ParentType::gridPtr() = std::make_unique<Grid>(upperRight, cells, periodic, overlap);
136 }
137 else
138 {
139 // construct using user defined partitioning
140 const auto partitioning = getParamFromGroup<std::array<int, dim>>(modelParamGroup, "Grid.Partitioning");
141 Dune::YaspFixedSizePartitioner<dim> lb(partitioning);
142 ParentType::gridPtr() = std::make_unique<Grid>(upperRight, cells, periodic, overlap, typename Grid::CollectiveCommunication(), &lb);
143 }
144
145 postProcessing_(modelParamGroup);
146 }
147
152 void init(const GlobalPosition& lowerLeft,
153 const GlobalPosition& upperRight,
154 const std::array<int, dim>& cells,
155 const std::string& modelParamGroup = "",
156 const int overlap = 1,
157 const std::bitset<dim> periodic = std::bitset<dim>{})
158 {
159 static_assert(std::is_same_v<Dune::EquidistantOffsetCoordinates<ct, dim>, Coordinates>,
160 "LowerLeft can only be specified with EquidistantOffsetCoordinates");
161
162 if (!hasParamInGroup(modelParamGroup, "Grid.Partitioning"))
163 {
164 // construct using default load balancing
165 ParentType::gridPtr() = std::make_unique<Grid>(lowerLeft, upperRight, cells, periodic, overlap);
166 }
167 else
168 {
169 // construct using user defined partitioning
170 const auto partitioning = getParamFromGroup<std::array<int, dim>>(modelParamGroup, "Grid.Partitioning");
171 Dune::YaspFixedSizePartitioner<dim> lb(partitioning);
172 ParentType::gridPtr() = std::make_unique<Grid>(lowerLeft, upperRight, cells, periodic, overlap, typename Grid::CollectiveCommunication(), &lb);
173 }
174
175 postProcessing_(modelParamGroup);
176 }
177
178private:
179
183 void postProcessing_(const std::string& modelParamGroup)
184 {
185 // Check if should refine the grid
186 const bool keepPhysicalOverlap = getParamFromGroup<bool>(modelParamGroup, "Grid.KeepPhysicalOverlap", true);
187 ParentType::grid().refineOptions(keepPhysicalOverlap);
188 ParentType::maybeRefineGrid(modelParamGroup);
189 ParentType::loadBalance();
190 }
191};
192
222template<class ctype, int dim>
223class GridManager<Dune::YaspGrid<dim, Dune::TensorProductCoordinates<ctype, dim> >>
224: public GridManagerBase<Dune::YaspGrid<dim, Dune::TensorProductCoordinates<ctype, dim> > >
225{
226public:
229
233 void init(const std::string& modelParamGroup = "")
234 {
235 // Only construction from the input file is possible
236 // Look for the necessary keys to construct from the input file
237 // The positions
238 std::array<std::vector<ctype>, dim> positions;
239 for (int i = 0; i < dim; ++i)
240 positions[i] = getParamFromGroup<std::vector<ctype>>(modelParamGroup, "Grid.Positions" + std::to_string(i));
241
242 // the number of cells (has a default)
243 std::array<std::vector<int>, dim> cells;
244 for (int i = 0; i < dim; ++i)
245 {
246 cells[i].resize(positions[i].size()-1, 1.0);
247 cells[i] = getParamFromGroup<std::vector<int>>(modelParamGroup, "Grid.Cells" + std::to_string(i), cells[i]);
248 }
249
250 // grading factor (has a default)
251 std::array<std::vector<ctype>, dim> grading;
252 for (int i = 0; i < dim; ++i)
253 {
254 grading[i].resize(positions[i].size()-1, 1.0);
255 grading[i] = getParamFromGroup<std::vector<ctype>>(modelParamGroup, "Grid.Grading" + std::to_string(i), grading[i]);
256 }
257
258 // call the generic function
259 init(positions, cells, grading, modelParamGroup);
260 }
261
265 void init(const std::array<std::vector<ctype>, dim>& positions,
266 const std::array<std::vector<int>, dim>& cells,
267 const std::array<std::vector<ctype>, dim>& grading,
268 const std::string& modelParamGroup = "")
269 {
270 // Additional parameters (they have a default)
271 const int overlap = getParamFromGroup<int>(modelParamGroup, "Grid.Overlap", 1);
272 const bool verbose = getParamFromGroup<bool>(modelParamGroup, "Grid.Verbosity", false);
273 // \todo TODO periodic boundaries with yasp (the periodicity concept of yasp grid is currently not supported, use dune-spgrid)
274 // const auto periodic = getParamFromGroup<std::bitset<dim>>(modelParamGroup, "Grid.Periodic", std::bitset<dim>{});
275 const std::bitset<dim> periodic;
276
277 // Some sanity checks
278 for (unsigned int dimIdx = 0; dimIdx < dim; ++dimIdx)
279 {
280 if (cells[dimIdx].size() + 1 != positions[dimIdx].size())
281 {
282 DUNE_THROW(Dune::RangeError, "Make sure to specify correct \"Cells\" and \"Positions\" arrays");
283 }
284 if (grading[dimIdx].size() + 1 != positions[dimIdx].size())
285 {
286 DUNE_THROW(Dune::RangeError, "Make sure to specify correct \"Grading\" and \"Positions\" arrays");
287 }
288 ctype temp = std::numeric_limits<ctype>::lowest();
289 for (unsigned int posIdx = 0; posIdx < positions[dimIdx].size(); ++posIdx)
290 {
291 if (temp > positions[dimIdx][posIdx])
292 {
293 DUNE_THROW(Dune::RangeError, "Make sure to specify a monotone increasing \"Positions\" array");
294 }
295 temp = positions[dimIdx][posIdx];
296 }
297 }
298
299 const auto globalPositions = computeGlobalPositions_(positions, cells, grading, verbose);
300
301 // make the grid
302 if (!hasParamInGroup(modelParamGroup, "Grid.Partitioning"))
303 {
304 // construct using default load balancing
305 ParentType::gridPtr() = std::make_shared<Grid>(globalPositions, periodic, overlap);
306 }
307 else
308 {
309 // construct using user defined partitioning
310 const auto partitioning = getParamFromGroup<std::array<int, dim>>(modelParamGroup, "Grid.Partitioning");
311 Dune::YaspFixedSizePartitioner<dim> lb(partitioning);
312 ParentType::gridPtr() = std::make_shared<Grid>(globalPositions, periodic, overlap, typename Grid::CollectiveCommunication(), &lb);
313 }
314
315 postProcessing_(modelParamGroup);
316 }
317
318private:
322 void postProcessing_(const std::string& modelParamGroup)
323 {
324 // Check if should refine the grid
325 const bool keepPhysicalOverlap = getParamFromGroup<bool>(modelParamGroup, "Grid.KeepPhysicalOverlap", true);
326 ParentType::grid().refineOptions(keepPhysicalOverlap);
327 ParentType::maybeRefineGrid(modelParamGroup);
328 ParentType::loadBalance();
329 }
330
332 std::array<std::vector<ctype>, dim>
333 computeGlobalPositions_(const std::array<std::vector<ctype>, dim>& positions,
334 const std::array<std::vector<int>, dim>& cells,
335 const std::array<std::vector<ctype>, dim>& grading,
336 bool verbose = false)
337 {
338 std::array<std::vector<ctype>, dim> globalPositions;
339 using std::pow;
340 using Dune::power;
341 for (int dimIdx = 0; dimIdx < dim; dimIdx++)
342 {
343 for (int zoneIdx = 0; zoneIdx < cells[dimIdx].size(); ++zoneIdx)
344 {
345 ctype lower = positions[dimIdx][zoneIdx];
346 ctype upper = positions[dimIdx][zoneIdx+1];
347 int numCells = cells[dimIdx][zoneIdx];
348 ctype gradingFactor = grading[dimIdx][zoneIdx];
349 ctype length = upper - lower;
350 ctype height = 1.0;
351 bool increasingCellSize = false;
352
353 if (verbose)
354 {
355 std::cout << "dim " << dimIdx
356 << " lower " << lower
357 << " upper " << upper
358 << " numCells " << numCells
359 << " grading " << gradingFactor;
360 }
361
362 if (gradingFactor > 1.0)
363 {
364 increasingCellSize = true;
365 }
366
367 // take absolute values and reverse cell size increment to achieve
368 // reverse behavior for negative values
369 if (gradingFactor < 0.0)
370 {
371 using std::abs;
372 gradingFactor = abs(gradingFactor);
373 if (gradingFactor < 1.0)
374 {
375 increasingCellSize = true;
376 }
377 }
378
379 // if the grading factor is exactly 1.0 do equal spacing
380 if (gradingFactor > 1.0 - 1e-7 && gradingFactor < 1.0 + 1e-7)
381 {
382 height = 1.0 / numCells;
383 if (verbose)
384 {
385 std::cout << " -> h " << height * length << std::endl;
386 }
387 }
388 // if grading factor is not 1.0, do power law spacing
389 else
390 {
391 height = (1.0 - gradingFactor) / (1.0 - power(gradingFactor, numCells));
392
393 if (verbose)
394 {
395 std::cout << " -> grading_eff " << gradingFactor
396 << " h_min " << height * power(gradingFactor, 0) * length
397 << " h_max " << height * power(gradingFactor, numCells-1) * length
398 << std::endl;
399 }
400 }
401
402 std::vector<ctype> localPositions;
403 localPositions.push_back(0);
404 for (int i = 0; i < numCells-1; i++)
405 {
406 ctype hI = height;
407 if (!(gradingFactor < 1.0 + 1e-7 && gradingFactor > 1.0 - 1e-7))
408 {
409 if (increasingCellSize)
410 {
411 hI *= power(gradingFactor, i);
412 }
413 else
414 {
415 hI *= power(gradingFactor, numCells-i-1);
416 }
417 }
418 localPositions.push_back(localPositions[i] + hI);
419 }
420
421 for (int i = 0; i < localPositions.size(); i++)
422 {
423 localPositions[i] *= length;
424 localPositions[i] += lower;
425 }
426
427 for (unsigned int i = 0; i < localPositions.size(); ++i)
428 {
429 globalPositions[dimIdx].push_back(localPositions[i]);
430 }
431 }
432 globalPositions[dimIdx].push_back(positions[dimIdx].back());
433 }
434
435 return globalPositions;
436 }
437};
438
439namespace Grid::Capabilities {
440
441// To the best of our knowledge YaspGrid is view thread-safe
442// This specialization can be removed after we depend on Dune release 2.9 and this is guaranteed by YaspGrid itself
443template<class Coordinates, int dim>
444struct MultithreadingSupported<Dune::YaspGrid<dim, Coordinates>>
445{
446 template<class GV>
447 static bool eval(const GV& gv) // default is independent of the grid view
448 { return true; }
449};
450
451} // end namespace Grid::Capabilities
452
453} // end namespace Dumux
454
455#endif
dune-grid capabilities compatibility layer
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:161
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
Exception thrown if a run-time parameter is not specified correctly.
Definition: exceptions.hh:60
Definition: gridcapabilities.hh:79
Definition: consistentlyorientedgrid.hh:32
The grid manager (this is the class used by the user) for all supported grid managers that constructs...
Definition: gridmanager_base.hh:324
The grid manager base interface (public) and methods common to most grid manager specializations (pro...
Definition: gridmanager_base.hh:67
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
typename Dune::YaspGrid< dim, Coordinates > Grid
Definition: gridmanager_yasp.hh:66
void init(const std::string &modelParamGroup="")
Make the grid. This is implemented by specializations of this method.
Definition: gridmanager_yasp.hh:72
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 >{})
Make the grid using input data not read from the input file.
Definition: gridmanager_yasp.hh:123
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 >{})
Make the grid using input data not read from the input file.
Definition: gridmanager_yasp.hh:152
typename Dune::YaspGrid< dim, Dune::TensorProductCoordinates< ctype, dim > > Grid
Definition: gridmanager_yasp.hh:227
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:265
void init(const std::string &modelParamGroup="")
Make the grid. This is implemented by specializations of this method.
Definition: gridmanager_yasp.hh:233
static bool eval(const GV &gv)
Definition: gridmanager_yasp.hh:447