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 |