GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/discretization/facecentered/staggered/fvelementgeometry.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 226 266 85.0%
Functions: 96 191 50.3%
Branches: 454 861 52.7%

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 FaceCenteredStaggeredDiscretization
10 * \copydoc Dumux::FaceCenteredStaggeredFVElementGeometry
11 */
12 #ifndef DUMUX_DISCRETIZATION_FACECENTERED_STAGGERED_FV_ELEMENT_GEOMETRY_HH
13 #define DUMUX_DISCRETIZATION_FACECENTERED_STAGGERED_FV_ELEMENT_GEOMETRY_HH
14
15 #include <utility>
16 #include <bitset>
17
18 #include <dune/common/rangeutilities.hh>
19 #include <dune/common/reservedvector.hh>
20 #include <dune/common/iteratorrange.hh>
21 #include <dune/common/exceptions.hh>
22
23 #include <dumux/common/indextraits.hh>
24 #include <dumux/common/parameters.hh>
25 #include <dumux/discretization/scvandscvfiterators.hh>
26 #include <dumux/discretization/facecentered/staggered/normalaxis.hh>
27 #include <dumux/discretization/facecentered/staggered/consistentlyorientedgrid.hh>
28
29 namespace Dumux {
30
31 #ifndef DOXYGEN
32 namespace Detail::FCStaggered {
33
34 template<class FVElementGeometry, class SubControlVolume>
35 56 typename SubControlVolume::Traits::Geometry scvGeometry(const FVElementGeometry& fvGeometry,
36 const SubControlVolume& scv)
37 {
38 56 typename SubControlVolume::Traits::CornerStorage corners{};
39 // select the containing element
40
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
112 const auto elementGeometry = (scv.elementIndex() != fvGeometry.elementIndex()) ?
41 fvGeometry.element().geometry() :
42 56 fvGeometry.gridGeometry().element(scv.elementIndex()).geometry();
43
44 56 const auto center = elementGeometry.center();
45 56 const auto dofAxis = scv.dofAxis();
46
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 56 times.
280 for (int i = 0; i < corners.size(); ++i)
47 {
48 224 auto& corner = corners[i];
49
50 // copy the corner of the corresponding element
51 224 corner = elementGeometry.corner(i);
52
53 // shift the corner such that the scv covers half of the element
54 // (keep the corner positions at the face with the staggered dof)
55
6/6
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 112 times.
✓ Branch 4 taken 112 times.
✓ Branch 5 taken 112 times.
672 if ((corner[dofAxis] - center[dofAxis]) * scv.directionSign() < 0.0)
56 336 corner[dofAxis] = center[dofAxis];
57 }
58
59 224 return {corners.front(), corners.back()};
60 }
61
62 template<class FVElementGeometry, class SubControlVolumeFace>
63 9468 typename SubControlVolumeFace::Traits::Geometry scvfGeometry(const FVElementGeometry& fvGeometry,
64 const SubControlVolumeFace& scvf)
65 {
66 9468 const auto normalAxis = scvf.normalAxis();
67 9468 const auto center = scvf.center();
68 18936 const auto shift = scvf.ipGlobal() - center;
69
2/2
✓ Branch 0 taken 9068 times.
✓ Branch 1 taken 400 times.
9468 const auto dofAxis = scvf.isLateral() ? Dumux::normalAxis(shift) : normalAxis;
70
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9468 times.
9468 const auto insideElementIndex = (fvGeometry.scv(scvf.insideScvIdx())).elementIndex();
71 9468 const auto elementGeometry = (insideElementIndex != fvGeometry.elementIndex()) ?
72 fvGeometry.element().geometry() :
73 9468 fvGeometry.gridGeometry().element(insideElementIndex).geometry();
74
75 18936 auto corners = std::array{
76 elementGeometry.corner(0),
77 9468 elementGeometry.corner(elementGeometry.corners() - 1)
78 };
79
80 // shift corners to scvf plane and halve lateral faces
81
2/2
✓ Branch 0 taken 18936 times.
✓ Branch 1 taken 9468 times.
28404 for (int i = 0; i < corners.size(); ++i)
82 {
83
2/2
✓ Branch 0 taken 18136 times.
✓ Branch 1 taken 800 times.
18936 auto& corner = corners[i];
84
4/4
✓ Branch 0 taken 18136 times.
✓ Branch 1 taken 800 times.
✓ Branch 2 taken 18136 times.
✓ Branch 3 taken 800 times.
37872 corner[normalAxis] = center[normalAxis];
85
4/4
✓ Branch 0 taken 18136 times.
✓ Branch 1 taken 800 times.
✓ Branch 2 taken 9068 times.
✓ Branch 3 taken 9068 times.
55208 if (scvf.isLateral() && (corner - center)*shift < 0.0)
86 36272 corner[dofAxis] = elementGeometry.center()[dofAxis];
87 }
88
89 18936 auto inPlaneAxes = std::move(std::bitset<SubControlVolumeFace::Traits::dimWorld>{}.set());
90 9468 inPlaneAxes.set(normalAxis, false);
91
92 28404 return {corners[0], corners[1], inPlaneAxes};
93 }
94
95 //! Get the scv on the outside side of a periodic boundary
96 template<class FVElementGeometry, class SubControlVolume>
97 12 const SubControlVolume& outsidePeriodicScv(const FVElementGeometry& fvGeometry,
98 const SubControlVolume& selfScv)
99 {
100
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
12 assert(fvGeometry.gridGeometry().dofOnPeriodicBoundary(selfScv.dofIndex()));
101
102
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 auto localOppositeIndex = FVElementGeometry::GridGeometry::GeometryHelper::localOppositeIdx(selfScv.localDofIndex());
103 12 const auto& normalScvf = std::next(scvfs(fvGeometry, selfScv).begin());
104
105 // at a lateral velocity, find the inner and outer normal velocities
106 12 const auto& orthogonalScvf = fvGeometry.lateralOrthogonalScvf(*normalScvf);
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 const auto orthogonalOutsideScv = fvGeometry.scv(orthogonalScvf.outsideScvIdx());
108
109 24 auto outsidePeriodicFVGeometry = localView(fvGeometry.gridGeometry());
110 12 const auto& periodicElement = fvGeometry.gridGeometry().element(orthogonalOutsideScv.elementIndex());
111 12 outsidePeriodicFVGeometry.bindElement(periodicElement);
112
113
2/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
✗ Branch 4 not taken.
30 for (const auto& outerPeriodicScv : scvs(outsidePeriodicFVGeometry))
114
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 18 times.
30 if (outerPeriodicScv.localDofIndex() == localOppositeIndex)
115 12 return outerPeriodicScv;
116
117 DUNE_THROW(Dune::InvalidStateException, "No outside periodic scv found");
118 }
119
120 } // end namespace Detail::FCStaggered
121 #endif // DOXYGEN
122
123 template<class GG, bool cachingEnabled>
124 class FaceCenteredStaggeredFVElementGeometry;
125
126 /*!
127 * \ingroup FaceCenteredStaggeredDiscretization
128 * \brief Stencil-local finite volume geometry (scvs and scvfs) for face-centered staggered models
129 * Specialization for grid caching enabled
130 */
131 template<class GG>
132 class FaceCenteredStaggeredFVElementGeometry<GG, /*cachingEnabled*/true>
133 {
134 using ThisType = FaceCenteredStaggeredFVElementGeometry<GG, /*cachingEnabled*/true>;
135 using GridView = typename GG::GridView;
136 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
137 static constexpr auto numScvsPerElement = GG::StaticInformation::numScvsPerElement;
138
139 public:
140 //! export type of subcontrol volume face
141 using SubControlVolume = typename GG::SubControlVolume;
142 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
143 using Element = typename GridView::template Codim<0>::Entity;
144 using GridGeometry = GG;
145
146 //! the maximum number of scvs per element
147 static constexpr std::size_t maxNumElementScvs = numScvsPerElement;
148
149 68307757 FaceCenteredStaggeredFVElementGeometry(const GridGeometry& gridGeometry)
150
19/21
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 6888 times.
✓ Branch 4 taken 2189314 times.
✓ Branch 5 taken 7201 times.
✓ Branch 6 taken 371406 times.
✓ Branch 7 taken 34 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 15 times.
✓ Branch 10 taken 34 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 14 times.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 14 times.
✓ Branch 16 taken 1768 times.
✓ Branch 17 taken 7 times.
✓ Branch 18 taken 5 times.
✓ Branch 19 taken 5317 times.
✓ Branch 20 taken 14 times.
✓ Branch 21 taken 2 times.
✗ Branch 22 not taken.
68307757 : gridGeometry_(&gridGeometry)
151 {}
152
153 //! Get a sub control volume with a global scv index
154 const SubControlVolume& scv(GridIndexType scvIdx) const
155
103/110
✓ Branch 0 taken 10144 times.
✓ Branch 1 taken 5344 times.
✓ Branch 2 taken 183 times.
✓ Branch 3 taken 447165 times.
✓ Branch 4 taken 183 times.
✓ Branch 5 taken 447165 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 5825101 times.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 5825101 times.
✓ Branch 10 taken 30 times.
✓ Branch 11 taken 148785384 times.
✓ Branch 12 taken 47 times.
✓ Branch 13 taken 181705945 times.
✓ Branch 14 taken 17 times.
✓ Branch 15 taken 176774711 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 176774728 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 32920578 times.
✓ Branch 20 taken 5032 times.
✓ Branch 21 taken 441888 times.
✓ Branch 22 taken 542992 times.
✓ Branch 23 taken 126939188 times.
✓ Branch 24 taken 593390 times.
✓ Branch 25 taken 141036220 times.
✓ Branch 26 taken 71990 times.
✓ Branch 27 taken 15076880 times.
✓ Branch 28 taken 1276672 times.
✓ Branch 29 taken 104091566 times.
✓ Branch 30 taken 1280344 times.
✓ Branch 31 taken 103557626 times.
✓ Branch 32 taken 20232 times.
✓ Branch 33 taken 4020 times.
✓ Branch 34 taken 272812 times.
✓ Branch 35 taken 292406 times.
✓ Branch 36 taken 274026 times.
✓ Branch 37 taken 293646 times.
✓ Branch 38 taken 953014 times.
✓ Branch 39 taken 89098032 times.
✓ Branch 40 taken 1053908 times.
✓ Branch 41 taken 89189410 times.
✓ Branch 42 taken 104972 times.
✓ Branch 43 taken 1046058 times.
✓ Branch 44 taken 122682 times.
✓ Branch 45 taken 33029568 times.
✓ Branch 46 taken 165796 times.
✓ Branch 47 taken 37412072 times.
✓ Branch 48 taken 57758 times.
✓ Branch 49 taken 5377010 times.
✓ Branch 50 taken 981768 times.
✓ Branch 51 taken 37979080 times.
✓ Branch 52 taken 974864 times.
✓ Branch 53 taken 38013962 times.
✓ Branch 54 taken 2445724 times.
✓ Branch 55 taken 6083852 times.
✓ Branch 56 taken 2440912 times.
✓ Branch 57 taken 6007968 times.
✓ Branch 58 taken 7184 times.
✓ Branch 59 taken 32870770 times.
✓ Branch 60 taken 543344 times.
✓ Branch 61 taken 39230030 times.
✓ Branch 62 taken 624640 times.
✓ Branch 63 taken 6447740 times.
✓ Branch 64 taken 5024 times.
✓ Branch 65 taken 38909164 times.
✓ Branch 66 taken 278600 times.
✓ Branch 67 taken 39972120 times.
✓ Branch 68 taken 273576 times.
✓ Branch 69 taken 900220 times.
✓ Branch 70 taken 991364 times.
✓ Branch 71 taken 5914252 times.
✓ Branch 72 taken 701124 times.
✓ Branch 73 taken 2995608 times.
✓ Branch 74 taken 5742632 times.
✓ Branch 75 taken 5748944 times.
✓ Branch 76 taken 2874928 times.
✓ Branch 77 taken 6191022 times.
✓ Branch 78 taken 612072 times.
✓ Branch 79 taken 1136882 times.
✓ Branch 80 taken 235454 times.
✓ Branch 81 taken 471624 times.
✓ Branch 82 taken 241970 times.
✓ Branch 83 taken 493488 times.
✓ Branch 84 taken 14964 times.
✓ Branch 85 taken 36480 times.
✓ Branch 86 taken 3360 times.
✓ Branch 87 taken 3816976 times.
✓ Branch 88 taken 18020 times.
✓ Branch 89 taken 46032 times.
✓ Branch 90 taken 3825236 times.
✓ Branch 91 taken 1482800 times.
✓ Branch 92 taken 10832 times.
✓ Branch 93 taken 24 times.
✓ Branch 94 taken 1454000 times.
✓ Branch 95 taken 99784 times.
✗ Branch 96 not taken.
✓ Branch 97 taken 21760 times.
✓ Branch 98 taken 99760 times.
✓ Branch 99 taken 1120 times.
✓ Branch 100 taken 21760 times.
✗ Branch 101 not taken.
✓ Branch 102 taken 1120 times.
✓ Branch 103 taken 4 times.
✗ Branch 104 not taken.
✓ Branch 105 taken 4 times.
✓ Branch 109 taken 40 times.
✗ Branch 110 not taken.
✓ Branch 112 taken 40 times.
✗ Branch 113 not taken.
4357788674 { return gridGeometry().scv(scvIdx); }
156
157 //! Get a sub control volume face with a global scvf index
158 const SubControlVolumeFace& scvf(GridIndexType scvfIdx) const
159
6/6
✓ Branch 0 taken 368053260 times.
✓ Branch 1 taken 80071277 times.
✓ Branch 2 taken 441495768 times.
✓ Branch 3 taken 96150931 times.
✓ Branch 4 taken 73442508 times.
✓ Branch 5 taken 16079654 times.
1075299718 { return gridGeometry().scvf(scvfIdx); }
160
161 //! Return a the lateral sub control volume face which is orthogonal to the given sub control volume face
162 313113844 const SubControlVolumeFace& lateralOrthogonalScvf(const SubControlVolumeFace& scvf) const
163 {
164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 313113844 times.
313113844 assert(scvf.isLateral());
165
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 313113844 times.
313113844 const auto otherGlobalIdx = scvfIndices_()[GridGeometry::GeometryHelper::lateralOrthogonalScvfLocalIndex(scvf.localIndex())];
166 939341532 return gridGeometry().scvf(otherGlobalIdx);
167
168 }
169
170 //! Return the frontal sub control volume face on a the boundary for a given sub control volume
171 6296258 const SubControlVolumeFace& frontalScvfOnBoundary(const SubControlVolume& scv) const
172 {
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6296258 times.
6296258 assert(scv.boundary());
174
175 // frontal boundary faces are always stored after the lateral faces
176 6296258 auto scvfIter = scvfs(*this, scv).begin();
177 6296258 const auto end = scvfs(*this, scv).end();
178
6/8
✓ Branch 1 taken 12592516 times.
✓ Branch 2 taken 13629552 times.
✓ Branch 3 taken 6296258 times.
✓ Branch 4 taken 6296258 times.
✓ Branch 5 taken 19925810 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 19925810 times.
✗ Branch 8 not taken.
26222068 while (!(scvfIter->isFrontal() && scvfIter->boundary()) && (scvfIter != end))
179 19925810 ++scvfIter;
180
181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6296258 times.
6296258 assert(scvfIter->isFrontal());
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6296258 times.
6296258 assert(scvfIter->boundary());
183 6296258 return *scvfIter;
184 }
185
186 //! iterator range for sub control volumes. Iterates over
187 //! all scvs of the bound element (not including neighbor scvs)
188 //! This is a free function found by means of ADL
189 //! To iterate over all sub control volumes of this FVElementGeometry use
190 //! for (auto&& scv : scvs(fvGeometry))
191 friend inline auto
192 78679980 scvs(const FaceCenteredStaggeredFVElementGeometry& fvGeometry)
193 236039940 { return fvGeometry.gridGeometry().scvs(fvGeometry); }
194
195 //! iterator range for sub control volumes faces. Iterates over
196 //! all scvfs of the bound element.
197 //! This is a free function found by means of ADL
198 //! To iterate over all sub control volume faces of this FVElementGeometry use
199 //! for (auto&& scvf : scvfs(fvGeometry))
200 friend inline auto
201 scvfs(const FaceCenteredStaggeredFVElementGeometry& fvGeometry)
202 {
203 using IndexContainerType = std::decay_t<decltype(fvGeometry.scvfIndices_())>;
204 using ScvfIterator = Dumux::ScvfIterator<SubControlVolumeFace, IndexContainerType, ThisType>;
205 7737110 return Dune::IteratorRange<ScvfIterator>(ScvfIterator(fvGeometry.scvfIndices_().begin(), fvGeometry),
206 3884043 ScvfIterator(fvGeometry.scvfIndices_().end(), fvGeometry));
207 }
208
209 //! iterator range for sub control volumes faces. Iterates over
210 //! all scvfs of the bound element belonging to the given sub control volume.
211 //! This is a free function found by means of ADL
212 //! To iterate over all sub control volume faces of this FVElementGeometry use
213 //! for (auto&& scvf : scvfs(fvGeometry, scv))
214 friend inline auto
215 96150931 scvfs(const FaceCenteredStaggeredFVElementGeometry& fvGeometry, const SubControlVolume& scv)
216 {
217 using IndexContainerType = std::decay_t<decltype(fvGeometry.scvfIndices_())>;
218 using ScvfIterator = Dumux::SkippingScvfIterator<SubControlVolumeFace, IndexContainerType, ThisType>;
219 96150931 auto begin = ScvfIterator::makeBegin(fvGeometry.scvfIndices_(), fvGeometry, scv.index());
220 96150931 auto end = ScvfIterator::makeEnd(fvGeometry.scvfIndices_(), fvGeometry, scv.index());
221 192301862 return Dune::IteratorRange<ScvfIterator>(begin, end);
222 }
223
224 //! number of sub control volumes in this fv element geometry
225 std::size_t numScv() const
226 { return numScvsPerElement; }
227
228 //! number of sub control volumes in this fv element geometry
229 std::size_t numScvf() const
230 298774 { return scvfIndices_().size(); }
231
232 //! Returns whether one of the geometry's scvfs lies on a boundary
233 5488004 bool hasBoundaryScvf() const
234 16464012 { return gridGeometry().hasBoundaryScvf(eIdx_); }
235
236 /*!
237 * \brief bind the local view (r-value overload)
238 * This overload is called when an instance of this class is a temporary in the usage context
239 * This allows a usage like this: `const auto view = localView(...).bind(element);`
240 */
241 FaceCenteredStaggeredFVElementGeometry bind(const Element& element) &&
242 {
243 662312 this->bind(element);
244
1/2
✓ Branch 1 taken 331156 times.
✗ Branch 2 not taken.
331156 return std::move(*this);
245 }
246
247 //! Binding of an element, called by the local jacobian to prepare element assembly
248 void bind(const Element& element) &
249
4/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 4 taken 2760 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1768 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1768 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1768 times.
✗ Branch 15 not taken.
3911570 { this->bindElement(element); }
250
251 /*!
252 * \brief bind the local view (r-value overload)
253 * This overload is called when an instance of this class is a temporary in the usage context
254 * This allows a usage like this: `const auto view = localView(...).bind(element);`
255 */
256 FaceCenteredStaggeredFVElementGeometry bindElement(const Element& element) &&
257 {
258
1/2
✓ Branch 2 taken 5304 times.
✗ Branch 3 not taken.
65375828 this->bindElement(element);
259
1/3
✗ Branch 1 not taken.
✓ Branch 2 taken 5304 times.
✗ Branch 3 not taken.
65375828 return std::move(*this);
260 }
261
262 //! Bind only element-local
263 95628923 void bindElement(const Element& element) &
264 {
265 95628923 elementPtr_ = &element;
266 191257846 eIdx_ = gridGeometry().elementMapper().index(element);
267 95628923 }
268
269 //! The grid geometry we are a restriction of
270 const GridGeometry& gridGeometry() const
271 {
272
89/152
✗ Branch 0 not taken.
✓ Branch 1 taken 166165350 times.
✓ Branch 2 taken 56947190 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 163306988 times.
✓ Branch 5 taken 57878704 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 96073814 times.
✓ Branch 8 taken 18593594 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 93619703 times.
✓ Branch 11 taken 17771754 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 44606 times.
✓ Branch 14 taken 141187509 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 8654 times.
✓ Branch 17 taken 178636684 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 257 times.
✓ Branch 20 taken 35971406 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 760 times.
✓ Branch 23 taken 122397400 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 264 times.
✓ Branch 26 taken 142494231 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 69877483 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 1550 times.
✓ Branch 32 taken 90210686 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 36 times.
✓ Branch 35 taken 125608722 times.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 90788840 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 72 times.
✓ Branch 41 taken 6726640 times.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✓ Branch 44 taken 2554510 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 1302 times.
✓ Branch 47 taken 93569248 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 2425 times.
✓ Branch 50 taken 55146956 times.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✓ Branch 53 taken 45897100 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 66 times.
✓ Branch 56 taken 426299692 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 10 times.
✓ Branch 59 taken 11327956 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 2250 times.
✓ Branch 62 taken 43365294 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 1650 times.
✓ Branch 65 taken 60272116 times.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✓ Branch 68 taken 260722798 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 320 times.
✓ Branch 71 taken 175446755 times.
✗ Branch 72 not taken.
✓ Branch 73 taken 320 times.
✓ Branch 74 taken 111160009 times.
✗ Branch 75 not taken.
✓ Branch 76 taken 640 times.
✓ Branch 77 taken 7211878 times.
✗ Branch 78 not taken.
✓ Branch 79 taken 640 times.
✓ Branch 80 taken 33249468 times.
✗ Branch 81 not taken.
✓ Branch 82 taken 640 times.
✓ Branch 83 taken 67012608 times.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✓ Branch 86 taken 162420900 times.
✗ Branch 87 not taken.
✓ Branch 88 taken 64 times.
✓ Branch 89 taken 69247106 times.
✗ Branch 90 not taken.
✓ Branch 91 taken 352 times.
✓ Branch 92 taken 22098888 times.
✗ Branch 93 not taken.
✓ Branch 94 taken 558 times.
✓ Branch 95 taken 19755844 times.
✓ Branch 96 taken 258016 times.
✗ Branch 97 not taken.
✓ Branch 98 taken 261823344 times.
✗ Branch 99 not taken.
✓ Branch 100 taken 2636 times.
✓ Branch 101 taken 41537398 times.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✓ Branch 104 taken 48103428 times.
✗ Branch 106 not taken.
✓ Branch 107 taken 52287402 times.
✗ Branch 109 not taken.
✓ Branch 110 taken 37923500 times.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✓ Branch 113 taken 5785356 times.
✓ Branch 114 taken 47214580 times.
✗ Branch 115 not taken.
✓ Branch 116 taken 140375736 times.
✓ Branch 117 taken 47826376 times.
✗ Branch 118 not taken.
✓ Branch 119 taken 159064350 times.
✓ Branch 120 taken 6627708 times.
✗ Branch 121 not taken.
✓ Branch 122 taken 14410914 times.
✓ Branch 123 taken 17980 times.
✗ Branch 124 not taken.
✓ Branch 125 taken 84546828 times.
✗ Branch 127 not taken.
✓ Branch 128 taken 49055680 times.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✓ Branch 131 taken 89642032 times.
✓ Branch 132 taken 9629200 times.
✗ Branch 133 not taken.
✓ Branch 134 taken 20453979 times.
✓ Branch 135 taken 18067430 times.
✗ Branch 136 not taken.
✓ Branch 137 taken 165704 times.
✓ Branch 138 taken 8274362 times.
✗ Branch 139 not taken.
✓ Branch 140 taken 846370 times.
✗ Branch 142 not taken.
✓ Branch 143 taken 84560 times.
✓ Branch 144 taken 15585360 times.
✗ Branch 145 not taken.
✓ Branch 146 taken 941993 times.
✗ Branch 148 not taken.
✓ Branch 149 taken 48580 times.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✓ Branch 153 taken 356020 times.
✗ Branch 154 not taken.
✓ Branch 155 taken 942 times.
✗ Branch 158 not taken.
✓ Branch 159 taken 39991 times.
4502081015 assert(gridGeometry_);
273 return *gridGeometry_;
274 }
275
276 std::size_t elementIndex() const
277
3/10
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3606 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 11 taken 956 times.
✓ Branch 12 taken 10 times.
464212415 { return eIdx_; }
278
279 //! The bound element
280 const Element& element() const
281 { return *elementPtr_; }
282
283 //! Returns true if the IP of an scvf lies on a concave corner
284 bool scvfIntegrationPointInConcaveCorner(const SubControlVolumeFace& scvf) const
285
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 124241256 times.
125372396 { return GG::GeometryHelper::scvfIntegrationPointInConcaveCorner(*this, scvf); }
286
287 //! Returns the the scvf of neighbor element with the same integration point and unit outer normal
288 15488 const SubControlVolumeFace& outsideScvfWithSameIntegrationPoint(const SubControlVolumeFace& scvf) const
289 {
290 15488 const auto& lateralOrthogonalScvf = this->lateralOrthogonalScvf(scvf);
291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15488 times.
15488 assert(!lateralOrthogonalScvf.boundary());
292
293
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 15488 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15488 times.
✓ Branch 4 taken 10144 times.
✓ Branch 5 taken 5344 times.
30976 const auto otherLocalIdx = GG::GeometryHelper::localIndexOutsideScvfWithSameIntegrationPoint(scvf, scv(scvf.insideScvIdx()));
294
295 15488 auto outsideFVGeometry = localView(gridGeometry());
296 30976 const auto outsideElementIdx = scv(lateralOrthogonalScvf.outsideScvIdx()).elementIndex();
297
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15488 outsideFVGeometry.bindElement(gridGeometry().element(outsideElementIdx));
298
299
2/4
✓ Branch 1 taken 246160 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 246160 times.
✗ Branch 4 not taken.
246160 for (const auto& otherScvf : scvfs(outsideFVGeometry))
300
2/2
✓ Branch 0 taken 15488 times.
✓ Branch 1 taken 230672 times.
246160 if (otherScvf.localIndex() == otherLocalIdx)
301 15488 return otherScvf;
302
303 DUNE_THROW(Dune::InvalidStateException, "No outside scvf found");
304 }
305
306 //! Get the scv on the outside side of a periodic boundary
307 const SubControlVolume& outsidePeriodicScv(const SubControlVolume& selfScv) const
308 {
309 12 return Detail::FCStaggered::outsidePeriodicScv(*this, selfScv);
310 }
311
312 //! Create the geometry of a given sub control volume
313 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
314 {
315 56 return Detail::FCStaggered::scvGeometry(*this, scv);
316 }
317
318 //! Create the geometry of a given sub control volume face
319 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
320 {
321
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
9468 return Detail::FCStaggered::scvfGeometry(*this, scvf);
322 }
323
324 private:
325
326 509738491 const auto& scvfIndices_() const
327 {
328
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 509738491 times.
509738491 return gridGeometry().scvfIndicesOfElement(eIdx_);
329 }
330
331 const Element* elementPtr_;
332 GridIndexType eIdx_;
333 const GridGeometry* gridGeometry_;
334 };
335
336 /*!
337 * \ingroup FaceCenteredStaggeredDiscretization
338 * \brief Stencil-local finite volume geometry (scvs and scvfs) for face-centered staggered models
339 * Specialization for grid caching disabled
340 */
341 template<class GG>
342 class FaceCenteredStaggeredFVElementGeometry<GG, /*cachingEnabled*/false>
343 {
344 using ThisType = FaceCenteredStaggeredFVElementGeometry<GG, /*cachingEnabled*/false>;
345
346 using GridView = typename GG::GridView;
347 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
348
349 //TODO include assert that checks for quad geometry
350
351 using StaticInfo = typename GG::StaticInformation;
352 static constexpr auto dim = StaticInfo::dim;
353 static constexpr auto numScvsPerElement = StaticInfo::numScvsPerElement;
354 static constexpr auto numLateralScvfsPerScv = StaticInfo::numLateralScvfsPerScv;
355 static constexpr auto numLateralScvfsPerElement = StaticInfo::numLateralScvfsPerElement;
356 static constexpr auto minNumScvfsPerElement = StaticInfo::minNumScvfsPerElement;
357 static constexpr auto maxNumScvfsPerElement = StaticInfo::maxNumScvfsPerElement;
358
359 using LocalIndexType = typename IndexTraits<GridView>::LocalIndex;
360
361 public:
362 //! export type of subcontrol volume face
363 using SubControlVolume = typename GG::SubControlVolume;
364 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
365 using Element = typename GridView::template Codim<0>::Entity;
366 using GridGeometry = GG;
367
368 //! the maximum number of scvs per element
369 static constexpr std::size_t maxNumElementScvs = numScvsPerElement;
370
371 1483778 FaceCenteredStaggeredFVElementGeometry(const GridGeometry& gridGeometry)
372 : gridGeometry_(&gridGeometry)
373 5935112 , geometryHelper_(gridGeometry.gridView())
374 1483778 {}
375
376 //! Get a sub control volume face with a global scvf index
377 const SubControlVolumeFace& scvf(const GridIndexType scvfIdx) const
378
4/4
✓ Branch 4 taken 11609472 times.
✓ Branch 5 taken 2472200 times.
✓ Branch 6 taken 11609472 times.
✓ Branch 7 taken 2472200 times.
36969454 { return scvfs_[findLocalIndex_(scvfIdx, scvfIndices_())]; }
379
380 //! iterator range for sub control volumes faces. Iterates over
381 //! all scvfs of the bound element.
382 //! This is a free function found by means of ADL
383 //! To iterate over all sub control volume faces of this FVElementGeometry use
384 //! for (auto&& scvf : scvfs(fvGeometry))
385 friend inline auto
386 scvfs(const FaceCenteredStaggeredFVElementGeometry& fvGeometry)
387 {
388 using Iter = typename decltype(fvGeometry.scvfs_)::const_iterator;
389 133656 return Dune::IteratorRange<Iter>(fvGeometry.scvfs_.begin(), fvGeometry.scvfs_.end());
390 }
391
392 //! iterator range for sub control volumes faces. Iterates over
393 //! all scvfs of the bound element belonging to the given sub control volume.
394 //! This is a free function found by means of ADL
395 //! To iterate over all sub control volume faces of this FVElementGeometry use
396 //! for (auto&& scvf : scvfs(fvGeometry, scv))
397 friend inline auto
398 2472200 scvfs(const FaceCenteredStaggeredFVElementGeometry& fvGeometry, const SubControlVolume& scv)
399 {
400 using IndexContainerType = std::decay_t<decltype(fvGeometry.scvfIndices_())>;
401 using ScvfIterator = Dumux::SkippingScvfIterator<SubControlVolumeFace, IndexContainerType, ThisType>;
402 2472200 auto begin = ScvfIterator::makeBegin(fvGeometry.scvfIndices_(), fvGeometry, scv.index());
403 2472200 auto end = ScvfIterator::makeEnd(fvGeometry.scvfIndices_(), fvGeometry, scv.index());
404 4944400 return Dune::IteratorRange<ScvfIterator>(begin, end);
405 }
406
407 //! Get a half sub control volume with a global scv index
408 67610688 const SubControlVolume& scv(const GridIndexType scvIdx) const
409 {
410
8/8
✓ Branch 0 taken 59306326 times.
✓ Branch 1 taken 8304362 times.
✓ Branch 2 taken 59306326 times.
✓ Branch 3 taken 8304362 times.
✓ Branch 4 taken 51001964 times.
✓ Branch 5 taken 8304362 times.
✓ Branch 6 taken 51001964 times.
✓ Branch 7 taken 8304362 times.
135221376 if (scvIdx >= scvIndicesOfElement_.front() && scvIdx <= scvIndicesOfElement_.back())
411 51001964 return scvs_[findLocalIndex_(scvIdx, scvIndicesOfElement_)];
412 else
413 16608724 return neighborScvs_[findLocalIndex_(scvIdx, neighborScvIndices_)];
414 }
415
416 //! iterator range for sub control volumes. Iterates over
417 //! all scvs of the bound element (not including neighbor scvs)
418 //! This is a free function found by means of ADL
419 //! To iterate over all sub control volumes of this FVElementGeometry use
420 //! for (auto&& scv : scvs(fvGeometry))
421 friend inline auto
422 scvs(const FaceCenteredStaggeredFVElementGeometry& g)
423 {
424 using IteratorType = typename std::array<SubControlVolume, 1>::const_iterator;
425 5537220 return Dune::IteratorRange<IteratorType>(g.scvs_.begin(), g.scvs_.end());
426 }
427
428 //! Return a the lateral sub control volume face which is orthogonal to the given sub control volume face
429 7920188 const SubControlVolumeFace& lateralOrthogonalScvf(const SubControlVolumeFace& scvf) const
430 {
431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7920188 times.
7920188 assert(scvf.isLateral());
432 7920188 const auto otherLocalIdx = GridGeometry::GeometryHelper::lateralOrthogonalScvfLocalIndex(scvf.localIndex());
433 15840376 return scvfs_[otherLocalIdx];
434 }
435
436 //! Return the frontal sub control volume face on a the boundary for a given sub control volume
437 245404 const SubControlVolumeFace& frontalScvfOnBoundary(const SubControlVolume& scv) const
438 {
439
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 245404 times.
245404 assert(scv.boundary());
440
441 // frontal boundary faces are always stored after the lateral faces
442 245404 auto scvfIter = scvfs(*this, scv).begin();
443 245404 const auto end = scvfs(*this, scv).end();
444
6/8
✓ Branch 1 taken 490808 times.
✓ Branch 2 taken 490808 times.
✓ Branch 4 taken 245404 times.
✓ Branch 5 taken 245404 times.
✓ Branch 6 taken 736212 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 736212 times.
✗ Branch 9 not taken.
981616 while (!(scvfIter->isFrontal() && scvfIter->boundary()) && (scvfIter != end))
445 736212 ++scvfIter;
446
447
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 245404 times.
245404 assert(scvfIter->isFrontal());
448
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 245404 times.
245404 assert(scvfIter->boundary());
449 245404 return *scvfIter;
450 }
451
452 //! Returns whether one of the geometry's scvfs lies on a boundary
453 62072 bool hasBoundaryScvf() const
454 186216 { return gridGeometry().hasBoundaryScvf(eIdx_); }
455
456 //! number of sub control volumes in this fv element geometry
457 std::size_t numScv() const
458 { return numScvsPerElement; }
459
460 //! number of sub control volumes in this fv element geometry
461 std::size_t numScvf() const
462 3668 { return scvfIndices_().size(); }
463
464 /*!
465 * \brief bind the local view (r-value overload)
466 * This overload is called when an instance of this class is a temporary in the usage context
467 * This allows a usage like this: `const auto view = localView(...).bind(element);`
468 */
469 FaceCenteredStaggeredFVElementGeometry bind(const Element& element) &&
470 {
471 this->bind_(element);
472 return std::move(*this);
473 }
474
475 void bind(const Element& element) &
476
3/8
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 4 taken 3018 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1768 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1768 times.
✗ Branch 12 not taken.
40090 { this->bind_(element); }
477
478 /*!
479 * \brief bind the local view (r-value overload)
480 * This overload is called when an instance of this class is a temporary in the usage context
481 * This allows a usage like this: `const auto view = localView(...).bind(element);`
482 */
483 1452712 FaceCenteredStaggeredFVElementGeometry bindElement(const Element& element) &&
484 {
485 152512 typename GG::LocalIntersectionMapper localIsMapper;
486 1605224 localIsMapper.update(gridGeometry().gridView(), element);
487 1452712 this->bindElement_(element, localIsMapper);
488 1452712 return std::move(*this);
489 }
490
491 493580 void bindElement(const Element& element) &
492 {
493 48480 typename GG::LocalIntersectionMapper localIsMapper;
494 542060 localIsMapper.update(gridGeometry().gridView(), element);
495 493580 this->bindElement_(element, localIsMapper);
496 493580 }
497
498 GridIndexType elementIndex() const
499 { return eIdx_; }
500
501 //! The bound element
502 const Element& element() const
503 { return *elementPtr_; }
504
505 //! The grid geometry we are a restriction of
506 const GridGeometry& gridGeometry() const
507 {
508
10/27
✗ Branch 2 not taken.
✓ Branch 3 taken 1452712 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 62072 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 27500 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 31036 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 124144 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 977904 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 977904 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 977904 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 41 not taken.
✓ Branch 42 taken 445100 times.
✓ Branch 43 taken 48480 times.
5124756 assert(gridGeometry_);
509 return *gridGeometry_;
510 }
511
512 //! Returns true if the IP of an scvf lies on a concave corner
513 bool scvfIntegrationPointInConcaveCorner(const SubControlVolumeFace& scvf) const
514
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3699872 times.
3699872 { return GG::GeometryHelper::scvfIntegrationPointInConcaveCorner(*this, scvf); }
515
516 //! Returns the the scvf of neighbor element with the same integration point and unit outer normal
517 //! Todo: this code can likely be improved, we don't need to build all of the outside geometry if we know how to build scvf.
518 SubControlVolumeFace outsideScvfWithSameIntegrationPoint(const SubControlVolumeFace& scvf) const
519 {
520 const SubControlVolumeFace& lateralOrthogonalScvf = this->lateralOrthogonalScvf(scvf);
521 assert(!lateralOrthogonalScvf.boundary());
522
523 const auto otherLocalIdx = GG::GeometryHelper::localIndexOutsideScvfWithSameIntegrationPoint(scvf, scv(scvf.insideScvIdx()));
524
525 auto outsideFVGeometry = localView(gridGeometry());
526 const auto outsideElementIdx = scv(lateralOrthogonalScvf.outsideScvIdx()).elementIndex();
527 outsideFVGeometry.bindElement(gridGeometry().element(outsideElementIdx));
528
529 for (const auto& otherScvf : scvfs(outsideFVGeometry))
530 if (otherScvf.localIndex() == otherLocalIdx)
531 return otherScvf;
532
533 DUNE_THROW(Dune::InvalidStateException, "No outside scvf found");
534 }
535
536 //! Get the scv on the outside side of a periodic boundary
537 SubControlVolume outsidePeriodicScv(const SubControlVolume& selfScv) const
538 {
539 return Detail::FCStaggered::outsidePeriodicScv(*this, selfScv);
540 }
541
542 //! Create the geometry of a given sub control volume
543 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
544 {
545 return Detail::FCStaggered::scvGeometry(*this, scv);
546 }
547
548 //! Create the geometry of a given sub control volume face
549 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
550 {
551 return Detail::FCStaggered::scvfGeometry(*this, scvf);
552 }
553
554 private:
555 //! Binding of an element preparing the geometries of the whole stencil
556 //! called by the local jacobian to prepare element assembly
557 40090 void bind_(const Element& element)
558 {
559 8840 typename GG::LocalIntersectionMapper localIsMapper;
560
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40090 times.
40090 localIsMapper.update(gridGeometry().gridView(), element);
561
562 40090 bindElement_(element, localIsMapper);
563
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40090 times.
40090 neighborScvIndices_.clear();
564
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40090 times.
40090 neighborScvs_.clear();
565
566
5/16
✗ Branch 0 not taken.
✓ Branch 1 taken 40090 times.
✓ Branch 4 taken 31250 times.
✓ Branch 5 taken 125000 times.
✓ Branch 6 taken 44200 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 35360 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
244650 for (const auto& intersection : intersections(gridGeometry().gridView(), element))
567 {
568
3/3
✓ Branch 0 taken 123125 times.
✓ Branch 1 taken 35955 times.
✓ Branch 2 taken 1280 times.
160360 if (intersection.neighbor())
569 {
570
4/5
✓ Branch 0 taken 60625 times.
✓ Branch 1 taken 94705 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17040 times.
✓ Branch 4 taken 17040 times.
155330 const auto localScvIdx = localIsMapper.realToRefIdx(intersection.indexInInside());
571
2/2
✓ Branch 0 taken 77665 times.
✓ Branch 1 taken 77665 times.
155330 const auto localOppositeScvIdx = geometryHelper_.localOppositeIdx(localScvIdx);
572
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 155330 times.
✗ Branch 2 not taken.
189410 const auto& neighborElement = intersection.outside();
573
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 155330 times.
✓ Branch 3 taken 34080 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 34080 times.
✗ Branch 7 not taken.
155330 const auto neighborElementIdx = gridGeometry().elementMapper().index(neighborElement);
574
1/2
✓ Branch 1 taken 34080 times.
✗ Branch 2 not taken.
189410 const auto& neighborElementGeometry = neighborElement.geometry();
575
576 // todo: could be done easier?
577 std::array<GridIndexType, numScvsPerElement> globalScvIndicesOfNeighborElement;
578 465990 std::iota(globalScvIndicesOfNeighborElement.begin(), globalScvIndicesOfNeighborElement.end(), neighborElementIdx*numScvsPerElement);
579
580 34080 typename GG::LocalIntersectionMapper localNeighborIsMapper;
581
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 155330 times.
✓ Branch 3 taken 34080 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 34080 times.
✗ Branch 7 not taken.
155330 localNeighborIsMapper.update(gridGeometry().gridView(), neighborElement);
582
583
7/20
✗ Branch 0 not taken.
✓ Branch 1 taken 34080 times.
✓ Branch 2 taken 121250 times.
✓ Branch 3 taken 519080 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 34080 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 10 taken 170400 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 136320 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 136320 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
1223630 for (const auto& neighborIntersection : intersections(gridGeometry().gridView(), neighborElement))
584 {
585
4/5
✓ Branch 0 taken 242500 times.
✓ Branch 1 taken 378820 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 68160 times.
✓ Branch 4 taken 68160 times.
621320 const auto localNeighborScvIdx = localNeighborIsMapper.realToRefIdx(neighborIntersection.indexInInside());
586
2/2
✓ Branch 0 taken 310660 times.
✓ Branch 1 taken 310660 times.
621320 if (localNeighborScvIdx != localScvIdx && localNeighborScvIdx != localOppositeScvIdx)
587 {
588
589
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 310660 times.
✓ Branch 3 taken 68160 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 68160 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 68160 times.
✗ Branch 10 not taken.
310660 const auto dofIndex = gridGeometry().intersectionMapper().globalIntersectionIndex(neighborElement, neighborIntersection.indexInInside());
590
1/2
✓ Branch 2 taken 68160 times.
✗ Branch 3 not taken.
378820 neighborScvs_.push_back(SubControlVolume(
591 neighborElementGeometry,
592 neighborIntersection.geometry(),
593
2/4
✓ Branch 1 taken 68160 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 68160 times.
✗ Branch 5 not taken.
621320 globalScvIndicesOfNeighborElement[localNeighborScvIdx],
594 localNeighborScvIdx,
595 dofIndex,
596
1/2
✓ Branch 1 taken 68160 times.
✗ Branch 2 not taken.
553160 Dumux::normalAxis(neighborIntersection.centerUnitOuterNormal()),
597 neighborElementIdx,
598 onDomainBoundary_(neighborIntersection)
599 ));
600
601 621320 neighborScvIndices_.push_back(globalScvIndicesOfNeighborElement[localNeighborScvIdx]);
602 }
603 }
604 }
605 }
606 40090 }
607
608 //! Bind only element-local
609 1986382 void bindElement_(const Element& element, const typename GG::LocalIntersectionMapper& localIsMapper)
610 {
611 1986382 elementPtr_ = &element;
612
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1986382 times.
1986382 eIdx_ = gridGeometry().elementMapper().index(element);
613 5959146 std::iota(scvIndicesOfElement_.begin(), scvIndicesOfElement_.end(), eIdx_*numScvsPerElement);
614 1986382 scvfs_.clear();
615 1986382 scvfs_.resize(minNumScvfsPerElement);
616
617 2196214 const auto& elementGeometry = element.geometry();
618
619
7/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1986382 times.
✓ Branch 3 taken 209832 times.
✓ Branch 4 taken 1776550 times.
✓ Branch 5 taken 7106200 times.
✓ Branch 6 taken 209832 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1049160 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 15 taken 839328 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
10981070 for (const auto& intersection : intersections(gridGeometry().gridView(), element))
620 {
621
2/4
✓ Branch 1 taken 839328 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 839328 times.
✗ Branch 5 not taken.
7945528 const auto localScvIdx = localIsMapper.realToRefIdx(intersection.indexInInside());
622 7945528 auto localScvfIdx = localScvIdx*(1 + numLateralScvfsPerScv);
623
2/4
✓ Branch 1 taken 839328 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 839328 times.
✗ Branch 6 not taken.
8784856 const auto& intersectionGeometry = intersection.geometry();
624
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 7945528 times.
✓ Branch 3 taken 839328 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 839328 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 839328 times.
✗ Branch 10 not taken.
7945528 const auto dofIndex = gridGeometry().intersectionMapper().globalIntersectionIndex(element, intersection.indexInInside());
625
626
3/3
✓ Branch 0 taken 3553100 times.
✓ Branch 1 taken 3972764 times.
✓ Branch 2 taken 419664 times.
8784856 scvs_[localScvIdx] = SubControlVolume(
627 elementGeometry,
628 intersectionGeometry,
629
2/4
✓ Branch 1 taken 839328 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 839328 times.
✗ Branch 5 not taken.
15891056 scvIndicesOfElement_[localScvIdx],
630 localScvIdx,
631 dofIndex,
632
1/2
✓ Branch 1 taken 839328 times.
✗ Branch 2 not taken.
15051728 Dumux::normalAxis(intersection.centerUnitOuterNormal()),
633 eIdx_,
634 onDomainBoundary_(intersection)
635 );
636
637 // the frontal sub control volume face at the element center
638
2/2
✓ Branch 0 taken 3972764 times.
✓ Branch 1 taken 3972764 times.
7945528 const auto localOppositeScvIdx = geometryHelper_.localOppositeIdx(localScvIdx);
639
1/2
✓ Branch 1 taken 839328 times.
✗ Branch 2 not taken.
15891056 scvfs_[localScvfIdx] = SubControlVolumeFace(
640 elementGeometry,
641 intersectionGeometry,
642
2/4
✓ Branch 1 taken 839328 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 839328 times.
✗ Branch 5 not taken.
15891056 std::array{scvIndicesOfElement_[localScvIdx], scvIndicesOfElement_[localOppositeScvIdx]},
643 localScvfIdx,
644
2/4
✓ Branch 2 taken 839328 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 839328 times.
✗ Branch 6 not taken.
7945528 scvfIndices_()[localScvfIdx],
645 intersection.centerUnitOuterNormal(),
646 SubControlVolumeFace::FaceType::frontal,
647 SubControlVolumeFace::BoundaryType::interior
648 );
649 7945528 ++localScvfIdx;
650
651 // the lateral sub control volume faces
652
3/4
✓ Branch 0 taken 15891056 times.
✓ Branch 1 taken 7945528 times.
✓ Branch 3 taken 15891056 times.
✗ Branch 4 not taken.
55618696 for (const auto lateralFacetIndex : Dune::transformedRangeView(geometryHelper_.localLaterFaceIndices(localScvIdx),
653
2/4
✓ Branch 1 taken 1678656 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1678656 times.
✗ Branch 5 not taken.
17569712 [&](auto&& idx) { return localIsMapper.refToRealIdx(idx) ;})
654 )
655 {
656
1/2
✓ Branch 1 taken 15891056 times.
✗ Branch 2 not taken.
17569712 const auto& lateralIntersection = geometryHelper_.intersection(lateralFacetIndex, element);
657
1/2
✓ Branch 1 taken 1678656 times.
✗ Branch 2 not taken.
17569712 const auto& lateralFacet = geometryHelper_.facet(lateralFacetIndex, element);
658 17569712 const auto& lateralFacetGeometry = lateralFacet.geometry();
659
660 // helper lambda to get the lateral scvf's global inside and outside scv indices
661 15891056 const auto globalScvIndicesForLateralFace = [&]
662 {
663 15891056 const auto globalOutsideScvIdx = [&]
664 {
665
3/3
✓ Branch 0 taken 14026934 times.
✓ Branch 1 taken 1812154 times.
✓ Branch 2 taken 51968 times.
15891056 if (lateralIntersection.neighbor())
666 {
667
1/2
✓ Branch 3 taken 1626688 times.
✗ Branch 4 not taken.
44777780 const auto parallelElemIdx = gridGeometry().elementMapper().index(lateralIntersection.outside());
668 // todo: could be done easier?
669 std::array<GridIndexType, numScvsPerElement> globalScvIndicesOfNeighborElement;
670 46404468 std::iota(globalScvIndicesOfNeighborElement.begin(), globalScvIndicesOfNeighborElement.end(), parallelElemIdx*numScvsPerElement);
671 30936312 return globalScvIndicesOfNeighborElement[localScvIdx];
672 }
673 else
674 422900 return gridGeometry().outsideVolVarIndex(scvfIndices_()[localScvfIdx]);
675
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15468156 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 422900 times.
15891056 }();
676
677 47673168 return std::array{scvIndicesOfElement_[localScvIdx], globalOutsideScvIdx};
678
1/2
✓ Branch 1 taken 15891056 times.
✗ Branch 2 not taken.
31782112 }();
679
680 31782112 const auto boundaryType = [&]
681 {
682
1/2
✓ Branch 0 taken 1678656 times.
✗ Branch 1 not taken.
31782112 if (onProcessorBoundary_(lateralIntersection))
683 return SubControlVolumeFace::BoundaryType::processorBoundary;
684
3/3
✓ Branch 0 taken 13841468 times.
✓ Branch 1 taken 1997620 times.
✓ Branch 2 taken 51968 times.
31782112 else if (onDomainBoundary_(lateralIntersection))
685 return SubControlVolumeFace::BoundaryType::physicalBoundary;
686 else
687 return SubControlVolumeFace::BoundaryType::interior;
688
1/2
✓ Branch 0 taken 14212400 times.
✗ Branch 1 not taken.
47673168 }();
689
690
1/2
✓ Branch 1 taken 1678656 times.
✗ Branch 2 not taken.
31782112 scvfs_[localScvfIdx] = SubControlVolumeFace(
691 elementGeometry,
692 intersectionGeometry,
693 lateralFacetGeometry,
694 globalScvIndicesForLateralFace, // TODO higher order
695 localScvfIdx,
696
2/4
✓ Branch 2 taken 1678656 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1678656 times.
✗ Branch 6 not taken.
15891056 scvfIndices_()[localScvfIdx],
697 lateralIntersection.centerUnitOuterNormal(),
698 SubControlVolumeFace::FaceType::lateral,
699 boundaryType
700 );
701 15891056 ++localScvfIdx;
702 }
703 }
704
705 // do a second loop over all intersections to add frontal boundary faces
706 1986382 auto localScvfIdx = minNumScvfsPerElement;
707
7/18
✗ Branch 0 not taken.
✓ Branch 1 taken 1986382 times.
✓ Branch 3 taken 209832 times.
✓ Branch 4 taken 1776550 times.
✓ Branch 5 taken 7106200 times.
✓ Branch 6 taken 209832 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1049160 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 839328 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
10981070 for (const auto& intersection : intersections(gridGeometry().gridView(), element))
708 {
709 // the frontal sub control volume face at a domain boundary (coincides with element face)
710
3/3
✓ Branch 0 taken 185466 times.
✓ Branch 1 taken 6946718 times.
✓ Branch 2 taken 813344 times.
7945528 if (onDomainBoundary_(intersection))
711 {
712
2/4
✓ Branch 1 taken 25984 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 25984 times.
✗ Branch 5 not taken.
211450 const auto localScvIdx = localIsMapper.realToRefIdx(intersection.indexInInside());
713 // the frontal sub control volume face at the boundary
714
3/6
✓ Branch 1 taken 25984 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 25984 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 25984 times.
✗ Branch 8 not taken.
422900 scvfs_.push_back(SubControlVolumeFace(
715 element.geometry(),
716 intersection.geometry(),
717
2/4
✓ Branch 1 taken 25984 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 25984 times.
✗ Branch 5 not taken.
422900 std::array{scvIndicesOfElement_[localScvIdx], scvIndicesOfElement_[localScvIdx]},
718 localScvfIdx,
719
2/4
✓ Branch 2 taken 25984 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 25984 times.
✗ Branch 6 not taken.
211450 scvfIndices_()[localScvfIdx],
720 intersection.centerUnitOuterNormal(),
721 SubControlVolumeFace::FaceType::frontal,
722 SubControlVolumeFace::BoundaryType::physicalBoundary
723 ));
724 211450 ++localScvfIdx;
725 }
726 }
727
728 if constexpr (!ConsistentlyOrientedGrid<typename GridView::Grid>{})
729 {
730
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 209829 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
209832 static const bool makeConsistentlyOriented = getParam<bool>("Grid.MakeConsistentlyOriented", true);
731
3/4
✓ Branch 0 taken 209832 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23492 times.
✓ Branch 3 taken 186340 times.
209832 if (makeConsistentlyOriented && scvfs_.size() > minNumScvfsPerElement)
732 {
733 // make sure frontal boundary scvfs are sorted correctly
734 70476 std::sort(scvfs_.begin() + minNumScvfsPerElement, scvfs_.end(),
735 [](const auto& scvfLeft, const auto& scvfRight)
736
6/72
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2492 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 2492 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 2492 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 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.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✓ Branch 67 taken 2492 times.
✗ Branch 68 not taken.
✓ Branch 69 taken 2492 times.
✗ Branch 70 not taken.
✓ Branch 71 taken 2492 times.
14952 { return scvfLeft.insideScvIdx() < scvfRight.insideScvIdx(); }
737 );
738 }
739 }
740 1986382 }
741
742 66419492 const auto& scvfIndices_() const
743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66419492 times.
66419492 { return gridGeometry().scvfIndicesOfElement(eIdx_); }
744
745 template<class Entry, class Container>
746 const LocalIndexType findLocalIndex_(const Entry& entry,
747 const Container& container) const
748 {
749 auto it = std::find(container.begin(), container.end(), entry);
750 assert(it != container.end() && "Could not find the entry! Make sure to properly bind this class!");
751 return std::distance(container.begin(), it);
752 }
753
754 28667300 bool onDomainBoundary_(const typename GridView::Intersection& intersection) const
755 {
756
3/12
✓ Branch 0 taken 28292718 times.
✓ Branch 1 taken 374582 times.
✓ Branch 2 taken 749164 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
29041882 return !intersection.neighbor() && intersection.boundary();
757 }
758
759 14212400 bool onProcessorBoundary_(const typename GridView::Intersection& intersection) const
760 {
761
3/6
✓ Branch 0 taken 14026934 times.
✓ Branch 1 taken 185466 times.
✓ Branch 2 taken 370932 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
14397866 return !intersection.neighbor() && !intersection.boundary();
762 }
763
764 Dune::ReservedVector<SubControlVolumeFace, maxNumScvfsPerElement> scvfs_;
765
766 Dune::ReservedVector<SubControlVolume, numLateralScvfsPerElement> neighborScvs_;
767 Dune::ReservedVector<GridIndexType, numLateralScvfsPerElement> neighborScvIndices_;
768
769 std::array<SubControlVolume, numScvsPerElement> scvs_;
770 std::array<GridIndexType, numScvsPerElement> scvIndicesOfElement_;
771
772 const GridGeometry* gridGeometry_;
773 const Element* elementPtr_;
774 GridIndexType eIdx_;
775 typename GridGeometry::GeometryHelper geometryHelper_;
776 };
777
778 } // end namespace Dumux
779
780 #endif
781