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-FileCopyrightInfo: 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/io/file/dgfparser/parser.hh> | ||
24 | #include <dune/grid/io/file/dgfparser/gridptr.hh> | ||
25 | #include <dumux/io/vtk/vtkreader.hh> | ||
26 | |||
27 | // UGGrid specific includes | ||
28 | #if HAVE_DUNE_UGGRID | ||
29 | #include <dune/grid/uggrid.hh> | ||
30 | #endif | ||
31 | |||
32 | #include "gmshgriddatahandle.hh" | ||
33 | |||
34 | namespace Dumux { | ||
35 | |||
36 | namespace Detail { | ||
37 | |||
38 | template<class Grid> | ||
39 | struct isUG : public std::false_type {}; | ||
40 | |||
41 | #if HAVE_DUNE_UGGRID | ||
42 | template<int dim> | ||
43 | struct isUG<Dune::UGGrid<dim>> : public std::true_type {}; | ||
44 | #endif | ||
45 | |||
46 | } // end namespace Details | ||
47 | |||
48 | /*! | ||
49 | * \ingroup InputOutput | ||
50 | * \brief Class for grid data attached to dgf or gmsh grid files | ||
51 | */ | ||
52 | template <class Grid> | ||
53 | class GridData | ||
54 | { | ||
55 | using Intersection = typename Grid::LeafIntersection; | ||
56 | using Element = typename Grid::template Codim<0>::Entity; | ||
57 | using Vertex = typename Grid::template Codim<Grid::dimension>::Entity; | ||
58 | using DataHandle = GmshGridDataHandle<Grid, Dune::GridFactory<Grid>, std::vector<int>>; | ||
59 | |||
60 | enum DataSourceType { dgf, gmsh, vtk }; | ||
61 | |||
62 | public: | ||
63 | //! constructor for gmsh grid data | ||
64 | 65 | GridData(std::shared_ptr<Grid> grid, std::shared_ptr<Dune::GridFactory<Grid>> factory, | |
65 | std::vector<int>&& elementMarkers, std::vector<int>&& boundaryMarkers, std::vector<int>&& faceMarkers = std::vector<int>{}) | ||
66 | : gridPtr_(grid) | ||
67 | , gridFactory_(factory) | ||
68 | , elementMarkers_(elementMarkers) | ||
69 | , boundaryMarkers_(boundaryMarkers) | ||
70 | , faceMarkers_(faceMarkers) | ||
71 |
6/22✓ Branch 3 taken 41 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 41 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 41 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 41 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 41 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 41 times.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
65 | , dataSourceType_(DataSourceType::gmsh) |
72 | 65 | {} | |
73 | |||
74 | //! constructor for dgf grid data | ||
75 | 83 | GridData(Dune::GridPtr<Grid> grid) | |
76 | : dgfGrid_(grid) | ||
77 |
8/26✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 76 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 76 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 76 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 76 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 76 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 76 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 76 times.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
664 | , dataSourceType_(DataSourceType::dgf) |
78 | 83 | {} | |
79 | |||
80 | //! constructor for gmsh grid data | ||
81 | 2 | GridData(std::shared_ptr<Grid> grid, std::shared_ptr<Dune::GridFactory<Grid>> factory, | |
82 | VTKReader::Data&& cellData, VTKReader::Data&& pointData) | ||
83 | : gridPtr_(grid) | ||
84 | , gridFactory_(factory) | ||
85 | , cellData_(cellData) | ||
86 | , pointData_(pointData) | ||
87 |
6/22✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
2 | , dataSourceType_(DataSourceType::vtk) |
88 | 2 | {} | |
89 | |||
90 | |||
91 | /*! | ||
92 | * \name DGF interface functions | ||
93 | */ | ||
94 | // \{ | ||
95 | |||
96 | /*! | ||
97 | * \brief Call the parameters function of the DGF grid pointer if available for vertex data | ||
98 | * \note You can only pass vertices that exist on level 0! | ||
99 | */ | ||
100 | 15686 | const std::vector<double>& parameters(const Vertex& vertex) const | |
101 | { | ||
102 |
1/2✓ Branch 0 taken 15686 times.
✗ Branch 1 not taken.
|
15686 | if (dataSourceType_ == DataSourceType::dgf) |
103 | { | ||
104 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 15686 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15686 times.
|
31372 | if (vertex.level() != 0) |
105 | ✗ | DUNE_THROW(Dune::IOError, "You can only obtain parameters for level 0 vertices!"); | |
106 | |||
107 | 15686 | return dgfGrid_.parameters(vertex); | |
108 | } | ||
109 | else | ||
110 | ✗ | DUNE_THROW(Dune::InvalidStateException, "The parameters method is only available if the grid was constructed with a DGF file."); | |
111 | } | ||
112 | |||
113 | /*! | ||
114 | * \brief Call the parameters function of the DGF grid pointer if available for element data | ||
115 | */ | ||
116 | 138294 | const std::vector<double>& parameters(const Element& element) const | |
117 | { | ||
118 |
1/2✓ Branch 0 taken 138294 times.
✗ Branch 1 not taken.
|
138294 | if (dataSourceType_ == DataSourceType::dgf) |
119 | { | ||
120 |
4/4✓ Branch 0 taken 29519 times.
✓ Branch 1 taken 56645 times.
✓ Branch 2 taken 81649 times.
✓ Branch 3 taken 26635 times.
|
194448 | if (element.hasFather()) |
121 | { | ||
122 | 89539 | auto level0Element = element; | |
123 |
5/5✓ Branch 0 taken 29519 times.
✓ Branch 1 taken 90887 times.
✓ Branch 2 taken 29519 times.
✓ Branch 3 taken 60877 times.
✓ Branch 4 taken 30010 times.
|
179444 | while(level0Element.hasFather()) |
124 |
1/2✓ Branch 1 taken 31358 times.
✗ Branch 2 not taken.
|
60877 | level0Element = level0Element.father(); |
125 | |||
126 |
1/2✓ Branch 1 taken 30010 times.
✗ Branch 2 not taken.
|
59529 | return dgfGrid_.parameters(level0Element); |
127 | } | ||
128 | else | ||
129 | { | ||
130 | 78765 | return dgfGrid_.parameters(element); | |
131 | } | ||
132 | } | ||
133 | else | ||
134 | ✗ | DUNE_THROW(Dune::InvalidStateException, "The parameters method is only available if the grid was constructed with a DGF file."); | |
135 | } | ||
136 | |||
137 | /*! | ||
138 | * \brief Call the parameters function of the DGF grid pointer if available | ||
139 | */ | ||
140 | template <class GridImp, class IntersectionImp> | ||
141 | const Dune::DGFBoundaryParameter::type& parameters(const Dune::Intersection<GridImp, IntersectionImp>& intersection) const | ||
142 | { | ||
143 | if (dataSourceType_ == DataSourceType::dgf) | ||
144 | return dgfGrid_.parameters(intersection); | ||
145 | else | ||
146 | DUNE_THROW(Dune::InvalidStateException, "The parameters method is only available if the grid was constructed with a DGF file."); | ||
147 | } | ||
148 | |||
149 | // \} | ||
150 | |||
151 | /*! | ||
152 | * \name Gmsh interface functions | ||
153 | */ | ||
154 | // \{ | ||
155 | |||
156 | /*! | ||
157 | * \brief Return the boundary domain marker (Gmsh physical entity number) of an intersection | ||
158 | Only available when using Gmsh with GridParameterGroup.DomainMarkers = 1. | ||
159 | * \param boundarySegmentIndex The boundary segment index of the intersection (intersection.boundarySegmentIndex() | ||
160 | */ | ||
161 | 759198 | int getBoundaryDomainMarker(int boundarySegmentIndex) const | |
162 | { | ||
163 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 759198 times.
|
759198 | if (dataSourceType_ != DataSourceType::gmsh) |
164 | ✗ | DUNE_THROW(Dune::InvalidStateException, "Domain markers are only available for gmsh grids."); | |
165 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 759198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 759198 times.
|
1518396 | if (boundarySegmentIndex >= boundaryMarkers_.size()) |
166 | ✗ | DUNE_THROW(Dune::RangeError, "Boundary segment index "<< boundarySegmentIndex << " bigger than number of boundary segments in grid.\n" | |
167 | "Make sure to call this function only for boundaries that were defined as physical entities in gmsh."); | ||
168 | 1518396 | return boundaryMarkers_[boundarySegmentIndex]; | |
169 | } | ||
170 | |||
171 | /*! | ||
172 | * \brief Return the boundary domain marker (Gmsh physical entity number) of an intersection | ||
173 | Only available when using Gmsh with GridParameterGroup.DomainMarkers = 1. | ||
174 | * \param intersection The intersection to be evaluated | ||
175 | */ | ||
176 | int getBoundaryDomainMarker(const Intersection& intersection) const | ||
177 |
6/12✓ Branch 1 taken 3781 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3781 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 17921 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 17921 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 84 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 84 times.
✗ Branch 17 not taken.
|
21786 | { return getBoundaryDomainMarker(intersection.boundarySegmentIndex()); } |
178 | |||
179 | /*! | ||
180 | * \brief Returns true if an intersection was inserted during grid creation | ||
181 | */ | ||
182 | bool wasInserted(const Intersection& intersection) const | ||
183 |
2/4✓ Branch 1 taken 480 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 480 times.
✗ Branch 5 not taken.
|
960 | { return gridFactory_->wasInserted(intersection); } |
184 | |||
185 | /*! | ||
186 | * \brief Return the element domain marker (Gmsh physical entity number) of an element. | ||
187 | Only available when using Gmsh with GridParameterGroup.DomainMarkers = 1. | ||
188 | * \param element The element to be evaluated | ||
189 | */ | ||
190 | 143962 | int getElementDomainMarker(const Element& element) const | |
191 | { | ||
192 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 142912 times.
|
143962 | if (dataSourceType_ != DataSourceType::gmsh) |
193 | ✗ | DUNE_THROW(Dune::InvalidStateException, "Domain markers are only available for gmsh grids."); | |
194 | |||
195 | // parameters are only given for level 0 elements | ||
196 | 207363 | auto level0element = element; | |
197 |
5/5✓ Branch 0 taken 63791 times.
✓ Branch 1 taken 189024 times.
✓ Branch 2 taken 63791 times.
✓ Branch 3 taken 126114 times.
✓ Branch 4 taken 62910 times.
|
398217 | while (level0element.hasFather()) |
198 |
1/2✓ Branch 1 taken 46112 times.
✗ Branch 2 not taken.
|
109903 | level0element = level0element.father(); |
199 | |||
200 | // in the parallel case the data is load balanced and then accessed with indices of the index set | ||
201 | // for UGGrid element data is read on all processes since UGGrid can't communicate element data (yet) | ||
202 |
6/8✗ Branch 0 not taken.
✓ Branch 1 taken 62910 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 62910 times.
✓ Branch 4 taken 32092 times.
✓ Branch 5 taken 30818 times.
✓ Branch 6 taken 32092 times.
✓ Branch 7 taken 30818 times.
|
368417 | if (gridPtr_->comm().size() > 1 && !Detail::isUG<Grid>::value) |
203 |
4/8✓ Branch 1 taken 32092 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32092 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 32092 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 32092 times.
✗ Branch 11 not taken.
|
96276 | return elementMarkers_[gridPtr_->levelGridView(0).indexSet().index(level0element)]; |
204 | else | ||
205 |
2/4✓ Branch 1 taken 30818 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30818 times.
✗ Branch 5 not taken.
|
223740 | return elementMarkers_[gridFactory_->insertionIndex(level0element)]; |
206 | } | ||
207 | |||
208 | /*! | ||
209 | * \brief Create a data handle for communication of the data in parallel simulations | ||
210 | * \note this data handle is the default | ||
211 | */ | ||
212 | template<bool ug = Detail::isUG<Grid>::value, typename std::enable_if_t<!ug, int> = 0> | ||
213 | DataHandle createGmshDataHandle() | ||
214 | { | ||
215 | 12 | return DataHandle(*gridPtr_, *gridFactory_, elementMarkers_, boundaryMarkers_, faceMarkers_); | |
216 | } | ||
217 | |||
218 | /*! | ||
219 | * \brief Create a data handle for communication of the data in parallel simulations | ||
220 | * \note this data handle is the specialized for UGGrid since UGGrid can't communicate element data (yet) | ||
221 | */ | ||
222 | template<bool ug = Detail::isUG<Grid>::value, typename std::enable_if_t<ug, int> = 0> | ||
223 | DataHandle createGmshDataHandle() | ||
224 | { | ||
225 | 12 | return DataHandle(*gridPtr_, *gridFactory_, elementMarkers_, boundaryMarkers_); | |
226 | } | ||
227 | |||
228 | // \} | ||
229 | |||
230 | /*! | ||
231 | * \name VTK interface functions | ||
232 | */ | ||
233 | // \{ | ||
234 | |||
235 | /*! | ||
236 | * \brief Get a element parameter | ||
237 | * \param element the element | ||
238 | * \param fieldName the name of the field to read from the vtk data | ||
239 | */ | ||
240 | 8531 | double getParameter(const Element& element, const std::string& fieldName) const | |
241 | { | ||
242 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8531 times.
|
8531 | if (dataSourceType_ != DataSourceType::vtk) |
243 | ✗ | DUNE_THROW(Dune::InvalidStateException, "This access function is only available for data from VTK files."); | |
244 | |||
245 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8531 times.
|
8531 | if (cellData_.count(fieldName) == 0) |
246 | ✗ | DUNE_THROW(Dune::IOError, "No field with the name " << fieldName << " found in cell data"); | |
247 | |||
248 | // parameters are only given for level 0 elements | ||
249 | 8531 | auto level0element = element; | |
250 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 8531 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8531 times.
|
17062 | while (level0element.hasFather()) |
251 | ✗ | level0element = level0element.father(); | |
252 | |||
253 | 8531 | return cellData_.at(fieldName)[gridFactory_->insertionIndex(level0element)]; | |
254 | } | ||
255 | |||
256 | /*! | ||
257 | * \brief Call the parameters function of the DGF grid pointer if available for vertex data | ||
258 | * \param vertex the vertex | ||
259 | * \param fieldName the name of the field to read from the vtk data | ||
260 | * \note You can only pass vertices that exist on level 0! | ||
261 | */ | ||
262 | 50690 | double getParameter(const Vertex& vertex, const std::string& fieldName) const | |
263 | { | ||
264 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 50690 times.
|
50690 | if (dataSourceType_ != DataSourceType::vtk) |
265 | ✗ | DUNE_THROW(Dune::InvalidStateException, "This access function is only available for data from VTK files."); | |
266 | |||
267 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 50690 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 50690 times.
|
101380 | if (vertex.level() != 0) |
268 | ✗ | DUNE_THROW(Dune::IOError, "You can only obtain parameters for level 0 vertices!"); | |
269 | |||
270 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 50690 times.
|
50690 | if (pointData_.count(fieldName) == 0) |
271 | ✗ | DUNE_THROW(Dune::IOError, "No field with the name " << fieldName << " found in point data"); | |
272 | |||
273 | 50690 | return pointData_.at(fieldName)[gridFactory_->insertionIndex(vertex)]; | |
274 | } | ||
275 | |||
276 | // \} | ||
277 | |||
278 | private: | ||
279 | // grid and grid factor for gmsh grid data / vtk grid data | ||
280 | std::shared_ptr<Grid> gridPtr_; | ||
281 | std::shared_ptr<Dune::GridFactory<Grid>> gridFactory_; | ||
282 | |||
283 | /*! | ||
284 | * \brief Element and boundary domain markers obtained from Gmsh physical entities | ||
285 | * They map from element indices / boundary ids to the physical entity number | ||
286 | */ | ||
287 | std::vector<int> elementMarkers_; | ||
288 | std::vector<int> boundaryMarkers_; | ||
289 | std::vector<int> faceMarkers_; | ||
290 | |||
291 | /*! | ||
292 | * \brief Cell and vertex data obtained from VTK files | ||
293 | */ | ||
294 | VTKReader::Data cellData_, pointData_; | ||
295 | |||
296 | // dgf grid data | ||
297 | Dune::GridPtr<Grid> dgfGrid_; | ||
298 | |||
299 | // specify which type of data we have | ||
300 | // TODO unfortunately all grid readers provide different data types, should be streamlined (changes in Dune) | ||
301 | DataSourceType dataSourceType_; | ||
302 | }; | ||
303 | |||
304 | } // namespace Dumux | ||
305 | |||
306 | #endif | ||
307 |