GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/porousmediumflow/richards/volumevariables.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 42 44 95.5%
Functions: 36 42 85.7%
Branches: 150 205 73.2%

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 RichardsModel
10 * \brief Volume averaged quantities required by the Richards model.
11 */
12
13 #ifndef DUMUX_RICHARDS_VOLUME_VARIABLES_HH
14 #define DUMUX_RICHARDS_VOLUME_VARIABLES_HH
15
16 #include <cassert>
17
18 #include <dune/common/exceptions.hh>
19
20 #include <dumux/common/typetraits/state.hh>
21
22 #include <dumux/porousmediumflow/volumevariables.hh>
23 #include <dumux/porousmediumflow/nonisothermal/volumevariables.hh>
24 #include <dumux/material/idealgas.hh>
25 #include <dumux/material/solidstates/updatesolidvolumefractions.hh>
26
27 namespace Dumux {
28
29 /*!
30 * \ingroup RichardsModel
31 * \brief Volume averaged quantities required by the Richards model.
32 *
33 * This contains the quantities which are are constant within a finite
34 * volume in the Richards model.
35 */
36 template <class Traits>
37
8/14
✗ Branch 0 not taken.
✓ Branch 1 taken 4575 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4440 times.
✓ Branch 4 taken 135 times.
✓ Branch 5 taken 4440 times.
✓ Branch 7 taken 135 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 15392 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 15392 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 15392 times.
✗ Branch 14 not taken.
136041105 class RichardsVolumeVariables
38 : public PorousMediumFlowVolumeVariables<Traits>
39 , public EnergyVolumeVariables<Traits, RichardsVolumeVariables<Traits> >
40 {
41 using ParentType = PorousMediumFlowVolumeVariables<Traits>;
42 using EnergyVolVars = EnergyVolumeVariables<Traits, RichardsVolumeVariables<Traits> >;
43 using Scalar = typename Traits::PrimaryVariables::value_type;
44 using PermeabilityType = typename Traits::PermeabilityType;
45 using ModelTraits = typename Traits::ModelTraits;
46
47 static constexpr int numFluidComps = ParentType::numFluidComponents();
48 static constexpr int numPhases = ParentType::numFluidPhases();
49
50 // checks if the fluid system uses the Richards model index convention
51 static constexpr auto fsCheck = ModelTraits::checkFluidSystem(typename Traits::FluidSystem{});
52
53 public:
54 //! Export type of the fluid system
55 using FluidSystem = typename Traits::FluidSystem;
56 //! Export type of the fluid state
57 using FluidState = typename Traits::FluidState;
58 //! Export type of the fluid state
59 //! Export type of solid state
60 using SolidState = typename Traits::SolidState;
61 //! Export type of solid system
62 using SolidSystem = typename Traits::SolidSystem;
63 using Indices = typename Traits::ModelTraits::Indices;
64
65 //! Export phase indices
66 static constexpr auto liquidPhaseIdx = Traits::FluidSystem::phase0Idx;
67 static constexpr auto gasPhaseIdx = Traits::FluidSystem::phase1Idx;
68
69 /*!
70 * \brief Updates all quantities for a given control volume.
71 *
72 * \param elemSol A vector containing all primary variables connected to the element
73 * \param problem The object specifying the problem which ought to
74 * be simulated
75 * \param element An element which contains part of the control volume
76 * \param scv The sub-control volume
77 */
78 template<class ElemSol, class Problem, class Element, class Scv>
79 63464783 void update(const ElemSol &elemSol,
80 const Problem &problem,
81 const Element &element,
82 const Scv& scv)
83 {
84 63464783 ParentType::update(elemSol, problem, element, scv);
85
86 126929566 const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol);
87
88 // precompute the minimum capillary pressure (entry pressure)
89 // needed to make sure we don't compute unphysical capillary pressures and thus saturations
90 63464783 minPc_ = fluidMatrixInteraction.endPointPc();
91
92 //update porosity before calculating the effective properties depending on it
93 63464783 updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numFluidComps);
94 63464783 completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_);
95
96 //////////
97 // specify the other parameters
98 //////////
99
2/4
✓ Branch 0 taken 7174144 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7174144 times.
✗ Branch 3 not taken.
126929566 relativePermeabilityWetting_ = fluidMatrixInteraction.krw(fluidState_.saturation(liquidPhaseIdx));
100 63464783 EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_);
101 168304716 permeability_ = problem.spatialParams().permeability(element, scv, elemSol);
102 63464783 EnergyVolVars::updateEffectiveThermalConductivity();
103 63464783 }
104
105 /*!
106 * \brief Fills the fluid state according to the primary variables.
107 *
108 * Taking the information from the primary variables,
109 * the fluid state is filled with every information that is
110 * necessary to evaluate the model's local residual.
111 *
112 * \param elemSol A vector containing all primary variables connected to the element
113 * \param problem The problem at hand.
114 * \param element The current element.
115 * \param scv The subcontrol volume.
116 * \param fluidState The fluid state to fill.
117 * \param solidState The solid state to fill.
118 */
119 template<class ElemSol, class Problem, class Element, class Scv>
120 63464783 void completeFluidState(const ElemSol& elemSol,
121 const Problem& problem,
122 const Element& element,
123 const Scv& scv,
124 FluidState& fluidState,
125 SolidState& solidState)
126 {
127 63464783 EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState);
128
129
4/4
✓ Branch 0 taken 3558473 times.
✓ Branch 1 taken 57614746 times.
✓ Branch 2 taken 3558473 times.
✓ Branch 3 taken 57614746 times.
126929566 const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol);
130
131
2/2
✓ Branch 0 taken 3558473 times.
✓ Branch 1 taken 59906310 times.
63464783 const auto& priVars = elemSol[scv.localDofIndex()];
132
133 // set the wetting pressure
134 using std::max;
135
4/4
✓ Branch 0 taken 3558473 times.
✓ Branch 1 taken 59906310 times.
✓ Branch 2 taken 527381 times.
✓ Branch 3 taken 11488 times.
64003652 fluidState.setPressure(liquidPhaseIdx, priVars[Indices::pressureIdx]);
136
4/4
✓ Branch 0 taken 3558473 times.
✓ Branch 1 taken 59906310 times.
✓ Branch 2 taken 59894822 times.
✓ Branch 3 taken 3569961 times.
67023256 fluidState.setPressure(gasPhaseIdx, max(problem.nonwettingReferencePressure(), fluidState.pressure(liquidPhaseIdx) + minPc_));
137
138 // compute the capillary pressure to compute the saturation
139 // make sure that we the capillary pressure is not smaller than the minimum pc
140 // this would possibly return unphysical values from regularized material laws
141 using std::max;
142
2/2
✓ Branch 0 taken 59894822 times.
✓ Branch 1 taken 3569961 times.
63464783 const Scalar pc = max(minPc_, problem.nonwettingReferencePressure() - fluidState.pressure(liquidPhaseIdx));
143 63464783 const Scalar sw = fluidMatrixInteraction.sw(pc);
144 63464783 fluidState.setSaturation(liquidPhaseIdx, sw);
145 63464783 fluidState.setSaturation(gasPhaseIdx, 1.0-sw);
146
147 // density and viscosity
148 typename FluidSystem::ParameterCache paramCache;
149 63464783 paramCache.updateAll(fluidState);
150 63464783 fluidState.setDensity(liquidPhaseIdx,
151 FluidSystem::density(fluidState, paramCache, liquidPhaseIdx));
152 63464783 fluidState.setDensity(gasPhaseIdx,
153 FluidSystem::density(fluidState, paramCache, gasPhaseIdx));
154
155 63464783 fluidState.setViscosity(liquidPhaseIdx,
156 FluidSystem::viscosity(fluidState, paramCache, liquidPhaseIdx));
157
158 // compute and set the enthalpy
159 126390697 fluidState.setEnthalpy(liquidPhaseIdx, EnergyVolVars::enthalpy(fluidState, paramCache, liquidPhaseIdx));
160 126390697 fluidState.setEnthalpy(gasPhaseIdx, EnergyVolVars::enthalpy(fluidState, paramCache, gasPhaseIdx));
161 63464783 }
162
163 /*!
164 * \brief Returns the fluid configuration at the given primary
165 * variables.
166 */
167 const FluidState &fluidState() const
168
2/4
✓ Branch 0 taken 371327 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 688123 times.
✗ Branch 3 not taken.
4389264 { return fluidState_; }
169
170 /*!
171 * \brief Returns the phase state for the control volume.
172 */
173 const SolidState &solidState() const
174
2/4
✓ Branch 2 taken 135 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 135 times.
✗ Branch 6 not taken.
539274 { return solidState_; }
175
176 /*!
177 * \brief Returns the temperature.
178 */
179 Scalar temperature() const
180
1/2
✓ Branch 0 taken 258810 times.
✗ Branch 1 not taken.
3720180 { return fluidState_.temperature(); }
181
182 /*!
183 * \brief Returns the average porosity [] within the control volume.
184 *
185 * The porosity is defined as the ratio of the pore space to the
186 * total volume, i.e. \f[ \Phi := \frac{V_{pore}}{V_{pore} + V_{rock}} \f]
187 */
188 Scalar porosity() const
189
4/4
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 8490017 times.
✓ Branch 6 taken 11 times.
✓ Branch 7 taken 8490017 times.
180814784 { return solidState_.porosity(); }
190
191 /*!
192 * \brief Returns the permeability within the control volume in \f$[m^2]\f$.
193 */
194 const PermeabilityType& permeability() const
195 { return permeability_; }
196
197 /*!
198 * \brief Returns the average absolute saturation [] of a given
199 * fluid phase within the finite volume.
200 *
201 * The saturation of a fluid phase is defined as the fraction of
202 * the pore volume filled by it, i.e.
203 * \f[ S_\alpha := \frac{V_\alpha}{V_{pore}} = \phi \frac{V_\alpha}{V} \f]
204 *
205 * \param phaseIdx The index of the fluid phase
206 */
207 Scalar saturation(const int phaseIdx = liquidPhaseIdx) const
208
16/16
✓ Branch 4 taken 224748 times.
✓ Branch 5 taken 15050 times.
✓ Branch 6 taken 224748 times.
✓ Branch 7 taken 15050 times.
✓ Branch 8 taken 246113 times.
✓ Branch 9 taken 8279 times.
✓ Branch 10 taken 246113 times.
✓ Branch 11 taken 8279 times.
✓ Branch 12 taken 14854789 times.
✓ Branch 13 taken 1483589 times.
✓ Branch 14 taken 14854789 times.
✓ Branch 15 taken 1483589 times.
✓ Branch 16 taken 14800917 times.
✓ Branch 17 taken 1483589 times.
✓ Branch 18 taken 14800917 times.
✓ Branch 19 taken 1483589 times.
228378316 { return fluidState_.saturation(phaseIdx); }
209
210 /*!
211 * \brief Returns the average mass density \f$\mathrm{[kg/m^3]}\f$ of a given
212 * fluid phase within the control volume.
213 *
214 * \param phaseIdx The index of the fluid phase
215 */
216 Scalar density(const int phaseIdx = liquidPhaseIdx) const
217
19/30
✓ Branch 0 taken 1250391 times.
✓ Branch 1 taken 44559 times.
✓ Branch 2 taken 1250391 times.
✓ Branch 3 taken 44559 times.
✓ Branch 4 taken 371327 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 371327 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 688123 times.
✓ Branch 9 taken 19047 times.
✓ Branch 10 taken 688123 times.
✓ Branch 11 taken 19047 times.
✓ Branch 12 taken 688123 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 688123 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 931 times.
✓ Branch 21 taken 48 times.
✓ Branch 22 taken 931 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 92 times.
✓ Branch 25 taken 43 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 44 times.
✓ Branch 28 taken 43 times.
✗ Branch 29 not taken.
1527203992 { return fluidState_.density(phaseIdx); }
218
219 /*!
220 * \brief Returns the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within
221 * the control volume.
222 *
223 * For the nonwetting phase (i.e. the gas phase), we assume
224 * infinite mobility, which implies that the nonwetting phase
225 * pressure is equal to the finite volume's reference pressure
226 * defined by the problem.
227 *
228 * \param phaseIdx The index of the fluid phase
229 */
230 Scalar pressure(const int phaseIdx = liquidPhaseIdx) const
231
12/20
✓ Branch 0 taken 3496 times.
✓ Branch 1 taken 15551 times.
✓ Branch 2 taken 3496 times.
✓ Branch 3 taken 15551 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 19047 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 19047 times.
✓ Branch 8 taken 18598996 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 18598996 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 18598996 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 18598996 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 931 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 931 times.
✗ Branch 19 not taken.
919534942 { return fluidState_.pressure(phaseIdx); }
232
233 /*!
234 * \brief Returns the effective mobility \f$\mathrm{[1/(Pa*s)]}\f$ of a given phase within
235 * the control volume.
236 *
237 * The mobility of a fluid phase is defined as the relative
238 * permeability of the phase (given by the chosen material law)
239 * divided by the dynamic viscosity of the fluid, i.e.
240 * \f[ \lambda_\alpha := \frac{k_{r\alpha}}{\mu_\alpha} \f]
241 *
242 * \param phaseIdx The index of the fluid phase
243 */
244 Scalar mobility(const int phaseIdx = liquidPhaseIdx) const
245
12/16
✓ Branch 0 taken 134582 times.
✓ Branch 1 taken 8279 times.
✓ Branch 2 taken 134582 times.
✓ Branch 3 taken 8279 times.
✓ Branch 4 taken 14819456 times.
✓ Branch 5 taken 1483589 times.
✓ Branch 6 taken 14819456 times.
✓ Branch 7 taken 1483589 times.
✓ Branch 8 taken 372511 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 372511 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 688123 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 688123 times.
✗ Branch 15 not taken.
404348870 { return relativePermeability(phaseIdx)/fluidState_.viscosity(phaseIdx); }
246
247 /*!
248 * \brief Returns the dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of a given phase within
249 * the control volume.
250 *
251 * \param phaseIdx The index of the fluid phase
252 * \note The nonwetting phase is infinitely mobile
253 */
254 Scalar viscosity(const int phaseIdx = liquidPhaseIdx) const
255
8/12
✓ Branch 0 taken 3496 times.
✓ Branch 1 taken 15551 times.
✓ Branch 2 taken 3496 times.
✓ Branch 3 taken 15551 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 19047 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 19047 times.
✓ Branch 14 taken 931 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 931 times.
✗ Branch 17 not taken.
140282 { return phaseIdx == liquidPhaseIdx ? fluidState_.viscosity(liquidPhaseIdx) : 0.0; }
256
257 /*!
258 * \brief Returns relative permeability [-] of a given phase within
259 * the control volume.
260 *
261 * \param phaseIdx The index of the fluid phase
262 */
263 Scalar relativePermeability(const int phaseIdx = liquidPhaseIdx) const
264
14/22
✓ Branch 0 taken 138078 times.
✓ Branch 1 taken 23830 times.
✓ Branch 2 taken 134582 times.
✓ Branch 3 taken 8279 times.
✓ Branch 4 taken 18539 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18539 times.
✓ Branch 7 taken 14800917 times.
✓ Branch 8 taken 1483589 times.
✓ Branch 9 taken 14800917 times.
✓ Branch 10 taken 1856100 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 372511 times.
✓ Branch 13 taken 931 times.
✓ Branch 14 taken 688123 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 688123 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
401150647 { return phaseIdx == liquidPhaseIdx ? relativePermeabilityWetting_ : 1.0; }
265
266 /*!
267 * \brief Returns the effective capillary pressure \f$\mathrm{[Pa]}\f$ within the
268 * control volume.
269 *
270 * The capillary pressure is defined as the difference in
271 * pressures of the nonwetting and the wetting phase, i.e.
272 * \f[ p_c = p_n - p_w \f]
273 *
274 * \note Capillary pressures are always larger than the entry pressure
275 * This regularization doesn't affect the residual in which pc is not needed.
276 */
277 Scalar capillaryPressure() const
278 {
279 using std::max;
280
34/41
✓ Branch 0 taken 554028 times.
✓ Branch 1 taken 57970 times.
✓ Branch 2 taken 554028 times.
✓ Branch 3 taken 57970 times.
✓ Branch 4 taken 554028 times.
✓ Branch 5 taken 57970 times.
✓ Branch 6 taken 192232 times.
✓ Branch 7 taken 62160 times.
✓ Branch 8 taken 192232 times.
✓ Branch 9 taken 62160 times.
✓ Branch 10 taken 192232 times.
✓ Branch 11 taken 62160 times.
✓ Branch 12 taken 192232 times.
✓ Branch 13 taken 62160 times.
✓ Branch 14 taken 14800917 times.
✓ Branch 15 taken 1835414 times.
✓ Branch 16 taken 14817484 times.
✓ Branch 17 taken 1835414 times.
✓ Branch 18 taken 14817484 times.
✓ Branch 19 taken 1835414 times.
✓ Branch 20 taken 14817484 times.
✓ Branch 21 taken 1483589 times.
✓ Branch 22 taken 14868213 times.
✓ Branch 23 taken 1483589 times.
✓ Branch 24 taken 14868213 times.
✓ Branch 25 taken 1483589 times.
✓ Branch 26 taken 14868213 times.
✓ Branch 27 taken 1483589 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 7419192 times.
✓ Branch 30 taken 745180 times.
✓ Branch 31 taken 7419192 times.
✓ Branch 32 taken 745180 times.
✓ Branch 33 taken 7419192 times.
✓ Branch 34 taken 745180 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
159485621 return max(minPc_, pressure(gasPhaseIdx) - pressure(liquidPhaseIdx));
281 }
282
283 /*!
284 * \brief Returns the pressureHead \f$\mathrm{[cm]}\f$ of a given phase within
285 * the control volume.
286 *
287 * For the nonwetting phase (i.e. the gas phase), we assume
288 * infinite mobility, which implies that the nonwetting phase
289 * pressure is equal to the finite volume's reference pressure
290 * defined by the problem.
291 *
292 * \param phaseIdx The index of the fluid phase
293 * \note this function is here as a convenience to the user to not have to
294 * manually do a conversion. It is not correct if the density is not constant
295 * or the gravity different
296 */
297 Scalar pressureHead(const int phaseIdx = liquidPhaseIdx) const
298 405504 { return 100.0 *(pressure(phaseIdx) - pressure(gasPhaseIdx))/density(phaseIdx)/9.81; }
299
300 /*!
301 * \brief Returns the water content of a fluid phase within the finite volume.
302 *
303 * The water content is defined as the fraction of
304 * the saturation divided by the porosity.
305
306 * \param phaseIdx The index of the fluid phase
307 * \note this function is here as a convenience to the user to not have to
308 * manually do a conversion.
309 */
310 Scalar waterContent(const int phaseIdx = liquidPhaseIdx) const
311 1285080 { return saturation(phaseIdx) * solidState_.porosity(); }
312
313 protected:
314 FluidState fluidState_; //!< the fluid state
315 SolidState solidState_;
316 Scalar relativePermeabilityWetting_; //!< the relative permeability of the wetting phase
317 PermeabilityType permeability_; //!< the intrinsic permeability
318 Scalar minPc_; //!< the minimum capillary pressure (entry pressure)
319
320 // Effective diffusion coefficients for the phases
321 Scalar effectiveDiffCoeff_;
322
323 };
324 } // end namespace Dumux
325
326 #endif
327