GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/material/fluidsystems/liquidphase2c.hh
Date: 2025-04-19 19:19:10
Exec Total Coverage
Lines: 45 45 100.0%
Functions: 12 12 100.0%
Branches: 30 48 62.5%

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 FluidSystems
10 * \copybrief Dumux::FluidSystems::LiquidPhaseTwoC
11 */
12 #ifndef DUMUX_LIQUID_TWOC_PHASE_HH
13 #define DUMUX_LIQUID_TWOC_PHASE_HH
14
15 #include <cassert>
16 #include <limits>
17
18 #include <dune/common/exceptions.hh>
19 #include <dumux/material/fluidsystems/base.hh>
20 #include <dumux/material/binarycoefficients/h2o_constant.hh>
21 #include <dumux/io/name.hh>
22
23 namespace Dumux::FluidSystems {
24
25 /*!
26 * \ingroup FluidSystems
27 * \brief A liquid phase consisting of a two components,
28 * a main component and a conservative tracer component
29 */
30 template <class Scalar, class MainComponent, class SecondComponent>
31 class LiquidPhaseTwoC
32 : public Base<Scalar, LiquidPhaseTwoC<Scalar, MainComponent, SecondComponent> >
33 {
34 using ThisType = LiquidPhaseTwoC<Scalar, MainComponent, SecondComponent>;
35 using BinaryCoefficients = BinaryCoeff::H2O_Component<Scalar, SecondComponent>;
36
37 public:
38 using ParameterCache = NullParameterCache;
39
40 static constexpr int numPhases = 1; //!< Number of phases in the fluid system
41 static constexpr int numComponents = 2; //!< Number of components in the fluid system
42
43 static constexpr int liquidPhaseIdx = 0; //!< index of the liquid phase
44 static constexpr int phase0Idx = liquidPhaseIdx; //!< index of the only phase
45
46 static constexpr int comp0Idx = 0; //!< index of the first component
47 static constexpr int comp1Idx = 1; //!< index of the second component
48 static constexpr int mainCompIdx = comp0Idx; //!< index of the main component
49 static constexpr int secondCompIdx = comp1Idx; //!< index of the secondary component
50
51 /*!
52 * \brief Initialize the fluid system's static parameters generically
53 */
54 static void init() {}
55
56 /****************************************
57 * Fluid phase related static parameters
58 ****************************************/
59 /*!
60 * \brief Return the human readable name of a fluid phase
61 *
62 * \param phaseIdx The index of the fluid phase to consider
63 */
64 81 static std::string phaseName(int phaseIdx = 0)
65 { return IOName::liquidPhase(); }
66
67 /*!
68 * \brief Returns whether the fluids are miscible
69 * \note There is only one phase, so miscibility makes no sense
70 */
71 static constexpr bool isMiscible()
72 { return false; }
73
74 /*!
75 * \brief A human readable name for the component.
76 *
77 * \param compIdx The index of the component to consider
78 */
79 12 static std::string componentName(int compIdx)
80
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 { return compIdx ? SecondComponent::name() : MainComponent::name(); }
81
82 /*!
83 * \brief A human readable name for the fluid system.
84 */
85 static std::string name()
86 { return "LiquidPhaseTwoC"; }
87
88 /*!
89 * \brief Returns whether the fluid is gaseous
90 */
91 static constexpr bool isGas(int phaseIdx = 0)
92 { return false; }
93
94 /*!
95 * \brief Returns true if and only if a fluid phase is assumed to
96 * be an ideal mixture.
97 *
98 * We define an ideal mixture as a fluid phase where the fugacity
99 * coefficients of all components times the pressure of the phase
100 * are independent on the fluid composition. This assumption is true
101 * if only a single component is involved. If you are unsure what
102 * this function should return, it is safe to return false. The
103 * only damage done will be (slightly) increased computation times
104 * in some cases.
105 *
106 * \param phaseIdx The index of the fluid phase to consider
107 */
108 static bool isIdealMixture(int phaseIdx = 0)
109 { return true; }
110
111 /*!
112 * \brief Returns true if the fluid is assumed to be compressible
113 */
114 static constexpr bool isCompressible(int phaseIdx = 0)
115 { return MainComponent::liquidIsCompressible(); }
116
117 /*!
118 * \brief Returns true if the fluid is assumed to be an ideal gas
119 */
120 static bool isIdealGas(int phaseIdx = 0)
121 { return false; /* we're a liquid! */ }
122
123 /*!
124 * \brief The mass in \f$\mathrm{[kg]}\f$ of one mole of the component.
125 */
126 84495305 static Scalar molarMass(int compIdx)
127
13/18
✓ Branch 0 taken 719000 times.
✓ Branch 1 taken 11732600 times.
✓ Branch 3 taken 10644199 times.
✓ Branch 4 taken 9925201 times.
✓ Branch 6 taken 40322025 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1016816 times.
✓ Branch 9 taken 1016816 times.
✓ Branch 11 taken 8051628 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1588156 times.
✓ Branch 15 taken 6952 times.
✓ Branch 18 taken 531 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 17380 times.
✗ Branch 22 not taken.
✗ Branch 2 not taken.
✓ Branch 10 taken 173000 times.
84495305 { return compIdx ? SecondComponent::molarMass() : MainComponent::molarMass(); }
128
129 /*!
130 * \brief Returns the critical temperature \f$\mathrm{[K]}\f$ of the main component
131 */
132 static Scalar criticalTemperature()
133 { return MainComponent::criticalTemperature(); }
134
135 /*!
136 * \brief Returns the critical pressure \f$\mathrm{[Pa]}\f$ of the main component
137 */
138 static Scalar criticalPressure()
139 { return MainComponent::criticalPressure(); }
140
141 /*!
142 * \brief Returns the temperature \f$\mathrm{[K]}\f$ at the main component's triple point.
143 */
144 static Scalar tripleTemperature()
145 { return MainComponent::tripleTemperature(); }
146
147 /*!
148 * \brief Returns the pressure \f$\mathrm{[Pa]}\f$ at the main component's triple point.
149 */
150 static Scalar triplePressure()
151 { return MainComponent::triplePressure(); }
152
153 /*!
154 * \brief The vapor pressure in \f$\mathrm{[Pa]}\f$ of the main component at a given
155 * temperature.
156 */
157 static Scalar vaporPressure(Scalar T)
158 { return MainComponent::vaporPressure(T); }
159
160 /*!
161 * \brief The density \f$\mathrm{[kg/m^3]}\f$ of the phase at a given pressure and temperature.
162 * \param temperature The temperature at which to evaluate the density
163 * \param pressure The pressure at which to evaluate the density
164 */
165 static Scalar density(Scalar temperature, Scalar pressure)
166 { return MainComponent::liquidDensity(temperature, pressure); }
167
168 using Base<Scalar, ThisType>::density;
169 //! \copydoc Base<Scalar,ThisType>::density(const FluidState&,int)
170 template <class FluidState>
171 5471009 static Scalar density(const FluidState &fluidState,
172 const int phaseIdx = 0)
173 {
174 5471009 const Scalar T = fluidState.temperature(phaseIdx);
175 5471009 const Scalar p = fluidState.pressure(phaseIdx);
176
177 // See: Eq. (7) in Class et al. (2002a)
178 // This assumes each gas molecule displaces exactly one
179 // molecule in the liquid.
180 5471009 const Scalar pureComponentMolarDensity = MainComponent::liquidMolarDensity(T, p);
181
182 return pureComponentMolarDensity
183 5471009 * (MainComponent::molarMass()*fluidState.moleFraction(phase0Idx, mainCompIdx)
184 5471009 + SecondComponent::molarMass()*fluidState.moleFraction(phase0Idx, secondCompIdx));
185 }
186
187 using Base<Scalar, ThisType>::molarDensity;
188 //! \copydoc Base<Scalar,ThisType>::molarDensity(const FluidState&,int)
189 template <class FluidState>
190 1 static Scalar molarDensity(const FluidState &fluidState, int phaseIdx)
191 {
192 5471009 const Scalar T = fluidState.temperature(phaseIdx);
193 5471009 const Scalar p = fluidState.pressure(phaseIdx);
194
195 // assume pure component or that each gas molecule displaces exactly one
196 // molecule in the liquid.
197 1 return MainComponent::liquidMolarDensity(T, p);
198 }
199
200 /*!
201 * \brief The pressure \f$\mathrm{[Pa]}\f$ of the component at a given density and temperature.
202 * \param temperature The temperature at which to evaluate the pressure
203 * \param density The density at which to evaluate the pressure
204 */
205 static Scalar pressure(Scalar temperature, Scalar density)
206 { return MainComponent::liquidPressure(temperature, density); }
207
208 /*!
209 * \brief Specific enthalpy \f$\mathrm{[J/kg]}\f$ the pure component as a liquid.
210 * \param temperature The temperature at which to evaluate the enthalpy
211 * \param pressure The pressure at which to evaluate the enthalpy
212 */
213 1 static const Scalar enthalpy(Scalar temperature, Scalar pressure)
214 1 { return MainComponent::liquidEnthalpy(temperature, pressure); }
215
216 using Base<Scalar, ThisType>::enthalpy;
217 //! \copydoc Base<Scalar,ThisType>::enthalpy(const FluidState&,int)
218 template <class FluidState>
219 1 static Scalar enthalpy(const FluidState &fluidState,
220 const int phaseIdx)
221 {
222 1 return enthalpy(fluidState.temperature(phaseIdx),
223 1 fluidState.pressure(phaseIdx));
224 }
225
226 /*!
227 * \brief Returns the specific enthalpy \f$\mathrm{[J/kg]}\f$ of a component in the specified phase
228 * \param fluidState The fluid state
229 * \param phaseIdx The index of the phase
230 * \param componentIdx The index of the component
231 */
232 template <class FluidState>
233 static Scalar componentEnthalpy(const FluidState &fluidState,
234 int phaseIdx,
235 int componentIdx)
236 {
237 const Scalar T = fluidState.temperature(phaseIdx);
238 const Scalar p = fluidState.pressure(phaseIdx);
239
240 if (componentIdx == mainCompIdx)
241 return MainComponent::liquidEnthalpy(T, p);
242 else if (componentIdx == secondCompIdx)
243 return SecondComponent::liquidEnthalpy(T, p);
244 else
245 DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << componentIdx);
246 }
247
248 /*!
249 * \brief Specific internal energy \f$\mathrm{[J/kg]}\f$ the pure component as a liquid.
250 * \param temperature The temperature at which to evaluate the internal energy
251 * \param pressure The pressure at which to evaluate the internal energy
252 */
253 static const Scalar internalEnergy(Scalar temperature, Scalar pressure)
254 { return MainComponent::liquidInternalEnergy(temperature, pressure); }
255
256 /*!
257 * \brief The dynamic liquid viscosity \f$\mathrm{[N/m^3*s]}\f$ of the pure component.
258 * \param temperature The temperature at which to evaluate the viscosity
259 * \param pressure The pressure at which to evaluate the viscosity
260 */
261 1 static Scalar viscosity(Scalar temperature, Scalar pressure)
262 1 { return MainComponent::liquidViscosity(temperature, pressure); }
263
264 using Base<Scalar, ThisType>::viscosity;
265 //! \copydoc Base<Scalar,ThisType>::viscosity(const FluidState&,int)
266 template <class FluidState>
267 1 static Scalar viscosity(const FluidState &fluidState,
268 const int phaseIdx)
269 {
270 1 return viscosity(fluidState.temperature(phaseIdx),
271 1 fluidState.pressure(phaseIdx));
272 }
273
274 using Base<Scalar, ThisType>::fugacityCoefficient;
275 //! \copydoc Base<Scalar,ThisType>::fugacityCoefficient(const FluidState&,int,int)
276 template <class FluidState>
277 2 static Scalar fugacityCoefficient(const FluidState &fluidState,
278 int phaseIdx,
279 int compIdx)
280 {
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 assert(0 <= phaseIdx && phaseIdx < numPhases);
282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 assert(0 <= compIdx && compIdx < numComponents);
283
284
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (phaseIdx == compIdx)
285 // We could calculate the real fugacity coefficient of
286 // the component in the fluid. Probably that's not worth
287 // the effort, since the fugacity coefficient of the other
288 // component is infinite anyway...
289 1 return 1.0;
290 return std::numeric_limits<Scalar>::infinity();
291 }
292
293 using Base<Scalar, ThisType>::diffusionCoefficient;
294 //! \copydoc Base<Scalar,ThisType>::diffusionCoefficient(const FluidState&,int,int)
295 template <class FluidState>
296 2 static Scalar diffusionCoefficient(const FluidState &fluidState,
297 int phaseIdx,
298 int compIdx)
299 {
300
10/20
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 2 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 2 times.
✗ Branch 29 not taken.
8 DUNE_THROW(Dune::InvalidStateException, "Not applicable: Diffusion coefficients");
301 }
302
303 using Base<Scalar, ThisType>::binaryDiffusionCoefficient;
304 //! \copydoc Base<Scalar,ThisType>::binaryDiffusionCoefficient(const FluidState&,int,int,int)
305 template <class FluidState>
306 5471012 static Scalar binaryDiffusionCoefficient(const FluidState &fluidState, int phaseIdx, int compIIdx, int compJIdx)
307 {
308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5471012 times.
5471012 assert(phaseIdx < numPhases);
309 5471012 return BinaryCoefficients::liquidDiffCoeff(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));
310 }
311
312 /*!
313 * \brief Thermal conductivity of the fluid \f$\mathrm{[W/(m K)]}\f$.
314 * \param temperature The temperature at which to evaluate the thermal conductivity
315 * \param pressure The pressure at which to evaluate the thermal conductivity
316 */
317 1 static Scalar thermalConductivity(Scalar temperature, Scalar pressure)
318 1 { return MainComponent::liquidThermalConductivity(temperature, pressure); }
319
320 using Base<Scalar, ThisType>::thermalConductivity;
321 //! \copydoc Base<Scalar,ThisType>::thermalConductivity(const FluidState&,int)
322 template <class FluidState>
323 1 static Scalar thermalConductivity(const FluidState &fluidState,
324 const int phaseIdx)
325 {
326 1 return thermalConductivity(fluidState.temperature(phaseIdx),
327 1 fluidState.pressure(phaseIdx));
328 }
329
330 /*!
331 * \brief Specific isobaric heat capacity of the fluid \f$\mathrm{[J/(kg K)]}\f$.
332 * \param temperature The temperature at which to evaluate the heat capacity
333 * \param pressure The pressure at which to evaluate the heat capacity
334 */
335 1 static Scalar heatCapacity(Scalar temperature, Scalar pressure)
336 1 { return MainComponent::liquidHeatCapacity(temperature, pressure); }
337
338 using Base<Scalar, ThisType>::heatCapacity;
339 //! \copydoc Base<Scalar,ThisType>::heatCapacity(const FluidState&,int)
340 template <class FluidState>
341 1 static Scalar heatCapacity(const FluidState &fluidState,
342 const int phaseIdx)
343 {
344 1 return heatCapacity(fluidState.temperature(phaseIdx),
345 1 fluidState.pressure(phaseIdx));
346 }
347 };
348
349 } // end namespace Dumux::FluidSystems
350
351 #endif
352