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