GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/io/grid/gridmanager_base.hh
Date: 2025-05-03 19:19:02
Exec Total Coverage
Lines: 88 98 89.8%
Functions: 121 165 73.3%
Branches: 97 352 27.6%

Line Branch Exec Source
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 //
7 /*!
8 * \file
9 * \ingroup InputOutput
10 * \brief Provides a grid manager for all supported grid managers with
11 * input file interfaces. Manages data via the grid data member.
12 */
13 #ifndef DUMUX_IO_GRID_MANAGER_BASE_HH
14 #define DUMUX_IO_GRID_MANAGER_BASE_HH
15
16 #include <array>
17 #include <bitset>
18 #include <memory>
19 #include <sstream>
20
21 #include <dune/common/exceptions.hh>
22 #include <dune/common/classname.hh>
23 #include <dune/common/parallel/communication.hh>
24 #include <dune/common/parallel/mpihelper.hh>
25 #include <dune/grid/io/file/dgfparser/dgfparser.hh>
26 #include <dune/grid/io/file/gmshreader.hh>
27 #include <dune/grid/common/gridfactory.hh>
28 #include <dune/grid/utility/structuredgridfactory.hh>
29
30 #include <dumux/common/typetraits/typetraits.hh>
31 #include <dumux/common/parameters.hh>
32 #include <dumux/discretization/method.hh>
33 #include <dumux/io/vtk/vtkreader.hh>
34
35 #include "griddata.hh"
36 #include "gridinput_.hh"
37
38 namespace Dumux {
39
40 /*!
41 * \ingroup InputOutput
42 * \brief The grid manager (this is the class used by the user) for all supported grid managers that constructs a grid
43 * from information in the input file and handles the data.
44 * \note This class is specialised below for all supported grid managers. It inherits the functionality of the base class Dumux::GridManagerBase.
45 */
46 template <class Grid>
47 class GridManager;
48
49 /*!
50 * \ingroup InputOutput
51 * \brief The grid manager base interface (public) and methods common
52 * to most grid manager specializations (protected).
53 */
54 template <class GridType>
55 class GridManagerBase
56 {
57 public:
58 using Grid = GridType;
59 using GridData = Dumux::GridData<Grid>;
60
61 /*!
62 * \brief Make the grid. Implement this method in the specialization of this class for a grid type.
63 */
64 void init(const std::string& modelParamGroup = "")
65 {
66 static_assert(AlwaysFalse<GridType>::value,
67 "The header with the GridManager specialization for your grid type is not included "
68 "or no specialization has been implemented!"
69 " In case of the latter, consider providing your own GridManager."
70 );
71 }
72
73 /*!
74 * \brief Returns a reference to the grid.
75 */
76 90560 Grid& grid()
77 {
78
2/2
✓ Branch 0 taken 153 times.
✓ Branch 1 taken 45735 times.
90560 if(enableDgfGridPointer_)
79 171 return *dgfGridPtr();
80 else
81 90389 return *gridPtr();
82 }
83
84 /*!
85 * \brief Returns a const reference to the grid.
86 */
87 const Grid& grid() const
88 {
89 if(enableDgfGridPointer_)
90 return *dgfGridPtr();
91 else
92 return *gridPtr();
93 }
94
95 /*!
96 * \brief Call loadBalance() function of the grid.
97 */
98 703 void loadBalance()
99 {
100
2/2
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 507 times.
703 if (Dune::MPIHelper::instance().size() > 1)
101 {
102 // if we may have dgf parameters use load balancing of the dgf pointer
103
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 46 times.
62 if(enableDgfGridPointer_)
104 {
105 14 dgfGridPtr().loadBalance();
106 // update the grid data
107
1/2
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
28 gridData_ = std::make_shared<GridData>(dgfGridPtr());
108 }
109
110 // if we have gmsh parameters we have to manually load balance the data
111
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 42 times.
48 else if (enableGmshDomainMarkers_)
112 {
113 // element and face markers are communicated during load balance
114 4 auto dh = gridData_->createGmshDataHandle();
115
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 gridPtr()->loadBalance(dh.interface());
116
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 gridPtr()->communicate(dh.interface(), Dune::InteriorBorder_All_Interface, Dune::ForwardCommunication);
117 4 }
118
119 // if we have VTK parameters we have to manually load balance the data
120
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 38 times.
44 else if (enableVtkData_)
121 {
122 if constexpr (Detail::GridData::CartesianGrid<Grid>)
123 {
124 gridData_->communicateStructuredVtkData();
125 }
126 else
127 {
128 // cell and point data is communicated during load balance
129 4 auto dh = gridData_->createVtkDataHandle();
130
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 gridPtr()->loadBalance(dh.interface());
131
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 gridPtr()->communicate(dh.interface(), Dune::InteriorBorder_All_Interface, Dune::ForwardCommunication);
132 4 }
133 }
134
135 else
136 40 gridPtr()->loadBalance();
137 }
138 703 }
139
140 /*!
141 * \brief Get an owning pointer to grid data associated with the grid
142 * \note Throws if no grid data is available
143 */
144 58 std::shared_ptr<GridData> getGridData() const
145 {
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if (!gridData_)
147 DUNE_THROW(Dune::IOError, "No grid data available");
148
149 58 return gridData_;
150 }
151
152 /*!
153 * \brief Check whether there is data associated with the grid
154 */
155 bool hasGridData() const
156 { return static_cast<bool>(gridData_); }
157
158 protected:
159
160 /*!
161 * \brief Returns a reference to the grid pointer (std::shared_ptr<Grid>)
162 */
163 108779 std::shared_ptr<Grid>& gridPtr()
164 {
165
1/2
✓ Branch 0 taken 63914 times.
✗ Branch 1 not taken.
108779 if(!enableDgfGridPointer_)
166 108779 return gridPtr_;
167 else
168 DUNE_THROW(Dune::InvalidStateException, "You are using DGF. To get the grid pointer use method dgfGridPtr()!");
169 }
170
171 /*!
172 * \brief Returns a reference to the DGF grid pointer (Dune::GridPtr<Grid>).
173 */
174 306 Dune::GridPtr<Grid>& dgfGridPtr()
175 {
176
1/2
✓ Branch 0 taken 277 times.
✗ Branch 1 not taken.
306 if(enableDgfGridPointer_)
177 306 return dgfGridPtr_;
178 else
179 DUNE_THROW(Dune::InvalidStateException, "The DGF grid pointer is only available if the grid was constructed with a DGF file!");
180 }
181
182 /*!
183 * \brief Returns the filename extension of a given filename
184 */
185
1/2
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
137 std::string getFileExtension(const std::string& fileName) const
186 {
187
1/2
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
137 std::size_t i = fileName.rfind('.', fileName.length());
188
1/2
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
137 if (i != std::string::npos)
189 {
190 137 return(fileName.substr(i+1, fileName.length() - i));
191 }
192 else
193 {
194 DUNE_THROW(Dune::IOError, "Please provide and extension for your grid file ('"<< fileName << "')!");
195 }
196 return "";
197 }
198
199 /*!
200 * \brief Makes a grid from a file. We currently support
201 * - dgf (Dune Grid Format)
202 * - msh (Gmsh mesh format)
203 * - vtp/vtu (VTK file formats)
204 */
205 69 void makeGridFromFile(const std::string& fileName,
206 const std::string& modelParamGroup)
207 {
208 // We found a file in the input file...does it have a supported extension?
209 69 const std::string extension = getFileExtension(fileName);
210
7/8
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 40 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
69 if (extension != "dgf" && extension != "msh" && extension != "vtu" && extension != "vtp")
211 DUNE_THROW(Dune::IOError, "Grid type " << Dune::className<Grid>() << " doesn't support grid files with extension: *."<< extension);
212
213 // Dune Grid Format (DGF) files
214
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 42 times.
69 if (extension == "dgf")
215 {
216
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
27 enableDgfGridPointer_ = true;
217
4/8
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 26 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 26 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 26 times.
✗ Branch 11 not taken.
27 dgfGridPtr() = Dune::GridPtr<Grid>(fileName.c_str(), Dune::MPIHelper::getCommunicator());
218
2/4
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 26 times.
27 gridData_ = std::make_shared<GridData>(dgfGridPtr_);
219 }
220
221 // Gmsh mesh format
222
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 2 times.
42 else if (extension == "msh")
223 {
224 // get some optional parameters
225
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 const bool verbose = getParamFromGroup<bool>(modelParamGroup, "Grid.Verbosity", false);
226
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 const bool boundarySegments = getParamFromGroup<bool>(modelParamGroup, "Grid.BoundarySegments", false);
227
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 const bool domainMarkers = getParamFromGroup<bool>(modelParamGroup, "Grid.DomainMarkers", false);
228
229
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 31 times.
40 if (domainMarkers)
230 {
231 9 enableGmshDomainMarkers_ = true;
232 9 std::vector<int> boundaryMarkers, elementMarkers;
233
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 auto gridFactory = std::make_unique<Dune::GridFactory<Grid>>();
234 // the gmsh reader reads the grid on rank 0
235
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
18 Dune::GmshReader<Grid>::read(*gridFactory, fileName, boundaryMarkers, elementMarkers, verbose, boundarySegments);
236
4/8
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 9 times.
18 gridPtr() = std::shared_ptr<Grid>(gridFactory->createGrid());
237
3/8
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
9 gridData_ = std::make_shared<GridData>(gridPtr_, std::move(gridFactory), std::move(elementMarkers), std::move(boundaryMarkers));
238 9 }
239 else
240 {
241
1/2
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
31 auto gridFactory = std::make_unique<Dune::GridFactory<Grid>>();
242
1/2
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
31 Dune::GmshReader<Grid>::read(*gridFactory, fileName, verbose, boundarySegments);
243
4/10
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 31 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 31 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
62 gridPtr() = std::shared_ptr<Grid>(gridFactory->createGrid());
244 31 }
245 }
246
247 // VTK file formats for unstructured grids
248
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 else if (extension == "vtu" || extension == "vtp")
249 {
250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (Dune::MPIHelper::getCommunication().size() > 1)
251 DUNE_THROW(Dune::NotImplemented, "Reading grids in parallel from VTK file formats is currently not supported!");
252
253
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 VTKReader vtkReader(fileName);
254 2 VTKReader::Data cellData, pointData;
255
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 auto gridFactory = std::make_unique<Dune::GridFactory<Grid>>();
256
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 const bool verbose = getParamFromGroup<bool>(modelParamGroup, "Grid.Verbosity", false);
257
4/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
4 gridPtr() = vtkReader.readGrid(*gridFactory, cellData, pointData, verbose);
258
3/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
2 gridData_ = std::make_shared<GridData>(gridPtr_, std::move(gridFactory), std::move(cellData), std::move(pointData));
259 4 }
260 69 }
261
262 /*!
263 * \brief Makes a grid from a DGF file. This is used by grid managers that only support DGF.
264 */
265 10 void makeGridFromDgfFile(const std::string& fileName)
266 {
267 // We found a file in the input file...does it have a supported extension?
268 10 const std::string extension = getFileExtension(fileName);
269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(extension != "dgf")
270 DUNE_THROW(Dune::IOError, "Grid type " << Dune::className<Grid>() << " only supports DGF (*.dgf) but the specified filename has extension: *."<< extension);
271
272
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 enableDgfGridPointer_ = true;
273
4/8
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 10 times.
✗ Branch 11 not taken.
10 dgfGridPtr() = Dune::GridPtr<Grid>(fileName.c_str(), Dune::MPIHelper::getCommunicator());
274
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
10 gridData_ = std::make_shared<GridData>(dgfGridPtr_);
275 10 }
276
277 /*!
278 * \brief The cell types for structured grids
279 */
280 enum CellType {Simplex, Cube};
281
282 /*!
283 * \brief Makes a structured cube grid using the structured grid factory
284 */
285 template <int dim, int dimworld>
286 88 void makeStructuredGrid(CellType cellType,
287 const std::string& modelParamGroup)
288 {
289 using GlobalPosition = Dune::FieldVector<typename Grid::ctype, dimworld>;
290 88 const auto upperRight = getParamFromGroup<GlobalPosition>(modelParamGroup, "Grid.UpperRight");
291 176 const auto lowerLeft = getParamFromGroup<GlobalPosition>(modelParamGroup, "Grid.LowerLeft", GlobalPosition(0.0));
292
293 using CellArray = std::array<unsigned int, dim>;
294 88 CellArray cells; cells.fill(1);
295 88 cells = getParamFromGroup<CellArray>(modelParamGroup, "Grid.Cells", cells);
296
297 // make the grid
298
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 11 times.
88 if (cellType == CellType::Cube)
299 {
300
3/6
✓ Branch 2 taken 77 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 77 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 77 times.
154 gridPtr() = Dune::StructuredGridFactory<Grid>::createCubeGrid(lowerLeft, upperRight, cells);
301 }
302
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 else if (cellType == CellType::Simplex)
303 {
304
3/6
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 11 times.
22 gridPtr() = Dune::StructuredGridFactory<Grid>::createSimplexGrid(lowerLeft, upperRight, cells);
305 }
306 else
307 {
308 DUNE_THROW(Dune::GridError, "Unknown cell type for making structured grid! Choose Cube or Simplex.");
309 }
310 88 }
311
312 /*!
313 * \brief Refines a grid after construction if GridParameterGroup.Refinement is set in the input file
314 */
315 795 void maybeRefineGrid(const std::string& modelParamGroup)
316 {
317
2/2
✓ Branch 2 taken 135 times.
✓ Branch 3 taken 522 times.
1590 if (hasParamInGroup(modelParamGroup, "Grid.Refinement"))
318 184 grid().globalRefine(getParamFromGroup<int>(modelParamGroup, "Grid.Refinement"));
319 795 }
320
321 /*!
322 * \brief A state variable if the DGF Dune::GridPtr has been enabled.
323 * It is always enabled if a DGF grid file was used to create the grid.
324 */
325 bool enableDgfGridPointer_ = false;
326
327 /*!
328 * \brief A state variable if domain markers have been read from a Gmsh file.
329 */
330 bool enableGmshDomainMarkers_ = false;
331
332 /*!
333 * \brief A state variable if cell or point data have been read from a VTK file.
334 */
335 bool enableVtkData_ = false;
336
337 std::shared_ptr<Grid> gridPtr_;
338 Dune::GridPtr<Grid> dgfGridPtr_;
339
340 std::shared_ptr<GridData> gridData_;
341 };
342
343 template <class Grid>
344 class GridManager : public GridManagerBase<Grid> {};
345
346 } // end namespace Dumux
347
348 #endif
349