GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/discretization/pq1bubble/fvelementgeometry.hh
Date: 2025-07-05 19:19:36
Exec Total Coverage
Lines: 71 71 100.0%
Functions: 28 28 100.0%
Branches: 121 229 52.8%

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 PQ1BubbleDiscretization
10 * \brief Base class for the local finite volume geometry for the pq1bubble method
11 * This builds up the sub control volumes and sub control volume faces
12 * for an element.
13 */
14 #ifndef DUMUX_DISCRETIZATION_PQ1BUBBLE_FV_ELEMENT_GEOMETRY_HH
15 #define DUMUX_DISCRETIZATION_PQ1BUBBLE_FV_ELEMENT_GEOMETRY_HH
16
17 #include <optional>
18 #include <utility>
19
20 #include <dune/common/exceptions.hh>
21 #include <dune/geometry/type.hh>
22 #include <dune/localfunctions/lagrange/pqkfactory.hh>
23
24 #include <dumux/common/indextraits.hh>
25 #include <dumux/discretization/scvandscvfiterators.hh>
26 #include <dumux/discretization/cvfe/localdof.hh>
27
28 #include <dumux/discretization/pq1bubble/geometryhelper.hh>
29
30 namespace Dumux {
31
32 /*!
33 * \ingroup PQ1BubbleDiscretization
34 * \brief Base class for the finite volume geometry vector for pq1bubble models
35 * This builds up the sub control volumes and sub control volume faces
36 * for each element.
37 * \tparam GG the finite volume grid geometry type
38 * \tparam enableGridGeometryCache if the grid geometry is cached or not
39 */
40 template<class GG, bool enableGridGeometryCache>
41 class PQ1BubbleFVElementGeometry;
42
43 //! specialization in case the FVElementGeometries are stored
44 template<class GG>
45
20/45
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 42900 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4800 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 4800 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4800 times.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 7200 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 7200 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 21600 times.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✓ Branch 30 taken 21600 times.
✗ Branch 31 not taken.
✓ Branch 33 taken 21600 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 21600 times.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✓ Branch 42 taken 1 times.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✓ Branch 20 taken 14400 times.
✓ Branch 25 taken 14400 times.
✓ Branch 32 taken 4 times.
234936 class PQ1BubbleFVElementGeometry<GG, true>
46 {
47 using GridView = typename GG::GridView;
48 static constexpr int dim = GridView::dimension;
49 static constexpr int dimWorld = GridView::dimensionworld;
50 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
51 using LocalIndexType = typename IndexTraits<GridView>::LocalIndex;
52 using CoordScalar = typename GridView::ctype;
53 using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
54 using GGCache = typename GG::Cache;
55 using GeometryHelper = typename GGCache::GeometryHelper;
56 public:
57 //! export the element type
58 using Element = typename GridView::template Codim<0>::Entity;
59 //! export type of subcontrol volume
60 using SubControlVolume = typename GG::SubControlVolume;
61 //! export type of subcontrol volume face
62 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
63 //! export type of finite volume grid geometry
64 using GridGeometry = GG;
65 //! the maximum number of scvs per element (2^dim for cubes)
66 // ToDo get this from GG
67 static constexpr std::size_t maxNumElementScvs = (1<<dim) + 1;
68
69 //! Constructor
70 1363076 PQ1BubbleFVElementGeometry(const GGCache& ggCache)
71
13/17
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 6 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 1 times.
✓ Branch 8 taken 4801 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 21601 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 21604 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 42002 times.
✓ Branch 7 taken 903 times.
✓ Branch 10 taken 4 times.
✓ Branch 13 taken 2 times.
840964 : ggCache_(&ggCache)
72 {}
73
74 //! Get a sub control volume with a local scv index
75 44269716 const SubControlVolume& scv(LocalIndexType scvIdx) const
76 {
77
3/4
✓ Branch 1 taken 64230 times.
✓ Branch 2 taken 223914 times.
✓ Branch 3 taken 14800 times.
✗ Branch 4 not taken.
44269716 return ggCache_->scvs(eIdx_)[scvIdx];
78 }
79
80 //! Get a sub control volume face with a local scvf index
81 const SubControlVolumeFace& scvf(LocalIndexType scvfIdx) const
82 {
83 return ggCache_->scvfs(eIdx_)[scvfIdx];
84 }
85
86 //! iterator range for sub control volumes. Iterates over
87 //! all scvs of the bound element.
88 //! This is a free function found by means of ADL
89 //! To iterate over all sub control volumes of this FVElementGeometry use
90 //! for (auto&& scv : scvs(fvGeometry))
91 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
92 68605725 scvs(const PQ1BubbleFVElementGeometry& fvGeometry)
93 {
94 using Iter = typename std::vector<SubControlVolume>::const_iterator;
95 68605725 const auto& s = fvGeometry.ggCache_->scvs(fvGeometry.eIdx_);
96 68605725 return Dune::IteratorRange<Iter>(s.begin(), s.end());
97 }
98
99 //! iterate over dof indices that belong to dofs associated with control volumes
100 friend inline auto cvLocalDofs(const PQ1BubbleFVElementGeometry& fvGeometry)
101 {
102 return Dune::transformedRangeView(
103 Dune::range(fvGeometry.numLocalDofs()-GeometryHelper::numNonCVLocalDofs(fvGeometry.element().type())),
104 [&](const auto i) { return CVFE::LocalDof
105 {
106 static_cast<LocalIndexType>(i),
107 static_cast<GridIndexType>(GeometryHelper::dofIndex(fvGeometry.gridGeometry().dofMapper(), fvGeometry.element(), i)),
108 static_cast<GridIndexType>(fvGeometry.elementIndex())
109 }; }
110 );
111 }
112
113 //! iterate over dof indices that are treated as hybrid dofs using the finite element method
114 template<bool enable = GridGeometry::enableHybridCVFE, std::enable_if_t<enable, int> = 0>
115 friend inline auto nonCVLocalDofs(const PQ1BubbleFVElementGeometry& fvGeometry)
116 {
117 return Dune::transformedRangeView(
118 Dune::range(fvGeometry.numLocalDofs()-GeometryHelper::numNonCVLocalDofs(fvGeometry.element().type()), fvGeometry.numLocalDofs()),
119 [&](const auto i) { return CVFE::LocalDof
120 {
121 static_cast<LocalIndexType>(i),
122 static_cast<GridIndexType>(GeometryHelper::dofIndex(fvGeometry.gridGeometry().dofMapper(), fvGeometry.element(), i)),
123 static_cast<GridIndexType>(fvGeometry.elementIndex())
124 }; }
125 );
126 }
127
128 //! an iterator over all local dofs
129 24127806 friend inline auto localDofs(const PQ1BubbleFVElementGeometry& fvGeometry)
130 {
131 return Dune::transformedRangeView(
132
9/17
✓ Branch 1 taken 179920 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16745280 times.
✓ Branch 5 taken 200 times.
✓ Branch 11 taken 2285244 times.
✗ Branch 12 not taken.
✓ Branch 16 taken 89960 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 89960 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 391904 times.
✗ Branch 23 not taken.
✗ Branch 6 not taken.
✓ Branch 8 taken 800 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 800 times.
✗ Branch 14 not taken.
24127806 Dune::range(fvGeometry.numLocalDofs()),
133 109566666 [&](const auto i) { return CVFE::LocalDof
134 {
135 static_cast<LocalIndexType>(i),
136 107356166 static_cast<GridIndexType>(GeometryHelper::dofIndex(fvGeometry.gridGeometry().dofMapper(), fvGeometry.element(), i)),
137 107356166 static_cast<GridIndexType>(fvGeometry.elementIndex())
138 214712332 }; }
139 );
140 }
141
142 //! an iterator over all local dofs related to an intersection
143 template<class Intersection>
144 friend inline auto localDofs(const PQ1BubbleFVElementGeometry& fvGeometry, const Intersection& intersection)
145 {
146 return Dune::transformedRangeView(
147 Dune::range(GeometryHelper::numLocalDofsIntersection(fvGeometry.element().type(), intersection.indexInInside())),
148 [&](const auto i)
149 {
150 auto localDofIdx = GeometryHelper::localDofIndexIntersection(fvGeometry.element().type(), intersection.indexInInside(), i);
151 return CVFE::LocalDof
152 {
153 static_cast<LocalIndexType>(localDofIdx),
154 static_cast<GridIndexType>(GeometryHelper::dofIndex(fvGeometry.gridGeometry().dofMapper(), fvGeometry.element(), localDofIdx)),
155 static_cast<GridIndexType>(fvGeometry.elementIndex())
156 };
157 }
158 );
159 }
160
161 //! get the position related to a localdof
162 template<class LocalDof>
163 auto dofPosition(const LocalDof& localDof) const
164 {
165 return GeometryHelper::dofPosition(this->element(), localDof.index());
166 }
167
168 //! iterator range for sub control volumes faces. Iterates over
169 //! all scvfs of the bound element.
170 //! This is a free function found by means of ADL
171 //! To iterate over all sub control volume faces of this FVElementGeometry use
172 //! for (auto&& scvf : scvfs(fvGeometry))
173 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
174 5500451 scvfs(const PQ1BubbleFVElementGeometry& fvGeometry)
175 {
176 using Iter = typename std::vector<SubControlVolumeFace>::const_iterator;
177 5500451 const auto& s = fvGeometry.ggCache_->scvfs(fvGeometry.eIdx_);
178 5500451 return Dune::IteratorRange<Iter>(s.begin(), s.end());
179 }
180
181 //! Get a local finite element basis
182 18690958 const FeLocalBasis& feLocalBasis() const
183 {
184 18690958 return gridGeometry().feCache().get(element_->type()).localBasis();
185 }
186
187 //! The total number of element-local dofs
188 31577760 std::size_t numLocalDofs() const
189 {
190
18/31
✓ Branch 1 taken 7200 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 707840 times.
✗ Branch 5 not taken.
✓ Branch 14 taken 115200 times.
✗ Branch 15 not taken.
✓ Branch 19 taken 39840 times.
✓ Branch 20 taken 21000 times.
✓ Branch 22 taken 39840 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 43200 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 58120 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 43720 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 21600 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 21600 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 7200 times.
✗ Branch 41 not taken.
✓ Branch 12 taken 420000 times.
✓ Branch 13 taken 4800 times.
✓ Branch 17 taken 105500 times.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✓ Branch 8 taken 83700 times.
✗ Branch 9 not taken.
✓ Branch 16 taken 20800 times.
✓ Branch 11 taken 100 times.
31577760 return GeometryHelper::numElementDofs(element().type());
191 }
192
193 //! The total number of sub control volumes
194 1502748 std::size_t numScv() const
195 {
196
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 913730 times.
1502748 return ggCache_->scvs(eIdx_).size();
197 }
198
199 //! The total number of sub control volume faces
200 144860 std::size_t numScvf() const
201 {
202
1/5
✗ Branch 0 not taken.
✓ Branch 1 taken 12000 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 2 not taken.
144860 return ggCache_->scvfs(eIdx_).size();
203 }
204
205 /*!
206 * \brief bind the local view (r-value overload)
207 * This overload is called when an instance of this class is a temporary in the usage context
208 * This allows a usage like this: `const auto view = localView(...).bind(element);`
209 */
210 101960 PQ1BubbleFVElementGeometry bind(const Element& element) &&
211 {
212
1/2
✓ Branch 1 taken 101960 times.
✗ Branch 2 not taken.
101960 this->bindElement(element);
213 101960 return std::move(*this);
214 }
215
216 //! this function is for compatibility reasons with cc methods
217 //! The pq1bubble stencil is always element-local so bind and bindElement
218 //! are identical.
219 679159 void bind(const Element& element) &
220
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 14012 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 3 taken 28948 times.
✗ Branch 4 not taken.
679159 { this->bindElement(element); }
221
222 /*!
223 * \brief bind the local view (r-value overload)
224 * This overload is called when an instance of this class is a temporary in the usage context
225 * This allows a usage like this: `const auto view = localView(...).bindElement(element);`
226 */
227 648072 PQ1BubbleFVElementGeometry bindElement(const Element& element) &&
228 {
229
1/2
✓ Branch 1 taken 648072 times.
✗ Branch 2 not taken.
648072 this->bindElement(element);
230 648072 return std::move(*this);
231 }
232
233 //! Binding of an element, has to be called before using the fvgeometries
234 //! Prepares all the volume variables within the element
235 //! For compatibility reasons with the FVGeometry cache being disabled
236 2562779 void bindElement(const Element& element) &
237 {
238
2/2
✓ Branch 0 taken 1137315 times.
✓ Branch 1 taken 1291064 times.
2562779 element_ = element;
239 // cache element index
240 2562779 eIdx_ = gridGeometry().elementMapper().index(element);
241 2562779 }
242
243 //! Returns true if bind/bindElement has already been called
244 693 bool isBound() const
245
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
641 { return static_cast<bool>(element_); }
246
247 //! The bound element
248 141005975 const Element& element() const
249
23/36
✓ Branch 1 taken 7220 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 707840 times.
✗ Branch 5 not taken.
✓ Branch 17 taken 220200 times.
✓ Branch 18 taken 500 times.
✓ Branch 22 taken 39840 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 7200 times.
✓ Branch 26 taken 14400 times.
✓ Branch 28 taken 28800 times.
✓ Branch 29 taken 14400 times.
✓ Branch 31 taken 43720 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 43720 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 21600 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 21600 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 7200 times.
✗ Branch 44 not taken.
✓ Branch 0 taken 24 times.
✓ Branch 12 taken 420000 times.
✓ Branch 13 taken 4800 times.
✓ Branch 20 taken 21000 times.
✗ Branch 21 not taken.
✓ Branch 8 taken 83700 times.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✓ Branch 16 taken 20800 times.
✓ Branch 19 taken 32640 times.
✗ Branch 27 not taken.
✗ Branch 30 not taken.
✓ Branch 3 taken 640 times.
✓ Branch 11 taken 100 times.
243364207 { return *element_; }
250
251 //! The grid geometry we are a restriction of
252 135326286 const GridGeometry& gridGeometry() const
253
12/16
✓ Branch 1 taken 66114 times.
✓ Branch 2 taken 100622 times.
✓ Branch 12 taken 4412 times.
✓ Branch 13 taken 9600 times.
✓ Branch 15 taken 5052 times.
✗ Branch 16 not taken.
✓ Branch 10 taken 7200 times.
✗ Branch 11 not taken.
✓ Branch 3 taken 203864 times.
✓ Branch 0 taken 1580 times.
✓ Branch 9 taken 4800 times.
✗ Branch 14 not taken.
✓ Branch 4 taken 41160 times.
✓ Branch 5 taken 2177904 times.
✓ Branch 18 taken 1920 times.
✗ Branch 19 not taken.
132465762 { return ggCache_->gridGeometry(); }
254
255 //! Returns whether one of the geometry's scvfs lies on a boundary
256 42775 bool hasBoundaryScvf() const
257
2/4
✓ Branch 0 taken 1362 times.
✓ Branch 1 taken 41413 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
42775 { return ggCache_->hasBoundaryScvf(eIdx_); }
258
259 //! The bound element index
260 109862506 std::size_t elementIndex() const
261
1/2
✓ Branch 3 taken 7200 times.
✗ Branch 4 not taken.
8604880 { return eIdx_; }
262
263 //! The intersection index the scvf belongs to
264 std::size_t intersectionIndex(const SubControlVolumeFace& scvf) const
265 {
266 const auto localScvfIdx = scvf.index() - GeometryHelper::numInteriorScvf(element().type());
267 return ggCache_->scvfBoundaryGeometryKeys(eIdx_)[localScvfIdx][0];
268 }
269
270 //! Geometry of a sub control volume
271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
272 {
273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (scv.isOverlapping())
274
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 8 times.
8 DUNE_THROW(Dune::NotImplemented, "Geometry of overlapping scv");
275
276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(isBound());
277 8 const auto geo = element().geometry();
278 8 const GeometryHelper helper(geo);
279 return {
280 8 helper.getScvGeometryType(scv.indexInElement()),
281 8 helper.getScvCorners(scv.indexInElement())
282 8 };
283 }
284
285 //! Geometry of a sub control volume face
286
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 684 times.
684 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
287 {
288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 684 times.
684 assert(isBound());
289
2/2
✓ Branch 0 taken 664 times.
✓ Branch 1 taken 20 times.
684 const auto geo = element().geometry();
290
2/2
✓ Branch 0 taken 664 times.
✓ Branch 1 taken 20 times.
684 if (scvf.boundary())
291 {
292 664 GeometryHelper helper(geo);
293 664 const auto localScvfIdx = scvf.index() - GeometryHelper::numInteriorScvf(element().type());
294 664 const auto [localFacetIndex, isScvfLocalIdx]
295 664 = ggCache_->scvfBoundaryGeometryKeys(eIdx_)[localScvfIdx];
296 return {
297 664 helper.getBoundaryScvfGeometryType(isScvfLocalIdx),
298 664 helper.getBoundaryScvfCorners(localFacetIndex, isScvfLocalIdx)
299 664 };
300 }
301 else
302 {
303 20 GeometryHelper helper(geo);
304 return {
305 40 helper.getInteriorScvfGeometryType(scvf.index()),
306 20 helper.getScvfCorners(scvf.index())
307 20 };
308 }
309 }
310
311 private:
312 const GGCache* ggCache_;
313 GridIndexType eIdx_;
314
315 std::optional<Element> element_;
316 };
317
318 } // end namespace Dumux
319
320 #endif
321