GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/discretization/facecentered/staggered/elementvolumevariables.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 125 126 99.2%
Functions: 117 124 94.4%
Branches: 108 148 73.0%

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 FaceCenteredStaggeredDiscretization
10 * \copydoc Dumux::FaceCenteredStaggeredElementVolumeVariables
11 */
12 #ifndef DUMUX_DISCRETIZATION_FACECENTERED_ELEMENTVOLUMEVARIABLES_HH
13 #define DUMUX_DISCRETIZATION_FACECENTERED_ELEMENTVOLUMEVARIABLES_HH
14
15 #include <algorithm>
16 #include <cassert>
17 #include <vector>
18 #include <utility>
19
20 #include <dumux/discretization/elementsolution.hh>
21
22 namespace Dumux {
23
24 /*!
25 * \ingroup FaceCenteredStaggeredDiscretization
26 * \brief Base class for the face variables vector
27 */
28 template<class GridVolumeVariables, bool cachingEnabled>
29 class FaceCenteredStaggeredElementVolumeVariables;
30
31 /*!
32 * \ingroup FaceCenteredStaggeredDiscretization
33 * \brief Class for the face variables vector. Specialization for the case of storing the face variables globally.
34 */
35 template<class GVV>
36 3418379 class FaceCenteredStaggeredElementVolumeVariables<GVV, /*cachingEnabled*/true>
37 {
38 using ThisType = FaceCenteredStaggeredElementVolumeVariables<GVV, /*cachingEnabled*/true>;
39 using GridGeometry = std::decay_t<decltype(std::declval<GVV>().problem().gridGeometry())>;
40 using FVElementGeometry = typename GridGeometry::LocalView;
41 using SubControlVolume = typename GridGeometry::SubControlVolume;
42
43 public:
44 //! export type of the grid volume variables
45 using GridVolumeVariables = GVV;
46
47 //! export type of the volume variables
48 using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
49
50 3099926 FaceCenteredStaggeredElementVolumeVariables(const GridVolumeVariables& gridVolumeVariables)
51
3/6
✓ Branch 1 taken 2730761 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 356714 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12451 times.
✗ Branch 8 not taken.
3099926 : gridVolumeVariablesPtr_(&gridVolumeVariables)
52
3/6
✓ Branch 1 taken 2730761 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 356714 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12451 times.
✗ Branch 8 not taken.
3099926 , numScv_(gridVolumeVariables.problem().gridGeometry().numScv())
53 {}
54
55 //! operator for the access with an scvf
56
1/2
✓ Branch 0 taken 222376780 times.
✗ Branch 1 not taken.
222376780 const VolumeVariables& operator [](const SubControlVolume& scv) const
57 {
58
1/2
✓ Branch 0 taken 222376780 times.
✗ Branch 1 not taken.
222376780 if (scv.index() < numScv_)
59 222376780 return gridVolVars().volVars(scv.index());
60 else
61 return boundaryVolumeVariables_[getLocalIdx_(scv.index())];
62 }
63
64 //! operator for the access with an index
65 //! needed for cc methods for the access to the boundary volume variables
66 2321546470 const VolumeVariables& operator [](const std::size_t scvIdx) const
67 {
68
2/2
✓ Branch 0 taken 2316776070 times.
✓ Branch 1 taken 4770400 times.
2321546470 if (scvIdx < numScv_)
69 2316776070 return gridVolVars().volVars(scvIdx);
70 else
71 4770400 return boundaryVolumeVariables_[getLocalIdx_(scvIdx)];
72 }
73
74 /*!
75 * \brief bind the local view (r-value overload)
76 * This overload is called when an instance of this class is a temporary in the usage context
77 * This allows a usage like this: `const auto view = localView(...).bind(element);`
78 */
79 template<class SolutionVector>
80 368865 ThisType bind(const typename FVElementGeometry::Element& element,
81 const FVElementGeometry& fvGeometry,
82 const SolutionVector& sol) &&
83 {
84
2/4
✓ Branch 1 taken 356714 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 12151 times.
✗ Branch 6 not taken.
368865 this->bind(element, fvGeometry, sol);
85 368865 return std::move(*this);
86 }
87
88 //! For compatibility reasons with the case of not storing the face vars.
89 //! function to be called before assembling an element, preparing the vol vars within the stencil
90 template<class SolutionVector>
91 3159338 void bind(const typename FVElementGeometry::Element& element,
92 const FVElementGeometry& fvGeometry,
93 const SolutionVector& sol) &
94 {
95
2/2
✓ Branch 1 taken 189218 times.
✓ Branch 2 taken 2919708 times.
3159338 if (!fvGeometry.hasBoundaryScvf())
96 return;
97
98 199434 clear_();
99 // upper bound of size is the number of all scvfs minus frontal scvfs
100 200118 boundaryVolVarIndices_.reserve(fvGeometry.numScvf()-element.subEntities(1));
101 200118 boundaryVolumeVariables_.reserve(fvGeometry.numScvf()-element.subEntities(1));
102
103
4/4
✓ Branch 0 taken 629188 times.
✓ Branch 1 taken 1978236 times.
✓ Branch 2 taken 2607424 times.
✓ Branch 3 taken 189218 times.
5687306 for (const auto& scvf : scvfs(fvGeometry))
104 {
105
4/4
✓ Branch 0 taken 629188 times.
✓ Branch 1 taken 1978236 times.
✓ Branch 2 taken 201532 times.
✓ Branch 3 taken 427656 times.
2743936 if (!scvf.boundary() || scvf.isFrontal() || scvf.processorBoundary())
106 2674772 continue;
107
108 // check if boundary is a pure dirichlet boundary
109 455496 const auto& problem = gridVolVars().problem();
110
2/3
✓ Branch 0 taken 321048 times.
✓ Branch 1 taken 72480 times.
✗ Branch 2 not taken.
455496 const auto bcTypes = problem.boundaryTypes(element, scvf);
111
112
2/2
✓ Branch 0 taken 358492 times.
✓ Branch 1 taken 69164 times.
511176 auto addBoundaryVolVars = [&](const auto& scvFace)
113 {
114
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 355178 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6816 times.
361994 const auto& scvI = fvGeometry.scv(scvFace.insideScvIdx());
115 361994 typename VolumeVariables::PrimaryVariables pv(
116
2/2
✓ Branch 0 taken 6630 times.
✓ Branch 1 taken 19482 times.
431092 problem.dirichlet(element, scvFace)[scvI.dofAxis()]
117 );
118 361994 const auto dirichletPriVars = elementSolution<FVElementGeometry>(pv);
119
120 361994 VolumeVariables volVars;
121 361994 volVars.update(dirichletPriVars, problem, element, scvI);
122
123 361994 boundaryVolumeVariables_.emplace_back(std::move(volVars));
124 361994 boundaryVolVarIndices_.push_back(scvFace.outsideScvIdx());
125 };
126
127
2/2
✓ Branch 0 taken 358492 times.
✓ Branch 1 taken 69164 times.
455496 if (bcTypes.hasDirichlet())
128 {
129
1/2
✓ Branch 1 taken 358492 times.
✗ Branch 2 not taken.
386332 addBoundaryVolVars(scvf);
130 386332 continue;
131 }
132
133 // treat domain corners
134
2/2
✓ Branch 1 taken 3816 times.
✓ Branch 2 taken 65348 times.
69164 if (const auto& orthogonalScvf = fvGeometry.lateralOrthogonalScvf(scvf); orthogonalScvf.boundary())
135
4/5
✓ Branch 1 taken 1112 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 162 times.
✓ Branch 4 taken 294 times.
✓ Branch 0 taken 2704 times.
3816 if (problem.boundaryTypes(element, orthogonalScvf).hasDirichlet())
136
1/2
✓ Branch 1 taken 3502 times.
✗ Branch 2 not taken.
3502 addBoundaryVolVars(scvf);
137
138 }
139
140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 189218 times.
199434 assert(boundaryVolumeVariables_.size() == boundaryVolVarIndices_.size());
141 }
142
143 /*!
144 * \brief bind the local view (r-value overload)
145 * This overload is called when an instance of this class is a temporary in the usage context
146 * This allows a usage like this: `const auto view = localView(...).bind(element);`
147 */
148 template<class SolutionVector>
149 ThisType bindElement(const typename FVElementGeometry::Element& element,
150 const FVElementGeometry& fvGeometry,
151 const SolutionVector& sol) &&
152 {
153 this->bindElement(element, fvGeometry, sol);
154 return std::move(*this);
155 }
156 //! Binding of an element, prepares only the face variables of the element
157 //! specialization for Staggered models
158 template<class SolutionVector>
159 void bindElement(const typename FVElementGeometry::Element& element,
160 const FVElementGeometry& fvGeometry,
161 const SolutionVector& sol) &
162 {}
163
164
165 //! The global volume variables object we are a restriction of
166 2539580506 const GridVolumeVariables& gridVolVars() const
167
3/4
✓ Branch 0 taken 314232 times.
✓ Branch 1 taken 96278 times.
✓ Branch 2 taken 6816 times.
✗ Branch 3 not taken.
2539647274 { return *gridVolumeVariablesPtr_; }
168
169 //! Returns true if volVars exist for the given scv index
170 335668 bool hasVolVars(const std::size_t scvIdx) const
171 {
172
2/2
✓ Branch 0 taken 1640 times.
✓ Branch 1 taken 334028 times.
335668 if (scvIdx < numScv_)
173 return true;
174 else
175 {
176 1640 const auto it = std::find(boundaryVolVarIndices_.begin(), boundaryVolVarIndices_.end(), scvIdx);
177 1640 return it != boundaryVolVarIndices_.end();
178 }
179 }
180
181 private:
182 //! Clear all local storage
183 189218 void clear_()
184 {
185
3/4
✓ Branch 0 taken 608 times.
✓ Branch 1 taken 186128 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2482 times.
189218 boundaryVolVarIndices_.clear();
186
3/4
✓ Branch 0 taken 608 times.
✓ Branch 1 taken 186128 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2482 times.
189826 boundaryVolumeVariables_.clear();
187 }
188
189 //! map a global scv index to the local storage index
190 4770400 int getLocalIdx_(const std::size_t volVarIdx) const
191 {
192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4770400 times.
4770400 const auto it = std::find(boundaryVolVarIndices_.begin(), boundaryVolVarIndices_.end(), volVarIdx);
193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4770400 times.
4770400 assert(it != boundaryVolVarIndices_.end() && "Could not find the current volume variables for volVarIdx!");
194 4770400 return std::distance(boundaryVolVarIndices_.begin(), it);
195 }
196
197 const GridVolumeVariables* gridVolumeVariablesPtr_;
198 const std::size_t numScv_;
199 std::vector<std::size_t> boundaryVolVarIndices_;
200 std::vector<VolumeVariables> boundaryVolumeVariables_;
201 };
202
203 /*!
204 * \ingroup FaceCenteredStaggeredDiscretization
205 * \brief Class for the face variables vector. Specialization for the case of not storing the face variables globally.
206 */
207 template<class GVV>
208 class FaceCenteredStaggeredElementVolumeVariables<GVV, /*cachingEnabled*/false>
209 {
210 using ThisType = FaceCenteredStaggeredElementVolumeVariables<GVV, /*cachingEnabled*/false>;
211 using GridGeometry = std::decay_t<decltype(std::declval<GVV>().problem().gridGeometry())>;
212 using FVElementGeometry = typename GridGeometry::LocalView;
213 using SubControlVolume = typename GridGeometry::SubControlVolume;
214
215 static constexpr auto dim = GridGeometry::GridView::dimension;
216 static constexpr auto numInsideVolVars = dim * 2;
217 static constexpr auto numOutsideVolVars = numInsideVolVars * 2 * (dim - 1);
218
219 public:
220 //! export type of the grid volume variables
221 using GridVolumeVariables = GVV;
222
223 //! export type of the volume variables
224 using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
225
226 31036 FaceCenteredStaggeredElementVolumeVariables(const GridVolumeVariables& globalFacesVars)
227 31036 : gridVolumeVariablesPtr_(&globalFacesVars) {}
228
229 //! const operator for the access with an scvf
230 1947000 const VolumeVariables& operator [](const SubControlVolume& scv) const
231 4088192 { return volumeVariables_[getLocalIdx_(scv.index())]; }
232
233 //! const operator for the access with an index
234 21530008 const VolumeVariables& operator [](const std::size_t scvIdx) const
235
9/12
✓ Branch 2 taken 5678552 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1903527 times.
✓ Branch 16 taken 1 times.
✓ Branch 17 taken 3775023 times.
✓ Branch 30 taken 1 times.
✓ Branch 31 taken 32031 times.
✓ Branch 12 taken 3 times.
✓ Branch 13 taken 149037 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
33553496 { return volumeVariables_[getLocalIdx_(scvIdx)]; }
236
237 //! operator for the access with an scvf
238 981166 VolumeVariables& operator [](const SubControlVolume& scv)
239
2/2
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 977900 times.
981166 { return volumeVariables_[getLocalIdx_(scv.index())]; }
240
241 // operator for the access with an index
242 VolumeVariables& operator [](const std::size_t scvIdx)
243 { return volumeVariables_[getLocalIdx_(scvIdx)]; }
244
245 /*!
246 * \brief bind the local view (r-value overload)
247 * This overload is called when an instance of this class is a temporary in the usage context
248 * This allows a usage like this: `const auto view = localView(...).bind(element);`
249 */
250 template<class SolutionVector>
251 ThisType bind(const typename FVElementGeometry::Element& element,
252 const FVElementGeometry& fvGeometry,
253 const SolutionVector& sol) &&
254 {
255 this->bind_(element, fvGeometry, sol);
256 return std::move(*this);
257 }
258
259 template<class SolutionVector>
260 31036 void bind(const typename FVElementGeometry::Element& element,
261 const FVElementGeometry& fvGeometry,
262 const SolutionVector& sol) &
263 {
264 31036 this->bind_(element, fvGeometry, sol);
265 }
266
267 /*!
268 * \brief bind the local view (r-value overload)
269 * This overload is called when an instance of this class is a temporary in the usage context
270 * This allows a usage like this: `const auto view = localView(...).bind(element);`
271 */
272 template<class SolutionVector>
273 ThisType bindElement(const typename FVElementGeometry::Element& element,
274 const FVElementGeometry& fvGeometry,
275 const SolutionVector& sol) &&
276 {
277 this->bindElement_(element, fvGeometry, sol);
278 return std::move(*this);
279 }
280
281 template<class SolutionVector>
282 27500 void bindElement(const typename FVElementGeometry::Element& element,
283 const FVElementGeometry& fvGeometry,
284 const SolutionVector& sol) &
285 27500 { this->bindElement_(element, fvGeometry, sol); }
286
287 //! The global volume variables object we are a restriction of
288 7624 const GridVolumeVariables& gridVolVars() const
289 66160 { return *gridVolumeVariablesPtr_; }
290
291 //! Returns true if volVars exist for the given scv index
292 bool hasVolVars(const std::size_t scvIdx) const
293 { return volVarsInserted_(scvIdx); }
294
295 private:
296 //! For compatibility reasons with the case of not storing the vol vars.
297 //! function to be called before assembling an element, preparing the vol vars within the stencil
298 template<class SolutionVector>
299 31036 void bind_(const typename FVElementGeometry::Element& element,
300 const FVElementGeometry& fvGeometry,
301 const SolutionVector& sol)
302 {
303 31036 clear_();
304
305 31036 const auto& problem = gridVolVars().problem();
306 31036 const auto& gridGeometry = fvGeometry.gridGeometry();
307
308 31036 volVarIndices_.reserve(numInsideVolVars + numInsideVolVars);
309 31036 volumeVariables_.reserve(numInsideVolVars + numInsideVolVars);
310
311
2/2
✓ Branch 0 taken 124144 times.
✓ Branch 1 taken 31036 times.
155180 for (const auto& scv : scvs(fvGeometry))
312 {
313
2/2
✓ Branch 0 taken 853760 times.
✓ Branch 1 taken 124144 times.
977904 for (const auto otherScvIdx : gridGeometry.connectivityMap()[scv.index()])
314 {
315 853760 if (!volVarsInserted_(otherScvIdx))
316 {
317 364808 const auto& otherScv = fvGeometry.scv(otherScvIdx);
318
1/2
✓ Branch 1 taken 364808 times.
✗ Branch 2 not taken.
364808 volVarIndices_.push_back(otherScvIdx);
319
1/2
✓ Branch 1 taken 364808 times.
✗ Branch 2 not taken.
364808 volumeVariables_.emplace_back();
320
1/2
✓ Branch 1 taken 364808 times.
✗ Branch 2 not taken.
364808 const auto& otherElement = gridGeometry.element(otherScv.elementIndex());
321
1/2
✓ Branch 1 taken 364808 times.
✗ Branch 2 not taken.
364808 volumeVariables_.back().update(
322 364808 elementSolution(otherElement, sol, gridGeometry),
323 problem, otherElement, otherScv
324 );
325 41408 }
326 }
327 }
328
329
2/2
✓ Branch 1 taken 3668 times.
✓ Branch 2 taken 27368 times.
31036 if (fvGeometry.hasBoundaryScvf())
330 {
331
4/4
✓ Branch 0 taken 11436 times.
✓ Branch 1 taken 36392 times.
✓ Branch 2 taken 47828 times.
✓ Branch 3 taken 3668 times.
51496 for (const auto& scvf : scvfs(fvGeometry))
332 {
333
4/4
✓ Branch 0 taken 11436 times.
✓ Branch 1 taken 36392 times.
✓ Branch 2 taken 3812 times.
✓ Branch 3 taken 7624 times.
47828 if (!scvf.boundary() || scvf.isFrontal())
334 46728 continue;
335
336 // check if boundary is a pure dirichlet boundary
337
2/2
✓ Branch 0 taken 6524 times.
✓ Branch 1 taken 1100 times.
7624 const auto& problem = gridVolVars().problem();
338
2/2
✓ Branch 0 taken 6524 times.
✓ Branch 1 taken 1100 times.
7624 const auto bcTypes = problem.boundaryTypes(element, scvf);
339
340
2/2
✓ Branch 0 taken 6524 times.
✓ Branch 1 taken 1100 times.
7624 auto addBoundaryVolVars = [&](const auto& scvFace)
341 {
342 6568 const auto& scvI = fvGeometry.scv(scvFace.insideScvIdx());
343 6568 typename VolumeVariables::PrimaryVariables pv(
344 6568 problem.dirichlet(element, scvFace)[scvI.dofAxis()]
345 );
346 6568 const auto dirichletPriVars = elementSolution<FVElementGeometry>(pv);
347
348 6568 VolumeVariables volVars;
349 6568 volVars.update(dirichletPriVars,
350 problem,
351 element,
352 scvI);
353
354 6568 volumeVariables_.emplace_back(std::move(volVars));
355 6568 volVarIndices_.push_back(scvFace.outsideScvIdx());
356 };
357
358
2/2
✓ Branch 0 taken 6524 times.
✓ Branch 1 taken 1100 times.
7624 if (bcTypes.hasDirichlet())
359 {
360
1/2
✓ Branch 1 taken 6524 times.
✗ Branch 2 not taken.
6524 addBoundaryVolVars(scvf);
361 6524 continue;
362 }
363
364 // treat domain corners
365
2/2
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 1056 times.
1100 if (const auto& orthogonalScvf = fvGeometry.lateralOrthogonalScvf(scvf); orthogonalScvf.boundary())
366
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 if (problem.boundaryTypes(element, orthogonalScvf).hasDirichlet())
367
1/2
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
44 addBoundaryVolVars(scvf);
368
369 }
370 }
371 31036 }
372
373 //! Binding of an element, prepares only the face variables of the element
374 //! specialization for Staggered models
375 template<class SolutionVector>
376 27500 void bindElement_(const typename FVElementGeometry::Element& element,
377 const FVElementGeometry& fvGeometry,
378 const SolutionVector& sol)
379 {
380 27500 clear_();
381 27500 const auto& problem = gridVolVars().problem();
382 27500 const auto& gridGeometry = fvGeometry.gridGeometry();
383 27500 volVarIndices_.reserve(numInsideVolVars);
384
385
2/2
✓ Branch 0 taken 110000 times.
✓ Branch 1 taken 27500 times.
137500 for (const auto& scv : scvs(fvGeometry))
386 {
387 110000 volVarIndices_.push_back(scv.index());
388 110000 volumeVariables_.emplace_back();
389 110000 volumeVariables_.back().update(
390 110000 elementSolution(element, sol, gridGeometry),
391 problem, element, scv
392 );
393 }
394 27500 }
395
396 //! Clear all local storage
397 58536 void clear_()
398 {
399
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27500 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 31036 times.
58536 volVarIndices_.clear();
400
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 27500 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27500 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 31036 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 31036 times.
58536 volumeVariables_.clear();
401 }
402
403 853760 bool volVarsInserted_(const std::size_t scvIdx) const
404 {
405
2/2
✓ Branch 0 taken 364808 times.
✓ Branch 1 taken 488952 times.
853760 return std::find(volVarIndices_.begin(), volVarIndices_.end(), scvIdx) != volVarIndices_.end();
406 }
407
408 62099862 int getLocalIdx_(const int scvfIdx) const
409 {
410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62099862 times.
62099862 const auto it = std::find(volVarIndices_.begin(), volVarIndices_.end(), scvfIdx);
411
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62099862 times.
62099862 assert(it != volVarIndices_.end() && "Could not find the current face variables for scvfIdx!");
412 62099862 return std::distance(volVarIndices_.begin(), it);
413 }
414
415 const GridVolumeVariables* gridVolumeVariablesPtr_;
416 std::vector<std::size_t> volVarIndices_;
417 std::vector<VolumeVariables> volumeVariables_;
418 };
419
420 } // end namespace Dumux
421
422 #endif
423