GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/discretization/box/fvelementgeometry.hh
Date: 2025-06-28 19:18:10
Exec Total Coverage
Lines: 140 140 100.0%
Functions: 65 67 97.0%
Branches: 355 561 63.3%

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 BoxDiscretization
10 * \brief Base class for the local finite volume geometry for box models
11 * This builds up the sub control volumes and sub control volume faces
12 * for an element.
13 */
14 #ifndef DUMUX_DISCRETIZATION_BOX_FV_ELEMENT_GEOMETRY_HH
15 #define DUMUX_DISCRETIZATION_BOX_FV_ELEMENT_GEOMETRY_HH
16
17 #include <optional>
18 #include <utility>
19 #include <unordered_map>
20 #include <array>
21 #include <vector>
22
23 #include <dune/geometry/type.hh>
24 #include <dune/localfunctions/lagrange/pqkfactory.hh>
25
26 #include <dumux/common/indextraits.hh>
27 #include <dumux/discretization/scvandscvfiterators.hh>
28 #include <dumux/discretization/box/boxgeometryhelper.hh>
29
30 namespace Dumux {
31
32 /*!
33 * \ingroup BoxDiscretization
34 * \brief Base class for the finite volume geometry vector for box 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 BoxFVElementGeometry;
42
43 //! specialization in case the FVElementGeometries are stored
44 template<class GG>
45
55/113
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 926114 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 101 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 7 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2688 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 2685 times.
✓ Branch 16 taken 452613 times.
✓ Branch 17 taken 2685 times.
✓ Branch 18 taken 444390 times.
✓ Branch 19 taken 8224 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 8224 times.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 937437 times.
✓ Branch 25 taken 470 times.
✓ Branch 26 taken 1 times.
✓ Branch 27 taken 937437 times.
✓ Branch 28 taken 666145 times.
✓ Branch 29 taken 1148333 times.
✓ Branch 30 taken 7200 times.
✓ Branch 31 taken 863040 times.
✓ Branch 32 taken 14001 times.
✓ Branch 33 taken 870240 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 21200 times.
✓ Branch 36 taken 2 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✓ Branch 40 taken 2253 times.
✓ Branch 41 taken 3 times.
✓ Branch 42 taken 21601 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 21607 times.
✓ Branch 45 taken 1189858 times.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✓ Branch 48 taken 1189860 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 1189858 times.
✓ Branch 51 taken 1 times.
✓ Branch 52 taken 2 times.
✓ Branch 53 taken 1 times.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✓ Branch 56 taken 1 times.
✓ Branch 57 taken 3 times.
✓ Branch 59 taken 1 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 1 times.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✓ Branch 68 taken 3200 times.
✗ Branch 69 not taken.
✓ Branch 71 taken 3200 times.
✗ Branch 72 not taken.
✓ Branch 73 taken 3200 times.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✓ Branch 80 taken 9600 times.
✗ Branch 81 not taken.
✓ Branch 82 taken 9600 times.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✓ Branch 89 taken 3200 times.
✗ Branch 90 not taken.
✓ Branch 92 taken 3200 times.
✗ Branch 93 not taken.
✓ Branch 94 taken 3200 times.
✗ Branch 95 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✓ Branch 101 taken 9600 times.
✗ Branch 102 not taken.
✓ Branch 104 taken 9600 times.
✗ Branch 105 not taken.
✓ Branch 106 taken 9600 times.
✗ Branch 107 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✓ Branch 113 taken 1 times.
✗ Branch 114 not taken.
✓ Branch 115 taken 1 times.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✗ Branch 58 not taken.
20146876 class BoxFVElementGeometry<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 static constexpr std::size_t maxNumElementScvs = (1<<dim);
67
68 /*!
69 * \brief Constructor
70 * \note Never use this directly and always construct this class via `localView(gridGeometry)`
71 */
72 13178220 BoxFVElementGeometry(const GGCache& ggCache)
73
31/45
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 711 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 31 times.
✓ Branch 8 taken 191 times.
✓ Branch 10 taken 1182330 times.
✓ Branch 11 taken 2719 times.
✓ Branch 13 taken 444392 times.
✓ Branch 14 taken 945664 times.
✓ Branch 18 taken 2 times.
✓ Branch 19 taken 210898 times.
✓ Branch 21 taken 23 times.
✓ Branch 22 taken 3 times.
✓ Branch 24 taken 2 times.
✓ Branch 25 taken 1189858 times.
✓ Branch 27 taken 2 times.
✓ Branch 28 taken 3 times.
✓ Branch 30 taken 2 times.
✗ Branch 31 not taken.
✓ Branch 33 taken 1 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 39 taken 3200 times.
✗ Branch 40 not taken.
✓ Branch 42 taken 9600 times.
✗ Branch 43 not taken.
✓ Branch 45 taken 3200 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 9600 times.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✓ Branch 51 taken 1 times.
✓ Branch 12 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 673344 times.
✓ Branch 20 taken 23852 times.
✓ Branch 23 taken 8 times.
✓ Branch 16 taken 472 times.
✗ Branch 9 not taken.
✓ Branch 6 taken 20 times.
✓ Branch 3 taken 926074 times.
✗ Branch 26 not taken.
✗ Branch 29 not taken.
10911938 : ggCache_(&ggCache) {}
74
75 //! Get a sub control volume with a local scv index
76 953196892 const SubControlVolume& scv(LocalIndexType scvIdx) const
77 {
78
14/17
✗ Branch 0 not taken.
✓ Branch 1 taken 195159312 times.
✓ Branch 2 taken 192627335 times.
✓ Branch 3 taken 3343104 times.
✓ Branch 6 taken 85610652 times.
✓ Branch 7 taken 331776 times.
✓ Branch 12 taken 30117888 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 9600 times.
✗ Branch 16 not taken.
✓ Branch 8 taken 60942298 times.
✓ Branch 9 taken 6144 times.
✓ Branch 5 taken 65238756 times.
✓ Branch 4 taken 932188 times.
✓ Branch 11 taken 80 times.
✓ Branch 14 taken 584128 times.
✓ Branch 10 taken 190172 times.
725918311 return ggCache_->scvs(eIdx_)[scvIdx];
79 }
80
81 //! Get a sub control volume face with a local scvf index
82 const SubControlVolumeFace& scvf(LocalIndexType scvfIdx) const
83 {
84 return ggCache_->scvfs(eIdx_)[scvfIdx];
85 }
86
87 //! iterator range for sub control volumes. Iterates over
88 //! all scvs of the bound element.
89 //! This is a free function found by means of ADL
90 //! To iterate over all sub control volumes of this FVElementGeometry use
91 //! for (auto&& scv : scvs(fvGeometry))
92 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
93 693011684 scvs(const BoxFVElementGeometry& fvGeometry)
94 {
95 using Iter = typename std::vector<SubControlVolume>::const_iterator;
96
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
693011684 const auto& s = fvGeometry.ggCache_->scvs(fvGeometry.eIdx_);
97
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
693011684 return Dune::IteratorRange<Iter>(s.begin(), s.end());
98 }
99
100 //! get the position related to a localdof
101 template<class LocalDof>
102 auto dofPosition(const LocalDof& localDof) const
103 {
104 return this->element().geometry().corner(localDof.index());
105 }
106
107 //! iterator range for sub control volumes faces. Iterates over
108 //! all scvfs of the bound element.
109 //! This is a free function found by means of ADL
110 //! To iterate over all sub control volume faces of this FVElementGeometry use
111 //! for (auto&& scvf : scvfs(fvGeometry))
112 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
113 42420359 scvfs(const BoxFVElementGeometry& fvGeometry)
114 {
115 using Iter = typename std::vector<SubControlVolumeFace>::const_iterator;
116 42420359 const auto& s = fvGeometry.ggCache_->scvfs(fvGeometry.eIdx_);
117 42420359 return Dune::IteratorRange<Iter>(s.begin(), s.end());
118 }
119
120 //! Get a local finite element basis
121 8828525 const FeLocalBasis& feLocalBasis() const
122 {
123
8/16
✓ Branch 2 taken 1551580 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1113600 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 257920 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 249600 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 9920 times.
✗ Branch 18 not taken.
✓ Branch 21 taken 9920 times.
✗ Branch 22 not taken.
✓ Branch 9 taken 22120 times.
✓ Branch 1 taken 4952441 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
8828525 return gridGeometry().feCache().get(element_->type()).localBasis();
124 }
125
126 //! The total number of element-local dofs
127 86893427 std::size_t numLocalDofs() const
128 {
129
3/6
✓ Branch 2 taken 74801 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9920 times.
✗ Branch 6 not taken.
✓ Branch 1 taken 4909680 times.
✗ Branch 0 not taken.
86893427 return numScv();
130 }
131
132 //! The total number of sub control volumes
133 235513572 std::size_t numScv() const
134 {
135
13/17
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 17982165 times.
✓ Branch 2 taken 32109994 times.
✓ Branch 3 taken 8232528 times.
✓ Branch 8 taken 947357 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1199778 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 9600 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 9600 times.
✗ Branch 18 not taken.
✓ Branch 4 taken 5006064 times.
✓ Branch 5 taken 8697 times.
✓ Branch 7 taken 23202928 times.
✓ Branch 6 taken 164616 times.
✓ Branch 10 taken 666144 times.
225666927 return ggCache_->scvs(eIdx_).size();
136 }
137
138 //! The total number of sub control volume faces
139 1331459 std::size_t numScvf() const
140 {
141
2/4
✓ Branch 1 taken 21309 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3200 times.
✗ Branch 5 not taken.
1331459 return ggCache_->scvfs(eIdx_).size();
142 }
143
144 /*!
145 * \brief bind the local view (r-value overload)
146 * This overload is called when an instance of this class is a temporary in the usage context
147 * This allows a usage like this: `const auto view = localView(...).bind(element);`
148 */
149 149133 BoxFVElementGeometry bind(const Element& element) &&
150 {
151
2/4
✓ Branch 1 taken 139074 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10059 times.
✗ Branch 5 not taken.
149133 this->bindElement(element);
152 149133 return std::move(*this);
153 }
154
155 //! this function is for compatibility reasons with cc methods
156 //! The box stencil is always element-local so bind and bindElement
157 //! are identical.
158 6442470 void bind(const Element& element) &
159
3/6
✓ Branch 1 taken 759 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 138216 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
6442470 { this->bindElement(element); }
160
161 /*!
162 * \brief bind the local view (r-value overload)
163 * This overload is called when an instance of this class is a temporary in the usage context
164 * This allows a usage like this: `const auto view = localView(...).bindElement(element);`
165 */
166 7028239 BoxFVElementGeometry bindElement(const Element& element) &&
167 {
168
5/7
✓ Branch 1 taken 2079169 times.
✓ Branch 2 taken 105046 times.
✓ Branch 4 taken 227357 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1189858 times.
✗ Branch 8 not taken.
✓ Branch 3 taken 15287 times.
7028239 this->bindElement(element);
169
2/3
✓ Branch 1 taken 8430 times.
✗ Branch 2 not taken.
✓ Branch 0 taken 105044 times.
7028239 return std::move(*this);
170 }
171
172 //! Binding of an element, has to be called before using the fvgeometries
173 //! Prepares all the volume variables within the element
174 //! For compatibility reasons with the FVGeometry cache being disabled
175 16568392 void bindElement(const Element& element) &
176 {
177
2/2
✓ Branch 0 taken 1634092 times.
✓ Branch 1 taken 6859127 times.
16568392 element_ = element;
178 // cache element index
179 16568392 eIdx_ = gridGeometry().elementMapper().index(element);
180 16568392 }
181
182 //! Returns true if bind/bindElement has already been called
183 101153 bool isBound() const
184
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
101109 { return static_cast<bool>(element_); }
185
186 //! The bound element
187 27979871 const Element& element() const
188
6/9
✓ Branch 0 taken 57576 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 143336 times.
✓ Branch 3 taken 16728 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 608 times.
✗ Branch 8 not taken.
✓ Branch 5 taken 608 times.
✗ Branch 6 not taken.
33528927 { return *element_; }
189
190 //! The bound element's index in the grid view
191 502400 GridIndexType elementIndex() const
192 502400 { return eIdx_; }
193
194 //! The grid geometry we are a restriction of
195 67564745 const GridGeometry& gridGeometry() const
196
32/46
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 7 taken 9773783 times.
✓ Branch 8 taken 2565 times.
✓ Branch 10 taken 212686 times.
✓ Branch 11 taken 192840 times.
✓ Branch 13 taken 5020153 times.
✓ Branch 14 taken 8216 times.
✓ Branch 16 taken 4562888 times.
✓ Branch 17 taken 131816 times.
✓ Branch 19 taken 4366642 times.
✓ Branch 20 taken 42076 times.
✓ Branch 25 taken 1093766 times.
✓ Branch 26 taken 14000 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 10909 times.
✓ Branch 33 taken 950 times.
✓ Branch 34 taken 18252 times.
✓ Branch 35 taken 58516 times.
✓ Branch 36 taken 40374 times.
✓ Branch 45 taken 9920 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 9920 times.
✗ Branch 49 not taken.
✓ Branch 52 taken 3200 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 3200 times.
✗ Branch 56 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 764951 times.
✓ Branch 9 taken 999 times.
✓ Branch 12 taken 25192 times.
✓ Branch 15 taken 213072 times.
✓ Branch 18 taken 1379696 times.
✓ Branch 22 taken 1 times.
✓ Branch 23 taken 1182326 times.
✓ Branch 30 taken 1548 times.
✓ Branch 31 taken 41652 times.
✗ Branch 37 not taken.
✓ Branch 40 taken 7200 times.
✗ Branch 41 not taken.
✓ Branch 24 taken 48540 times.
✗ Branch 1 not taken.
✗ Branch 32 not taken.
✗ Branch 27 not taken.
67735399 { return ggCache_->gridGeometry(); }
197
198 //! Returns whether one of the geometry's scvfs lies on a boundary
199 2291779 bool hasBoundaryScvf() const
200
12/12
✓ Branch 0 taken 214192 times.
✓ Branch 1 taken 1733943 times.
✓ Branch 2 taken 302372 times.
✓ Branch 3 taken 23020 times.
✓ Branch 4 taken 6778 times.
✓ Branch 5 taken 1804 times.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 28 times.
✓ Branch 8 taken 432 times.
✓ Branch 9 taken 592 times.
✓ Branch 10 taken 6778 times.
✓ Branch 11 taken 1804 times.
2291779 { return ggCache_->hasBoundaryScvf(eIdx_); }
201
202 //! Geometry of a sub control volume
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27584 times.
28424 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
204 {
205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27584 times.
28424 assert(isBound());
206
1/2
✓ Branch 1 taken 17944 times.
✗ Branch 2 not taken.
28424 const auto geo = element().geometry();
207
2/4
✓ Branch 1 taken 26952 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 26952 times.
✗ Branch 5 not taken.
28424 return { Dune::GeometryTypes::cube(dim), GeometryHelper(geo).getScvCorners(scv.indexInElement()) };
208 9008 }
209
210 //! Geometry of a sub control volume face
211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73568 times.
89644 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
212 {
213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73568 times.
89644 assert(isBound());
214
2/3
✓ Branch 0 taken 62696 times.
✓ Branch 1 taken 10872 times.
✗ Branch 2 not taken.
89644 const auto geo = element().geometry();
215
2/2
✓ Branch 0 taken 73556 times.
✓ Branch 1 taken 12 times.
89644 const GeometryHelper geometryHelper(geo);
216
2/2
✓ Branch 0 taken 73556 times.
✓ Branch 1 taken 12 times.
89644 if (scvf.boundary())
217 {
218
1/2
✓ Branch 1 taken 10860 times.
✗ Branch 2 not taken.
89632 const auto localBoundaryIndex = scvf.index() - geometryHelper.numInteriorScvf();
219
2/4
✓ Branch 1 taken 10860 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10860 times.
✗ Branch 5 not taken.
89632 const auto& key = ggCache_->scvfBoundaryGeometryKeys(eIdx_)[localBoundaryIndex];
220
1/2
✓ Branch 1 taken 10860 times.
✗ Branch 2 not taken.
179072 return { Dune::GeometryTypes::cube(dim-1), geometryHelper.getBoundaryScvfCorners(key[0], key[1]) };
221 }
222 else
223
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
12 return { Dune::GeometryTypes::cube(dim-1), geometryHelper.getScvfCorners(scvf.index()) };
224 21720 }
225
226 private:
227 const GGCache* ggCache_;
228 GridIndexType eIdx_;
229
230 std::optional<Element> element_;
231 };
232
233 //! specialization in case the FVElementGeometries are not stored
234 template<class GG>
235 class BoxFVElementGeometry<GG, false>
236 {
237 using GridView = typename GG::GridView;
238 static constexpr int dim = GridView::dimension;
239 static constexpr int dimWorld = GridView::dimensionworld;
240 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
241 using LocalIndexType = typename IndexTraits<GridView>::LocalIndex;
242 using CoordScalar = typename GridView::ctype;
243 using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType;
244 using GGCache = typename GG::Cache;
245 using GeometryHelper = typename GGCache::GeometryHelper;
246 public:
247 //! export the element type
248 using Element = typename GridView::template Codim<0>::Entity;
249 //! export type of subcontrol volume
250 using SubControlVolume = typename GG::SubControlVolume;
251 //! export type of subcontrol volume face
252 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
253 //! export type of finite volume grid geometry
254 using GridGeometry = GG;
255 //! the maximum number of scvs per element (2^dim for cubes)
256 static constexpr std::size_t maxNumElementScvs = (1<<dim);
257
258 /*!
259 * \brief Constructor
260 * \note Never use this directly and always construct this class via `localView(gridGeometry)`
261 */
262 5343504 BoxFVElementGeometry(const GGCache& ggCache)
263
15/23
✓ Branch 1 taken 267 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11349 times.
✓ Branch 5 taken 4466 times.
✓ Branch 7 taken 2262042 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1732931 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 108849 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 387697 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 32261 times.
✗ Branch 20 not taken.
✓ Branch 6 taken 16 times.
✓ Branch 3 taken 5541 times.
✗ Branch 0 not taken.
✓ Branch 9 taken 2 times.
✓ Branch 12 taken 30330 times.
✓ Branch 15 taken 1 times.
✓ Branch 18 taken 2 times.
✓ Branch 22 taken 604311 times.
✗ Branch 23 not taken.
5343504 : ggCache_(&ggCache) {}
264
265 //! Get a sub control volume with a local scv index
266 1213734434 const SubControlVolume& scv(LocalIndexType scvIdx) const
267 {
268
16/18
✗ Branch 0 not taken.
✓ Branch 1 taken 176164230 times.
✓ Branch 2 taken 165437875 times.
✓ Branch 3 taken 11282051 times.
✓ Branch 5 taken 212973688 times.
✓ Branch 6 taken 213001940 times.
✓ Branch 7 taken 11097964 times.
✓ Branch 8 taken 30954712 times.
✓ Branch 9 taken 3268377 times.
✓ Branch 10 taken 1373616 times.
✓ Branch 11 taken 25884 times.
✓ Branch 12 taken 78593300 times.
✓ Branch 15 taken 444400 times.
✓ Branch 16 taken 42888 times.
✓ Branch 4 taken 12800 times.
✓ Branch 13 taken 25344 times.
✓ Branch 14 taken 10247584 times.
✗ Branch 17 not taken.
895743464 return scvs_[scvIdx];
269 }
270
271 //! Get a sub control volume face with a local scvf index
272 const SubControlVolumeFace& scvf(LocalIndexType scvfIdx) const
273 {
274 return scvfs_[scvfIdx];
275 }
276
277 //! iterator range for sub control volumes. Iterates over
278 //! all scvs of the bound element.
279 //! This is a free function found by means of ADL
280 //! To iterate over all sub control volumes of this FVElementGeometry use
281 //! for (auto&& scv : scvs(fvGeometry))
282 friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator>
283 1081244250 scvs(const BoxFVElementGeometry& fvGeometry)
284 {
285 using Iter = typename std::vector<SubControlVolume>::const_iterator;
286
1/2
✓ Branch 1 taken 234 times.
✗ Branch 2 not taken.
1081244250 return Dune::IteratorRange<Iter>(fvGeometry.scvs_.begin(), fvGeometry.scvs_.end());
287 }
288
289 //! get the position related to a localdof
290 template<class LocalDof>
291 auto dofPosition(const LocalDof& localDof) const
292 {
293 return this->element().geometry().corner(localDof.index());
294 }
295
296 //! iterator range for sub control volumes faces. Iterates over
297 //! all scvfs of the bound element.
298 //! This is a free function found by means of ADL
299 //! To iterate over all sub control volume faces of this FVElementGeometry use
300 //! for (auto&& scvf : scvfs(fvGeometry))
301 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
302 45543316 scvfs(const BoxFVElementGeometry& fvGeometry)
303 {
304 using Iter = typename std::vector<SubControlVolumeFace>::const_iterator;
305 45543316 return Dune::IteratorRange<Iter>(fvGeometry.scvfs_.begin(), fvGeometry.scvfs_.end());
306 }
307
308 //! Get a local finite element basis
309 16374607 const FeLocalBasis& feLocalBasis() const
310 {
311
1/2
✓ Branch 1 taken 5362908 times.
✗ Branch 2 not taken.
16374607 return gridGeometry().feCache().get(element_->type()).localBasis();
312 }
313
314 //! The total number of element-local dofs
315 105419194 std::size_t numLocalDofs() const
316 {
317
1/2
✓ Branch 1 taken 5362908 times.
✗ Branch 2 not taken.
105419194 return numScv();
318 }
319
320 //! The total number of sub control volumes
321 258251229 std::size_t numScv() const
322 {
323
21/25
✓ Branch 1 taken 2941013 times.
✓ Branch 2 taken 6683740 times.
✓ Branch 3 taken 10296692 times.
✓ Branch 4 taken 13152078 times.
✓ Branch 5 taken 8280266 times.
✓ Branch 6 taken 17188996 times.
✓ Branch 7 taken 3306632 times.
✓ Branch 8 taken 14935724 times.
✓ Branch 11 taken 69952 times.
✓ Branch 12 taken 610 times.
✓ Branch 14 taken 695680 times.
✓ Branch 15 taken 312788 times.
✓ Branch 17 taken 52000 times.
✗ Branch 18 not taken.
✓ Branch 22 taken 100000 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 25280 times.
✓ Branch 26 taken 12640 times.
✓ Branch 29 taken 304 times.
✗ Branch 30 not taken.
✓ Branch 9 taken 673452 times.
✓ Branch 10 taken 5225736 times.
✗ Branch 16 not taken.
✓ Branch 13 taken 146336 times.
✓ Branch 0 taken 1603 times.
239235267 return scvs_.size();
324 }
325
326 //! The total number of sub control volume faces
327 4285079 std::size_t numScvf() const
328 {
329
1/2
✓ Branch 3 taken 100 times.
✗ Branch 4 not taken.
4285079 return scvfs_.size();
330 }
331
332 /*!
333 * \brief bind the local view (r-value overload)
334 * This overload is called when an instance of this class is a temporary in the usage context
335 * This allows a usage like this: `const auto view = localView(...).bind(element);`
336 */
337 BoxFVElementGeometry bind(const Element& element) &&
338 {
339 this->bindElement(element);
340 return std::move(*this);
341 }
342
343 //! this function is for compatibility reasons with cc methods
344 //! The box stencil is always element-local so bind and bindElement
345 //! are identical.
346 4287475 void bind(const Element& element) &
347
5/11
✓ Branch 1 taken 58120 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 133738 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 14240 times.
✓ Branch 8 taken 14102 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 15 taken 100 times.
✗ Branch 16 not taken.
✗ Branch 9 not taken.
4287475 { this->bindElement(element); }
348
349 /*!
350 * \brief bind the local view (r-value overload)
351 * This overload is called when an instance of this class is a temporary in the usage context
352 * This allows a usage like this: `const auto view = localView(...).bindElement(element);`
353 */
354 1060899 BoxFVElementGeometry bindElement(const Element& element) &&
355 {
356
3/6
✓ Branch 1 taken 312599 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 144000 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 604300 times.
✗ Branch 8 not taken.
1060899 this->bindElement(element);
357 1060899 return std::move(*this);
358 }
359
360 //! Binding of an element, has to be called before using the fvgeometries
361 //! Prepares all the volume variables within the element
362 //! For compatibility reasons with the FVGeometry cache being disabled
363 8724493 void bindElement(const Element& element) &
364 {
365
2/2
✓ Branch 0 taken 1820436 times.
✓ Branch 1 taken 3825676 times.
8724493 element_ = element;
366 8724493 eIdx_ = gridGeometry().elementMapper().index(element);
367 8724493 makeElementGeometries_();
368 8724493 }
369
370 //! Returns true if bind/bindElement has already been called
371 277 bool isBound() const
372
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
233 { return static_cast<bool>(element_); }
373
374 //! The bound element
375 40374689 const Element& element() const
376
3/5
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 100 times.
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
✗ Branch 2 not taken.
40582085 { return *element_; }
377
378 //! The bound element's index in the grid view
379 GridIndexType elementIndex() const
380 { return eIdx_; }
381
382 //! The grid geometry we are a restriction of
383 94366149 const GridGeometry& gridGeometry() const
384
12/14
✓ Branch 1 taken 5962073 times.
✓ Branch 2 taken 3725597 times.
✓ Branch 3 taken 3913807 times.
✓ Branch 4 taken 5034879 times.
✓ Branch 5 taken 203879 times.
✓ Branch 6 taken 1418494 times.
✓ Branch 7 taken 16434 times.
✓ Branch 8 taken 5850 times.
✓ Branch 0 taken 2512 times.
✓ Branch 9 taken 58416 times.
✓ Branch 10 taken 12077286 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2999526 times.
✗ Branch 14 not taken.
94158417 { return ggCache_->gridGeometry(); }
385
386 //! Returns whether one of the geometry's scvfs lies on a boundary
387 3028328 bool hasBoundaryScvf() const
388
4/5
✓ Branch 0 taken 399218 times.
✓ Branch 1 taken 2172812 times.
✓ Branch 2 taken 413268 times.
✓ Branch 3 taken 43030 times.
✗ Branch 4 not taken.
3028328 { return hasBoundaryScvf_; }
389
390 //! Geometry of a sub control volume
391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240 times.
240 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
392 {
393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240 times.
240 assert(isBound());
394
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
240 const auto geo = element().geometry();
395
2/4
✓ Branch 1 taken 240 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
312 return { Dune::GeometryTypes::cube(dim), GeometryHelper(geo).getScvCorners(scv.indexInElement()) };
396 }
397
398 //! Geometry of a sub control volume face
399
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
400 {
401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 assert(isBound());
402
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
36 const auto geo = element().geometry();
403
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
36 const GeometryHelper geometryHelper(geo);
404
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
36 if (scvf.boundary())
405 {
406 24 const auto localBoundaryIndex = scvf.index() - geometryHelper.numInteriorScvf();
407 24 const auto& key = scvfBoundaryGeometryKeys_[localBoundaryIndex];
408 48 return { Dune::GeometryTypes::cube(dim-1), geometryHelper.getBoundaryScvfCorners(key[0], key[1]) };
409 }
410 else
411 12 return { Dune::GeometryTypes::cube(dim-1), geometryHelper.getScvfCorners(scvf.index()) };
412 }
413
414 private:
415 8724493 void makeElementGeometries_()
416 {
417 8724493 hasBoundaryScvf_ = false;
418
419 // get the element geometry
420 8724493 const auto& element = *element_;
421
1/2
✓ Branch 1 taken 3038349 times.
✗ Branch 2 not taken.
8724493 const auto elementGeometry = element.geometry();
422
1/2
✓ Branch 1 taken 3038349 times.
✗ Branch 2 not taken.
8724493 const auto refElement = referenceElement(elementGeometry);
423
424 // get the sub control volume geometries of this element
425 8724493 GeometryHelper geometryHelper(elementGeometry);
426
427 // construct the sub control volumes
428
1/2
✓ Branch 1 taken 3038349 times.
✗ Branch 2 not taken.
8724493 scvs_.resize(elementGeometry.corners());
429
3/3
✓ Branch 0 taken 29124790 times.
✓ Branch 1 taken 8961001 times.
✓ Branch 2 taken 236508 times.
38322299 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
430 {
431 // get associated dof index
432
1/2
✓ Branch 1 taken 12153396 times.
✗ Branch 2 not taken.
29597806 const auto dofIdxGlobal = gridGeometry().vertexMapper().subIndex(element, scvLocalIdx, dim);
433
434 // add scv to the local container
435
1/2
✓ Branch 1 taken 12153396 times.
✗ Branch 2 not taken.
56387554 scvs_[scvLocalIdx] = SubControlVolume(
436 32405864 geometryHelper.getScvCorners(scvLocalIdx),
437 scvLocalIdx,
438 eIdx_,
439 dofIdxGlobal
440 );
441 }
442
443 // construct the sub control volume faces
444
1/2
✓ Branch 1 taken 3038349 times.
✗ Branch 2 not taken.
8724493 const auto numInnerScvf = geometryHelper.numInteriorScvf();
445
1/2
✓ Branch 1 taken 3038349 times.
✗ Branch 2 not taken.
8724493 scvfs_.resize(numInnerScvf);
446
2/2
✓ Branch 0 taken 424414 times.
✓ Branch 1 taken 8300079 times.
8724493 scvfBoundaryGeometryKeys_.clear();
447
448 8724493 LocalIndexType scvfLocalIdx = 0;
449
2/2
✓ Branch 0 taken 27044798 times.
✓ Branch 1 taken 8724493 times.
35769291 for (; scvfLocalIdx < numInnerScvf; ++scvfLocalIdx)
450 {
451 // find the local scv indices this scvf is connected to
452
1/2
✓ Branch 2 taken 27044798 times.
✗ Branch 3 not taken.
54089596 std::vector<LocalIndexType> localScvIndices({static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
453
1/2
✓ Branch 2 taken 12154914 times.
✗ Branch 3 not taken.
27044798 static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
454
455
1/2
✓ Branch 1 taken 27044798 times.
✗ Branch 2 not taken.
27044798 const auto& corners = geometryHelper.getScvfCorners(scvfLocalIdx);
456 29475576 scvfs_[scvfLocalIdx] = SubControlVolumeFace(
457 corners,
458
1/2
✓ Branch 1 taken 2895214 times.
✗ Branch 2 not taken.
51658818 geometryHelper.normal(corners, localScvIndices),
459 element,
460 elementGeometry,
461 scvfLocalIdx,
462 std::move(localScvIndices),
463 false
464 );
465 }
466
467 // construct the sub control volume faces on the domain boundary
468
11/13
✓ Branch 1 taken 7748139 times.
✓ Branch 2 taken 14850348 times.
✓ Branch 7 taken 15400772 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 15646545 times.
✓ Branch 10 taken 2092762 times.
✓ Branch 11 taken 18655 times.
✓ Branch 12 taken 507742 times.
✓ Branch 3 taken 209178 times.
✓ Branch 4 taken 6359847 times.
✓ Branch 5 taken 8847752 times.
✓ Branch 6 taken 802937 times.
✗ Branch 0 not taken.
77238073 for (const auto& intersection : intersections(gridGeometry().gridView(), element))
469 {
470
4/5
✓ Branch 0 taken 517621 times.
✓ Branch 1 taken 17665274 times.
✓ Branch 2 taken 8376017 times.
✓ Branch 3 taken 3287548 times.
✗ Branch 4 not taken.
31887729 if (intersection.boundary() && !intersection.neighbor())
471 {
472 1497733 const auto isGeometry = intersection.geometry();
473 1497733 hasBoundaryScvf_ = true;
474
475
3/3
✓ Branch 0 taken 2467997 times.
✓ Branch 1 taken 1748033 times.
✓ Branch 2 taken 239692 times.
4455722 for (unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < isGeometry.corners(); ++isScvfLocalIdx)
476 {
477 // find the scv this scvf is connected to
478
1/3
✓ Branch 1 taken 436311 times.
✗ Branch 2 not taken.
✗ Branch 0 not taken.
2957989 const LocalIndexType insideScvIdx = static_cast<LocalIndexType>(refElement.subEntity(intersection.indexInInside(), 1, isScvfLocalIdx, dim));
479
1/4
✓ Branch 1 taken 2957989 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2957989 std::vector<LocalIndexType> localScvIndices = {insideScvIdx, insideScvIdx};
480
481
1/2
✓ Branch 1 taken 84374 times.
✗ Branch 2 not taken.
2957989 scvfs_.emplace_back(
482
2/4
✓ Branch 1 taken 2892541 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 416432 times.
✗ Branch 5 not taken.
3439869 geometryHelper.getBoundaryScvfCorners(intersection.indexInInside(), isScvfLocalIdx),
483
2/3
✓ Branch 0 taken 24488 times.
✓ Branch 1 taken 2933501 times.
✗ Branch 2 not taken.
2957989 intersection.centerUnitOuterNormal(),
484 intersection,
485 isGeometry,
486 isScvfLocalIdx,
487 scvfLocalIdx,
488 std::move(localScvIndices),
489
2/3
✓ Branch 0 taken 1014692 times.
✓ Branch 1 taken 1943297 times.
✗ Branch 2 not taken.
2957989 true
490 );
491
492
1/3
✓ Branch 1 taken 2957989 times.
✗ Branch 2 not taken.
✗ Branch 0 not taken.
2957989 scvfBoundaryGeometryKeys_.emplace_back(std::array<LocalIndexType, 2>{{
493
1/2
✓ Branch 1 taken 2957989 times.
✗ Branch 2 not taken.
2957989 static_cast<LocalIndexType>(intersection.indexInInside()),
494 static_cast<LocalIndexType>(isScvfLocalIdx)
495 }});
496
497 // increment local counter
498 2957989 scvfLocalIdx++;
499 }
500 448316 }
501 }
502 8724493 }
503
504 //! The bound element
505 GridIndexType eIdx_;
506 std::optional<Element> element_;
507
508 //! The global geometry cache
509 const GGCache* ggCache_;
510
511 //! vectors to store the geometries locally after binding an element
512 std::vector<SubControlVolume> scvs_;
513 std::vector<SubControlVolumeFace> scvfs_;
514 std::vector<std::array<LocalIndexType, 2>> scvfBoundaryGeometryKeys_;
515
516 bool hasBoundaryScvf_ = false;
517 };
518
519 } // end namespace Dumux
520
521 #endif
522