GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/porousmediumflow/compositional/localresidual.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 48 52 92.3%
Functions: 161 549 29.3%
Branches: 80 134 59.7%

Line Branch Exec Source
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 //
4 // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 /*!
8 * \file
9 * \ingroup PorousmediumflowModels
10 * \brief Element-wise calculation of the local residual for problems
11 * using compositional fully implicit model.
12 */
13
14 #ifndef DUMUX_COMPOSITIONAL_LOCAL_RESIDUAL_HH
15 #define DUMUX_COMPOSITIONAL_LOCAL_RESIDUAL_HH
16
17 #include <vector>
18 #include <dune/common/exceptions.hh>
19 #include <dumux/common/properties.hh>
20 #include <dumux/common/numeqvector.hh>
21 #include <dumux/discretization/method.hh>
22 #include <dumux/flux/referencesystemformulation.hh>
23
24 namespace Dumux {
25
26 /*!
27 * \ingroup PorousmediumflowModels
28 * \brief Element-wise calculation of the local residual for problems
29 * using compositional fully implicit model.
30 */
31 template<class TypeTag>
32 class CompositionalLocalResidual: public GetPropType<TypeTag, Properties::BaseLocalResidual>
33 {
34 using ParentType = GetPropType<TypeTag, Properties::BaseLocalResidual>;
35 using Implementation = GetPropType<TypeTag, Properties::LocalResidual>;
36 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
37 using Problem = GetPropType<TypeTag, Properties::Problem>;
38 using FVElementGeometry = typename GetPropType<TypeTag, Properties::GridGeometry>::LocalView;
39 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
40 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
41 using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>;
42 using FluxVariables = GetPropType<TypeTag, Properties::FluxVariables>;
43 using ElementFluxVariablesCache = typename GetPropType<TypeTag, Properties::GridFluxVariablesCache>::LocalView;
44 using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView;
45 using Element = typename GridView::template Codim<0>::Entity;
46 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
47 using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>;
48 using EnergyLocalResidual = GetPropType<TypeTag, Properties::EnergyLocalResidual>;
49 using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
50 using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>;
51 using Indices = typename ModelTraits::Indices;
52
53 static constexpr int numPhases = ModelTraits::numFluidPhases();
54 static constexpr int numComponents = ModelTraits::numFluidComponents();
55 static constexpr bool useMoles = ModelTraits::useMoles();
56
57 enum { conti0EqIdx = Indices::conti0EqIdx };
58
59 //! The index of the component balance equation that gets replaced with the total mass balance
60 static constexpr int replaceCompEqIdx = ModelTraits::replaceCompEqIdx();
61 static constexpr bool useTotalMoleOrMassBalance = replaceCompEqIdx < numComponents;
62
63 public:
64
6/12
✓ Branch 1 taken 8595688 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8595688 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 117062 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 117062 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 433160 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 433160 times.
✗ Branch 17 not taken.
19668974 using ParentType::ParentType;
65
66 /*!
67 * \brief Evaluates the amount of all conservation quantities
68 * (e.g. phase mass) within a sub-control volume.
69 *
70 * The result should be averaged over the volume (e.g. phase mass
71 * inside a sub control volume divided by the volume)
72 *
73 * \param problem The problem
74 * \param scv The sub control volume
75 * \param volVars The current or previous volVars
76 */
77 396809096 NumEqVector computeStorage(const Problem& problem,
78 const SubControlVolume& scv,
79 const VolumeVariables& volVars) const
80 {
81 412947036 NumEqVector storage(0.0);
82
83 const auto massOrMoleDensity = [](const auto& volVars, const int phaseIdx)
84
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
2662099888 { return useMoles ? volVars.molarDensity(phaseIdx) : volVars.density(phaseIdx); };
85
86 const auto massOrMoleFraction= [](const auto& volVars, const int phaseIdx, const int compIdx)
87
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1185764032 { return useMoles ? volVars.moleFraction(phaseIdx, compIdx) : volVars.massFraction(phaseIdx, compIdx); };
88
89 // compute storage term of all components within all phases
90
8/8
✓ Branch 0 taken 729717230 times.
✓ Branch 1 taken 391582118 times.
✓ Branch 2 taken 4779866 times.
✓ Branch 3 taken 4779866 times.
✓ Branch 4 taken 3466380 times.
✓ Branch 5 taken 3466380 times.
✓ Branch 6 taken 3289104 times.
✓ Branch 7 taken 3289104 times.
1164029184 for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
91 {
92
8/8
✓ Branch 0 taken 1621293838 times.
✓ Branch 1 taken 735926900 times.
✓ Branch 2 taken 4779866 times.
✓ Branch 3 taken 10468412 times.
✓ Branch 4 taken 3466380 times.
✓ Branch 5 taken 6932760 times.
✓ Branch 6 taken 3289104 times.
✓ Branch 7 taken 6578208 times.
2422224172 for (int compIdx = 0; compIdx < numComponents; ++compIdx)
93 {
94 1524721288 auto eqIdx = conti0EqIdx + compIdx;
95
2/2
✓ Branch 0 taken 51075432 times.
✓ Branch 1 taken 33429912 times.
84505344 if (eqIdx != replaceCompEqIdx)
96 1637712112 storage[eqIdx] += volVars.porosity()
97 2974108824 * volVars.saturation(phaseIdx)
98 1637712112 * massOrMoleDensity(volVars, phaseIdx)
99 2325535872 * massOrMoleFraction(volVars, phaseIdx, compIdx);
100 }
101
102 // in case one balance is substituted by the total mole balance
103 if (useTotalMoleOrMassBalance)
104 33429912 storage[replaceCompEqIdx] += massOrMoleDensity(volVars, phaseIdx)
105 33429912 * volVars.porosity()
106 66859824 * volVars.saturation(phaseIdx);
107
108 //! The energy storage in the fluid phase with index phaseIdx
109 1190283800 EnergyLocalResidual::fluidPhaseStorage(storage, scv, volVars, phaseIdx);
110 }
111
112 //! The energy storage in the solid matrix
113 656669268 EnergyLocalResidual::solidPhaseStorage(storage, scv, volVars);
114
115 410477284 return storage;
116 }
117
118 /*!
119 * \brief Evaluates the total flux of all conservation quantities
120 * over a face of a sub-control volume.
121 *
122 * \param problem The problem
123 * \param element The current element.
124 * \param fvGeometry The finite-volume geometry
125 * \param elemVolVars The volume variables of the current element
126 * \param scvf The sub control volume face to compute the flux on
127 * \param elemFluxVarsCache The cache related to flux computation
128 */
129 409059907 NumEqVector computeFlux(const Problem& problem,
130 const Element& element,
131 const FVElementGeometry& fvGeometry,
132 const ElementVolumeVariables& elemVolVars,
133 const SubControlVolumeFace& scvf,
134 const ElementFluxVariablesCache& elemFluxVarsCache) const
135 {
136 409059907 FluxVariables fluxVars;
137 409059907 fluxVars.init(problem, element, fvGeometry, elemVolVars, scvf, elemFluxVarsCache);
138 static constexpr auto referenceSystemFormulation = FluxVariables::MolecularDiffusionType::referenceSystemFormulation();
139 // get upwind weights into local scope
140 409059907 NumEqVector flux(0.0);
141
142 const auto massOrMoleDensity = [](const auto& volVars, const int phaseIdx)
143
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5695879432 { return useMoles ? volVars.molarDensity(phaseIdx) : volVars.density(phaseIdx); };
144
145 const auto massOrMoleFraction= [](const auto& volVars, const int phaseIdx, const int compIdx)
146
0/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1161868832 { return useMoles ? volVars.moleFraction(phaseIdx, compIdx) : volVars.massFraction(phaseIdx, compIdx); };
147
148 // advective fluxes
149
2/2
✓ Branch 0 taken 722567775 times.
✓ Branch 1 taken 377157963 times.
1163529626 for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
150 {
151 754469719 const auto diffusiveFluxes = fluxVars.molecularDiffusionFlux(phaseIdx);
152
3/3
✓ Branch 0 taken 850118014 times.
✓ Branch 1 taken 1051111295 times.
✓ Branch 2 taken 318234184 times.
2315169325 for (int compIdx = 0; compIdx < numComponents; ++compIdx)
153 {
154 // get equation index
155 1560699606 const auto eqIdx = conti0EqIdx + compIdx;
156
157 // the physical quantities for which we perform upwinding
158 8166950662 const auto upwindTerm = [&massOrMoleDensity, &massOrMoleFraction, phaseIdx, compIdx] (const auto& volVars)
159
22/42
✓ Branch 0 taken 6718577 times.
✓ Branch 1 taken 87963764 times.
✓ Branch 2 taken 6718577 times.
✓ Branch 3 taken 87963764 times.
✓ Branch 4 taken 8703657 times.
✓ Branch 5 taken 31419704 times.
✓ Branch 6 taken 8703657 times.
✓ Branch 7 taken 31419704 times.
✓ Branch 8 taken 8703657 times.
✓ Branch 9 taken 76920600 times.
✓ Branch 10 taken 8703657 times.
✓ Branch 11 taken 76920600 times.
✓ Branch 12 taken 8703657 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 6280103 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 6280103 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6319767 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6319767 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 6319767 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 6319767 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 6319767 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 2024744 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 2024744 times.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
6702604896 { return massOrMoleDensity(volVars, phaseIdx)*massOrMoleFraction(volVars, phaseIdx, compIdx)*volVars.mobility(phaseIdx); };
160
161
2/2
✓ Branch 0 taken 35125504 times.
✓ Branch 1 taken 23069552 times.
66214704 if (eqIdx != replaceCompEqIdx)
162
2/2
✓ Branch 1 taken 35608887 times.
✓ Branch 2 taken 27150087 times.
1533620230 flux[eqIdx] += fluxVars.advectiveFlux(phaseIdx, upwindTerm);
163
164 // diffusive fluxes (only for the component balances)
165
2/2
✓ Branch 0 taken 35125504 times.
✓ Branch 1 taken 23069552 times.
66214704 if(eqIdx != replaceCompEqIdx)
166 {
167 //check for the reference system and adapt units of the diffusive flux accordingly.
168 if (referenceSystemFormulation == ReferenceSystemFormulation::massAveraged)
169
4/4
✓ Branch 0 taken 35608887 times.
✓ Branch 1 taken 27150087 times.
✓ Branch 2 taken 35608887 times.
✓ Branch 3 taken 27150087 times.
2464301514 flux[eqIdx] += useMoles ? diffusiveFluxes[compIdx]/FluidSystem::molarMass(compIdx)
170 2259895584 : diffusiveFluxes[compIdx];
171 else if (referenceSystemFormulation == ReferenceSystemFormulation::molarAveraged)
172 flux[eqIdx] += useMoles ? diffusiveFluxes[compIdx]
173 : diffusiveFluxes[compIdx]*FluidSystem::molarMass(compIdx);
174 else
175 DUNE_THROW(Dune::NotImplemented, "other reference systems than mass and molar averaged are not implemented");
176 }
177 }
178
179 // in case one balance is substituted by the total mole balance
180 if (useTotalMoleOrMassBalance)
181 {
182 // the physical quantities for which we perform upwinding
183 135396880 const auto upwindTerm = [&massOrMoleDensity, phaseIdx] (const auto& volVars)
184
10/24
✓ Branch 0 taken 8703657 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8703657 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8703657 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8703657 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 8703657 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6319767 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6319767 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 6319767 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 6319767 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6319767 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
102196496 { return massOrMoleDensity(volVars, phaseIdx)*volVars.mobility(phaseIdx); };
185
186 27079376 flux[replaceCompEqIdx] += fluxVars.advectiveFlux(phaseIdx, upwindTerm);
187
188
2/2
✓ Branch 0 taken 58195056 times.
✓ Branch 1 taken 23069552 times.
93294080 for(int compIdx = 0; compIdx < numComponents; ++compIdx)
189 {
190 //check for the reference system and adapt units of the diffusive flux accordingly.
191 if (referenceSystemFormulation == ReferenceSystemFormulation::massAveraged)
192
4/4
✓ Branch 0 taken 11013600 times.
✓ Branch 1 taken 11013600 times.
✓ Branch 2 taken 11013600 times.
✓ Branch 3 taken 11013600 times.
162476256 flux[replaceCompEqIdx] += useMoles ? diffusiveFluxes[compIdx]/FluidSystem::molarMass(compIdx) : diffusiveFluxes[compIdx];
193 else if (referenceSystemFormulation == ReferenceSystemFormulation::molarAveraged)
194 flux[replaceCompEqIdx] += useMoles ? diffusiveFluxes[compIdx]
195 : diffusiveFluxes[compIdx]*FluidSystem::molarMass(compIdx);
196 else
197 DUNE_THROW(Dune::NotImplemented, "other reference systems than mass and molar averaged are not implemented");
198 }
199 }
200
201 //! Add advective phase energy fluxes. For isothermal model the contribution is zero.
202 754469719 EnergyLocalResidual::heatConvectionFlux(flux, fluxVars, phaseIdx);
203
204 if constexpr (ModelTraits::enableCompositionalDispersion())
205 {
206 if constexpr (FVElementGeometry::GridGeometry::discMethod == DiscretizationMethods::box && numPhases == 1)
207 {
208 8657600 const auto dispersionFluxes = fluxVars.compositionalDispersionFlux(phaseIdx);
209
3/3
✓ Branch 0 taken 5523200 times.
✓ Branch 1 taken 14553600 times.
✓ Branch 2 taken 5896000 times.
25972800 for (int compIdx = 0; compIdx < numComponents; ++compIdx)
210 {
211 51945600 flux[compIdx] += dispersionFluxes[compIdx];
212 }
213 }
214 else
215 DUNE_THROW(Dune::NotImplemented, "Dispersion Fluxes are only implemented for single phase flows using the Box method.");
216 }
217
218 }
219
220 //! Add diffusive and dispersive energy fluxes. For isothermal model the contribution is zero.
221 409059907 EnergyLocalResidual::heatConductionFlux(flux, fluxVars);
222 409059907 EnergyLocalResidual::heatDispersionFlux(flux, fluxVars);
223
224 409059907 return flux;
225 }
226
227 protected:
228 Implementation *asImp_()
229 { return static_cast<Implementation *> (this); }
230
231 const Implementation *asImp_() const
232 { return static_cast<const Implementation *> (this); }
233 };
234
235 } // end namespace Dumux
236
237 #endif
238