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 | * \brief @copybrief Dumux::FluidSystems::Spe5 | ||
11 | */ | ||
12 | #ifndef DUMUX_SPE5_FLUID_SYSTEM_HH | ||
13 | #define DUMUX_SPE5_FLUID_SYSTEM_HH | ||
14 | |||
15 | #include "spe5parametercache.hh" | ||
16 | |||
17 | #include <dumux/common/spline.hh> | ||
18 | #include <dumux/material/eos/pengrobinsonmixture.hh> | ||
19 | #include <dumux/io/name.hh> | ||
20 | |||
21 | namespace Dumux { | ||
22 | namespace FluidSystems { | ||
23 | |||
24 | /*! | ||
25 | * \ingroup FluidSystems | ||
26 | * \brief The fluid system for the SPE-5 benchmark problem. | ||
27 | * | ||
28 | * A three-phase fluid system featuring gas, oil and water as phases and the seven | ||
29 | * components distilled water, Methane \f$(\mathrm{C_1})\f$, Propane \f$(\mathrm{C_3})\f$, | ||
30 | * Pentane \f$(\mathrm{C_5})\f$, Heptane \f$(\mathrm{C_7})\f$, Decane | ||
31 | * \f$(\mathrm{C_{10}})\f$, Pentadecane \f$(\mathrm{C_{15}})\f$ and Icosane | ||
32 | * \f$(\mathrm{C_{20}})\f$. For the water phase the IAPWS-97 formulation is used as | ||
33 | * equation of state, while for the gas and oil phases a Peng-Robinson | ||
34 | * equation of state with slightly modified parameters is used. This fluid system is highly | ||
35 | * non-linear, and the gas and oil phases also cannot be considered ideal. | ||
36 | * | ||
37 | * See: | ||
38 | * | ||
39 | * J.E. Killough, et al.: Fifth Comparative Solution Project: | ||
40 | * Evaluation of Miscible Flood Simulators, Ninth SPE Symposium on | ||
41 | * Reservoir Simulation, 1987 \cite SPE5 | ||
42 | */ | ||
43 | template <class Scalar> | ||
44 | class Spe5 | ||
45 | { | ||
46 | using ThisType = FluidSystems::Spe5<Scalar>; | ||
47 | |||
48 | using PengRobinsonMixture = Dumux::PengRobinsonMixture<Scalar, ThisType>; | ||
49 | using PengRobinson = Dumux::PengRobinson<Scalar>; | ||
50 | |||
51 | public: | ||
52 | using ParameterCache = Spe5ParameterCache<Scalar, ThisType>; | ||
53 | |||
54 | /**************************************** | ||
55 | * Fluid phase parameters | ||
56 | ****************************************/ | ||
57 | |||
58 | //! Number of phases in the fluid system | ||
59 | static const int numPhases = 3; | ||
60 | |||
61 | //! Index of the gas phase | ||
62 | static const int gPhaseIdx = 0; | ||
63 | //! Index of the water phase | ||
64 | static const int wPhaseIdx = 1; | ||
65 | //! Index of the oil phase | ||
66 | static const int oPhaseIdx = 2; | ||
67 | |||
68 | //! The component for pure water to be used | ||
69 | using H2O = Dumux::Components::H2O<Scalar>; | ||
70 | |||
71 | /*! | ||
72 | * \brief Return the human readable name of a fluid phase | ||
73 | * \param phaseIdx The index of the fluid phase to consider | ||
74 | */ | ||
75 | 3 | static std::string phaseName(int phaseIdx) | |
76 | { | ||
77 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | assert(0 <= phaseIdx && phaseIdx < numPhases); |
78 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
3 | switch (phaseIdx) |
79 | { | ||
80 | 1 | case gPhaseIdx: return IOName::gaseousPhase(); | |
81 | 1 | case wPhaseIdx: return IOName::aqueousPhase(); | |
82 | 1 | case oPhaseIdx: return IOName::naplPhase(); | |
83 | } | ||
84 | ✗ | DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); | |
85 | } | ||
86 | |||
87 | /*! | ||
88 | * \brief Returns whether the fluids are miscible | ||
89 | */ | ||
90 | static constexpr bool isMiscible() | ||
91 | { return true; } | ||
92 | |||
93 | /*! | ||
94 | * \brief Return whether a phase is gaseous | ||
95 | * \param phaseIdx The index of the fluid phase to consider | ||
96 | */ | ||
97 | static constexpr bool isGas(int phaseIdx) | ||
98 | { | ||
99 | assert(0 <= phaseIdx && phaseIdx < numPhases); | ||
100 | return phaseIdx == gPhaseIdx; | ||
101 | } | ||
102 | |||
103 | /*! | ||
104 | * \brief Return whether a phase is compressible | ||
105 | * \param phaseIdx The index of the fluid phase to consider | ||
106 | * | ||
107 | * In the SPE-5 problems all fluids are compressible... | ||
108 | */ | ||
109 | static constexpr bool isCompressible(int phaseIdx) | ||
110 | { | ||
111 | assert(0 <= phaseIdx && phaseIdx < numPhases); | ||
112 | return true; | ||
113 | } | ||
114 | |||
115 | /*! | ||
116 | * \brief Returns true if and only if a fluid phase is assumed to | ||
117 | * be an ideal mixture. | ||
118 | * | ||
119 | * We define an ideal mixture as a fluid phase where the fugacity | ||
120 | * coefficients of all components times the pressure of the phase | ||
121 | * are independent on the fluid composition. This assumption is true | ||
122 | * if Henry's law and Raoult's law apply. If you are unsure what | ||
123 | * this function should return, it is safe to return false. The | ||
124 | * only damage done will be (slightly) increased computation times | ||
125 | * in some cases. | ||
126 | * \param phaseIdx The index of the fluid phase to consider | ||
127 | */ | ||
128 | static bool isIdealMixture(int phaseIdx) | ||
129 | { | ||
130 | // always use the reference oil for the fugacity coefficients, | ||
131 | // so they cannot be dependent on composition and they the | ||
132 | // phases thus always an ideal mixture | ||
133 | return phaseIdx == wPhaseIdx; | ||
134 | } | ||
135 | |||
136 | /*! | ||
137 | * \brief Returns true if and only if a fluid phase is assumed to | ||
138 | * be an ideal gas. | ||
139 | * | ||
140 | * \param phaseIdx The index of the fluid phase to consider | ||
141 | */ | ||
142 | static bool isIdealGas(int phaseIdx) | ||
143 | { | ||
144 | assert(0 <= phaseIdx && phaseIdx < numPhases); | ||
145 | return false; // gas is not ideal here! | ||
146 | } | ||
147 | |||
148 | /**************************************** | ||
149 | * Component related parameters | ||
150 | ****************************************/ | ||
151 | |||
152 | //! Number of components in the fluid system | ||
153 | static const int numComponents = 7; | ||
154 | |||
155 | static const int H2OIdx = 0; | ||
156 | static const int C1Idx = 1; | ||
157 | static const int C3Idx = 2; | ||
158 | static const int C6Idx = 3; | ||
159 | static const int C10Idx = 4; | ||
160 | static const int C15Idx = 5; | ||
161 | static const int C20Idx = 6; | ||
162 | |||
163 | /*! | ||
164 | * \brief Return the human readable name of a component | ||
165 | * \param compIdx The index of the component to consider | ||
166 | */ | ||
167 | 7 | static std::string componentName(int compIdx) | |
168 | { | ||
169 |
21/42✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 1 times.
✗ Branch 31 not taken.
✓ Branch 33 taken 1 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 39 taken 1 times.
✗ Branch 40 not taken.
✓ Branch 42 taken 1 times.
✗ Branch 43 not taken.
✓ Branch 45 taken 1 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 1 times.
✗ Branch 49 not taken.
✓ Branch 51 taken 1 times.
✗ Branch 52 not taken.
✓ Branch 54 taken 1 times.
✗ Branch 55 not taken.
✓ Branch 57 taken 1 times.
✗ Branch 58 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
|
7 | static std::string name[] = { |
170 | H2O::name(), | ||
171 | std::string("C1"), | ||
172 | std::string("C3"), | ||
173 | std::string("C6"), | ||
174 | std::string("C10"), | ||
175 | std::string("C15"), | ||
176 | std::string("C20") | ||
177 | }; | ||
178 | |||
179 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | assert(0 <= compIdx && compIdx < numComponents); |
180 | 7 | return name[compIdx]; | |
181 | } | ||
182 | |||
183 | /*! | ||
184 | * \brief Return the molar mass of a component in \f$\mathrm{[kg/mol]}\f$. | ||
185 | * \param compIdx The index of the component to consider | ||
186 | */ | ||
187 | static Scalar molarMass(int compIdx) | ||
188 | { | ||
189 | static const Scalar M[] = { | ||
190 | H2O::molarMass(), | ||
191 | 16.04e-3, // C1 | ||
192 | 44.10e-3, // C3 | ||
193 | 86.18e-3, // C6 | ||
194 | 142.29e-3, // C10 | ||
195 | 206.00e-3, // C15 | ||
196 | 282.00e-3 // C20 | ||
197 | }; | ||
198 | |||
199 | assert(0 <= compIdx && compIdx < numComponents); | ||
200 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
506072 | return M[compIdx]; |
201 | } | ||
202 | |||
203 | /*! | ||
204 | * \brief Critical temperature of a component \f$\mathrm{[K]}\f$. | ||
205 | * \param compIdx The index of the component to consider | ||
206 | */ | ||
207 | static Scalar criticalTemperature(int compIdx) | ||
208 | { | ||
209 | static const Scalar Tcrit[] = { | ||
210 | H2O::criticalTemperature(), // H2O | ||
211 | 343.0*5/9, // C1 | ||
212 | 665.7*5/9, // C3 | ||
213 | 913.4*5/9, // C6 | ||
214 | 1111.8*5/9, // C10 | ||
215 | 1270.0*5/9, // C15 | ||
216 | 1380.0*5/9 // C20 | ||
217 | }; | ||
218 | |||
219 | assert(0 <= compIdx && compIdx < numComponents); | ||
220 |
4/4✓ Branch 0 taken 36845 times.
✓ Branch 1 taken 14738 times.
✓ Branch 2 taken 36880 times.
✓ Branch 3 taken 14752 times.
|
103215 | return Tcrit[compIdx]; |
221 | } | ||
222 | |||
223 | /*! | ||
224 | * \brief Critical pressure of a component \f$\mathrm{[Pa]}\f$. | ||
225 | * \param compIdx The index of the component to consider | ||
226 | */ | ||
227 | static Scalar criticalPressure(int compIdx) | ||
228 | { | ||
229 | static const Scalar pcrit[] = { | ||
230 | H2O::criticalPressure(), // H2O | ||
231 | 667.8 * 6894.7573, // C1 | ||
232 | 616.3 * 6894.7573, // C3 | ||
233 | 436.9 * 6894.7573, // C6 | ||
234 | 304.0 * 6894.7573, // C10 | ||
235 | 200.0 * 6894.7573, // C15 | ||
236 | 162.0 * 6894.7573 // C20 | ||
237 | }; | ||
238 | |||
239 | assert(0 <= compIdx && compIdx < numComponents); | ||
240 |
4/4✓ Branch 0 taken 36845 times.
✓ Branch 1 taken 14738 times.
✓ Branch 2 taken 36880 times.
✓ Branch 3 taken 14752 times.
|
103215 | return pcrit[compIdx]; |
241 | } | ||
242 | |||
243 | /*! | ||
244 | * \brief Molar volume of a component at the critical point \f$\mathrm{[m^3/mol]}\f$. | ||
245 | * \param compIdx The index of the component to consider | ||
246 | */ | ||
247 | static Scalar criticalMolarVolume(int compIdx) | ||
248 | { | ||
249 | static const Scalar R = 8.314472; | ||
250 | static const Scalar vcrit[] = { | ||
251 | H2O::criticalMolarVolume(), // H2O | ||
252 | 0.290*R*criticalTemperature(1)/criticalPressure(1), // C1 | ||
253 | 0.277*R*criticalTemperature(2)/criticalPressure(2), // C3 | ||
254 | 0.264*R*criticalTemperature(3)/criticalPressure(3), // C6 | ||
255 | 0.257*R*criticalTemperature(4)/criticalPressure(4), // C10 | ||
256 | 0.245*R*criticalTemperature(5)/criticalPressure(5), // C15 | ||
257 | 0.235*R*criticalTemperature(6)/criticalPressure(6) // C20 | ||
258 | }; | ||
259 | |||
260 | assert(0 <= compIdx && compIdx < numComponents); | ||
261 | return vcrit[compIdx]; | ||
262 | } | ||
263 | |||
264 | /*! | ||
265 | * \brief The acentric factor of a component \f$\mathrm{[-]}\f$. | ||
266 | * \param compIdx The index of the component to consider | ||
267 | */ | ||
268 | static Scalar acentricFactor(int compIdx) | ||
269 | { | ||
270 | static const Scalar accFac[] = { | ||
271 | 0.344, // H2O (from Reid, et al.) | ||
272 | 0.0130, // C1 | ||
273 | 0.1524, // C3 | ||
274 | 0.3007, // C6 | ||
275 | 0.4885, // C10 | ||
276 | 0.6500, // C15 | ||
277 | 0.8500 // C20 | ||
278 | }; | ||
279 | |||
280 | assert(0 <= compIdx && compIdx < numComponents); | ||
281 |
4/4✓ Branch 0 taken 36845 times.
✓ Branch 1 taken 14738 times.
✓ Branch 2 taken 36880 times.
✓ Branch 3 taken 14752 times.
|
103215 | return accFac[compIdx]; |
282 | } | ||
283 | |||
284 | /*! | ||
285 | * \brief Returns the interaction coefficient for two components. | ||
286 | * \param comp1Idx The index of component 1 to consider | ||
287 | * \param comp2Idx The index of component 2 to consider | ||
288 | * | ||
289 | * The values are given by the SPE5 paper. | ||
290 | */ | ||
291 | static Scalar interactionCoefficient(int comp1Idx, int comp2Idx) | ||
292 | { | ||
293 | using std::min; | ||
294 | using std::max; | ||
295 |
6/6✓ Branch 0 taken 154749 times.
✓ Branch 1 taken 206332 times.
✓ Branch 2 taken 795858 times.
✓ Branch 3 taken 1061144 times.
✓ Branch 4 taken 154686 times.
✓ Branch 5 taken 206248 times.
|
2579017 | int i = min(comp1Idx, comp2Idx); |
296 |
6/6✓ Branch 0 taken 154749 times.
✓ Branch 1 taken 206332 times.
✓ Branch 2 taken 795858 times.
✓ Branch 3 taken 1061144 times.
✓ Branch 4 taken 154686 times.
✓ Branch 5 taken 206248 times.
|
2579017 | int j = max(comp1Idx, comp2Idx); |
297 |
12/12✓ Branch 0 taken 81059 times.
✓ Branch 1 taken 280022 times.
✓ Branch 2 taken 51583 times.
✓ Branch 3 taken 29476 times.
✓ Branch 4 taken 416878 times.
✓ Branch 5 taken 1440124 times.
✓ Branch 6 taken 265286 times.
✓ Branch 7 taken 151592 times.
✓ Branch 8 taken 81026 times.
✓ Branch 9 taken 279908 times.
✓ Branch 10 taken 51562 times.
✓ Branch 11 taken 29464 times.
|
2579017 | if (i == C1Idx && (j == C15Idx || j == C20Idx)) |
298 | return 0.05; | ||
299 |
12/12✓ Branch 0 taken 66321 times.
✓ Branch 1 taken 265284 times.
✓ Branch 2 taken 29476 times.
✓ Branch 3 taken 36845 times.
✓ Branch 4 taken 341082 times.
✓ Branch 5 taken 1364328 times.
✓ Branch 6 taken 151592 times.
✓ Branch 7 taken 189490 times.
✓ Branch 8 taken 66294 times.
✓ Branch 9 taken 265176 times.
✓ Branch 10 taken 29464 times.
✓ Branch 11 taken 36830 times.
|
2368485 | else if (i == C3Idx && (j == C15Idx || j == C20Idx)) |
300 | return 0.005; | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | /**************************************** | ||
305 | * Methods which compute stuff | ||
306 | ****************************************/ | ||
307 | |||
308 | /*! | ||
309 | * \brief Initialize the fluid system's static parameters | ||
310 | */ | ||
311 | 2 | static void init() | |
312 | { | ||
313 | PengRobinsonParamsMixture<Scalar, ThisType, gPhaseIdx, /*useSpe5=*/true> prParams; | ||
314 | |||
315 | // find envelopes of the 'a' and 'b' parameters for the range | ||
316 | // 273.15K <= T <= 373.15K and 10e3 Pa <= p <= 100e6 Pa. For | ||
317 | // this we take advantage of the fact that 'a' and 'b' for | ||
318 | // mixtures is just a convex combination of the attractive and | ||
319 | // repulsive parameters of the pure components | ||
320 | 2 | Scalar minT = 273.15, maxT = 373.15; | |
321 | 2 | Scalar minP = 1e4, maxP = 100e6; | |
322 | |||
323 | 2 | Scalar minA = 1e100, maxA = -1e100; | |
324 | 2 | Scalar minB = 1e100, maxB = -1e100; | |
325 | |||
326 | 2 | prParams.updatePure(minT, minP); | |
327 | using std::min; | ||
328 | using std::max; | ||
329 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
|
16 | for (int compIdx = 0; compIdx < numComponents; ++compIdx) { |
330 |
4/4✓ Branch 0 taken 10 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 4 times.
|
28 | minA = min(prParams.pureParams(compIdx).a(), minA); |
331 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
|
14 | maxA = max(prParams.pureParams(compIdx).a(), maxA); |
332 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
|
14 | minB = min(prParams.pureParams(compIdx).b(), minB); |
333 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | maxB = max(prParams.pureParams(compIdx).b(), maxB); |
334 | } | ||
335 | |||
336 | 2 | prParams.updatePure(maxT, minP); | |
337 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
|
16 | for (int compIdx = 0; compIdx < numComponents; ++compIdx) { |
338 |
4/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 2 times.
|
28 | minA = min(prParams.pureParams(compIdx).a(), minA); |
339 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | maxA = max(prParams.pureParams(compIdx).a(), maxA); |
340 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
|
14 | minB = min(prParams.pureParams(compIdx).b(), minB); |
341 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
|
26 | maxB = max(prParams.pureParams(compIdx).b(), maxB); |
342 | } | ||
343 | |||
344 | 2 | prParams.updatePure(minT, maxP); | |
345 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
|
16 | for (int compIdx = 0; compIdx < numComponents; ++compIdx) { |
346 |
2/4✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
28 | minA = min(prParams.pureParams(compIdx).a(), minA); |
347 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
|
14 | maxA = max(prParams.pureParams(compIdx).a(), maxA); |
348 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
|
14 | minB = min(prParams.pureParams(compIdx).b(), minB); |
349 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
|
26 | maxB = max(prParams.pureParams(compIdx).b(), maxB); |
350 | } | ||
351 | |||
352 | 2 | prParams.updatePure(maxT, maxP); | |
353 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
|
16 | for (int compIdx = 0; compIdx < numComponents; ++compIdx) { |
354 |
4/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 2 times.
|
28 | minA = min(prParams.pureParams(compIdx).a(), minA); |
355 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | maxA = max(prParams.pureParams(compIdx).a(), maxA); |
356 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
|
14 | minB = min(prParams.pureParams(compIdx).b(), minB); |
357 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
|
26 | maxB = max(prParams.pureParams(compIdx).b(), maxB); |
358 | } | ||
359 | |||
360 | 2 | PengRobinson::init(/*aMin=*/minA, /*aMax=*/maxA, /*na=*/100, | |
361 | /*bMin=*/minB, /*bMax=*/maxB, /*nb=*/200); | ||
362 | 2 | } | |
363 | |||
364 | /*! | ||
365 | * \brief Calculate the density \f$\mathrm{[kg/m^3]}\f$ of a fluid phase | ||
366 | * | ||
367 | * | ||
368 | * \param fluidState An arbitrary fluid state | ||
369 | * \param paramCache Container for cache parameters | ||
370 | * \param phaseIdx The index of the fluid phase to consider | ||
371 | */ | ||
372 | template <class FluidState> | ||
373 | 56830 | static Scalar density(const FluidState &fluidState, | |
374 | const ParameterCache ¶mCache, | ||
375 | int phaseIdx) | ||
376 | { | ||
377 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56830 times.
|
56830 | assert(0 <= phaseIdx && phaseIdx < numPhases); |
378 | |||
379 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 56827 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 56827 times.
|
113657 | return fluidState.averageMolarMass(phaseIdx)/paramCache.molarVolume(phaseIdx); |
380 | } | ||
381 | |||
382 | /*! | ||
383 | * \brief The molar density \f$\rho_{mol,\alpha}\f$ | ||
384 | * of a fluid phase \f$\alpha\f$ in \f$\mathrm{[mol/m^3]}\f$ | ||
385 | * | ||
386 | * The molar density is defined by the | ||
387 | * mass density \f$\rho_\alpha\f$ and the mean molar mass \f$\overline M_\alpha\f$: | ||
388 | * | ||
389 | * \f[\rho_{mol,\alpha} = \frac{\rho_\alpha}{\overline M_\alpha} \;.\f] | ||
390 | */ | ||
391 | template <class FluidState> | ||
392 | ✗ | static Scalar molarDensity(const FluidState &fluidState, const ParameterCache ¶mCache, int phaseIdx) | |
393 | { | ||
394 |
7/14✗ Branch 0 not taken.
✓ Branch 1 taken 4986 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9975 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 34902 times.
✓ Branch 6 taken 23268 times.
✓ Branch 7 taken 11634 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6966 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
|
56830 | return 1.0/paramCache.molarVolume(phaseIdx); |
395 | } | ||
396 | |||
397 | /*! | ||
398 | * \brief Calculate the dynamic viscosity of a fluid phase \f$\mathrm{[Pa*s]}\f$ | ||
399 | * \param fs An arbitrary fluid state | ||
400 | * \param paramCache Container for cache parameters | ||
401 | * \param phaseIdx The index of the fluid phase to consider | ||
402 | */ | ||
403 | template <class FluidState> | ||
404 | ✗ | static Scalar viscosity(const FluidState &fs, | |
405 | const ParameterCache ¶mCache, | ||
406 | int phaseIdx) | ||
407 | { | ||
408 | ✗ | assert(0 <= phaseIdx && phaseIdx <= numPhases); | |
409 | |||
410 | ✗ | if (phaseIdx == gPhaseIdx) { | |
411 | // given by SPE-5 in table on page 64. we use a constant | ||
412 | // viscosity, though... | ||
413 | ✗ | return 0.0170e-2 * 0.1; | |
414 | } | ||
415 | ✗ | else if (phaseIdx == wPhaseIdx) | |
416 | // given by SPE-5: 0.7 centi-Poise = 0.0007 Pa s | ||
417 | ✗ | return 0.7e-2 * 0.1; | |
418 | else { | ||
419 | ✗ | assert(phaseIdx == oPhaseIdx); | |
420 | // given by SPE-5 in table on page 64. we use a constant | ||
421 | // viscosity, though... | ||
422 | ✗ | return 0.208e-2 * 0.1; | |
423 | } | ||
424 | } | ||
425 | |||
426 | /*! | ||
427 | * \brief Calculate the fugacity coefficient \f$\mathrm{[-]}\f$ of an individual | ||
428 | * component in a fluid phase | ||
429 | * | ||
430 | * The fugacity coefficient \f$\mathrm{\phi^\kappa_\alpha}\f$ is connected | ||
431 | * to the fugacity \f$\mathrm{f^\kappa_\alpha}\f$ and the component's mole | ||
432 | * fraction in a phase \f$\mathrm{x^\kappa_\alpha}\f$ by means of the | ||
433 | * relation | ||
434 | * | ||
435 | * \f[ f^\kappa_\alpha = \phi^\kappa_\alpha \cdot x^\kappa_\alpha \cdot p_alpha \f] | ||
436 | * \param fs An arbitrary fluid state | ||
437 | * \param paramCache Container for cache parameters | ||
438 | * \param phaseIdx The index of the fluid phase to consider | ||
439 | * \param compIdx The index of the component to consider | ||
440 | */ | ||
441 | template <class FluidState> | ||
442 | 316386 | static Scalar fugacityCoefficient(const FluidState &fs, | |
443 | const ParameterCache ¶mCache, | ||
444 | int phaseIdx, | ||
445 | int compIdx) | ||
446 | { | ||
447 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 316386 times.
|
316386 | assert(0 <= phaseIdx && phaseIdx <= numPhases); |
448 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 316386 times.
|
316386 | assert(0 <= compIdx && compIdx <= numComponents); |
449 | |||
450 |
2/2✓ Branch 0 taken 265216 times.
✓ Branch 1 taken 51170 times.
|
316386 | if (phaseIdx == oPhaseIdx || phaseIdx == gPhaseIdx) |
451 | 265216 | return PengRobinsonMixture::computeFugacityCoefficient(fs, | |
452 | paramCache, | ||
453 | phaseIdx, | ||
454 | 265216 | compIdx); | |
455 | else { | ||
456 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 51170 times.
|
51170 | assert(phaseIdx == wPhaseIdx); |
457 | 102333 | return henryCoeffWater_(compIdx, fs.temperature(wPhaseIdx)) | |
458 | 102333 | / fs.pressure(wPhaseIdx); | |
459 | } | ||
460 | } | ||
461 | |||
462 | |||
463 | /*! | ||
464 | * \brief Calculate the binary molecular diffusion coefficient for | ||
465 | * a component in a fluid phase \f$\mathrm{[mol^2 * s / (kg*m^3)]}\f$ | ||
466 | * | ||
467 | * Molecular diffusion of a component \f$\mathrm{\kappa}\f$ is caused by a | ||
468 | * gradient of the chemical potential and follows the law | ||
469 | * | ||
470 | * \f[ J = - D grad \mu_\kappa \f] | ||
471 | * | ||
472 | * where \f$\mathrm{\mu_\kappa}\f$ is the component's chemical potential, | ||
473 | * \f$\mathrm{D}\f$ is the diffusion coefficient and \f$\mathrm{J}\f$ is the | ||
474 | * diffusive flux. \f$\mathrm{\mu_\kappa}\f$ is connected to the component's | ||
475 | * fugacity \f$\mathrm{f_\kappa}\f$ by the relation | ||
476 | * | ||
477 | * \f[ \mu_\kappa = R T_\alpha \mathrm{ln} \frac{f_\kappa}{p_\alpha} \f] | ||
478 | * | ||
479 | * where \f$\mathrm{p_\alpha}\f$ and \f$\mathrm{T_\alpha}\f$ are the fluid phase' | ||
480 | * pressure and temperature. | ||
481 | * \param fs An arbitrary fluid state | ||
482 | * \param paramCache Container for cache parameters | ||
483 | * \param phaseIdx The index of the fluid phase to consider | ||
484 | * \param compIdx The index of the component to consider | ||
485 | */ | ||
486 | template <class FluidState> | ||
487 | 21 | static Scalar diffusionCoefficient(const FluidState &fs, | |
488 | const ParameterCache ¶mCache, | ||
489 | int phaseIdx, | ||
490 | int compIdx) | ||
491 |
7/16✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✓ Branch 11 taken 21 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 21 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 21 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 21 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 21 times.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 21 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
|
231 | { DUNE_THROW(Dune::NotImplemented, "Diffusion coefficients"); } |
492 | |||
493 | /*! | ||
494 | * \brief Given a phase's composition, temperature and pressure, | ||
495 | * return the binary diffusion coefficient \f$\mathrm{[m^2/s]}\f$ for components | ||
496 | * \f$i\f$ and \f$j\f$ in this phase. | ||
497 | * | ||
498 | * \param fluidState An arbitrary fluid state | ||
499 | * \param paramCache Container for cache parameters | ||
500 | * \param phaseIdx The index of the fluid phase to consider | ||
501 | * \param compIIdx The index of the first component to consider | ||
502 | * \param compJIdx The index of the second component to consider | ||
503 | */ | ||
504 | template <class FluidState> | ||
505 | 147 | static Scalar binaryDiffusionCoefficient(const FluidState &fluidState, | |
506 | const ParameterCache ¶mCache, | ||
507 | int phaseIdx, | ||
508 | int compIIdx, | ||
509 | int compJIdx) | ||
510 |
7/16✓ Branch 2 taken 147 times.
✗ Branch 3 not taken.
✓ Branch 11 taken 147 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 147 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 147 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 147 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 147 times.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 147 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
|
1617 | { DUNE_THROW(Dune::NotImplemented, "Binary diffusion coefficients"); } |
511 | |||
512 | /*! | ||
513 | * \brief Given a phase's composition, temperature and pressure, | ||
514 | * calculate its specific enthalpy \f$\mathrm{[J/kg]}\f$. | ||
515 | * \param fs An arbitrary fluid state | ||
516 | * \param paramCache Container for cache parameters | ||
517 | * \param phaseIdx The index of the fluid phase to consider | ||
518 | */ | ||
519 | template <class FluidState> | ||
520 | 3 | static Scalar enthalpy(const FluidState &fs, | |
521 | const ParameterCache ¶mCache, | ||
522 | int phaseIdx) | ||
523 |
7/16✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 11 taken 3 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 3 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 3 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 3 times.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 3 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
|
33 | { DUNE_THROW(Dune::NotImplemented, "Enthalpies"); } |
524 | |||
525 | /*! | ||
526 | * \brief Given a phase's composition, temperature and pressure, | ||
527 | * calculate its thermal conductivity \f$\mathrm{[W/(m K)]}\f$. | ||
528 | * \param fluidState An arbitrary fluid state | ||
529 | * \param paramCache Container for cache parameters | ||
530 | * \param phaseIdx The index of the fluid phase to consider | ||
531 | */ | ||
532 | template <class FluidState> | ||
533 | 3 | static Scalar thermalConductivity(const FluidState &fluidState, | |
534 | const ParameterCache ¶mCache, | ||
535 | int phaseIdx) | ||
536 |
7/16✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 11 taken 3 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 3 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 3 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 3 times.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 3 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
|
33 | { DUNE_THROW(Dune::NotImplemented, "Thermal conductivities"); } |
537 | |||
538 | /*! | ||
539 | * \brief Given a phase's composition, temperature and pressure, | ||
540 | * calculate its heat capacity \f$\mathrm{[J/(kg K)]}\f$. | ||
541 | * \param fluidState An arbitrary fluid state | ||
542 | * \param paramCache Container for cache parameters | ||
543 | * \param phaseIdx The index of the fluid phase to consider | ||
544 | */ | ||
545 | template <class FluidState> | ||
546 | 3 | static Scalar heatCapacity(const FluidState &fluidState, | |
547 | const ParameterCache ¶mCache, | ||
548 | int phaseIdx) | ||
549 |
7/16✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 11 taken 3 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 3 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 3 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 3 times.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 3 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
|
33 | { DUNE_THROW(Dune::NotImplemented, "Heat capacities"); } |
550 | |||
551 | |||
552 | private: | ||
553 | 51170 | static Scalar henryCoeffWater_(int compIdx, Scalar temperature) | |
554 | { | ||
555 | // use henry's law for the solutes and the vapor pressure for | ||
556 | // the solvent. | ||
557 |
7/8✓ Branch 0 taken 7310 times.
✓ Branch 1 taken 7310 times.
✓ Branch 2 taken 7310 times.
✓ Branch 3 taken 7310 times.
✓ Branch 4 taken 7310 times.
✓ Branch 5 taken 7310 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7310 times.
|
51170 | switch (compIdx) { |
558 | 7310 | case H2OIdx: return H2O::vaporPressure(temperature); | |
559 | |||
560 | // the values of the Henry constant for the solutes have | ||
561 | // are faked so far... | ||
562 | case C1Idx: return 5.57601e+09; | ||
563 | 7310 | case C3Idx: return 1e10; | |
564 | 7310 | case C6Idx: return 1e10; | |
565 | 7310 | case C10Idx: return 1e10; | |
566 | 7310 | case C15Idx: return 1e10; | |
567 | 7310 | case C20Idx: return 1e10; | |
568 | ✗ | default: DUNE_THROW(Dune::InvalidStateException, "Unknown component index " << compIdx); | |
569 | } | ||
570 | } | ||
571 | }; | ||
572 | |||
573 | } // end namespace FluidSystems | ||
574 | } // end namespace Dumux | ||
575 | |||
576 | #endif | ||
577 |