GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/discretization/porenetwork/fvelementgeometry.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 39 46 84.8%
Functions: 11 23 47.8%
Branches: 132 218 60.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-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 PoreNetworkDiscretization
10 * \brief Base class for the local geometry for porenetworks
11 */
12 #ifndef DUMUX_DISCRETIZATION_PNM_FV_ELEMENT_GEOMETRY_HH
13 #define DUMUX_DISCRETIZATION_PNM_FV_ELEMENT_GEOMETRY_HH
14
15 #include <optional>
16 #include <array>
17 #include <utility>
18
19 #include <dune/geometry/type.hh>
20
21 #include <dumux/common/indextraits.hh>
22 #include <dumux/discretization/scvandscvfiterators.hh>
23
24 namespace Dumux::PoreNetwork {
25
26 /*!
27 * \ingroup PoreNetworkDiscretization
28 * \brief Base class for the local geometry for porenetworks
29 * \tparam GG the finite volume grid geometry type
30 * \tparam enableFVGridGeometryCache if the grid geometry is cached or not
31 */
32 template<class GG, bool enableFVGridGeometryCache>
33 class PNMFVElementGeometry;
34
35 //! specialization in case the FVElementGeometries are stored
36 template<class GG>
37 class PNMFVElementGeometry<GG, true>
38 {
39 using GridView = typename GG::GridView;
40 static constexpr int dim = GridView::dimension;
41 static constexpr int dimWorld = GridView::dimensionworld;
42 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
43 using LocalIndexType = typename IndexTraits<GridView>::LocalIndex;
44 using CoordScalar = typename GridView::ctype;
45 using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
46 public:
47 //! export type of subcontrol volume
48 using SubControlVolume = typename GG::SubControlVolume;
49 //! export type of subcontrol volume face
50 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
51 //! export type of finite volume grid geometry
52 using GridGeometry = GG;
53 //! export element type
54 using Element = typename GridView::template Codim<0>::Entity;
55 //! the maximum number of scvs per element
56 static constexpr std::size_t maxNumElementScvs = 2;
57
58 //! Constructor
59 PNMFVElementGeometry(const GridGeometry& gridGeometry)
60 : gridGeometryPtr_(&gridGeometry) {}
61
62 //! Get a sub control volume with a local scv index
63 const SubControlVolume& scv(LocalIndexType scvIdx) const
64 {
65 return gridGeometry().scvs(eIdx_)[scvIdx];
66 }
67
68 //! Get a sub control volume face with a local scvf index
69 const SubControlVolumeFace& scvf(LocalIndexType scvfIdx) const
70 {
71 return gridGeometry().scvfs(eIdx_)[scvfIdx];
72 }
73
74 //! iterator range for sub control volumes. Iterates over
75 //! all scvs of the bound element.
76 //! This is a free function found by means of ADL
77 //! To iterate over all sub control volumes of this FVElementGeometry use
78 //! for (auto&& scv : scvs(fvGeometry))
79 friend inline auto scvs(const PNMFVElementGeometry& fvGeometry)
80 {
81 const auto& g = fvGeometry.gridGeometry();
82 using Iter = typename std::decay_t<decltype(g.scvs(fvGeometry.eIdx_))>::const_iterator;
83 return Dune::IteratorRange<Iter>(g.scvs(fvGeometry.eIdx_).begin(), g.scvs(fvGeometry.eIdx_).end());
84 }
85
86 //! iterator range for sub control volumes faces. Iterates over
87 //! all scvfs of the bound element.
88 //! This is a free function found by means of ADL
89 //! To iterate over all sub control volume faces of this FVElementGeometry use
90 //! for (auto&& scvf : scvfs(fvGeometry))
91 friend inline auto scvfs(const PNMFVElementGeometry& fvGeometry)
92 {
93 const auto& g = fvGeometry.gridGeometry();
94 using Iter = typename std::decay_t<decltype(g.scvfs(fvGeometry.eIdx_))>::const_iterator;
95 return Dune::IteratorRange<Iter>(g.scvfs(fvGeometry.eIdx_).begin(), g.scvfs(fvGeometry.eIdx_).end());
96 }
97
98 //! Get a local finite element basis
99 const FeLocalBasis& feLocalBasis() const
100 {
101 return gridGeometry().feCache().get(element_->type()).localBasis();
102 }
103
104 //! The total number of sub control volumes
105 std::size_t numScv() const
106 {
107 return gridGeometry().scvs(eIdx_).size();
108 }
109
110 //! The total number of sub control volume faces
111 std::size_t numScvf() const
112 {
113 return gridGeometry().scvfs(eIdx_).size();
114 }
115
116 /*!
117 * \brief bind the local view (r-value overload)
118 * This overload is called when an instance of this class is a temporary in the usage context
119 * This allows a usage like this: `const auto view = localView(...).bind(element);`
120 */
121 PNMFVElementGeometry bind(const Element& element) &&
122 {
123 this->bindElement(element);
124 return std::move(*this);
125 }
126
127 //! this function is for compatibility reasons with cc methods
128 //! The box stencil is always element-local so bind and bindElement
129 //! are identical.
130 void bind(const Element& element) &
131 { this->bindElement(element); }
132
133 /*!
134 * \brief bind the local view (r-value overload)
135 * This overload is called when an instance of this class is a temporary in the usage context
136 * This allows a usage like this: `const auto view = localView(...).bindElement(element);`
137 */
138 PNMFVElementGeometry bindElement(const Element& element) &&
139 {
140 this->bindElement(element);
141 return std::move(*this);
142 }
143
144 //! Binding of an element, has to be called before using the fvgeometries
145 //! Prepares all the volume variables within the element
146 //! For compatibility reasons with the FVGeometry cache being disabled
147 void bindElement(const Element& element) &
148 {
149 element_ = element;
150 eIdx_ = gridGeometry().elementMapper().index(element);
151 }
152
153 //! Returns true if bind/bindElement has already been called
154 bool isBound() const
155 { return static_cast<bool>(element_); }
156
157 //! The bound element
158 const Element& element() const
159 { return *element_; }
160
161 //! The global finite volume geometry we are a restriction of
162 const GridGeometry& gridGeometry() const
163 { return *gridGeometryPtr_; }
164
165 //! Returns whether one of the geometry's scvfs lies on a boundary
166 bool hasBoundaryScvf() const
167 { return gridGeometry().hasBoundaryScvf(eIdx_); }
168
169 //! Create the geometry of a given sub control volume
170 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
171 {
172 const auto geo = element().geometry();
173 return {
174 Dune::GeometryTypes::simplex(dim),
175 std::array{{ geo.corner(scv.indexInElement()), geo.center() }}
176 };
177 }
178
179 //! Create the geometry of a given sub control volume face
180 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
181 { return { scvf.center() }; }
182
183 private:
184 std::optional<Element> element_;
185 const GridGeometry* gridGeometryPtr_;
186
187 GridIndexType eIdx_;
188 };
189
190 //! specialization in case the FVElementGeometries are not stored
191 template<class GG>
192
7/15
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 1011839 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 316416 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 23 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 521572 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1233344 times.
✗ Branch 16 not taken.
4838212 class PNMFVElementGeometry<GG, false>
193 {
194 using GridView = typename GG::GridView;
195 static constexpr int dim = GridView::dimension;
196 static constexpr int dimWorld = GridView::dimensionworld;
197 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
198 using LocalIndexType = typename IndexTraits<GridView>::LocalIndex;
199 using CoordScalar = typename GridView::ctype;
200 using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
201
202 public:
203 //! export type of subcontrol volume
204 using SubControlVolume = typename GG::SubControlVolume;
205 //! export type of subcontrol volume face
206 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
207 //! export type of finite volume grid geometry
208 using GridGeometry = GG;
209 //! export element type
210 using Element = typename GridView::template Codim<0>::Entity;
211 //! the maximum number of scvs per element
212 static constexpr std::size_t maxNumElementScvs = 2;
213
214 //! Constructor
215 PNMFVElementGeometry(const GridGeometry& gridGeometry)
216
40/77
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 97583 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 125041 times.
✓ Branch 8 taken 97583 times.
✓ Branch 9 taken 785189 times.
✓ Branch 10 taken 125041 times.
✓ Branch 11 taken 23 times.
✓ Branch 12 taken 785189 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 23 times.
✓ Branch 15 taken 308632 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 308632 times.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 4028 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 4028 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 8736 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 8736 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 2 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 2 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 59 not taken.
✓ Branch 65 taken 338742 times.
✗ Branch 66 not taken.
✓ Branch 68 taken 338742 times.
✗ Branch 69 not taken.
✓ Branch 71 taken 338742 times.
✗ Branch 72 not taken.
✓ Branch 74 taken 338742 times.
✗ Branch 75 not taken.
✓ Branch 77 taken 182830 times.
✗ Branch 78 not taken.
✓ Branch 80 taken 182830 times.
✗ Branch 81 not taken.
✓ Branch 83 taken 182830 times.
✗ Branch 84 not taken.
✓ Branch 86 taken 182830 times.
✗ Branch 87 not taken.
✓ Branch 93 taken 2 times.
✗ Branch 94 not taken.
✓ Branch 96 taken 2 times.
✗ Branch 97 not taken.
✓ Branch 99 taken 2 times.
✗ Branch 100 not taken.
✓ Branch 102 taken 2 times.
✗ Branch 103 not taken.
✓ Branch 105 taken 1 times.
✗ Branch 106 not taken.
✓ Branch 108 taken 1 times.
✗ Branch 109 not taken.
✓ Branch 111 taken 1 times.
✗ Branch 112 not taken.
✓ Branch 114 taken 1 times.
✗ Branch 115 not taken.
11223256 : gridGeometryPtr_(&gridGeometry) {}
217
218 //! Get a sub control volume with a local scv index
219 const SubControlVolume& scv(LocalIndexType scvIdx) const
220 {
221
40/48
✓ Branch 0 taken 2522980 times.
✓ Branch 1 taken 2030005 times.
✓ Branch 2 taken 2522980 times.
✓ Branch 3 taken 2030005 times.
✓ Branch 4 taken 2522980 times.
✓ Branch 5 taken 2030005 times.
✓ Branch 6 taken 2522980 times.
✓ Branch 7 taken 2030005 times.
✓ Branch 8 taken 1092264 times.
✓ Branch 9 taken 2420 times.
✓ Branch 10 taken 1092264 times.
✓ Branch 11 taken 2420 times.
✓ Branch 12 taken 1092264 times.
✓ Branch 13 taken 2420 times.
✓ Branch 14 taken 1092264 times.
✓ Branch 15 taken 2420 times.
✓ Branch 16 taken 1 times.
✓ Branch 17 taken 2522975 times.
✓ Branch 18 taken 1 times.
✓ Branch 19 taken 2522975 times.
✓ Branch 20 taken 1 times.
✓ Branch 21 taken 2522975 times.
✓ Branch 22 taken 1 times.
✓ Branch 23 taken 2522975 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 1092264 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 1092264 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 1092264 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 1092264 times.
✓ Branch 32 taken 22032 times.
✓ Branch 33 taken 16808 times.
✓ Branch 34 taken 22032 times.
✓ Branch 35 taken 16808 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 32058562 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 32058562 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 32058562 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 32058562 times.
✓ Branch 44 taken 18206 times.
✓ Branch 45 taken 25653 times.
✓ Branch 46 taken 18206 times.
✓ Branch 47 taken 25653 times.
173497626 return scvs_[scvIdx];
222 }
223
224 //! Get a sub control volume face with a local scvf index
225 const SubControlVolumeFace& scvf(LocalIndexType scvfIdx) const
226 {
227
8/12
✓ Branch 0 taken 3606 times.
✓ Branch 1 taken 31948674 times.
✓ Branch 2 taken 3606 times.
✓ Branch 3 taken 31948674 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 36 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 36 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 588 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 588 times.
63905808 return scvfs_[0];
228 }
229
230 //! iterator range for sub control volumes. Iterates over
231 //! all scvs of the bound element.
232 //! This is a free function found by means of ADL
233 //! To iterate over all sub control volumes of this FVElementGeometry use
234 //! for (auto&& scv : scvs(fvGeometry))
235 friend inline auto scvs(const PNMFVElementGeometry& fvGeometry)
236 {
237 using Iter = typename std::decay_t<decltype(fvGeometry.scvs_)>::const_iterator;
238
6/12
✓ Branch 0 taken 2522976 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2522976 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2522976 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1092264 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1092264 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1092264 times.
✗ Branch 11 not taken.
366939762 return Dune::IteratorRange<Iter>(fvGeometry.scvs_.begin(), fvGeometry.scvs_.end());
239 }
240
241 //! iterator range for sub control volumes faces. Iterates over
242 //! all scvfs of the bound element.
243 //! This is a free function found by means of ADL
244 //! To iterate over all sub control volume faces of this FVElementGeometry use
245 //! for (auto&& scvf : scvfs(fvGeometry))
246 friend inline auto scvfs(const PNMFVElementGeometry& fvGeometry)
247 {
248 using Iter = typename std::decay_t<decltype(fvGeometry.scvfs_)>::const_iterator;
249
3/6
✓ Branch 0 taken 38840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38840 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 38840 times.
✗ Branch 5 not taken.
136487151 return Dune::IteratorRange<Iter>(fvGeometry.scvfs_.begin(), fvGeometry.scvfs_.end());
250 }
251
252 //! Get a local finite element basis
253 const FeLocalBasis& feLocalBasis() const
254 {
255 return gridGeometry().feCache().get(element_->type()).localBasis();
256 }
257
258 //! The total number of sub control volumes
259 std::size_t numScv() const
260 {
261
5/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 247262 times.
✓ Branch 2 taken 2522978 times.
✓ Branch 3 taken 31 times.
✓ Branch 4 taken 1092264 times.
✗ Branch 5 not taken.
19557045 return scvs_.size();
262 }
263
264 //! The total number of sub control volume faces
265 std::size_t numScvf() const
266 {
267 5419140 return scvfs_.size();
268 }
269
270 /*!
271 * \brief bind the local view (r-value overload)
272 * This overload is called when an instance of this class is a temporary in the usage context
273 * This allows a usage like this: `const auto view = localView(...).bind(element);`
274 */
275 318007 PNMFVElementGeometry bind(const Element& element) &&
276 {
277 318007 this->bindElement(element);
278
1/2
✓ Branch 0 taken 318007 times.
✗ Branch 1 not taken.
318007 return std::move(*this);
279 }
280
281 //! this function is for compatibility reasons with cc methods
282 //! The box stencil is always element-local so bind and bindElement
283 //! are identical.
284 void bind(const Element& element) &
285
7/22
✓ Branch 1 taken 36822 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 51646 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 15 taken 1007 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 2184 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 2184 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1007 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 1007 times.
✗ Branch 28 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
1424135 { this->bindElement(element); }
286
287 /*!
288 * \brief bind the local view (r-value overload)
289 * This overload is called when an instance of this class is a temporary in the usage context
290 * This allows a usage like this: `const auto view = localView(...).bindElement(element);`
291 */
292 998 PNMFVElementGeometry bindElement(const Element& element) &&
293 {
294 998 this->bindElement(element);
295
1/2
✓ Branch 0 taken 998 times.
✗ Branch 1 not taken.
998 return std::move(*this);
296 }
297
298 //! Binding of an element, has to be called before using the fvgeometries
299 //! Prepares all the volume variables within the element
300 //! For compatibility reasons with the FVGeometry cache being disabled
301 3953329 void bindElement(const Element& element) &
302 {
303
2/2
✓ Branch 0 taken 1166603 times.
✓ Branch 1 taken 2786726 times.
3953329 element_ = element;
304 7906658 eIdx_ = gridGeometry().elementMapper().index(element);
305 3953329 makeElementGeometries(element);
306 3953329 }
307
308 //! Returns true if bind/bindElement has already been called
309 bool isBound() const
310 { return static_cast<bool>(element_); }
311
312 //! The bound element
313 const Element& element() const
314
2/4
✓ Branch 0 taken 3606 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3606 times.
✗ Branch 3 not taken.
6447648 { return *element_; }
315
316 //! The global finite volume geometry we are a restriction of
317 const GridGeometry& gridGeometry() const
318 { return *gridGeometryPtr_; }
319
320 //! Returns whether one of the geometry's scvfs lies on a boundary
321 bool hasBoundaryScvf() const
322 { return hasBoundaryScvf_; }
323
324 //! Create the geometry of a given sub control volume
325 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
326 {
327 const auto geo = element().geometry();
328 return {
329 Dune::GeometryTypes::simplex(dim),
330 std::array{{ geo.corner(scv.indexInElement()), geo.center() }}
331 };
332 }
333
334 //! Create the geometry of a given sub control volume face
335 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
336 { return { scvf.center() }; }
337
338 private:
339
340 3953329 void makeElementGeometries(const Element& element)
341 {
342 3953329 hasBoundaryScvf_ = false;
343
344 // get the element geometry
345 3953329 auto elementGeometry = element.geometry();
346
347 // construct the sub control volumes
348
4/4
✓ Branch 0 taken 7906658 times.
✓ Branch 1 taken 3953329 times.
✓ Branch 2 taken 7906658 times.
✓ Branch 3 taken 3953329 times.
15813316 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
349 {
350 // get associated dof index
351 15813316 const auto dofIdxGlobal = gridGeometry().vertexMapper().subIndex(element, scvLocalIdx, dim);
352
353 // get the corners
354 15812792 auto corners = std::array{elementGeometry.corner(scvLocalIdx), elementGeometry.center()};
355
356 // get the fractional volume associated with the scv
357 15813316 const auto volume = gridGeometry().poreVolume(dofIdxGlobal) / gridGeometry().coordinationNumber(dofIdxGlobal);
358
359 // add scv to the local container
360
2/2
✓ Branch 0 taken 2100963 times.
✓ Branch 1 taken 5805695 times.
7906658 scvs_[scvLocalIdx] = SubControlVolume(dofIdxGlobal,
361 scvLocalIdx,
362 eIdx_,
363 7906658 std::move(corners),
364 volume);
365
366
4/4
✓ Branch 0 taken 2100963 times.
✓ Branch 1 taken 5805695 times.
✓ Branch 2 taken 2100963 times.
✓ Branch 3 taken 5805695 times.
15813316 if (gridGeometry().poreLabel(dofIdxGlobal) > 0)
367 2100963 hasBoundaryScvf_ = true;
368 }
369
370 // construct the inner sub control volume face
371 11859463 auto unitOuterNormal = elementGeometry.corner(1) - elementGeometry.corner(0);
372 7906658 unitOuterNormal /= unitOuterNormal.two_norm();
373 3953329 LocalIndexType scvfLocalIdx = 0;
374 3953329 scvfs_[0] = SubControlVolumeFace(elementGeometry.center(),
375 3953329 std::move(unitOuterNormal),
376 7906658 gridGeometry().throatCrossSectionalArea(gridGeometry().elementMapper().index(element)),
377 scvfLocalIdx++,
378 std::array<LocalIndexType, 2>({0, 1}));
379 3953329 }
380
381 //! The bound element
382 std::optional<Element> element_;
383 GridIndexType eIdx_;
384
385 //! The global geometry this is a restriction of
386 const GridGeometry* gridGeometryPtr_;
387
388 //! vectors to store the geometries locally after binding an element
389 std::array<SubControlVolume, 2> scvs_;
390 std::array<SubControlVolumeFace, 1> scvfs_;
391
392 bool hasBoundaryScvf_ = false;
393 };
394
395 } // end namespace Dumux::PoreNetwork
396
397 #endif
398