GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/porousmediumflow/fluxvariablescachefiller.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 188 188 100.0%
Functions: 295 300 98.3%
Branches: 114 145 78.6%

Line Branch Exec Source
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 //
4 // SPDX-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 PorousmediumflowModels
10 * \brief A helper class to fill the flux variables cache
11 */
12 #ifndef DUMUX_POROUSMEDIUM_FLUXVARIABLESCACHE_FILLER_HH
13 #define DUMUX_POROUSMEDIUM_FLUXVARIABLESCACHE_FILLER_HH
14
15 #include <dumux/common/properties.hh>
16 #include <dumux/common/parameters.hh>
17
18 #include <dumux/discretization/method.hh>
19 #include <dumux/discretization/extrusion.hh>
20 #include <dumux/flux/referencesystemformulation.hh>
21 #include <dumux/discretization/cellcentered/tpfa/computetransmissibility.hh>
22
23 namespace Dumux {
24
25 // forward declaration
26 template<class TypeTag, class DiscretizationMethod>
27 class PorousMediumFluxVariablesCacheFillerImplementation;
28
29 /*!
30 * \ingroup PorousmediumflowModels
31 * \brief The flux variables cache filler class for porous media
32 *
33 * Helps filling the flux variables cache depending several policies
34 */
35 template<class TypeTag>
36 using PorousMediumFluxVariablesCacheFiller = PorousMediumFluxVariablesCacheFillerImplementation<TypeTag, typename GetPropType<TypeTag, Properties::GridGeometry>::DiscretizationMethod>;
37
38 //! Specialization of the flux variables cache filler for the cell centered tpfa method
39 template<class TypeTag>
40 class PorousMediumFluxVariablesCacheFillerImplementation<TypeTag, DiscretizationMethods::CCTpfa>
41 {
42 using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>;
43 using Problem = GetPropType<TypeTag, Properties::Problem>;
44 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
45 using GridView = typename GridGeometry::GridView;
46 using FVElementGeometry = typename GridGeometry::LocalView;
47 using SubControlVolume = typename GridGeometry::SubControlVolume;
48 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
49 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
50
51 using Element = typename GridView::template Codim<0>::Entity;
52
53 static constexpr bool advectionEnabled = ModelTraits::enableAdvection();
54 static constexpr bool diffusionEnabled = ModelTraits::enableMolecularDiffusion();
55 static constexpr bool heatConductionEnabled = ModelTraits::enableEnergyBalance();
56
57 static constexpr bool advectionIsSolDependent = getPropValue<TypeTag, Properties::SolutionDependentAdvection>();
58 static constexpr bool diffusionIsSolDependent = getPropValue<TypeTag, Properties::SolutionDependentMolecularDiffusion>();
59 static constexpr bool heatConductionIsSolDependent = getPropValue<TypeTag, Properties::SolutionDependentHeatConduction>();
60
61
62 public:
63 static constexpr bool isSolDependent = (advectionEnabled && advectionIsSolDependent) ||
64 (diffusionEnabled && diffusionIsSolDependent) ||
65 (heatConductionEnabled && heatConductionIsSolDependent);
66
67 //! The constructor. Sets the problem pointer
68 34576215 PorousMediumFluxVariablesCacheFillerImplementation(const Problem& problem)
69 34576215 : problemPtr_(&problem) {}
70
71 /*!
72 * \brief function to fill the flux variables caches
73 *
74 * \param fluxVarsCacheContainer Either the element or global flux variables cache
75 * \param scvfFluxVarsCache The flux var cache to be updated corresponding to the given scvf
76 * \param element The finite element
77 * \param fvGeometry The finite volume geometry
78 * \param elemVolVars The element volume variables
79 * \param scvf The corresponding sub-control volume face
80 * \param forceUpdateAll if true, forces all caches to be updated (even the solution-independent ones)
81 */
82 template<class FluxVariablesCacheContainer, class FluxVariablesCache>
83 265943703 void fill(FluxVariablesCacheContainer& fluxVarsCacheContainer,
84 FluxVariablesCache& scvfFluxVarsCache,
85 const Element& element,
86 const FVElementGeometry& fvGeometry,
87 const ElementVolumeVariables& elemVolVars,
88 const SubControlVolumeFace& scvf,
89 bool forceUpdateAll = false)
90 {
91 // fill the physics-related quantities of the caches
92
5/6
✓ Branch 0 taken 92455953 times.
✓ Branch 1 taken 146489748 times.
✓ Branch 2 taken 5620998 times.
✓ Branch 3 taken 5000000 times.
✓ Branch 4 taken 48000 times.
✗ Branch 5 not taken.
264718775 if (forceUpdateAll)
93 {
94 if constexpr (advectionEnabled)
95 100332971 fillAdvection_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
96 if constexpr (diffusionEnabled)
97 45803318 fillDiffusion_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
98 if constexpr (heatConductionEnabled)
99 15876958 fillHeatConduction_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
100 }
101 else
102 {
103 if constexpr (advectionEnabled && advectionIsSolDependent)
104 123349854 fillAdvection_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
105 if constexpr (diffusionEnabled && diffusionIsSolDependent)
106 150984428 fillDiffusion_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
107 if constexpr (heatConductionEnabled && heatConductionIsSolDependent)
108 57553128 fillHeatConduction_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
109 }
110 253974129 }
111
112 private:
113
114 451472581 const Problem& problem() const
115 444991041 { return *problemPtr_; }
116
117 //! method to fill the advective quantities
118 template<class FluxVariablesCache>
119 208578749 void fillAdvection_(FluxVariablesCache& scvfFluxVarsCache,
120 const Element& element,
121 const FVElementGeometry& fvGeometry,
122 const ElementVolumeVariables& elemVolVars,
123 const SubControlVolumeFace& scvf)
124 {
125 using AdvectionType = GetPropType<TypeTag, Properties::AdvectionType>;
126 using AdvectionFiller = typename AdvectionType::Cache::Filler;
127
128 // forward to the filler for the advective quantities
129 208578749 AdvectionFiller::fill(scvfFluxVarsCache, problem(), element, fvGeometry, elemVolVars, scvf, *this);
130 118662209 }
131
132 //! method to fill the diffusive quantities
133 template<class FluxVariablesCache>
134 125099828 void fillDiffusion_(FluxVariablesCache& scvfFluxVarsCache,
135 const Element& element,
136 const FVElementGeometry& fvGeometry,
137 const ElementVolumeVariables& elemVolVars,
138 const SubControlVolumeFace& scvf)
139 {
140 using DiffusionType = GetPropType<TypeTag, Properties::MolecularDiffusionType>;
141 using DiffusionFiller = typename DiffusionType::Cache::Filler;
142 using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
143
144 static constexpr int numPhases = ModelTraits::numFluidPhases();
145 static constexpr int numComponents = ModelTraits::numFluidComponents();
146
147 // forward to the filler of the diffusive quantities
148 if constexpr (FluidSystem::isTracerFluidSystem())
149
2/2
✓ Branch 0 taken 14050000 times.
✓ Branch 1 taken 14050000 times.
30672796 for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
150
2/2
✓ Branch 0 taken 28100000 times.
✓ Branch 1 taken 14050000 times.
44722796 for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx)
151 29386398 DiffusionFiller::fill(scvfFluxVarsCache, phaseIdx, compIdx, problem(), element, fvGeometry, elemVolVars, scvf, *this);
152 else
153
2/2
✓ Branch 0 taken 193672578 times.
✓ Branch 1 taken 103812454 times.
311959780 for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
154
2/2
✓ Branch 0 taken 399556612 times.
✓ Branch 1 taken 193672578 times.
614941312 for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx)
155
4/4
✓ Branch 0 taken 204270716 times.
✓ Branch 1 taken 195285896 times.
✓ Branch 2 taken 7999112 times.
✓ Branch 3 taken 3999556 times.
420030694 if (compIdx != FluidSystem::getMainComponent(phaseIdx))
156 213507868 DiffusionFiller::fill(scvfFluxVarsCache, phaseIdx, compIdx, problem(), element, fvGeometry, elemVolVars, scvf, *this);
157 125099828 }
158
159 //! method to fill the quantities related to heat conduction
160 template<class FluxVariablesCache>
161 68107128 void fillHeatConduction_(FluxVariablesCache& scvfFluxVarsCache,
162 const Element& element,
163 const FVElementGeometry& fvGeometry,
164 const ElementVolumeVariables& elemVolVars,
165 const SubControlVolumeFace& scvf)
166 {
167 using HeatConductionType = GetPropType<TypeTag, Properties::HeatConductionType>;
168 using HeatConductionFiller = typename HeatConductionType::Cache::Filler;
169
170 // forward to the filler of the diffusive quantities
171 68107128 HeatConductionFiller::fill(scvfFluxVarsCache, problem(), element, fvGeometry, elemVolVars, scvf, *this);
172 68107128 }
173
174 const Problem* problemPtr_;
175 };
176
177 //! Specialization of the flux variables cache filler for the cell centered mpfa method
178 template<class TypeTag>
179 class PorousMediumFluxVariablesCacheFillerImplementation<TypeTag, DiscretizationMethods::CCMpfa>
180 {
181 using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>;
182 using Problem = GetPropType<TypeTag, Properties::Problem>;
183 using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView;
184 using Element = typename GridView::template Codim<0>::Entity;
185 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
186
187 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
188 using FVElementGeometry = typename GridGeometry::LocalView;
189 using MpfaHelper = typename GridGeometry::MpfaHelper;
190 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
191 using Extrusion = Extrusion_t<GridGeometry>;
192 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
193 using ElementFluxVariablesCache = typename GetPropType<TypeTag, Properties::GridFluxVariablesCache>::LocalView;
194
195 using PrimaryInteractionVolume = GetPropType<TypeTag, Properties::PrimaryInteractionVolume>;
196 using PrimaryDataHandle = typename ElementFluxVariablesCache::PrimaryIvDataHandle;
197 using PrimaryLocalFaceData = typename PrimaryInteractionVolume::Traits::LocalFaceData;
198 using SecondaryInteractionVolume = GetPropType<TypeTag, Properties::SecondaryInteractionVolume>;
199 using SecondaryDataHandle = typename ElementFluxVariablesCache::SecondaryIvDataHandle;
200 using SecondaryLocalFaceData = typename SecondaryInteractionVolume::Traits::LocalFaceData;
201
202 static constexpr int dim = GridView::dimension;
203 static constexpr int dimWorld = GridView::dimensionworld;
204
205 static constexpr bool advectionEnabled = ModelTraits::enableAdvection();
206 static constexpr bool diffusionEnabled = ModelTraits::enableMolecularDiffusion();
207 static constexpr bool heatConductionEnabled = ModelTraits::enableEnergyBalance();
208
209 static constexpr bool advectionIsSolDependent = getPropValue<TypeTag, Properties::SolutionDependentAdvection>();
210 static constexpr bool diffusionIsSolDependent = getPropValue<TypeTag, Properties::SolutionDependentMolecularDiffusion>();
211 static constexpr bool heatConductionIsSolDependent = getPropValue<TypeTag, Properties::SolutionDependentHeatConduction>();
212
213 public:
214 //! This cache filler is always solution-dependent, as it updates the
215 //! vectors of cell unknowns with which the transmissibilities have to be
216 //! multiplied in order to obtain the fluxes.
217 static constexpr bool isSolDependent = true;
218
219 //! The constructor. Sets problem pointer.
220 15007789 PorousMediumFluxVariablesCacheFillerImplementation(const Problem& problem)
221 15007789 : problemPtr_(&problem) {}
222
223 /*!
224 * \brief function to fill the flux variables caches
225 *
226 * \param fluxVarsCacheStorage Class that holds the scvf flux vars caches
227 * \param scvfFluxVarsCache The flux var cache to be updated corresponding to the given scvf
228 * \param ivDataStorage Class that stores the interaction volumes & handles
229 * \param fvGeometry The finite volume geometry
230 * \param elemVolVars The element volume variables (primary/secondary variables)
231 * \param scvf The corresponding sub-control volume face
232 * \param forceUpdateAll if true, forces all caches to be updated (even the solution-independent ones)
233 */
234 template<class FluxVarsCacheStorage, class FluxVariablesCache, class IVDataStorage>
235 68046960 void fill(FluxVarsCacheStorage& fluxVarsCacheStorage,
236 FluxVariablesCache& scvfFluxVarsCache,
237 IVDataStorage& ivDataStorage,
238 const FVElementGeometry& fvGeometry,
239 const ElementVolumeVariables& elemVolVars,
240 const SubControlVolumeFace& scvf,
241 bool forceUpdateAll = false)
242 {
243 // Set pointers
244 68046960 fvGeometryPtr_ = &fvGeometry;
245
2/2
✓ Branch 0 taken 8678349 times.
✓ Branch 1 taken 32661174 times.
68046960 elemVolVarsPtr_ = &elemVolVars;
246
2/2
✓ Branch 0 taken 8678349 times.
✓ Branch 1 taken 32661174 times.
68046960 const auto& gridGeometry = fvGeometry.gridGeometry();
247
248 // 1. prepare interaction volume (iv)
249 // 2. solve for all transmissibilities and store them in data handles
250 // 3. set pointers to transmissibilities in caches of all the scvfs of the iv
251
2/2
✓ Branch 0 taken 26832 times.
✓ Branch 1 taken 235643 times.
68046960 if (gridGeometry.vertexUsesSecondaryInteractionVolume(scvf.vertexIndex()))
252 {
253
2/2
✓ Branch 0 taken 10608 times.
✓ Branch 1 taken 16224 times.
40248 if (forceUpdateAll)
254 {
255 // create new interaction volume
256 15912 const auto ivIndexInContainer = ivDataStorage.secondaryInteractionVolumes.size();
257 15912 const auto& indexSet = gridGeometry.gridInteractionVolumeIndexSets().secondaryIndexSet(scvf);
258 15912 ivDataStorage.secondaryInteractionVolumes.emplace_back();
259 15912 secondaryIv_ = &ivDataStorage.secondaryInteractionVolumes.back();
260 15912 secondaryIv_->bind(indexSet, problem(), fvGeometry);
261
262 // create the corresponding data handle
263 15912 ivDataStorage.secondaryDataHandles.emplace_back();
264 15912 secondaryIvDataHandle_ = &ivDataStorage.secondaryDataHandles.back();
265 15912 prepareDataHandle_(*secondaryIv_, *secondaryIvDataHandle_, forceUpdateAll);
266
267 // fill the caches for all the scvfs in the interaction volume
268 15912 fillCachesInInteractionVolume_<FluxVariablesCache>(fluxVarsCacheStorage, *secondaryIv_, ivIndexInContainer);
269 }
270 else
271 {
272 // get previously created interaction volume/handle
273 24336 const auto ivIndexInContainer = scvfFluxVarsCache.ivIndexInContainer();
274 24336 secondaryIv_ = &ivDataStorage.secondaryInteractionVolumes[ivIndexInContainer];
275 24336 secondaryIvDataHandle_ = &ivDataStorage.secondaryDataHandles[ivIndexInContainer];
276 24336 prepareDataHandle_(*secondaryIv_, *secondaryIvDataHandle_, forceUpdateAll);
277
278 // fill the caches for all the scvfs in the interaction volume
279 24336 fillCachesInInteractionVolume_<FluxVariablesCache>(fluxVarsCacheStorage, *secondaryIv_, ivIndexInContainer);
280 }
281 }
282
283 // primary interaction volume type
284 else
285 {
286
2/2
✓ Branch 0 taken 8698782 times.
✓ Branch 1 taken 32613909 times.
68006712 if (forceUpdateAll)
287 {
288 // create new interaction volume
289 13132810 const auto ivIndexInContainer = ivDataStorage.primaryInteractionVolumes.size();
290 13132810 const auto& indexSet = gridGeometry.gridInteractionVolumeIndexSets().primaryIndexSet(scvf);
291 13132810 ivDataStorage.primaryInteractionVolumes.emplace_back();
292 13132810 primaryIv_ = &ivDataStorage.primaryInteractionVolumes.back();
293 13132810 primaryIv_->bind(indexSet, problem(), fvGeometry);
294
295 // create the corresponding data handle
296 13132810 ivDataStorage.primaryDataHandles.emplace_back();
297 13132810 primaryIvDataHandle_ = &ivDataStorage.primaryDataHandles.back();
298 16590998 prepareDataHandle_(*primaryIv_, *primaryIvDataHandle_, forceUpdateAll);
299
300 // fill the caches for all the scvfs in the interaction volume
301 13132810 fillCachesInInteractionVolume_<FluxVariablesCache>(fluxVarsCacheStorage, *primaryIv_, ivIndexInContainer);
302 }
303 else
304 {
305 // get previously created interaction volume/handle
306 54873902 const auto ivIndexInContainer = scvfFluxVarsCache.ivIndexInContainer();
307 54873902 primaryIv_ = &ivDataStorage.primaryInteractionVolumes[ivIndexInContainer];
308 54873902 primaryIvDataHandle_ = &ivDataStorage.primaryDataHandles[ivIndexInContainer];
309 85496122 prepareDataHandle_(*primaryIv_, *primaryIvDataHandle_, forceUpdateAll);
310
311 // fill the caches for all the scvfs in the interaction volume
312 54873902 fillCachesInInteractionVolume_<FluxVariablesCache>(fluxVarsCacheStorage, *primaryIv_, ivIndexInContainer);
313 }
314 }
315 68046960 }
316
317 //! returns the stored interaction volume pointer
318 664782782 const PrimaryInteractionVolume& primaryInteractionVolume() const
319 664782782 { return *primaryIv_; }
320
321 //! returns the stored interaction volume pointer
322 317856 const SecondaryInteractionVolume& secondaryInteractionVolume() const
323 317856 { return *secondaryIv_; }
324
325 //! returns the stored data handle pointer
326 664782782 const PrimaryDataHandle& primaryIvDataHandle() const
327 664782782 { return *primaryIvDataHandle_; }
328
329 //! returns the stored data handle pointer
330 317856 const SecondaryDataHandle& secondaryIvDataHandle() const
331 317856 { return *secondaryIvDataHandle_; }
332
333 //! returns the currently stored iv-local face data object
334 3770288 const PrimaryLocalFaceData& primaryIvLocalFaceData() const
335 3770288 { return *primaryLocalFaceData_; }
336
337 //! returns the currently stored iv-local face data object
338 211904 const SecondaryLocalFaceData& secondaryIvLocalFaceData() const
339 211904 { return *secondaryLocalFaceData_; }
340
341 private:
342
343 357136596 const Problem& problem() const { return *problemPtr_; }
344 1225858246 const FVElementGeometry& fvGeometry() const { return *fvGeometryPtr_; }
345 845125168 const ElementVolumeVariables& elemVolVars() const { return *elemVolVarsPtr_; }
346
347 //! Method to fill the flux var caches within an interaction volume
348 template<class FluxVariablesCache, class FluxVarsCacheStorage, class InteractionVolume>
349 68179056 void fillCachesInInteractionVolume_(FluxVarsCacheStorage& fluxVarsCacheStorage,
350 InteractionVolume& iv,
351 unsigned int ivIndexInContainer)
352 {
353 // determine if secondary interaction volumes are used here
354 static constexpr bool isSecondary = MpfaHelper::considerSecondaryIVs()
355 && std::is_same_v<InteractionVolume, SecondaryInteractionVolume>;
356
357 // First we update data which are not dependent on the physical processes.
358 // We store pointers to the other flux var caches, so that we have to obtain
359 // this data only once and can use it again in the sub-cache fillers.
360 68179056 const auto numGlobalScvfs = iv.localFaceData().size();
361
1/2
✓ Branch 2 taken 41339523 times.
✗ Branch 3 not taken.
68179056 std::vector<const SubControlVolumeFace*> ivScvfs(numGlobalScvfs);
362
1/4
✓ Branch 1 taken 41339523 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
68179056 std::vector<FluxVariablesCache*> ivFluxVarCaches(numGlobalScvfs);
363
364 68179056 unsigned int i = 0;
365
2/2
✓ Branch 0 taken 380733078 times.
✓ Branch 1 taken 41339523 times.
718573282 for (const auto& d : iv.localFaceData())
366 {
367 // obtain the scvf
368
2/2
✓ Branch 0 taken 68631250 times.
✓ Branch 1 taken 67581854 times.
650394226 const auto& scvfJ = fvGeometry().scvf(d.gridScvfIndex());
369
2/2
✓ Branch 0 taken 68631250 times.
✓ Branch 1 taken 67581854 times.
650394226 ivScvfs[i] = &scvfJ;
370 650394226 ivFluxVarCaches[i] = &fluxVarsCacheStorage[scvfJ];
371
2/2
✓ Branch 0 taken 81885708 times.
✓ Branch 1 taken 84924548 times.
650394226 ivFluxVarCaches[i]->setIvIndexInContainer(ivIndexInContainer);
372
2/2
✓ Branch 0 taken 81885708 times.
✓ Branch 1 taken 84924548 times.
650394226 ivFluxVarCaches[i]->setUpdateStatus(true);
373
2/2
✓ Branch 0 taken 81885708 times.
✓ Branch 1 taken 84924548 times.
650394226 ivFluxVarCaches[i]->setSecondaryIvUsage(isSecondary);
374
2/2
✓ Branch 0 taken 81885708 times.
✓ Branch 1 taken 84924548 times.
650394226 ivFluxVarCaches[i]->setIvLocalFaceIndex(d.ivLocalScvfIndex());
375 if (dim < dimWorld)
376
2/2
✓ Branch 0 taken 81885708 times.
✓ Branch 1 taken 84924548 times.
310812320 if (d.isOutsideFace())
377 153214870 ivFluxVarCaches[i]->setIndexInOutsideFaces(d.scvfLocalOutsideScvfIndex());
378 650394226 i++;
379 }
380
381 if constexpr (advectionEnabled)
382
1/2
✓ Branch 0 taken 18140190 times.
✗ Branch 1 not taken.
68830224 fillAdvection_(iv, ivScvfs, ivFluxVarCaches);
383 if constexpr (diffusionEnabled)
384
1/2
✓ Branch 1 taken 19047261 times.
✗ Branch 2 not taken.
34250962 fillDiffusion_(iv, ivScvfs, ivFluxVarCaches);
385 if constexpr (heatConductionEnabled)
386
1/2
✓ Branch 0 taken 4152072 times.
✗ Branch 1 not taken.
4387592 fillHeatConduction_(iv, ivScvfs, ivFluxVarCaches);
387 136358112 }
388
389 //! fills the advective quantities (enabled advection)
390 template<class InteractionVolume, class FluxVariablesCache>
391 524950 void fillAdvection_(InteractionVolume& iv,
392 const std::vector<const SubControlVolumeFace*>& ivScvfs,
393 const std::vector<FluxVariablesCache*>& ivFluxVarCaches)
394 {
395 using AdvectionType = GetPropType<TypeTag, Properties::AdvectionType>;
396 using AdvectionFiller = typename AdvectionType::Cache::Filler;
397
398 // fill advection caches
399
4/4
✓ Branch 0 taken 162523338 times.
✓ Branch 1 taken 20296069 times.
✓ Branch 2 taken 218209740 times.
✓ Branch 3 taken 21043454 times.
424326172 for (unsigned int i = 0; i < iv.localFaceData().size(); ++i)
400 {
401 // set pointer to current local face data object
402 // ifs are evaluated at compile time and are optimized away
403 if (std::is_same_v<PrimaryInteractionVolume, SecondaryInteractionVolume>)
404 {
405 // we cannot make a distinction, thus we set both pointers
406 378741982 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
407 378741982 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
408 }
409 else if (std::is_same_v<InteractionVolume, PrimaryInteractionVolume>)
410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1885144 times.
3770288 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
411 else
412
1/2
✓ Branch 0 taken 105952 times.
✗ Branch 1 not taken.
211904 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
413
414 // fill this scvfs cache
415 381487590 AdvectionFiller::fill(*ivFluxVarCaches[i],
416
2/2
✓ Branch 0 taken 105952 times.
✓ Branch 1 taken 1885144 times.
3982192 problem(),
417 3982192 iv.element(iv.localFaceData()[i].ivLocalInsideScvIndex()),
418 3982192 fvGeometry(),
419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1885144 times.
3982192 elemVolVars(),
420
2/2
✓ Branch 0 taken 105952 times.
✓ Branch 1 taken 1885144 times.
323885630 *ivScvfs[i],
421 *this);
422 }
423 524950 }
424
425 //! fills the diffusive quantities (diffusion enabled)
426 template<class InteractionVolume, class FluxVariablesCache>
427 23298608 void fillDiffusion_(InteractionVolume& iv,
428 const std::vector<const SubControlVolumeFace*>& ivScvfs,
429 const std::vector<FluxVariablesCache*>& ivFluxVarCaches)
430 {
431 using DiffusionType = GetPropType<TypeTag, Properties::MolecularDiffusionType>;
432 using DiffusionFiller = typename DiffusionType::Cache::Filler;
433
434 static constexpr int numPhases = ModelTraits::numFluidPhases();
435 static constexpr int numComponents = ModelTraits::numFluidComponents();
436
437
2/2
✓ Branch 0 taken 37768317 times.
✓ Branch 1 taken 23036133 times.
61591875 for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
438 {
439
2/2
✓ Branch 0 taken 75536634 times.
✓ Branch 1 taken 37768317 times.
114879801 for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx)
440 {
441 using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
442 if constexpr (!FluidSystem::isTracerFluidSystem())
443
2/2
✓ Branch 0 taken 34568560 times.
✓ Branch 1 taken 34568560 times.
70187020 if (compIdx == FluidSystem::getMainComponent(phaseIdx))
444 35093510 continue;
445
446 // fill diffusion caches
447
2/2
✓ Branch 0 taken 314682336 times.
✓ Branch 1 taken 40968074 times.
360157552 for (unsigned int i = 0; i < iv.localFaceData().size(); ++i)
448 {
449 // set pointer to current local face data object
450 // ifs are evaluated at compile time and are optimized away
451 if constexpr (std::is_same_v<PrimaryInteractionVolume, SecondaryInteractionVolume>)
452 {
453 // we cannot make a distinction, thus we set both pointers
454 310700144 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
455 310700144 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
456 }
457 else if constexpr (std::is_same_v<InteractionVolume, PrimaryInteractionVolume>)
458 7540576 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
459 else
460 423808 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
461
462 // fill this scvfs cache
463 318664528 DiffusionFiller::fill(*ivFluxVarCaches[i],
464 phaseIdx,
465 compIdx,
466 318664528 problem(),
467 318664528 iv.element(iv.localFaceData()[i].ivLocalInsideScvIndex()),
468 318664528 fvGeometry(),
469 318664528 elemVolVars(),
470 318664528 *ivScvfs[i],
471 *this);
472 }
473 }
474 }
475 23298608 }
476
477 //! fills the quantities related to heat conduction (heat conduction enabled)
478 template<class InteractionVolume, class FluxVariablesCache>
479 3988872 void fillHeatConduction_(InteractionVolume& iv,
480 const std::vector<const SubControlVolumeFace*>& ivScvfs,
481 const std::vector<FluxVariablesCache*>& ivFluxVarCaches)
482 {
483 using HeatConductionType = GetPropType<TypeTag, Properties::HeatConductionType>;
484 using HeatConductionFiller = typename HeatConductionType::Cache::Filler;
485
486 // fill heat conduction caches
487
3/5
✓ Branch 1 taken 28035800 times.
✓ Branch 2 taken 3988872 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 0 taken 651168 times.
32675840 for (unsigned int i = 0; i < iv.localFaceData().size(); ++i)
488 {
489 // set pointer to current local face data object
490 // ifs are evaluated at compile time and are optimized away
491 if constexpr (std::is_same_v<PrimaryInteractionVolume, SecondaryInteractionVolume>)
492 {
493 // we cannot make a distinction, thus we set both pointers
494 28523768 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
495 28523768 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
496 }
497 else if constexpr (std::is_same_v<InteractionVolume, PrimaryInteractionVolume>)
498 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
499 else
500 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
501
502 // fill this scvfs cache
503 28523768 HeatConductionFiller::fill(*ivFluxVarCaches[i],
504 problem(),
505 iv.element(iv.localFaceData()[i].ivLocalInsideScvIndex()),
506 fvGeometry(),
507 elemVolVars(),
508 28523768 *ivScvfs[i],
509 *this);
510 }
511 }
512
513 //! Solves the local systems and stores the result in the handles
514 template< class InteractionVolume, class DataHandle>
515 38559998 void prepareDataHandle_([[maybe_unused]] InteractionVolume& iv, [[maybe_unused]] DataHandle& handle, [[maybe_unused]] bool forceUpdate)
516 {
517 // (maybe) solve system subject to intrinsic permeability
518 if constexpr (advectionEnabled)
519 {
520 using AdvectionType = GetPropType<TypeTag, Properties::AdvectionType>;
521 if constexpr (AdvectionType::discMethod == DiscretizationMethods::ccmpfa)
522 35360241 prepareAdvectionHandle_(iv, handle, forceUpdate);
523 }
524
525 // (maybe) solve system subject to diffusion tensors
526 if constexpr (diffusionEnabled)
527 {
528 using DiffusionType = GetPropType<TypeTag, Properties::MolecularDiffusionType>;
529 if constexpr (DiffusionType::discMethod == DiscretizationMethods::ccmpfa)
530 23298608 prepareDiffusionHandles_(iv, handle, forceUpdate);
531 }
532
533 // (maybe) solve system subject to thermal conductivity
534 if constexpr (heatConductionEnabled)
535 {
536 using HeatConductionType = GetPropType<TypeTag, Properties::HeatConductionType>;
537 if constexpr (HeatConductionType::discMethod == DiscretizationMethods::ccmpfa)
538 4152072 prepareHeatConductionHandle_(iv, handle, forceUpdate);
539 }
540 20262051 }
541
542 //! prepares the quantities necessary for advective fluxes in the handle
543 template<class InteractionVolume, class DataHandle>
544 35360241 void prepareAdvectionHandle_(InteractionVolume& iv, DataHandle& handle, bool forceUpdateAll)
545 {
546 // get instance of the interaction volume-local assembler
547 using Traits = typename InteractionVolume::Traits;
548 using IvLocalAssembler = typename Traits::template LocalAssembler<Problem, FVElementGeometry, ElementVolumeVariables>;
549
2/2
✓ Branch 0 taken 2802998 times.
✓ Branch 1 taken 23687223 times.
35360241 IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
550
551 // lambda to obtain the permeability tensor
552
1/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 4 taken 14395352 times.
✗ Branch 5 not taken.
90216858 auto getK = [] (const auto& volVars) { return volVars.permeability(); };
553
554 // Assemble T only if permeability is sol-dependent or if update is forced
555
2/2
✓ Branch 0 taken 2802998 times.
✓ Branch 1 taken 23687223 times.
26490221 if (forceUpdateAll || advectionIsSolDependent)
556 11673018 localAssembler.assembleMatrices(handle.advectionHandle(), iv, getK);
557
558 // assemble pressure vectors
559
2/2
✓ Branch 0 taken 63537512 times.
✓ Branch 1 taken 35097766 times.
99422703 for (unsigned int pIdx = 0; pIdx < ModelTraits::numFluidPhases(); ++pIdx)
560 {
561 // set context in handle
562
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 63537467 times.
64062462 handle.advectionHandle().setPhaseIndex(pIdx);
563
564 // maybe (re-)assemble gravity contribution vector
565
4/4
✓ Branch 0 taken 208920570 times.
✓ Branch 1 taken 4170020 times.
✓ Branch 2 taken 52288 times.
✓ Branch 3 taken 86000 times.
425434628 auto getRho = [pIdx] (const auto& volVars) { return volVars.density(pIdx); };
566
4/6
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 63537467 times.
✓ Branch 3 taken 45 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 45 times.
✗ Branch 7 not taken.
64062462 static const bool enableGravity = getParamFromGroup<bool>(problem().paramGroup(), "Problem.EnableGravity");
567
2/2
✓ Branch 0 taken 46753812 times.
✓ Branch 1 taken 16783700 times.
64062462 if (enableGravity)
568 47278762 localAssembler.assembleGravity(handle.advectionHandle(), iv, getRho);
569
570 // reassemble pressure vector
571 354247203 auto getPressure = [pIdx] (const auto& volVars) { return volVars.pressure(pIdx); };
572 64062462 localAssembler.assembleU(handle.advectionHandle(), iv, getPressure);
573 }
574 35360241 }
575
576 //! prepares the quantities necessary for diffusive fluxes in the handle
577 template<class InteractionVolume, class DataHandle>
578 23298608 void prepareDiffusionHandles_(InteractionVolume& iv,
579 DataHandle& handle,
580 bool forceUpdateAll)
581 {
582
2/2
✓ Branch 0 taken 37768317 times.
✓ Branch 1 taken 23036133 times.
61591875 for (unsigned int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
583 {
584
2/2
✓ Branch 0 taken 75536634 times.
✓ Branch 1 taken 37768317 times.
114879801 for (unsigned int compIdx = 0; compIdx < ModelTraits::numFluidComponents(); ++compIdx)
585 {
586 // skip main component
587 using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
588 if constexpr (!FluidSystem::isTracerFluidSystem())
589
2/2
✓ Branch 0 taken 34568560 times.
✓ Branch 1 taken 34568560 times.
70187020 if (compIdx == FluidSystem::getMainComponent(phaseIdx))
590 35093510 continue;
591
592 // fill data in the handle
593
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 40968074 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 40968058 times.
41493024 handle.diffusionHandle().setPhaseIndex(phaseIdx);
594
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 40968058 times.
41493024 handle.diffusionHandle().setComponentIndex(compIdx);
595
596 using DiffusionType = GetPropType<TypeTag, Properties::MolecularDiffusionType>;
597
598 // get instance of the interaction volume-local assembler
599 using Traits = typename InteractionVolume::Traits;
600 using IvLocalAssembler = typename Traits::template LocalAssembler<Problem, FVElementGeometry, ElementVolumeVariables>;
601
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 40968058 times.
41493024 IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
602
603 // maybe (re-)assemble matrices
604 if (forceUpdateAll || diffusionIsSolDependent)
605 {
606 // lambda to obtain diffusion coefficient
607 360364704 const auto getD = [&](const auto& volVars)
608 {
609 if constexpr (FluidSystem::isTracerFluidSystem())
610 44793088 return volVars.effectiveDiffusionCoefficient(0, 0, compIdx);
611 else
612
1/4
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 11242416 times.
✗ Branch 7 not taken.
274078592 return volVars.effectiveDiffusionCoefficient(phaseIdx, FluidSystem::getMainComponent(phaseIdx), compIdx);
613 };
614
615 // Effective diffusion coefficients might be zero if saturation = 0.
616 // Compute epsilon to detect obsolete rows in the iv-local matrices during assembly
617
4/6
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 40968058 times.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 16 times.
✗ Branch 7 not taken.
41493024 static const auto zeroD = getParamFromGroup<Scalar>(
618 20 problem().paramGroup(),
619 "Mpfa.ZeroEffectiveDiffusionCoefficientThreshold",
620
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
40 1e-16
621 );
622
623 // compute a representative transmissibility for this interaction volume, using
624 // the threshold for zero diffusion coefficients, and use this as epsilon
625
2/2
✓ Branch 0 taken 1505211 times.
✓ Branch 1 taken 3627653 times.
41493024 const auto& scv = fvGeometry().scv(iv.localScv(0).gridScvIndex());
626 41493024 const auto& scvf = fvGeometry().scvf(iv.localScvf(0).gridScvfIndex());
627 41493024 const auto& vv = elemVolVars()[scv];
628
1/2
✓ Branch 1 taken 471286 times.
✗ Branch 2 not taken.
41493024 const auto eps = Extrusion::area(fvGeometry(), scvf)*computeTpfaTransmissibility(
629
1/2
✓ Branch 1 taken 471286 times.
✗ Branch 2 not taken.
41493024 fvGeometry(), scvf, scv, zeroD, vv.extrusionFactor()
630 );
631
632
1/2
✓ Branch 1 taken 471286 times.
✗ Branch 2 not taken.
41493024 localAssembler.assembleMatrices(handle.diffusionHandle(), iv, getD, eps);
633 }
634
635 // assemble vector of mole fractions
636 200814444 auto getMassOrMoleFraction = [phaseIdx, compIdx] (const auto& volVars)
637 {
638 159321420 return (DiffusionType::referenceSystemFormulation() == ReferenceSystemFormulation::massAveraged) ? volVars.massFraction(phaseIdx, compIdx) :
639 115030252 volVars.moleFraction(phaseIdx, compIdx);
640 };
641
642 41493024 localAssembler.assembleU(handle.diffusionHandle(), iv, getMassOrMoleFraction);
643 }
644 }
645 23298608 }
646
647 //! prepares the quantities necessary for conductive fluxes in the handle
648 template<class InteractionVolume, class DataHandle>
649 4152072 void prepareHeatConductionHandle_(InteractionVolume& iv, DataHandle& handle, bool forceUpdateAll)
650 {
651 // get instance of the interaction volume-local assembler
652 using Traits = typename InteractionVolume::Traits;
653 using IvLocalAssembler = typename Traits::template LocalAssembler<Problem, FVElementGeometry, ElementVolumeVariables>;
654 4152072 IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
655
656 // lambda to obtain the effective thermal conductivity
657
1/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 4 taken 8974686 times.
✗ Branch 5 not taken.
31702112 auto getLambda = [] (const auto& volVars) { return volVars.effectiveThermalConductivity(); };
658
659 // maybe (re-)assemble matrices
660 if (forceUpdateAll || heatConductionIsSolDependent)
661 4152072 localAssembler.assembleMatrices(handle.heatConductionHandle(), iv, getLambda);
662
663 // assemble vector of temperatures
664 15248822 auto getTemperature = [] (const auto& volVars) { return volVars.temperature(); };
665 4152072 localAssembler.assembleU(handle.heatConductionHandle(), iv, getTemperature);
666 4152072 }
667
668 const Problem* problemPtr_;
669 const FVElementGeometry* fvGeometryPtr_;
670 const ElementVolumeVariables* elemVolVarsPtr_;
671
672 // We store pointers to an inner and a boundary interaction volume.
673 // These are updated during the filling of the caches and the
674 // physics-related caches have access to them
675 PrimaryInteractionVolume* primaryIv_;
676 SecondaryInteractionVolume* secondaryIv_;
677
678 // pointer to the current interaction volume data handle
679 PrimaryDataHandle* primaryIvDataHandle_;
680 SecondaryDataHandle* secondaryIvDataHandle_;
681
682 // We do an interaction volume-wise filling of the caches
683 // While filling, we store a pointer to the current localScvf
684 // face data object of the IV so that the individual caches
685 // can access it and don't have to retrieve it again
686 const PrimaryLocalFaceData* primaryLocalFaceData_;
687 const SecondaryLocalFaceData* secondaryLocalFaceData_;
688 };
689
690 } // end namespace Dumux
691
692 #endif
693