version 3.11-dev
griddata.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//
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>
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
37namespace Dumux {
38
39namespace Detail {
40
41template<class Grid>
42struct isUG : public std::false_type {};
43
44#if HAVE_DUNE_UGGRID
45template<int dim>
46struct isUG<Dune::UGGrid<dim>> : public std::true_type {};
47#endif
48
49} // end namespace Details
50
55template <class Grid>
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>;
64public:
65 enum class DataSourceType { dgf, gmsh, vtk };
66
68 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 : gridPtr_(std::move(grid))
71 , gridInput_(std::make_shared<GridInput>(gridPtr_, std::move(factory)))
72 , elementMarkers_(elementMarkers)
73 , boundaryMarkers_(boundaryMarkers)
74 , faceMarkers_(faceMarkers)
75 , dataSourceType_(DataSourceType::gmsh)
76 {}
77
79 GridData(Dune::GridPtr<Grid> grid)
80 : dgfGrid_(std::move(grid))
81 , dataSourceType_(DataSourceType::dgf)
82 {}
83
85 GridData(std::shared_ptr<Grid> grid, std::shared_ptr<Dune::GridFactory<Grid>> factory,
86 VTKReader::Data&& cellData, VTKReader::Data&& pointData)
87 : gridPtr_(std::move(grid))
88 , gridInput_(std::make_shared<GridInput>(gridPtr_, std::move(factory)))
89 , cellData_(cellData)
90 , pointData_(pointData)
91 , dataSourceType_(DataSourceType::vtk)
92 {}
93
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
108 // \{
109
114 const std::vector<double>& parameters(const Vertex& vertex) const
115 {
116 if (dataSourceType_ == DataSourceType::dgf)
117 {
118 if (vertex.level() != 0)
119 DUNE_THROW(Dune::IOError, "You can only obtain parameters for level 0 vertices!");
120
121 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
130 const std::vector<double>& parameters(const Element& element) const
131 {
132 if (dataSourceType_ == DataSourceType::dgf)
133 {
134 if (element.hasFather())
135 {
136 auto level0Element = element;
137 while(level0Element.hasFather())
138 level0Element = level0Element.father();
139
140 return dgfGrid_.parameters(level0Element);
141 }
142 else
143 {
144 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
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
168 // \{
169
175 int getBoundaryDomainMarker(int boundarySegmentIndex) const
176 {
177 if (dataSourceType_ != DataSourceType::gmsh)
178 DUNE_THROW(Dune::InvalidStateException, "Domain markers are only available for gmsh grids.");
179 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 return boundaryMarkers_[boundarySegmentIndex];
183 }
184
190 int getBoundaryDomainMarker(const Intersection& intersection) const
191 { return getBoundaryDomainMarker(intersection.boundarySegmentIndex()); }
192
196 bool wasInserted(const Intersection& intersection) const
197 { return gridInput_->wasInserted(intersection); }
198
204 int getElementDomainMarker(const Element& element) const
205 {
206 if (dataSourceType_ != DataSourceType::gmsh)
207 DUNE_THROW(Dune::InvalidStateException, "Domain markers are only available for gmsh grids.");
208
209 // parameters are only given for level 0 elements
210 auto level0element = element;
211 while (level0element.hasFather())
212 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 if (gridPtr_->comm().size() > 1 && !Detail::isUG<Grid>::value)
217 return elementMarkers_[gridPtr_->levelGridView(0).indexSet().index(level0element)];
218 else
219 return elementMarkers_[gridInput_->insertionIndex(level0element)];
220 }
221
226 template<bool ug = Detail::isUG<Grid>::value, typename std::enable_if_t<!ug, int> = 0>
228 {
229 return GmshDataHandle(*gridPtr_, *gridInput_, elementMarkers_, boundaryMarkers_, faceMarkers_);
230 }
231
236 template<bool ug = Detail::isUG<Grid>::value, typename std::enable_if_t<ug, int> = 0>
238 {
239 return GmshDataHandle(*gridPtr_, *gridInput_, elementMarkers_, boundaryMarkers_);
240 }
241
242 // \}
243
247 // \{
248
254 double getParameter(const Element& element, const std::string& fieldName) const
255 { return getArrayParameter<double, 1>(element, fieldName)[0]; }
256
264 template<class T, std::size_t size>
265 std::array<T, size> getArrayParameter(const Element& element, const std::string& fieldName) const
266 {
267 if (dataSourceType_ != DataSourceType::vtk)
268 DUNE_THROW(Dune::InvalidStateException, "This access function is only available for data from VTK files.");
269
270 if (cellData_.count(fieldName) == 0)
271 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 auto level0element = element;
275 while (level0element.hasFather())
276 level0element = level0element.father();
277
278 // different index depending on whether we have communicated user data (parallel setting) or not (sequential setting)
279 const auto index = [&]{
280 if (gridPtr_->comm().size() > 1)
281 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 return gridInput_->insertionIndex(level0element);
286 }();
287
288 std::array<T, size> param;
289 const auto& data = cellData_.at(fieldName);
290
291 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 for (std::size_t i = 0; i < size; ++i)
295 param[i] = static_cast<T>(data[i + size*index]);
296 return param;
297 }
298
305 double getParameter(const Vertex& vertex, const std::string& fieldName) const
306 { return getArrayParameter<double, 1>(vertex, fieldName)[0]; }
307
316 template<class T, std::size_t size>
317 std::array<T, size> getArrayParameter(const Vertex& vertex, const std::string& fieldName) const
318 {
319 if (dataSourceType_ != DataSourceType::vtk)
320 DUNE_THROW(Dune::InvalidStateException, "This access function is only available for data from VTK files.");
321
322 if (vertex.level() != 0)
323 DUNE_THROW(Dune::IOError, "You can only obtain parameters for level 0 vertices!");
324
325 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 const auto index = [&]{
330 if (gridPtr_->comm().size() > 1)
331 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 return gridInput_->insertionIndex(vertex);
336 }();
337
338 std::array<T, size> param;
339 const auto& data = pointData_.at(fieldName);
340
341 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 for (std::size_t i = 0; i < size; ++i)
345 param[i] = static_cast<T>(data[i + size*index]);
346 return param;
347 }
348
353 {
354 if (dataSourceType_ != DataSourceType::vtk)
355 DUNE_THROW(Dune::InvalidStateException, "This access function is only available for data from VTK files.");
356
357 return VtkDataHandle(*gridPtr_, *gridInput_, cellData_, pointData_);
358 }
359
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
374 { return dataSourceType_; }
375
376private:
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
385 std::vector<int> elementMarkers_;
386 std::vector<int> boundaryMarkers_;
387 std::vector<int> faceMarkers_;
388
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
Class for grid data attached to dgf or gmsh grid files.
Definition: griddata.hh:57
GridData(std::shared_ptr< Grid > grid, std::shared_ptr< Dune::GridFactory< Grid > > factory, std::vector< int > &&elementMarkers, std::vector< int > &&boundaryMarkers, std::vector< int > &&faceMarkers=std::vector< int >{})
constructor for gmsh grid data
Definition: griddata.hh:68
GridData(std::shared_ptr< Grid > grid, std::shared_ptr< ImageGrid > imageGrid, VTKReader::Data &&cellData, VTKReader::Data &&pointData)
constructor for structured VTK grid data
Definition: griddata.hh:96
double getParameter(const Vertex &vertex, const std::string &fieldName) const
Call the parameters function of the DGF grid pointer if available for vertex data.
Definition: griddata.hh:305
int getBoundaryDomainMarker(const Intersection &intersection) const
Return the boundary domain marker (Gmsh physical entity number) of an intersection Only available whe...
Definition: griddata.hh:190
double getParameter(const Element &element, const std::string &fieldName) const
Get an element parameter.
Definition: griddata.hh:254
GridData(std::shared_ptr< Grid > grid, std::shared_ptr< Dune::GridFactory< Grid > > factory, VTKReader::Data &&cellData, VTKReader::Data &&pointData)
constructor for unstructured VTK grid data
Definition: griddata.hh:85
void communicateStructuredVtkData()
Communication of the data in parallel simulations for structured grid is done manually.
Definition: griddata.hh:363
const Dune::DGFBoundaryParameter::type & parameters(const Dune::Intersection< GridImp, IntersectionImp > &intersection) const
Call the parameters function of the DGF grid pointer if available.
Definition: griddata.hh:155
GridData(Dune::GridPtr< Grid > grid)
constructor for dgf grid data
Definition: griddata.hh:79
VtkDataHandle createVtkDataHandle()
Create a data handle for communication of the data in parallel simulations via the grid.
Definition: griddata.hh:352
const std::vector< double > & parameters(const Vertex &vertex) const
Call the parameters function of the DGF grid pointer if available for vertex data.
Definition: griddata.hh:114
std::array< T, size > getArrayParameter(const Vertex &vertex, const std::string &fieldName) const
Call the parameters function of the DGF grid pointer if available for vertex data.
Definition: griddata.hh:317
int getBoundaryDomainMarker(int boundarySegmentIndex) const
Return the boundary domain marker (Gmsh physical entity number) of an intersection Only available whe...
Definition: griddata.hh:175
GmshDataHandle createGmshDataHandle()
Create a data handle for communication of the data in parallel simulations.
Definition: griddata.hh:227
std::array< T, size > getArrayParameter(const Element &element, const std::string &fieldName) const
Get an element parameter that is an array.
Definition: griddata.hh:265
int getElementDomainMarker(const Element &element) const
Return the element domain marker (Gmsh physical entity number) of an element. Only available when usi...
Definition: griddata.hh:204
DataSourceType dataSourceType() const
Definition: griddata.hh:373
DataSourceType
Definition: griddata.hh:65
const std::vector< double > & parameters(const Element &element) const
Call the parameters function of the DGF grid pointer if available for element data.
Definition: griddata.hh:130
bool wasInserted(const Intersection &intersection) const
Returns true if an intersection was inserted during grid creation.
Definition: griddata.hh:196
std::unordered_map< std::string, std::vector< double > > Data
the cell / point data type for point data read from a grid file
Definition: vtkreader.hh:350
A data handle for commucating grid data for gmsh grids.
void communicateStructuredVtkData(const Grid &grid, const GridInput &gridInput, ::Dumux::VTKReader::Data &cellData, ::Dumux::VTKReader::Data &pointData)
Definition: vtkgriddatahandle.hh:305
Definition: adapt.hh:17
Definition: common/pdesolver.hh:24
Definition: griddata.hh:42
A data handle for commucating grid data for gmsh grids.
Definition: gmshgriddatahandle.hh:37
A data handle for communicating grid data for VTK grids.
Definition: vtkgriddatahandle.hh:44
A data handle for communicating grid data for VTK grids.
A vtk file reader using tinyxml2 as xml backend.