3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
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
29#include <dune/common/deprecated.hh>
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// TODO: deprecated: remove this after 3.1 is released
38#include <dune/grid/io/file/vtk.hh>
39// TODO: deprecated: remove this after 3.1 is released
40#include <dune/grid/io/file/dgfparser/dgfwriter.hh>
41#endif
42
43#ifndef DUMUX_IO_GRID_MANAGER_HH
45#endif
46
49
50#if HAVE_DUNE_SUBGRID
51namespace Dumux {
52namespace Concept {
53
58template<class Element>
59struct ElementSelector
60{
61 template<class F>
62 auto require(F&& f) -> decltype(
63 bool(f(std::declval<const Element&>()))
64 );
65};
66} // end namespace Concept
67
72template <class HostGrid, class HostGridManager = GridManager<HostGrid>>
73class SubGridManagerBase
74: public GridManagerBase<Dune::SubGrid<HostGrid::dimension, HostGrid>>
75{
76 static constexpr int dim = HostGrid::dimension;
77 using HostElement = typename HostGrid::template Codim<0>::Entity;
78
79public:
80 using Grid = Dune::SubGrid<dim, HostGrid>;
81
85 template<class ES,
86 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
87 void init(HostGrid& hostGrid,
88 const ES& selector,
89 const std::string& paramGroup = "")
90 {
91 this->gridPtr() = createGrid_(hostGrid, selector, paramGroup);
92 loadBalance();
93 }
94
98 template<class ES,
99 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
100 void init(const ES& selector,
101 const std::string& paramGroup = "")
102 {
103 initHostGrid_(paramGroup);
104 this->gridPtr() = createGrid_(hostGridManager_->grid(), selector, paramGroup);
105 loadBalance();
106 }
107
111 template<class ElementSelector>
112 [[deprecated("Create an instance of this class and use subgridManager.init(hostGrid, selector, paramGroup)")]]
113 static std::unique_ptr<Grid> makeGrid(HostGrid& hostGrid,
114 const ElementSelector& selector,
115 const std::string& paramGroup = "")
116 {
117 std::cerr << "Deprecation warning: SubGridManager::makeGrid is deprecated."
118 << "Create an instance of this class and use subgridManager.init(hostGrid, selector, paramGroup)." << std::endl;
119
120 auto subgridPtr = createGrid_(hostGrid, selector, paramGroup);
121
122 // TODO: remove this after 3.1 is released
123 // If desired, write out the final subgrid as a dgf file.
124 if (getParamFromGroup<bool>(paramGroup, "Grid.WriteSubGridToDGF", false))
125 {
126 std::cerr << "Deprecation warning: SubGridManager: Grid.WriteSubGridToDGF is deprecated."
127 << "Use Dune::VTKWriter to write out your grid manually." << std::endl;
128
129 const auto postfix = getParamFromGroup<std::string>(paramGroup, "Problem.Name", "");
130 const std::string name = postfix == "" ? "subgrid" : "subgrid_" + postfix;
131 Dune::DGFWriter<typename Grid::LeafGridView> writer(subgridPtr->leafGridView());
132 writer.write(name + ".dgf");
133 }
134
135 // TODO: remove this after 3.1 is released
136 // If desired, write out the hostgrid as vtk file.
137 if (getParamFromGroup<bool>(paramGroup, "Grid.WriteSubGridToVtk", false))
138 {
139 std::cerr << "Deprecation warning: SubGridManager: Grid.WriteSubGridToVtk is deprecated."
140 << "Use Dune::VTKWriter to write out your grid manually." << std::endl;
141
142 const auto postfix = getParamFromGroup<std::string>(paramGroup, "Problem.Name", "");
143 const std::string name = postfix == "" ? "subgrid" : "subgrid_" + postfix;
144 Dune::VTKWriter<typename Grid::LeafGridView> vtkWriter(subgridPtr->leafGridView());
145 vtkWriter.write(name);
146 }
147
148 // Return a unique pointer to the subgrid.
149 return subgridPtr;
150 }
151
155 void loadBalance()
156 {
157 if (Dune::MPIHelper::getCollectiveCommunication().size() > 1)
158 this->grid().loadBalance();
159 }
160
161protected:
162
166 template<class ES,
167 typename std::enable_if_t<Dune::models<Concept::ElementSelector<HostElement>, ES>(), int> = 0>
168 static std::unique_ptr<Grid> createGrid_(HostGrid& hostGrid,
169 const ES& selector,
170 const std::string& paramGroup = "")
171 {
172 // A unique pointer to the subgrid.
173 auto subgridPtr = std::make_unique<Grid>(hostGrid);
174
175 // A container to store the host grid elements' ids.
176 std::set<typename HostGrid::Traits::GlobalIdSet::IdType> elementsForSubgrid;
177 const auto& globalIDset = subgridPtr->getHostGrid().globalIdSet();
178
179 // Construct the subgrid.
180 subgridPtr->createBegin();
181
182 // Loop over all elements of the host grid and use the selector to
183 // choose which elements to add to the subgrid.
184 auto hostGridView = subgridPtr->getHostGrid().leafGridView();
185 for (const auto& e : elements(hostGridView))
186 if (selector(e))
187 elementsForSubgrid.insert(globalIDset.template id<0>(e));
188
189 if (elementsForSubgrid.empty())
190 DUNE_THROW(Dune::GridError, "No elements in subgrid");
191
192 subgridPtr->insertSetPartial(elementsForSubgrid);
193 subgridPtr->createEnd();
194
195 // Return a unique pointer to the subgrid.
196 return subgridPtr;
197 }
198
199 void initHostGrid_(const std::string& paramGroup)
200 {
201 hostGridManager_ = std::make_unique<HostGridManager>();
202 hostGridManager_->init(paramGroup);
203 }
204
208 HostGrid& hostGrid_()
209 {
210 return hostGridManager_->grid();
211 }
212
213 std::unique_ptr<HostGridManager> hostGridManager_;
214};
215
224template<int dim, class HostGrid>
225class GridManager<Dune::SubGrid<dim, HostGrid>>
226: public SubGridManagerBase<HostGrid, GridManager<HostGrid>>
227{};
228
239template<int dim, class Coordinates>
240class GridManager<Dune::SubGrid<dim, Dune::YaspGrid<dim, Coordinates>>>
241: public SubGridManagerBase<Dune::YaspGrid<dim, Coordinates>, GridManager<Dune::YaspGrid<dim, Coordinates>>>
242{
243 using ParentType = SubGridManagerBase<Dune::YaspGrid<dim, Coordinates>,
244 GridManager<Dune::YaspGrid<dim, Coordinates>>>;
245public:
246 using typename ParentType::Grid;
247 using ParentType::init;
248
254 void init(const std::string& paramGroup = "")
255 {
256 // check if there is an image file we can construct the element selector from
257 if (hasParamInGroup(paramGroup, "Grid.Image"))
258 {
259 const auto imgFileName = getParamFromGroup<std::string>(paramGroup, "Grid.Image");
260 const auto ext = this->getFileExtension(imgFileName);
261 if (ext == "pbm")
262 {
263 if (dim != 2)
264 DUNE_THROW(Dune::GridError, "Portable Bitmap Format only supports dim == 2");
265
266 // read image
267 const auto img = NetPBMReader::readPBM(imgFileName);
268 createGridFromImage_(img, paramGroup);
269 }
270 else
271 DUNE_THROW(Dune::IOError, "The SubGridManager doesn't support image files with extension: *." << ext);
272
273 }
274 else
275 DUNE_THROW(Dune::IOError, "SubGridManager couldn't construct element selector. Specify Grid.Image in the input file!");
276 }
277
278private:
279 template<class Img>
280 void createGridFromImage_(const Img& img, const std::string& paramGroup)
281 {
282 // check if the number of cells matches
283 std::array<int, dim> cells; cells.fill(1);
284 cells = getParamFromGroup<std::array<int, dim>>(paramGroup, "Grid.Cells", cells);
285
286 if (img.header().nCols != cells[0])
287 DUNE_THROW(Dune::GridError, "Host grid has wrong number of cells in x-direction. Expected "
288 << img.header().nCols << ", got " << cells[0]);
289 if (img.header().nRows != cells[1])
290 DUNE_THROW(Dune::GridError, "Host grid has wrong number of cells in y-direction. Expected "
291 << img.header().nRows << ", got " << cells[1]);
292
293
294 // construct the host grid
295 this->initHostGrid_(paramGroup);
296
297 // check if the marker is customized, per default
298 // we mark all cells that are encoded as 0
299 const bool marked = getParamFromGroup<bool>(paramGroup, "Grid.Marker", 0);
300
301 // Create the selector
302 auto elementSelector = [this, &img, &marked](const auto& element)
303 {
304 const auto eIdx = this->hostGrid_().leafGridView().indexSet().index(element);
305 return img[eIdx] == marked;
306 };
307
308 // create the grid
309 this->gridPtr() = this->createGrid_(this->hostGrid_(), elementSelector, paramGroup);
310 this->loadBalance();
311 }
312};
313
315template<int dim, class HostGrid>
316class BoundaryFlag<Dune::SubGrid<dim, HostGrid>>
317{
318public:
319 BoundaryFlag() : flag_(-1) {}
320
321 template<class Intersection>
322 BoundaryFlag(const Intersection& i) : flag_(-1) {}
323
324 using value_type = int;
325
326 value_type get() const
327 { DUNE_THROW(Dune::NotImplemented, "Sub-grid doesn't implement boundary segment indices!"); }
328
329private:
330 int flag_;
331};
332
333} // end namespace Dumux
334#endif // HAVE_DUNE_SUBGRID
335#endif
Boundary flag to store e.g. in sub control volume faces.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
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:454
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
Definition: common/properties/model.hh:34
std::size_t value_type
Definition: boundaryflag.hh:51
value_type get() const
Definition: boundaryflag.hh:53
void loadBalance()
Call loadBalance() function of the grid.
Definition: gridmanager_base.hh:95
std::shared_ptr< Grid > & gridPtr()
Returns a reference to the grid pointer (std::shared_ptr<Grid>)
Definition: gridmanager_base.hh:134
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
std::string getFileExtension(const std::string &fileName) const
Returns the filename extension of a given filename.
Definition: gridmanager_base.hh:156
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:142
Convience header that includes all grid manager specializations.