GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/io/grid/griddata.hh
Date: 2025-05-03 19:19:02
Exec Total Coverage
Lines: 94 110 85.5%
Functions: 42 96 43.8%
Branches: 72 465 15.5%

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 Class for grid data attached to dgf or gmsh grid files
11 */
12 #ifndef DUMUX_IO_GRID_DATA_HH
13 #define DUMUX_IO_GRID_DATA_HH
14
15 #include <vector>
16 #include <memory>
17 #include <type_traits>
18
19 #include <dune/common/exceptions.hh>
20 #include <dune/common/parallel/communication.hh>
21 #include <dune/common/parallel/mpihelper.hh>
22 #include <dune/grid/common/gridfactory.hh>
23 #include <dune/grid/common/capabilities.hh>
24 #include <dune/grid/io/file/dgfparser/parser.hh>
25 #include <dune/grid/io/file/dgfparser/gridptr.hh>
26 #include <dumux/io/vtk/vtkreader.hh>
27
28 // UGGrid specific includes
29 #if HAVE_DUNE_UGGRID
30 #include <dune/grid/uggrid.hh>
31 #endif
32
33 #include "gridinput_.hh"
34 #include "gmshgriddatahandle.hh"
35 #include "vtkgriddatahandle.hh"
36
37 namespace Dumux {
38
39 namespace Detail {
40
41 template<class Grid>
42 struct isUG : public std::false_type {};
43
44 #if HAVE_DUNE_UGGRID
45 template<int dim>
46 struct isUG<Dune::UGGrid<dim>> : public std::true_type {};
47 #endif
48
49 } // end namespace Details
50
51 /*!
52 * \ingroup InputOutput
53 * \brief Class for grid data attached to dgf or gmsh grid files
54 */
55 template <class Grid>
56 class GridData
57 {
58 using Intersection = typename Grid::LeafIntersection;
59 using Element = typename Grid::template Codim<0>::Entity;
60 using Vertex = typename Grid::template Codim<Grid::dimension>::Entity;
61 using GridInput = Detail::GridData::GridInput<Grid>;
62 using GmshDataHandle = GmshGridDataHandle<Grid, GridInput, std::vector<int>>;
63 using VtkDataHandle = VtkGridDataHandle<Grid, GridInput, std::vector<double>>;
64 public:
65 enum class DataSourceType { dgf, gmsh, vtk };
66
67 //! constructor for gmsh grid data
68 65 GridData(std::shared_ptr<Grid> grid, std::shared_ptr<Dune::GridFactory<Grid>> factory,
69 std::vector<int>&& elementMarkers, std::vector<int>&& boundaryMarkers, std::vector<int>&& faceMarkers = std::vector<int>{})
70
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
65 : gridPtr_(std::move(grid))
71
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
65 , gridInput_(std::make_shared<GridInput>(gridPtr_, std::move(factory)))
72
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
65 , elementMarkers_(elementMarkers)
73
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
65 , boundaryMarkers_(boundaryMarkers)
74
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
65 , faceMarkers_(faceMarkers)
75
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
65 , dataSourceType_(DataSourceType::gmsh)
76 65 {}
77
78 //! constructor for dgf grid data
79 88 GridData(Dune::GridPtr<Grid> grid)
80
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
88 : dgfGrid_(std::move(grid))
81
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
88 , dataSourceType_(DataSourceType::dgf)
82 88 {}
83
84 //! constructor for unstructured VTK grid data
85 8 GridData(std::shared_ptr<Grid> grid, std::shared_ptr<Dune::GridFactory<Grid>> factory,
86 VTKReader::Data&& cellData, VTKReader::Data&& pointData)
87
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 : gridPtr_(std::move(grid))
88
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 , gridInput_(std::make_shared<GridInput>(gridPtr_, std::move(factory)))
89
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 , cellData_(cellData)
90
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 , pointData_(pointData)
91
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
16 , dataSourceType_(DataSourceType::vtk)
92 8 {}
93
94 //! constructor for structured VTK grid data
95 template<class ImageGrid>
96 GridData(std::shared_ptr<Grid> grid, std::shared_ptr<ImageGrid> imageGrid,
97 VTKReader::Data&& cellData, VTKReader::Data&& pointData)
98 : gridPtr_(std::move(grid))
99 , gridInput_(std::make_shared<GridInput>(gridPtr_, std::move(imageGrid)))
100 , cellData_(cellData)
101 , pointData_(pointData)
102 , dataSourceType_(DataSourceType::vtk)
103 {}
104
105 /*!
106 * \name DGF interface functions
107 */
108 // \{
109
110 /*!
111 * \brief Call the parameters function of the DGF grid pointer if available for vertex data
112 * \note You can only pass vertices that exist on level 0!
113 */
114 15686 const std::vector<double>& parameters(const Vertex& vertex) const
115 {
116
1/2
✓ Branch 0 taken 15686 times.
✗ Branch 1 not taken.
15686 if (dataSourceType_ == DataSourceType::dgf)
117 {
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15686 times.
15686 if (vertex.level() != 0)
119 DUNE_THROW(Dune::IOError, "You can only obtain parameters for level 0 vertices!");
120
121 15686 return dgfGrid_.parameters(vertex);
122 }
123 else
124 DUNE_THROW(Dune::InvalidStateException, "The parameters method is only available if the grid was constructed with a DGF file.");
125 }
126
127 /*!
128 * \brief Call the parameters function of the DGF grid pointer if available for element data
129 */
130 138294 const std::vector<double>& parameters(const Element& element) const
131 {
132
1/2
✓ Branch 0 taken 138294 times.
✗ Branch 1 not taken.
138294 if (dataSourceType_ == DataSourceType::dgf)
133 {
134
2/2
✓ Branch 0 taken 59529 times.
✓ Branch 1 taken 78765 times.
138294 if (element.hasFather())
135 {
136 59529 auto level0Element = element;
137
4/5
✓ Branch 1 taken 90887 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 31358 times.
✓ Branch 4 taken 30010 times.
✓ Branch 0 taken 29519 times.
120406 while(level0Element.hasFather())
138 60877 level0Element = level0Element.father();
139
140
1/2
✓ Branch 1 taken 30010 times.
✗ Branch 2 not taken.
59529 return dgfGrid_.parameters(level0Element);
141 30010 }
142 else
143 {
144 78765 return dgfGrid_.parameters(element);
145 }
146 }
147 else
148 DUNE_THROW(Dune::InvalidStateException, "The parameters method is only available if the grid was constructed with a DGF file.");
149 }
150
151 /*!
152 * \brief Call the parameters function of the DGF grid pointer if available
153 */
154 template <class GridImp, class IntersectionImp>
155 const Dune::DGFBoundaryParameter::type& parameters(const Dune::Intersection<GridImp, IntersectionImp>& intersection) const
156 {
157 if (dataSourceType_ == DataSourceType::dgf)
158 return dgfGrid_.parameters(intersection);
159 else
160 DUNE_THROW(Dune::InvalidStateException, "The parameters method is only available if the grid was constructed with a DGF file.");
161 }
162
163 // \}
164
165 /*!
166 * \name Gmsh interface functions
167 */
168 // \{
169
170 /*!
171 * \brief Return the boundary domain marker (Gmsh physical entity number) of an intersection
172 Only available when using Gmsh with GridParameterGroup.DomainMarkers = 1.
173 * \param boundarySegmentIndex The boundary segment index of the intersection (intersection.boundarySegmentIndex()
174 */
175 759198 int getBoundaryDomainMarker(int boundarySegmentIndex) const
176 {
177
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 759198 times.
759198 if (dataSourceType_ != DataSourceType::gmsh)
178 DUNE_THROW(Dune::InvalidStateException, "Domain markers are only available for gmsh grids.");
179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 759198 times.
759198 if (boundarySegmentIndex >= boundaryMarkers_.size())
180 DUNE_THROW(Dune::RangeError, "Boundary segment index "<< boundarySegmentIndex << " bigger than number of boundary segments in grid.\n"
181 "Make sure to call this function only for boundaries that were defined as physical entities in gmsh.");
182 759198 return boundaryMarkers_[boundarySegmentIndex];
183 }
184
185 /*!
186 * \brief Return the boundary domain marker (Gmsh physical entity number) of an intersection
187 Only available when using Gmsh with GridParameterGroup.DomainMarkers = 1.
188 * \param intersection The intersection to be evaluated
189 */
190
3/6
✓ Branch 1 taken 3781 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17921 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 84 times.
✗ Branch 8 not taken.
21786 int getBoundaryDomainMarker(const Intersection& intersection) const
191
3/6
✓ Branch 1 taken 3781 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17921 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 84 times.
✗ Branch 8 not taken.
21786 { return getBoundaryDomainMarker(intersection.boundarySegmentIndex()); }
192
193 /*!
194 * \brief Returns true if an intersection was inserted during grid creation
195 */
196 480 bool wasInserted(const Intersection& intersection) const
197
2/4
✓ Branch 1 taken 480 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 480 times.
✗ Branch 4 not taken.
480 { return gridInput_->wasInserted(intersection); }
198
199 /*!
200 * \brief Return the element domain marker (Gmsh physical entity number) of an element.
201 Only available when using Gmsh with GridParameterGroup.DomainMarkers = 1.
202 * \param element The element to be evaluated
203 */
204 144487 int getElementDomainMarker(const Element& element) const
205 {
206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143437 times.
144487 if (dataSourceType_ != DataSourceType::gmsh)
207
0/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
144487 DUNE_THROW(Dune::InvalidStateException, "Domain markers are only available for gmsh grids.");
208
209 // parameters are only given for level 0 elements
210 144487 auto level0element = element;
211
4/5
✓ Branch 1 taken 189549 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 46112 times.
✓ Branch 4 taken 63401 times.
✓ Branch 0 taken 63791 times.
254390 while (level0element.hasFather())
212 109903 level0element = level0element.father();
213
214 // in the parallel case the data is load balanced and then accessed with indices of the index set
215 // for UGGrid element data is read on all processes since UGGrid can't communicate element data (yet)
216
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 63401 times.
✓ Branch 2 taken 32092 times.
✓ Branch 3 taken 31309 times.
144487 if (gridPtr_->comm().size() > 1 && !Detail::isUG<Grid>::value)
217
2/4
✓ Branch 1 taken 32092 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32092 times.
✗ Branch 5 not taken.
32092 return elementMarkers_[gridPtr_->levelGridView(0).indexSet().index(level0element)];
218 else
219
1/2
✓ Branch 1 taken 31309 times.
✗ Branch 2 not taken.
112395 return elementMarkers_[gridInput_->insertionIndex(level0element)];
220 63892 }
221
222 /*!
223 * \brief Create a data handle for communication of the data in parallel simulations
224 * \note this data handle is the default
225 */
226 template<bool ug = Detail::isUG<Grid>::value, typename std::enable_if_t<!ug, int> = 0>
227 4 GmshDataHandle createGmshDataHandle()
228 {
229 4 return GmshDataHandle(*gridPtr_, *gridInput_, elementMarkers_, boundaryMarkers_, faceMarkers_);
230 }
231
232 /*!
233 * \brief Create a data handle for communication of the data in parallel simulations
234 * \note this data handle is the specialized for UGGrid since UGGrid can't communicate element data (yet)
235 */
236 template<bool ug = Detail::isUG<Grid>::value, typename std::enable_if_t<ug, int> = 0>
237 4 GmshDataHandle createGmshDataHandle()
238 {
239 4 return GmshDataHandle(*gridPtr_, *gridInput_, elementMarkers_, boundaryMarkers_);
240 }
241
242 // \}
243
244 /*!
245 * \name VTK interface functions
246 */
247 // \{
248
249 /*!
250 * \brief Get an element parameter
251 * \param element the element
252 * \param fieldName the name of the field to read from the vtk data
253 */
254 23795 double getParameter(const Element& element, const std::string& fieldName) const
255
1/2
✓ Branch 1 taken 23795 times.
✗ Branch 2 not taken.
23795 { return getArrayParameter<double, 1>(element, fieldName)[0]; }
256
257 /*!
258 * \brief Get an element parameter that is an array
259 * \param element the element
260 * \param fieldName the name of the field to read from the vtk data
261 * \tparam T the parameter scalar type
262 * \tparam size the number of parameters in the array
263 */
264 template<class T, std::size_t size>
265 23795 std::array<T, size> getArrayParameter(const Element& element, const std::string& fieldName) const
266 {
267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23795 times.
23795 if (dataSourceType_ != DataSourceType::vtk)
268 DUNE_THROW(Dune::InvalidStateException, "This access function is only available for data from VTK files.");
269
270 23795 if (cellData_.count(fieldName) == 0)
271
0/36
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 1 not taken.
✗ Branch 4 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
✗ Branch 28 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
23795 DUNE_THROW(Dune::IOError, "No field with the name " << fieldName << " found in cell data.");
272
273 // parameters are only given for level 0 elements
274 23795 auto level0element = element;
275
3/5
✓ Branch 1 taken 33971 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10176 times.
✓ Branch 4 taken 15264 times.
✗ Branch 0 not taken.
33971 while (level0element.hasFather())
276 10176 level0element = level0element.father();
277
278 // different index depending on whether we have communicated user data (parallel setting) or not (sequential setting)
279 64433 const auto index = [&]{
280
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 20319 times.
✓ Branch 2 taken 7632 times.
✓ Branch 3 taken 7632 times.
23795 if (gridPtr_->comm().size() > 1)
281 7632 return gridPtr_->levelGridView(0).indexSet().index(level0element);
282 else if (Detail::GridData::CartesianGrid<Grid>)
283 return gridPtr_->levelGridView(0).indexSet().index(level0element);
284 else
285 16163 return gridInput_->insertionIndex(level0element);
286
1/2
✓ Branch 1 taken 15264 times.
✗ Branch 2 not taken.
23795 }();
287
288 std::array<T, size> param;
289
2/4
✓ Branch 1 taken 15264 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15264 times.
✗ Branch 5 not taken.
23795 const auto& data = cellData_.at(fieldName);
290
291
3/4
✓ Branch 1 taken 20319 times.
✓ Branch 2 taken 3476 times.
✓ Branch 3 taken 15264 times.
✗ Branch 4 not taken.
23795 if (const std::size_t nc = data.size()/gridPtr_->levelGridView(0).size(0); size != nc)
292 DUNE_THROW(Dune::IOError, "Array size " << size << " does not match number of components of field " << nc);
293
294
2/2
✓ Branch 0 taken 23795 times.
✓ Branch 1 taken 23795 times.
47590 for (std::size_t i = 0; i < size; ++i)
295 23795 param[i] = static_cast<T>(data[i + size*index]);
296 23795 return param;
297 15264 }
298
299 /*!
300 * \brief Call the parameters function of the DGF grid pointer if available for vertex data
301 * \param vertex the vertex
302 * \param fieldName the name of the field to read from the vtk data
303 * \note You can only pass vertices that exist on level 0!
304 */
305 53413 double getParameter(const Vertex& vertex, const std::string& fieldName) const
306
1/2
✓ Branch 1 taken 53413 times.
✗ Branch 2 not taken.
53413 { return getArrayParameter<double, 1>(vertex, fieldName)[0]; }
307
308 /*!
309 * \brief Call the parameters function of the DGF grid pointer if available for vertex data
310 * \param vertex the vertex
311 * \param fieldName the name of the field to read from the vtk data
312 * \tparam T the parameter scalar type
313 * \tparam size the number of parameters in the array
314 * \note You can only pass vertices that exist on level 0 (otherwise: undefined behaviour).
315 */
316 template<class T, std::size_t size>
317 53413 std::array<T, size> getArrayParameter(const Vertex& vertex, const std::string& fieldName) const
318 {
319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53413 times.
53413 if (dataSourceType_ != DataSourceType::vtk)
320
1/22
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 53413 times.
53413 DUNE_THROW(Dune::InvalidStateException, "This access function is only available for data from VTK files.");
321
322
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53413 times.
53413 if (vertex.level() != 0)
323 DUNE_THROW(Dune::IOError, "You can only obtain parameters for level 0 vertices!");
324
325 53413 if (pointData_.count(fieldName) == 0)
326 DUNE_THROW(Dune::IOError, "No field with the name " << fieldName << " found in point data");
327
328 // different index depending on whether we have communicated user data (parallel setting) or not (sequential setting)
329 160239 const auto index = [&]{
330
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 53413 times.
✓ Branch 2 taken 1398 times.
✓ Branch 3 taken 1325 times.
53413 if (gridPtr_->comm().size() > 1)
331 1398 return gridPtr_->levelGridView(0).indexSet().index(vertex);
332 else if (Detail::GridData::CartesianGrid<Grid>)
333 return gridPtr_->levelGridView(0).indexSet().index(vertex);
334 else
335 52015 return gridInput_->insertionIndex(vertex);
336 53413 }();
337
338 std::array<T, size> param;
339 53413 const auto& data = pointData_.at(fieldName);
340
341
1/2
✓ Branch 1 taken 53413 times.
✗ Branch 2 not taken.
53413 if (const std::size_t nc = data.size()/gridPtr_->levelGridView(0).size(Grid::dimension); size != nc)
342 DUNE_THROW(Dune::IOError, "Array size " << size << " does not match number of components of field " << nc);
343
344
2/2
✓ Branch 0 taken 53413 times.
✓ Branch 1 taken 53413 times.
106826 for (std::size_t i = 0; i < size; ++i)
345 53413 param[i] = static_cast<T>(data[i + size*index]);
346 53413 return param;
347 }
348
349 /*!
350 * \brief Create a data handle for communication of the data in parallel simulations via the grid
351 */
352 4 VtkDataHandle createVtkDataHandle()
353 {
354
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (dataSourceType_ != DataSourceType::vtk)
355 DUNE_THROW(Dune::InvalidStateException, "This access function is only available for data from VTK files.");
356
357 4 return VtkDataHandle(*gridPtr_, *gridInput_, cellData_, pointData_);
358 }
359
360 /*!
361 * \brief Communication of the data in parallel simulations for structured grid is done manually
362 */
363 void communicateStructuredVtkData()
364 {
365 if (dataSourceType_ != DataSourceType::vtk)
366 DUNE_THROW(Dune::InvalidStateException, "This access function is only available for data from VTK files.");
367
368 Detail::VtkData::communicateStructuredVtkData(*gridPtr_, *gridInput_, cellData_, pointData_);
369 }
370
371 // \}
372
373 DataSourceType dataSourceType() const
374 { return dataSourceType_; }
375
376 private:
377 // grid and grid factor for gmsh grid data / vtk grid data
378 std::shared_ptr<Grid> gridPtr_;
379 std::shared_ptr<GridInput> gridInput_;
380
381 /*!
382 * \brief Element and boundary domain markers obtained from Gmsh physical entities
383 * They map from element indices / boundary ids to the physical entity number
384 */
385 std::vector<int> elementMarkers_;
386 std::vector<int> boundaryMarkers_;
387 std::vector<int> faceMarkers_;
388
389 /*!
390 * \brief Cell and vertex data obtained from VTK files
391 */
392 VTKReader::Data cellData_, pointData_;
393
394 // dgf grid data
395 Dune::GridPtr<Grid> dgfGrid_;
396
397 // specify which type of data we have
398 // TODO unfortunately all grid readers provide different data types, should be streamlined (changes in Dune)
399 DataSourceType dataSourceType_;
400 };
401
402 } // namespace Dumux
403
404 #endif
405