GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/porousmediumflow/fluxvariablescachefiller.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 160 182 87.9%
Functions: 322 734 43.9%
Branches: 137 167 82.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-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 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 33108446 PorousMediumFluxVariablesCacheFillerImplementation(const Problem& problem)
69 34222446 : 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 249296541 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 91769185 times.
✓ Branch 1 taken 144379494 times.
✓ Branch 2 taken 5620998 times.
✓ Branch 3 taken 5000000 times.
✓ Branch 4 taken 48000 times.
✗ Branch 5 not taken.
260041187 if (forceUpdateAll)
93 {
94 if constexpr (advectionEnabled)
95 128419827 fillAdvection_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
96 if constexpr (diffusionEnabled)
97 39484770 fillDiffusion_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
98 if constexpr (heatConductionEnabled)
99 15531118 fillHeatConduction_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
100 }
101 else
102 {
103 if constexpr (advectionEnabled && advectionIsSolDependent)
104 198964734 fillAdvection_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
105 if constexpr (diffusionEnabled && diffusionIsSolDependent)
106 144746256 fillDiffusion_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
107 if constexpr (heatConductionEnabled && heatConductionIsSolDependent)
108 55037498 fillHeatConduction_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
109 }
110 249296541 }
111
112 private:
113
114 const Problem& problem() const
115 { return *problemPtr_; }
116
117 //! method to fill the advective quantities
118 template<class FluxVariablesCache>
119 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 224850471 AdvectionFiller::fill(scvfFluxVarsCache, problem(), element, fvGeometry, elemVolVars, scvf, *this);
130 }
131
132 //! method to fill the diffusive quantities
133 template<class FluxVariablesCache>
134 122658136 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 15336398 times.
✓ Branch 1 taken 15336398 times.
30775736 for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
150
2/2
✓ Branch 0 taken 15336398 times.
✓ Branch 1 taken 29386398 times.
44825736 for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx)
151 29437868 DiffusionFiller::fill(scvfFluxVarsCache, phaseIdx, compIdx, problem(), element, fvGeometry, elemVolVars, scvf, *this);
152 else
153
2/2
✓ Branch 0 taken 191770006 times.
✓ Branch 1 taken 101913460 times.
306320974 for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
154
2/2
✓ Branch 0 taken 380746954 times.
✓ Branch 1 taken 206742996 times.
603560374 for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx)
155
4/4
✓ Branch 0 taken 202352382 times.
✓ Branch 1 taken 193367562 times.
✓ Branch 2 taken 8003864 times.
✓ Branch 3 taken 4001932 times.
412436458 if (compIdx != FluidSystem::getMainComponent(phaseIdx))
156 209710156 DiffusionFiller::fill(scvfFluxVarsCache, phaseIdx, compIdx, problem(), element, fvGeometry, elemVolVars, scvf, *this);
157 122658136 }
158
159 //! method to fill the quantities related to heat conduction
160 template<class FluxVariablesCache>
161 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 69292338 HeatConductionFiller::fill(scvfFluxVarsCache, problem(), element, fvGeometry, elemVolVars, scvf, *this);
172 }
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 14717628 PorousMediumFluxVariablesCacheFillerImplementation(const Problem& problem)
221 14717628 : 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 66886440 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 66886440 fvGeometryPtr_ = &fvGeometry;
245 66886440 elemVolVarsPtr_ = &elemVolVars;
246 66886440 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
4/4
✓ Branch 0 taken 26832 times.
✓ Branch 1 taken 235643 times.
✓ Branch 2 taken 26832 times.
✓ Branch 3 taken 235643 times.
67279294 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 31824 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 8515702 times.
✓ Branch 1 taken 31676149 times.
66846192 if (forceUpdateAll)
287 {
288 // create new interaction volume
289 12939810 const auto ivIndexInContainer = ivDataStorage.primaryInteractionVolumes.size();
290 25879620 const auto& indexSet = gridGeometry.gridInteractionVolumeIndexSets().primaryIndexSet(scvf);
291 12939810 ivDataStorage.primaryInteractionVolumes.emplace_back();
292 12939810 primaryIv_ = &ivDataStorage.primaryInteractionVolumes.back();
293 12939810 primaryIv_->bind(indexSet, problem(), fvGeometry);
294
295 // create the corresponding data handle
296 12939810 ivDataStorage.primaryDataHandles.emplace_back();
297 12939810 primaryIvDataHandle_ = &ivDataStorage.primaryDataHandles.back();
298 16397998 prepareDataHandle_(*primaryIv_, *primaryIvDataHandle_, forceUpdateAll);
299
300 // fill the caches for all the scvfs in the interaction volume
301 12939810 fillCachesInInteractionVolume_<FluxVariablesCache>(fluxVarsCacheStorage, *primaryIv_, ivIndexInContainer);
302 }
303 else
304 {
305 // get previously created interaction volume/handle
306 53906382 const auto ivIndexInContainer = scvfFluxVarsCache.ivIndexInContainer();
307 53906382 primaryIv_ = &ivDataStorage.primaryInteractionVolumes[ivIndexInContainer];
308 53906382 primaryIvDataHandle_ = &ivDataStorage.primaryDataHandles[ivIndexInContainer];
309 84528602 prepareDataHandle_(*primaryIv_, *primaryIvDataHandle_, forceUpdateAll);
310
311 // fill the caches for all the scvfs in the interaction volume
312 53906382 fillCachesInInteractionVolume_<FluxVariablesCache>(fluxVarsCacheStorage, *primaryIv_, ivIndexInContainer);
313 }
314 }
315 66886440 }
316
317 //! returns the stored interaction volume pointer
318 const PrimaryInteractionVolume& primaryInteractionVolume() const
319 { return *primaryIv_; }
320
321 //! returns the stored interaction volume pointer
322 const SecondaryInteractionVolume& secondaryInteractionVolume() const
323 { return *secondaryIv_; }
324
325 //! returns the stored data handle pointer
326 const PrimaryDataHandle& primaryIvDataHandle() const
327 { return *primaryIvDataHandle_; }
328
329 //! returns the stored data handle pointer
330 const SecondaryDataHandle& secondaryIvDataHandle() const
331 { return *secondaryIvDataHandle_; }
332
333 //! returns the currently stored iv-local face data object
334 const PrimaryLocalFaceData& primaryIvLocalFaceData() const
335 { return *primaryLocalFaceData_; }
336
337 //! returns the currently stored iv-local face data object
338 const SecondaryLocalFaceData& secondaryIvLocalFaceData() const
339 { return *secondaryLocalFaceData_; }
340
341 private:
342
343 const Problem& problem() const { return *problemPtr_; }
344 const FVElementGeometry& fvGeometry() const { return *fvGeometryPtr_; }
345 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 67018536 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 133565786 const auto numGlobalScvfs = iv.localFaceData().size();
361 134037072 std::vector<const SubControlVolumeFace*> ivScvfs(numGlobalScvfs);
362
3/8
✓ Branch 1 taken 40218683 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40218683 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 40218683 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
201055608 std::vector<FluxVariablesCache*> ivFluxVarCaches(numGlobalScvfs);
363
364 67018536 unsigned int i = 0;
365
4/4
✓ Branch 0 taken 319724395 times.
✓ Branch 1 taken 92815470 times.
✓ Branch 2 taken 317839251 times.
✓ Branch 3 taken 92579827 times.
1547953060 for (const auto& d : iv.localFaceData())
366 {
367 // obtain the scvf
368
2/2
✓ Branch 0 taken 68631250 times.
✓ Branch 1 taken 67581854 times.
641824602 const auto& scvfJ = fvGeometry().scvf(d.gridScvfIndex());
369
2/2
✓ Branch 0 taken 68631250 times.
✓ Branch 1 taken 67581854 times.
641824602 ivScvfs[i] = &scvfJ;
370
4/4
✓ Branch 0 taken 68631250 times.
✓ Branch 1 taken 77108082 times.
✓ Branch 2 taken 81605734 times.
✓ Branch 3 taken 67581854 times.
1077642322 ivFluxVarCaches[i] = &fluxVarsCacheStorage[scvfJ];
371
2/2
✓ Branch 0 taken 78157478 times.
✓ Branch 1 taken 80556338 times.
641824602 ivFluxVarCaches[i]->setIvIndexInContainer(ivIndexInContainer);
372
2/2
✓ Branch 0 taken 78157478 times.
✓ Branch 1 taken 80556338 times.
641824602 ivFluxVarCaches[i]->setUpdateStatus(true);
373
2/2
✓ Branch 0 taken 78157478 times.
✓ Branch 1 taken 80556338 times.
641824602 ivFluxVarCaches[i]->setSecondaryIvUsage(isSecondary);
374
2/2
✓ Branch 0 taken 78157478 times.
✓ Branch 1 taken 80556338 times.
641824602 ivFluxVarCaches[i]->setIvLocalFaceIndex(d.ivLocalScvfIndex());
375 if (dim < dimWorld)
376
2/2
✓ Branch 0 taken 78157478 times.
✓ Branch 1 taken 80556338 times.
302715880 if (d.isOutsideFace())
377 149486640 ivFluxVarCaches[i]->setIndexInOutsideFaces(d.scvfLocalOutsideScvfIndex());
378 641824602 i++;
379 }
380
381 if constexpr (advectionEnabled)
382
2/3
✓ Branch 0 taken 3042000 times.
✓ Branch 1 taken 15098190 times.
✗ Branch 2 not taken.
67018536 fillAdvection_(iv, ivScvfs, ivFluxVarCaches);
383 if constexpr (diffusionEnabled)
384
1/2
✓ Branch 1 taken 19047261 times.
✗ Branch 2 not taken.
33090442 fillDiffusion_(iv, ivScvfs, ivFluxVarCaches);
385 if constexpr (heatConductionEnabled)
386
1/2
✓ Branch 1 taken 3031232 times.
✗ Branch 2 not taken.
3227072 fillHeatConduction_(iv, ivScvfs, ivFluxVarCaches);
387 67018536 }
388
389 //! fills the advective quantities (enabled advection)
390 template<class InteractionVolume, class FluxVariablesCache>
391 34239401 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
12/12
✓ Branch 0 taken 351857390 times.
✓ Branch 1 taken 37713258 times.
✓ Branch 2 taken 351857390 times.
✓ Branch 3 taken 37713258 times.
✓ Branch 4 taken 349972246 times.
✓ Branch 5 taken 37477615 times.
✓ Branch 6 taken 20463792 times.
✓ Branch 7 taken 2505425 times.
✓ Branch 8 taken 20463792 times.
✓ Branch 9 taken 2505425 times.
✓ Branch 10 taken 20463792 times.
✓ Branch 11 taken 2505425 times.
1167937122 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 740660172 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
407 740660172 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
408 }
409 else if (std::is_same_v<InteractionVolume, PrimaryInteractionVolume>)
410 7540576 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
411 else
412 423808 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
413
414 // fill this scvfs cache
415 1060116098 AdvectionFiller::fill(*ivFluxVarCaches[i],
416 problem(),
417 748624556 iv.element(iv.localFaceData()[i].ivLocalInsideScvIndex()),
418 fvGeometry(),
419 elemVolVars(),
420 748624556 *ivScvfs[i],
421 *this);
422 }
423 34239401 }
424
425 //! fills the diffusive quantities (diffusion enabled)
426 template<class InteractionVolume, class FluxVariablesCache>
427 22177768 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 36647477 times.
✓ Branch 1 taken 21915293 times.
59350195 for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
438 {
439
2/2
✓ Branch 0 taken 66111845 times.
✓ Branch 1 taken 43830586 times.
111517281 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 33447720 times.
✓ Branch 1 taken 33447720 times.
67945340 if (compIdx == FluidSystem::getMainComponent(phaseIdx))
444 continue;
445
446 // fill diffusion caches
447
6/6
✓ Branch 0 taken 306270440 times.
✓ Branch 1 taken 39847234 times.
✓ Branch 2 taken 306270440 times.
✓ Branch 3 taken 39847234 times.
✓ Branch 4 taken 302500152 times.
✓ Branch 5 taken 39375948 times.
1035003108 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 604576496 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
455 604576496 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
456 }
457 else if constexpr (std::is_same_v<InteractionVolume, PrimaryInteractionVolume>)
458 15081152 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
459 else
460 847616 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
461
462 // fill this scvfs cache
463 922793512 DiffusionFiller::fill(*ivFluxVarCaches[i],
464 phaseIdx,
465 compIdx,
466 problem(),
467 620505264 iv.element(iv.localFaceData()[i].ivLocalInsideScvIndex()),
468 fvGeometry(),
469 elemVolVars(),
470 620505264 *ivScvfs[i],
471 *this);
472 }
473 }
474 }
475 22177768 }
476
477 //! fills the quantities related to heat conduction (heat conduction enabled)
478 template<class InteractionVolume, class FluxVariablesCache>
479 3031232 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
6/6
✓ Branch 0 taken 20111872 times.
✓ Branch 1 taken 3031232 times.
✓ Branch 2 taken 20111872 times.
✓ Branch 3 taken 3031232 times.
✓ Branch 4 taken 20111872 times.
✓ Branch 5 taken 3031232 times.
63366848 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 40223744 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
495 40223744 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 60335616 HeatConductionFiller::fill(*ivFluxVarCaches[i],
504 problem(),
505 40223744 iv.element(iv.localFaceData()[i].ivLocalInsideScvIndex()),
506 fvGeometry(),
507 elemVolVars(),
508 40223744 *ivScvfs[i],
509 *this);
510 }
511 3031232 }
512
513 //! Solves the local systems and stores the result in the handles
514 template< class InteractionVolume, class DataHandle>
515 19141211 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 34239401 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 22177768 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 3031232 prepareHeatConductionHandle_(iv, handle, forceUpdate);
539 }
540 19141211 }
541
542 //! prepares the quantities necessary for advective fluxes in the handle
543 template<class InteractionVolume, class DataHandle>
544 34239401 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.
34239401 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 10027142 times.
✗ Branch 5 not taken.
80758202 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 21104356 localAssembler.assembleMatrices(handle.advectionHandle(), iv, getK);
557
558 // assemble pressure vectors
559
2/2
✓ Branch 0 taken 62416672 times.
✓ Branch 1 taken 33976926 times.
97181023 for (unsigned int pIdx = 0; pIdx < ModelTraits::numFluidPhases(); ++pIdx)
560 {
561 // set context in handle
562
4/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 62416620 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 62416620 times.
125883244 handle.advectionHandle().setPhaseIndex(pIdx);
563
564 // maybe (re-)assemble gravity contribution vector
565
8/8
✓ Branch 0 taken 208920570 times.
✓ Branch 1 taken 4170020 times.
✓ Branch 2 taken 208920570 times.
✓ Branch 3 taken 4170020 times.
✓ Branch 4 taken 52288 times.
✓ Branch 5 taken 86000 times.
✓ Branch 6 taken 52288 times.
✓ Branch 7 taken 86000 times.
849819356 auto getRho = [pIdx] (const auto& volVars) { return volVars.density(pIdx); };
566
6/8
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 62416620 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 7 times.
✓ Branch 6 taken 45 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 45 times.
✗ Branch 10 not taken.
62941622 static const bool enableGravity = getParamFromGroup<bool>(problem().paramGroup(), "Problem.EnableGravity");
567
2/2
✓ Branch 0 taken 46753812 times.
✓ Branch 1 taken 15662860 times.
62941622 if (enableGravity)
568 89879084 localAssembler.assembleGravity(handle.advectionHandle(), iv, getRho);
569
570 // reassemble pressure vector
571 593828918 auto getPressure = [pIdx] (const auto& volVars) { return volVars.pressure(pIdx); };
572 116857768 localAssembler.assembleU(handle.advectionHandle(), iv, getPressure);
573 }
574 34239401 }
575
576 //! prepares the quantities necessary for diffusive fluxes in the handle
577 template<class InteractionVolume, class DataHandle>
578 22177768 void prepareDiffusionHandles_(InteractionVolume& iv,
579 DataHandle& handle,
580 bool forceUpdateAll)
581 {
582
2/2
✓ Branch 0 taken 36647477 times.
✓ Branch 1 taken 21915293 times.
59350195 for (unsigned int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
583 {
584
2/2
✓ Branch 0 taken 73294954 times.
✓ Branch 1 taken 36647477 times.
111517281 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 33447720 times.
✓ Branch 1 taken 33447720 times.
67945340 if (compIdx == FluidSystem::getMainComponent(phaseIdx))
590 33972670 continue;
591
592 // fill data in the handle
593
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 39847234 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 39847234 times.
80744368 handle.diffusionHandle().setPhaseIndex(phaseIdx);
594
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 39847218 times.
40372184 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 39847218 times.
40372184 IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
602
603 // maybe (re-)assemble matrices
604 if (forceUpdateAll || diffusionIsSolDependent)
605 {
606 // lambda to obtain diffusion coefficient
607 40372184 const auto getD = [&](const auto& volVars)
608 {
609 if constexpr (FluidSystem::isTracerFluidSystem())
610 89586176 return volVars.effectiveDiffusionCoefficient(0, 0, compIdx);
611 else
612
1/4
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 6874206 times.
✗ Branch 7 not taken.
264619936 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 39847218 times.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 16 times.
✗ Branch 7 not taken.
40372184 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
4/4
✓ Branch 0 taken 1209628 times.
✓ Branch 1 taken 2842076 times.
✓ Branch 2 taken 1209628 times.
✓ Branch 3 taken 2842076 times.
80744368 const auto& scv = fvGeometry().scv(iv.localScv(0).gridScvIndex());
626 80744368 const auto& scvf = fvGeometry().scvf(iv.localScvf(0).gridScvfIndex());
627 40372184 const auto& vv = elemVolVars()[scv];
628 80744368 const auto eps = Extrusion::area(fvGeometry(), scvf)*computeTpfaTransmissibility(
629 fvGeometry(), scvf, scv, zeroD, vv.extrusionFactor()
630 );
631
632
1/2
✓ Branch 1 taken 39847234 times.
✗ Branch 2 not taken.
40372184 localAssembler.assembleMatrices(handle.diffusionHandle(), iv, getD, eps);
633 }
634
635 // assemble vector of mole fractions
636 78121798 auto getMassOrMoleFraction = [phaseIdx, compIdx] (const auto& volVars)
637 {
638 177510594 return (DiffusionType::referenceSystemFormulation() == ReferenceSystemFormulation::massAveraged) ? volVars.massFraction(phaseIdx, compIdx) :
639 volVars.moleFraction(phaseIdx, compIdx);
640 };
641
642
1/2
✓ Branch 1 taken 39375948 times.
✗ Branch 2 not taken.
40372184 localAssembler.assembleU(handle.diffusionHandle(), iv, getMassOrMoleFraction);
643 }
644 }
645 22177768 }
646
647 //! prepares the quantities necessary for conductive fluxes in the handle
648 template<class InteractionVolume, class DataHandle>
649 3031232 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 3031232 IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
655
656 // lambda to obtain the effective thermal conductivity
657
2/8
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 7 taken 4606476 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4606476 times.
✗ Branch 11 not taken.
44486912 auto getLambda = [] (const auto& volVars) { return volVars.effectiveThermalConductivity(); };
658
659 // maybe (re-)assemble matrices
660 if (forceUpdateAll || heatConductionIsSolDependent)
661 6062464 localAssembler.assembleMatrices(handle.heatConductionHandle(), iv, getLambda);
662
663 // assemble vector of temperatures
664 21439384 auto getTemperature = [] (const auto& volVars) { return volVars.temperature(); };
665 3031232 localAssembler.assembleU(handle.heatConductionHandle(), iv, getTemperature);
666 3031232 }
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