version 3.11-dev
Loading...
Searching...
No Matches
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// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
13#ifndef DUMUX_IO_GRID_MANAGER_SUB_HH
14#define DUMUX_IO_GRID_MANAGER_SUB_HH
15
16#include <memory>
17#include <utility>
18#include <algorithm>
19#include <stack>
20#include <vector>
21#include <numeric>
22
23#include <dune/common/shared_ptr.hh>
24#include <dune/common/concept.hh>
25#include <dune/common/exceptions.hh>
26#include <dune/grid/common/exceptions.hh>
27#include <dune/grid/yaspgrid.hh>
28
29// SubGrid specific includes
30#if HAVE_DUNE_SUBGRID
31#include <dune/subgrid/subgrid.hh>
34#endif
35
36#ifndef DUMUX_IO_GRID_MANAGER_BASE_HH
38#endif
40
43
44#if HAVE_DUNE_SUBGRID
45namespace Dumux {
46namespace Concept {
47
52template<class Element>
54{
55 template<class F>
56 auto require(F&& f) -> decltype(
57 bool(f(std::declval<const Element&>()))
58 );
59};
60} // end namespace Concept
61
66template <class HostGrid, class HostGridManager = GridManager<HostGrid>>
68: public GridManagerBase<Dune::SubGrid<HostGrid::dimension, HostGrid>>
69{
70 static constexpr int dim = HostGrid::dimension;
71 using HostElement = typename HostGrid::template Codim<0>::Entity;
72 using GlobalPosition = typename HostElement::Geometry::GlobalCoordinate;
73
74public:
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() = std::make_unique<Grid>(hostGrid);
87 updateSubGrid_(selector);
89 }
90
94 template<class ES,
95 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
96 void init(const ES& selector,
97 const std::string& paramGroup = "")
98 {
99 initHostGrid_(paramGroup);
100 this->gridPtr() = std::make_unique<Grid>(hostGridManager_->grid());
101 updateSubGrid_(selector);
102 loadBalance();
103 }
104
109 {
110 if (Dune::MPIHelper::getCommunication().size() > 1)
111 this->grid().loadBalance();
112 }
113
117 template<class ES,
118 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
119 void update(const ES& selector)
120 {
121 updateSubGrid_(selector);
122 loadBalance();
123 }
124
125protected:
126
130 template<class ES,
131 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
132 void updateSubGrid_(const ES& selector)
133 {
134 auto& subgridPtr = this->gridPtr();
135
136 // A container to store the host grid elements' ids.
137 std::set<typename HostGrid::Traits::GlobalIdSet::IdType> elementsForSubgrid;
138 const auto& globalIDset = subgridPtr->getHostGrid().globalIdSet();
139
140 // Construct the subgrid.
141 subgridPtr->createBegin();
142
143 // Loop over all elements of the host grid and use the selector to
144 // choose which elements to add to the subgrid.
145 auto hostGridView = subgridPtr->getHostGrid().leafGridView();
146 for (const auto& e : elements(hostGridView))
147 if (selector(e))
148 elementsForSubgrid.insert(globalIDset.template id<0>(e));
149
150 if (elementsForSubgrid.empty())
151 DUNE_THROW(Dune::GridError, "No elements in subgrid");
152
153 subgridPtr->insertSetPartial(elementsForSubgrid);
154 subgridPtr->createEnd();
155 }
156
157 void initHostGrid_(const std::string& paramGroup)
158 {
159 hostGridManager_ = std::make_unique<HostGridManager>();
160 hostGridManager_->init(paramGroup);
161 }
162
163 void initHostGrid_(const GlobalPosition& lowerLeft,
164 const GlobalPosition& upperRight,
165 const std::array<int, dim>& cells,
166 const std::string& paramGroup,
167 const int overlap = 1,
168 const std::bitset<dim> periodic = std::bitset<dim>{})
169 {
170 hostGridManager_ = std::make_unique<HostGridManager>();
171 hostGridManager_->init(lowerLeft, upperRight, cells, paramGroup, overlap, periodic);
172 }
173
177 HostGrid& hostGrid_()
178 {
179 return hostGridManager_->grid();
180 }
181
182 std::unique_ptr<HostGridManager> hostGridManager_;
183};
184
193template<int dim, class HostGrid>
194class GridManager<Dune::SubGrid<dim, HostGrid>>
195: public SubGridManagerBase<HostGrid, GridManager<HostGrid>>
196{};
197
216template<int dim, class Coordinates>
217class GridManager<Dune::SubGrid<dim, Dune::YaspGrid<dim, Coordinates>>>
218: public SubGridManagerBase<Dune::YaspGrid<dim, Coordinates>, GridManager<Dune::YaspGrid<dim, Coordinates>>>
219{
222public:
223 using typename ParentType::Grid;
224 using ParentType::init;
225
231 void init(const std::string& paramGroup = "")
232 {
233 const auto overlap = getParamFromGroup<int>(paramGroup, "Grid.Overlap", 1);
234 const auto periodic = getParamFromGroup<std::bitset<dim>>(paramGroup, "Grid.Periodic", std::bitset<dim>{});
235
236 // check if there is an image file we can construct the element selector from
237 if (hasParamInGroup(paramGroup, "Grid.Image"))
238 {
239 const auto imgFileName = getParamFromGroup<std::string>(paramGroup, "Grid.Image");
240 const auto ext = this->getFileExtension(imgFileName);
241 if (ext == "pbm")
242 {
243 if (dim != 2)
244 DUNE_THROW(Dune::GridError, "Portable Bitmap Format only supports dim == 2");
245
246 // read image
247 const auto img = NetPBMReader::readPBM(imgFileName);
248 createGridFromImage_(img, paramGroup, overlap, periodic);
249 }
250 else
251 DUNE_THROW(Dune::IOError, "The SubGridManager doesn't support image files with extension: *." << ext);
252
253 }
254 else if (hasParamInGroup(paramGroup, "Grid.BinaryMask"))
255 {
256 const auto maskFileName = getParamFromGroup<std::string>(paramGroup, "Grid.BinaryMask");
257 std::ifstream mask(maskFileName, std::ios_base::binary);
258 std::vector<char> buffer(std::istreambuf_iterator<char>(mask), std::istreambuf_iterator<char>{});
259 const auto cells = getParamFromGroup<std::array<int, dim>>(paramGroup, "Grid.Cells");
260 if (const auto c = std::accumulate(cells.begin(), cells.end(), 1, std::multiplies<int>{}); c != buffer.size())
261 DUNE_THROW(Dune::IOError, "Grid dimensions doesn't match number of cells specified " << c << ":" << buffer.size());
262
263 maybePostProcessBinaryMask_(buffer, cells, paramGroup);
264
265 using GlobalPosition = typename ParentType::Grid::template Codim<0>::Geometry::GlobalCoordinate;
266 const auto lowerLeft = GlobalPosition(0.0);
267 const auto upperRight = [&]{
268 if (hasParamInGroup(paramGroup, "Grid.PixelDimensions"))
269 {
270 auto upperRight = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.PixelDimensions");
271 for (int i = 0; i < upperRight.size(); ++i)
272 upperRight[i] *= cells[i];
273 upperRight += lowerLeft;
274 return upperRight;
275 }
276 else
277 return getParamFromGroup<GlobalPosition>(paramGroup, "Grid.UpperRight");
278 }();
279
280 // construct the host grid
281 this->initHostGrid_(lowerLeft, upperRight, cells, paramGroup, overlap, periodic);
282
283 // check if the marker is customized, per default
284 // we use all cells that are encoded as 0
285 const char marker = getParamFromGroup<char>(paramGroup, "Grid.Marker", 0);
286 const auto elementSelector = [&](const auto& element)
287 {
288 auto level0 = element;
289 while(level0.hasFather())
290 level0 = level0.father();
291 const auto eIdx = this->hostGrid_().levelGridView(0).indexSet().index(level0);
292 return buffer[eIdx] != marker;
293 };
294
295 // create the grid
296 this->gridPtr() = std::make_unique<Grid>(this->hostGrid_());
297 this->updateSubGrid_(elementSelector);
298 this->loadBalance();
299 }
300 else
301 {
302 std::cerr << "No element selector provided and Grid.Image or Grid.BinaryMask not found" << std::endl;
303 std::cerr << "Constructing sub-grid with all elements of the host grid" << std::endl;
304
305 // create host grid
306 using GlobalPosition = typename ParentType::Grid::template Codim<0>::Geometry::GlobalCoordinate;
307 const auto lowerLeft = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.LowerLeft", GlobalPosition(0.0));
308 const auto upperRight = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.UpperRight");
309 const auto cells = getParamFromGroup<std::array<int, dim>>(paramGroup, "Grid.Cells");
310 this->initHostGrid_(lowerLeft, upperRight, cells, paramGroup, overlap, periodic);
311 const auto elementSelector = [](const auto& element){ return true; };
312 // create the grid
313 this->gridPtr() = std::make_unique<Grid>(this->hostGrid_());
314 this->updateSubGrid_(elementSelector);
315 this->loadBalance();
316 }
317 }
318
319private:
320 template<class Img>
321 void createGridFromImage_(const Img& img, const std::string& paramGroup, const int overlap, const std::bitset<dim> periodic)
322 {
323 using GlobalPosition = typename ParentType::Grid::template Codim<0>::Geometry::GlobalCoordinate;
324 const bool repeated = hasParamInGroup(paramGroup,"Grid.Repeat");
325
326 // get the number of cells
327 const std::array<int, dim> imageDimensions{static_cast<int>(img.header().nCols), static_cast<int>(img.header().nRows)};
328 std::array<int, dim> cells{imageDimensions[0], imageDimensions[1]};
329
330 std::array<int, dim> repeatsDefault; repeatsDefault.fill(1);
331 const auto numRepeats = getParamFromGroup<std::array<int, dim>>(paramGroup, "Grid.Repeat", repeatsDefault);
332 for (int i = 0; i < dim; i++)
333 cells[i] = cells[i] * numRepeats[i];
334
335 // get the corner coordinates
336 const auto [lowerLeft, upperRight] = [&]()
337 {
338 const auto lowerLeft = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.LowerLeft", GlobalPosition(0.0));
339 if (hasParamInGroup(paramGroup, "Grid.PixelDimensions"))
340 {
341 auto upperRight = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.PixelDimensions");
342 for (int i = 0; i < upperRight.size(); ++i)
343 upperRight[i] *= cells[i];
344 upperRight += lowerLeft;
345 return std::make_pair(lowerLeft, upperRight);
346 }
347 else
348 return std::make_pair(lowerLeft, getParamFromGroup<GlobalPosition>(paramGroup, "Grid.UpperRight"));
349 }();
350
351 // construct the host grid
352 this->initHostGrid_(lowerLeft, upperRight, cells, paramGroup, overlap, periodic);
353
354 // check if the marker is customized, per default
355 // we mark all cells that are encoded as 0
356 const bool marked = getParamFromGroup<bool>(paramGroup, "Grid.Marker", false);
357
358 // Create the element selector for a single image
359 const auto elementSelector = [&](const auto& element)
360 {
361 auto eIdx = this->hostGrid_().leafGridView().indexSet().index(element);
362
363 // if the hostgrid was refined, get the index of the original, un-refined
364 // host grid element which fits with the image's indices
365 if (element.hasFather())
366 {
367 auto level0Element = element.father();
368 while (level0Element.hasFather())
369 level0Element = level0Element.father();
370
371 assert(level0Element.level() == 0);
372 eIdx = this->hostGrid_().levelGridView(0).indexSet().index(level0Element);
373 }
374 return img[eIdx] == marked;
375 };
376
377 // Create the element selector for a repeated image
378 const auto repeatedElementSelector = [&](const auto& element)
379 {
380 auto eIdx = this->hostGrid_().leafGridView().indexSet().index(element);
381
382 // if the hostgrid was refined, get the index of the original, un-refined
383 // host grid element which fits with the image's indices
384 if (element.hasFather())
385 {
386 auto level0Element = element.father();
387 while (level0Element.hasFather())
388 level0Element = level0Element.father();
389
390 assert(level0Element.level() == 0);
391 eIdx = this->hostGrid_().levelGridView(0).indexSet().index(level0Element);
392 }
393
394 // figure out the size of the repeat, and the size of the target repeated grid
395 const int numCols = imageDimensions[0];
396 const int numRows = imageDimensions[1];
397
398 // map the eIdx to the original img index
399 const int repeatUnitIndex = eIdx % (numCols * numRepeats[0] * numRows);
400 const int imgI = repeatUnitIndex % numCols;
401 const int imgJ = repeatUnitIndex / (numCols * numRepeats[0]);
402 return img[ (imgJ * numCols + imgI) ] == marked;
403 };
404
405 // create the grid
406 if (repeated)
407 {
408 this->gridPtr() = std::make_unique<Grid>(this->hostGrid_());
409 this->updateSubGrid_(repeatedElementSelector);
410 }
411 else
412 {
413 this->gridPtr() = std::make_unique<Grid>(this->hostGrid_());
414 this->updateSubGrid_(elementSelector);
415 }
416
417 this->loadBalance();
418 }
419
420private:
421 void maybePostProcessBinaryMask_(std::vector<char>& mask, const std::array<int, dim>& cells, const std::string& paramGroup) const
422 {
423 // implements pruning for directional connectivity scenario (e.g. flow from left to right)
424 // all cells that don't connect the boundaries in X (or Y or Z) direction are removed
425 if (hasParamInGroup(paramGroup, "Grid.KeepOnlyConnected"))
426 {
427 std::vector<int> marker(mask.size(), 0);
428 const std::string direction = getParamFromGroup<std::string>(paramGroup, "Grid.KeepOnlyConnected");
429 if constexpr (dim == 3)
430 {
431 if (direction == "Y")
432 {
433 std::cout << "Keeping only cells connected to both boundaries in y-direction" << std::endl;
434 flood_(mask, marker, cells, 0, 0, 0, cells[0], 1, cells[2], 1);
435 flood_(mask, marker, cells, 0, cells[1]-1, 0, cells[0], cells[1], cells[2], 2);
436 }
437 else if (direction == "Z")
438 {
439 std::cout << "Keeping only cells connected to both boundaries in z-direction" << std::endl;
440 flood_(mask, marker, cells, 0, 0, 0, cells[0], cells[1], 1, 1);
441 flood_(mask, marker, cells, 0, 0, cells[2]-1, cells[0], cells[1], cells[2], 2);
442 }
443 else
444 {
445 std::cout << "Keeping only cells connected to both boundaries in x-direction" << std::endl;
446 flood_(mask, marker, cells, 0, 0, 0, 1, cells[1], cells[2], 1);
447 flood_(mask, marker, cells, cells[0]-1, 0, 0, cells[0], cells[1], cells[2], 2);
448 }
449
450 for (unsigned int i = 0; i < cells[0]; ++i)
451 for (unsigned int j = 0; j < cells[1]; ++j)
452 for (unsigned int k = 0; k < cells[2]; ++k)
453 if (const auto ijk = getIJK_(i, j, k, cells); marker[ijk] < 2)
454 mask[ijk] = false;
455 }
456
457 else if constexpr (dim == 2)
458 {
459 if (direction == "Y")
460 {
461 std::cout << "Keeping only cells connected to both boundaries in y-direction" << std::endl;
462 flood_(mask, marker, cells, 0, 0, cells[0], 1, 1);
463 flood_(mask, marker, cells, 0, cells[1]-1, cells[0], cells[1], 2);
464 }
465 else
466 {
467 std::cout << "Keeping only cells connected to both boundaries in x-direction" << std::endl;
468 flood_(mask, marker, cells, 0, 0, 1, cells[1], 1);
469 flood_(mask, marker, cells, cells[0]-1, 0, cells[0], cells[1], 2);
470 }
471
472 for (unsigned int i = 0; i < cells[0]; ++i)
473 for (unsigned int j = 0; j < cells[1]; ++j)
474 if (const auto ij = getIJ_(i, j, cells); marker[ij] < 2)
475 mask[ij] = false;
476 }
477 else
478 DUNE_THROW(Dune::NotImplemented, "KeepOnlyConnected only implemented for 2D and 3D");
479 }
480 }
481
482 void flood_(std::vector<char>& mask, std::vector<int>& markers, const std::array<int, 3>& cells,
483 unsigned int iMin, unsigned int jMin, unsigned int kMin,
484 unsigned int iMax, unsigned int jMax, unsigned int kMax,
485 int marker) const
486 {
487 // flood-fill with marker starting from all seed cells in the range
488 for (unsigned int i = iMin; i < iMax; ++i)
489 for (unsigned int j = jMin; j < jMax; ++j)
490 for (unsigned int k = kMin; k < kMax; ++k)
491 fill_(mask, markers, cells, i, j, k, marker);
492 }
493
494 void flood_(std::vector<char>& mask, std::vector<int>& markers, const std::array<int, 2>& cells,
495 unsigned int iMin, unsigned int jMin,
496 unsigned int iMax, unsigned int jMax,
497 int marker) const
498 {
499 // flood-fill with marker starting from all seed cells in the range
500 for (unsigned int i = iMin; i < iMax; ++i)
501 for (unsigned int j = jMin; j < jMax; ++j)
502 fill_(mask, markers, cells, i, j, marker);
503 }
504
505 void fill_(std::vector<char>& mask, std::vector<int>& markers, const std::array<int, 3>& cells,
506 unsigned int i, unsigned int j, unsigned int k, int marker) const
507 {
508 std::stack<std::tuple<unsigned int, unsigned int, unsigned int>> st;
509 st.push(std::make_tuple(i, j, k));
510 while(!st.empty())
511 {
512 std::tie(i, j, k) = st.top();
513 st.pop();
514
515 if (i >= cells[0] || j >= cells[1] || k >= cells[2])
516 continue;
517
518 const auto ijk = getIJK_(i, j, k, cells);
519 if (!mask[ijk] || markers[ijk] >= marker)
520 continue;
521
522 markers[ijk] += 1;
523
524 // we rely on -1 wrapping over for unsigned int = 0
525 st.push(std::make_tuple(i+1, j, k));
526 st.push(std::make_tuple(i-1, j, k));
527 st.push(std::make_tuple(i, j+1, k));
528 st.push(std::make_tuple(i, j-1, k));
529 st.push(std::make_tuple(i, j, k+1));
530 st.push(std::make_tuple(i, j, k-1));
531 }
532 }
533
534 void fill_(std::vector<char>& mask, std::vector<int>& markers, const std::array<int, 2>& cells,
535 unsigned int i, unsigned int j, int marker) const
536 {
537 std::stack<std::tuple<unsigned int, unsigned int>> st;
538 st.push(std::make_tuple(i, j));
539 while(!st.empty())
540 {
541 std::tie(i, j) = st.top();
542 st.pop();
543
544 if (i >= cells[0] || j >= cells[1])
545 continue;
546
547 const auto ij = getIJ_(i, j, cells);
548 if (!mask[ij] || markers[ij] >= marker)
549 continue;
550
551 markers[ij] += 1;
552
553 // we rely on -1 wrapping over for unsigned int = 0
554 st.push(std::make_tuple(i+1, j));
555 st.push(std::make_tuple(i-1, j));
556 st.push(std::make_tuple(i, j+1));
557 st.push(std::make_tuple(i, j-1));
558 }
559 }
560
561 int getIJK_(int i, int j, int k, const std::array<int, 3>& cells) const
562 { return i + j*cells[0] + k*cells[0]*cells[1]; }
563
564 int getIJ_(int i, int j, const std::array<int, 2>& cells) const
565 { return i + j*cells[0]; }
566};
567
569template<int dim, class HostGrid>
570class BoundaryFlag<Dune::SubGrid<dim, HostGrid>>
571{
572public:
573 BoundaryFlag() : flag_(invalidFlag_) {}
574
575 template<class Intersection>
576 BoundaryFlag(const Intersection& i) : flag_(invalidFlag_) {}
577
578 using value_type = int;
579
581 { DUNE_THROW(Dune::NotImplemented, "Sub-grid doesn't implement boundary segment indices!"); }
582
583 operator bool() const { return flag_ != invalidFlag_; }
584
585private:
586 static constexpr value_type invalidFlag_ = -1;
587 value_type flag_;
588};
589
591template<int dim, typename HostGrid, bool MapIndexStorage>
592struct PeriodicGridTraits<Dune::SubGrid<dim, HostGrid, MapIndexStorage>>
593{
594private:
596
597 const Grid& subGrid_;
598 const PeriodicGridTraits<HostGrid> hostTraits_;
599
600public:
602
603 PeriodicGridTraits(const Grid& subGrid)
604 : subGrid_(subGrid), hostTraits_(subGrid_.getHostGrid()) {};
605
606 bool isPeriodic (const typename Grid::LeafIntersection& intersection) const
607 {
608 const auto& hostElement = subGrid_.template getHostEntity<0>(intersection.inside());
609 for (const auto& hostIntersection : intersections(subGrid_.getHostGrid().leafGridView(), hostElement))
610 {
611 if (hostIntersection.indexInInside() == intersection.indexInInside())
612 {
613 const bool periodicInHostGrid = hostTraits_.isPeriodic(hostIntersection);
614 return periodicInHostGrid && subGrid_.template contains<0>(hostIntersection.outside());
615 }
616 }
617 return false;
618 }
619
621 {
622 for (const auto& element : elements(subGrid_.leafGridView()))
623 {
624 for (const auto& intersection : intersections(subGrid_.leafGridView(), element))
625 {
626 const auto& hostElement = subGrid_.template getHostEntity<0>(intersection.inside());
627 for (const auto& hostIntersection : intersections(subGrid_.getHostGrid().leafGridView(), hostElement))
628 {
629 if (hostIntersection.indexInInside() == intersection.indexInInside())
630 {
631 const bool periodicInHostGrid = hostTraits_.isPeriodic(hostIntersection);
632 if (periodicInHostGrid && !subGrid_.template contains<0>(hostIntersection.outside()))
633 DUNE_THROW(Dune::GridError, "Periodic boundary in host grid but outside"
634 << " element not included in subgrid. If this is intentional,"
635 << " take additional care with boundary conditions and remove"
636 << " verification call.");
637 break;
638 }
639 }
640 }
641 }
642 }
643};
644
645} // end namespace Dumux
646#endif // HAVE_DUNE_SUBGRID
647#endif
Boundary flag to store e.g. in sub control volume faces.
BoundaryFlag()
Definition gridmanager_sub.hh:573
BoundaryFlag(const Intersection &i)
Definition gridmanager_sub.hh:576
value_type get() const
Definition gridmanager_sub.hh:580
int value_type
Definition gridmanager_sub.hh:578
std::size_t value_type
Definition boundaryflag.hh:28
void init(const std::string &paramGroup="")
Make the subgrid without host grid and element selector This means we try to construct the element se...
Definition gridmanager_sub.hh:231
The grid manager base interface (public) and methods common to most grid manager specializations (pro...
Definition gridmanager_base.hh:56
void loadBalance()
Definition gridmanager_base.hh:98
std::shared_ptr< Grid > & gridPtr()
Definition gridmanager_base.hh:163
std::string getFileExtension(const std::string &fileName) const
Definition gridmanager_base.hh:185
The grid manager (this is the class used by the user) for all supported grid managers that constructs...
Definition gridmanager_base.hh:344
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:81
The base class for grid managers for dune-subgrid.
Definition gridmanager_sub.hh:69
void initHostGrid_(const std::string &paramGroup)
Definition gridmanager_sub.hh:157
void loadBalance()
Call loadBalance() function of the grid.
Definition gridmanager_sub.hh:108
Dune::SubGrid< dim, HostGrid > Grid
Definition gridmanager_sub.hh:75
std::unique_ptr< GridManager< Dune::YaspGrid< dim, Coordinates > > > hostGridManager_
Definition gridmanager_sub.hh:182
void updateSubGrid_(const ES &selector)
Update the subgrid.
Definition gridmanager_sub.hh:132
void init(HostGrid &hostGrid, const ES &selector, const std::string &paramGroup="")
Make the grid using an externally created host grid.
Definition gridmanager_sub.hh:82
HostGrid & hostGrid_()
Returns a reference to the host grid.
Definition gridmanager_sub.hh:177
void init(const ES &selector, const std::string &paramGroup="")
Make the grid and create the host grid internally.
Definition gridmanager_sub.hh:96
void initHostGrid_(const GlobalPosition &lowerLeft, const GlobalPosition &upperRight, const std::array< int, dim > &cells, const std::string &paramGroup, const int overlap=1, const std::bitset< dim > periodic=std::bitset< dim >{})
Definition gridmanager_sub.hh:163
void update(const ES &selector)
Update the existing subgrid.
Definition gridmanager_sub.hh:119
Definition consistentlyorientedgrid.hh:23
Provides a grid manager for all supported grid managers with input file interfaces....
@ element
Definition fieldtype.hh:23
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:149
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:165
Definition facetgridmanager.hh:89
Definition adapt.hh:17
Definition common/pdesolver.hh:24
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Grid properties related to periodicity.
A simple reader class for raster images.
A simple writer class for raster images.
The element selector concept.
Definition gridmanager_sub.hh:54
auto require(F &&f) -> decltype(bool(f(std::declval< const Element & >())))
bool isPeriodic(const typename Grid::LeafIntersection &intersection) const
Definition gridmanager_sub.hh:606
PeriodicGridTraits(const Grid &subGrid)
Definition gridmanager_sub.hh:603
void verifyConformingPeriodicBoundary() const
Definition gridmanager_sub.hh:620