version 3.7
brine_co2.hh
Go to the documentation of this file.
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//
12#ifndef DUMUX_BINARY_COEFF_BRINE_CO2_HH
13#define DUMUX_BINARY_COEFF_BRINE_CO2_HH
14
15#include <dune/common/math.hh>
16
17#include <type_traits>
18#include <dune/common/debugstream.hh>
25
26namespace Dumux::BinaryCoeff {
27
32template<class Scalar, class CO2Impl, bool verbose = true>
33class Brine_CO2 {
35
36 static constexpr bool rawCO2Table = Deprecated::BrineCO2Helper<CO2Impl>::isRawTable();
37 using CO2Component = typename std::conditional_t< rawCO2Table,
39 CO2Impl >;
40 using CO2 = CO2Component;
42 static constexpr int lPhaseIdx = 0; // index of the liquid phase
43 static constexpr int gPhaseIdx = 1; // index of the gas phase
44
45public:
53 static Scalar gasDiffCoeff(Scalar temperature, Scalar pressure)
54 {
55 static const bool hasGasDiffCoeff = hasParam("BinaryCoefficients.GasDiffCoeff");
56 if (!hasGasDiffCoeff) //in case one might set that user-specific as e.g. in dumux-lecture/mm/convectivemixing
57 {
58 //Diffusion coefficient of water in the CO2 phase
59 constexpr Scalar PI = 3.141593;
60 constexpr Scalar k = 1.3806504e-23; // Boltzmann constant
61 constexpr Scalar c = 4; // slip parameter, can vary between 4 (slip condition) and 6 (stick condition)
62 constexpr Scalar R_h = 1.72e-10; // hydrodynamic radius of the solute
63 const Scalar mu = CO2::gasViscosity(temperature, pressure); // CO2 viscosity
64 return k / (c * PI * R_h) * (temperature / mu);
65 }
66 else
67 {
68 static const Scalar D = getParam<Scalar>("BinaryCoefficients.GasDiffCoeff");
69 return D;
70 }
71 }
72
79 static Scalar liquidDiffCoeff(Scalar temperature, Scalar pressure)
80 {
81 //Diffusion coefficient of CO2 in the brine phase
82 static const bool hasLiquidDiffCoeff = hasParam("BinaryCoefficients.LiquidDiffCoeff");
83 if (!hasLiquidDiffCoeff) //in case one might set that user-specific as e.g. in dumux-lecture/mm/convectivemixing
84 return 2e-9;
85 else
86 {
87 const Scalar D = getParam<Scalar>("BinaryCoefficients.LiquidDiffCoeff");
88 return D;
89 }
90 }
91
109 static void calculateMoleFractions(const Scalar temperature,
110 const Scalar pg,
111 const Scalar salinity,
112 const int knownPhaseIdx,
113 Scalar &xlCO2,
114 Scalar &ygH2O)
115 {
116
117 const Scalar A = computeA_(temperature, pg);
118
119 /* salinity: conversion from mass fraction to mol fraction */
120 const Scalar x_NaCl = salinityToMoleFrac_(salinity);
121
122 // if both phases are present the mole fractions in each phase can be calculate
123 // with the mutual solubility function
124 if (knownPhaseIdx < 0)
125 {
126 const Scalar molalityNaCl = molFracToMolality_(x_NaCl); // molality of NaCl //CHANGED
127 const Scalar m0_CO2 = molalityCO2inPureWater_(temperature, pg); // molality of CO2 in pure water
128 const Scalar gammaStar = activityCoefficient_(temperature, pg, molalityNaCl);// activity coefficient of CO2 in brine
129 const Scalar m_CO2 = m0_CO2 / gammaStar; // molality of CO2 in brine
130 xlCO2 = m_CO2 / (molalityNaCl + 55.508 + m_CO2); // mole fraction of CO2 in brine
131 ygH2O = A * (1 - xlCO2 - x_NaCl); // mole fraction of water in the gas phase
132 }
133
134 // if only liquid phase is present the mole fraction of CO2 in brine is given and
135 // and the virtual equilibrium mole fraction of water in the non-existing gas phase can be estimated
136 // with the mutual solubility function
137 if (knownPhaseIdx == lPhaseIdx)
138 ygH2O = A * (1 - xlCO2 - x_NaCl);
139
140 // if only gas phase is present the mole fraction of water in the gas phase is given and
141 // and the virtual equilibrium mole fraction of CO2 in the non-existing liquid phase can be estimated
142 // with the mutual solubility function
143 if (knownPhaseIdx == gPhaseIdx)
144 xlCO2 = 1 - x_NaCl - ygH2O / A;
145 }
146
154 static Scalar fugacityCoefficientCO2(Scalar T, Scalar pg)
155 {
156 const Scalar V = 1 / (CO2::gasDensity(T, pg) / CO2::molarMass()) * 1.e6; // molar volume in cm^3/mol
157 const Scalar pg_bar = pg / 1.e5; // gas phase pressure in bar
158 const Scalar a_CO2 = (7.54e7 - 4.13e4 * T); // mixture parameter of Redlich-Kwong equation
159 constexpr Scalar b_CO2 = 27.8; // mixture parameter of Redlich-Kwong equation
160 constexpr Scalar R = IdealGas::R * 10.; // ideal gas constant with unit bar cm^3 /(K mol)
161
162 using std::log;
163 using std::exp;
164 using std::pow;
165 const Scalar lnPhiCO2 = log(V / (V - b_CO2)) + b_CO2 / (V - b_CO2) - 2 * a_CO2 / (R
166 * pow(T, 1.5) * b_CO2) * log((V + b_CO2) / V) + a_CO2 * b_CO2
167 / (R * pow(T, 1.5) * b_CO2 * b_CO2) * (log((V + b_CO2) / V)
168 - b_CO2 / (V + b_CO2)) - log(pg_bar * V / (R * T));
169
170 return exp(lnPhiCO2); // fugacity coefficient of CO2
171 }
172
180 static Scalar fugacityCoefficientH2O(Scalar T, Scalar pg)
181 {
182 const Scalar V = 1 / (CO2::gasDensity(T, pg) / CO2::molarMass()) * 1.e6; // molar volume in cm^3/mol
183 const Scalar pg_bar = pg / 1.e5; // gas phase pressure in bar
184 const Scalar a_CO2 = (7.54e7 - 4.13e4 * T);// mixture parameter of Redlich-Kwong equation
185 constexpr Scalar a_CO2_H2O = 7.89e7;// mixture parameter of Redlich-Kwong equation
186 constexpr Scalar b_CO2 = 27.8;// mixture parameter of Redlich-Kwong equation
187 constexpr Scalar b_H2O = 18.18;// mixture parameter of Redlich-Kwong equation
188 constexpr Scalar R = IdealGas::R * 10.; // ideal gas constant with unit bar cm^3 /(K mol)
189
190 using std::log;
191 using std::pow;
192 using std::exp;
193 const Scalar lnPhiH2O = log(V / (V - b_CO2)) + b_H2O / (V - b_CO2) - 2 * a_CO2_H2O
194 / (R * pow(T, 1.5) * b_CO2) * log((V + b_CO2) / V) + a_CO2
195 * b_H2O / (R * pow(T, 1.5) * b_CO2 * b_CO2) * (log((V + b_CO2)
196 / V) - b_CO2 / (V + b_CO2)) - log(pg_bar * V / (R * T));
197
198 return exp(lnPhiH2O); // fugacity coefficient of H2O
199 }
200
201private:
206 static Scalar salinityToMoleFrac_(Scalar salinity)
207 {
208 constexpr Scalar Mw = H2O::molarMass(); // molecular weight of water [kg/mol]
209 constexpr Scalar Ms = 58.8e-3; // molecular weight of NaCl [kg/mol]
210
211 const Scalar X_NaCl = salinity;
212 // salinity: conversion from mass fraction to mol fraction
213 const Scalar x_NaCl = -Mw * X_NaCl / ((Ms - Mw) * X_NaCl - Ms);
214 return x_NaCl;
215 }
216
223 static Scalar molFracToMolality_(Scalar x_NaCl)
224 {
225 // conversion from mol fraction to molality (dissolved CO2 neglected)
226 return 55.508 * x_NaCl / (1 - x_NaCl);
227 }
228
236 static Scalar molalityCO2inPureWater_(Scalar temperature, Scalar pg)
237 {
238 const Scalar A = computeA_(temperature, pg); // according to Spycher, Pruess and Ennis-King (2003)
239 const Scalar B = computeB_(temperature, pg); // according to Spycher, Pruess and Ennis-King (2003)
240 const Scalar yH2OinGas = (1 - B) / (1. / A - B); // equilibrium mol fraction of H2O in the gas phase
241 const Scalar xCO2inWater = B * (1 - yH2OinGas); // equilibrium mol fraction of CO2 in the water phase
242 return (xCO2inWater * 55.508) / (1 - xCO2inWater); // CO2 molality
243 }
244
254 static Scalar activityCoefficient_(Scalar temperature, Scalar pg, Scalar molalityNaCl)
255 {
256 const Scalar lambda = computeLambda_(temperature, pg); // lambda_{CO2-Na+}
257 const Scalar xi = computeXi_(temperature, pg); // Xi_{CO2-Na+-Cl-}
258 const Scalar lnGammaStar = 2 * lambda * molalityNaCl + xi * molalityNaCl
259 * molalityNaCl;
260 using std::exp;
261 return exp(lnGammaStar); // molal activity coefficient of CO2 in brine
262 }
263
272 static Scalar computeA_(Scalar T, Scalar pg)
273 {
274 const Scalar deltaP = pg / 1e5 - 1; // pressure range [bar] from p0 = 1bar to pg[bar]
275 const Scalar v_av_H2O = 18.1; // average partial molar volume of H2O [cm^3/mol]
276 constexpr Scalar R = IdealGas::R * 10;
277 const Scalar k0_H2O = equilibriumConstantH2O_(T); // equilibrium constant for H2O at 1 bar
278 const Scalar phi_H2O = fugacityCoefficientH2O(T, pg); // fugacity coefficient of H2O for the water-CO2 system
279 const Scalar pg_bar = pg / 1.e5;
280 using std::exp;
281 return k0_H2O / (phi_H2O * pg_bar) * exp(deltaP * v_av_H2O / (R * T));
282 }
283
292 static Scalar computeB_(Scalar T, Scalar pg)
293 {
294 const Scalar deltaP = pg / 1e5 - 1; // pressure range [bar] from p0 = 1bar to pg[bar]
295 constexpr Scalar v_av_CO2 = 32.6; // average partial molar volume of CO2 [cm^3/mol]
296 constexpr Scalar R = IdealGas::R * 10;
297 const Scalar k0_CO2 = equilibriumConstantCO2_(T); // equilibrium constant for CO2 at 1 bar
298 const Scalar phi_CO2 = fugacityCoefficientCO2(T, pg); // fugacity coefficient of CO2 for the water-CO2 system
299 const Scalar pg_bar = pg / 1.e5;
300 using std::exp;
301 return phi_CO2 * pg_bar / (55.508 * k0_CO2) * exp(-(deltaP
302 * v_av_CO2) / (R * T));
303 }
304
312 static Scalar computeLambda_(Scalar T, Scalar pg)
313 {
314 constexpr Scalar c[6] = { -0.411370585, 6.07632013E-4, 97.5347708,
315 -0.0237622469, 0.0170656236, 1.41335834E-5 };
316
317 using std::log;
318 const Scalar pg_bar = pg / 1.0E5; /* conversion from Pa to bar */
319 return c[0] + c[1] * T + c[2] / T + c[3] * pg_bar / T + c[4] * pg_bar
320 / (630.0 - T) + c[5] * T * log(pg_bar);
321 }
322
330 static Scalar computeXi_(Scalar T, Scalar pg)
331 {
332 constexpr Scalar c[4] = { 3.36389723E-4, -1.98298980E-5,
333 2.12220830E-3, -5.24873303E-3 };
334
335 Scalar pg_bar = pg / 1.0E5; /* conversion from Pa to bar */
336 return c[0] + c[1] * T + c[2] * pg_bar / T + c[3] * pg_bar / (630.0 - T);
337 }
338
345 static Scalar equilibriumConstantCO2_(Scalar T)
346 {
347 const Scalar TinC = T - 273.15; //temperature in °C
348 constexpr Scalar c[3] = { 1.189, 1.304e-2, -5.446e-5 };
349 const Scalar logk0_CO2 = c[0] + c[1] * TinC + c[2] * TinC * TinC;
350 using std::pow;
351 return pow(10, logk0_CO2);
352 }
353
360 static Scalar equilibriumConstantH2O_(Scalar T)
361 {
362 const Scalar TinC = T - 273.15; //temperature in °C
363 constexpr Scalar c[4] = { -2.209, 3.097e-2, -1.098e-4, 2.048e-7 };
364 const Scalar logk0_H2O = c[0] + c[1] * TinC + c[2] * TinC * TinC + c[3]
365 * TinC * TinC * TinC;
366 using std::pow;
367 return pow(10, logk0_H2O);
368 }
369};
370
377template<class Scalar, class CO2Impl, bool verbose = true>
379{
382 using CO2 = CO2Impl;
384
385public:
394 static Scalar moleFracCO2InBrine(Scalar temperature, Scalar pg, Scalar rhoCO2)
395 {
396 // regularisations:
397 if (pg > 2.5e8) {
398 pg = 2.5e8;
399 }
400 if (pg < 2.e5) {
401 pg = 2.e5;
402 }
403 if (temperature < 275.) {
404 temperature = 275;
405 }
406 if (temperature > 600.) {
407 temperature = 600;
408 }
409
410 const Scalar Mw = H2O::molarMass(); /* molecular weight of water [kg/mol] */
411 const Scalar Ms = 58.8e-3; /* molecular weight of NaCl [kg/mol] */
412
413 const Scalar X_NaCl = Brine::salinity();
414 /* salinity: conversion from mass fraction to mole fraction */
415 const Scalar x_NaCl = -Mw * X_NaCl / ((Ms - Mw) * X_NaCl - Ms);
416
417 // salinity: conversion from mole fraction to molality
418 const Scalar mol_NaCl = -55.56 * x_NaCl / (x_NaCl - 1);
419
420 const Scalar A = computeA_(temperature, pg); /* mu_{CO2}^{l(0)}/RT */
421 const Scalar B = computeB_(temperature, pg); /* lambda_{CO2-Na+} */
422 const Scalar C = computeC_(temperature, pg); /* Xi_{CO2-Na+-Cl-} */
423 const Scalar pgCO2 = partialPressureCO2_(temperature, pg);
424 const Scalar phiCO2 = fugacityCoeffCO2_(temperature, pgCO2, rhoCO2);
425
426 using std::log;
427 using Dune::power;
428 const Scalar exponent = A - log(phiCO2) + 2*B*mol_NaCl + C*power(mol_NaCl,2);
429
430 using std::exp;
431 const Scalar mol_CO2w = pgCO2 / (1e5 * exp(exponent)); /* paper: equation (6) */
432
433 const Scalar x_CO2w = mol_CO2w / (mol_CO2w + 55.56); /* conversion: molality to mole fraction */
434 //Scalar X_CO2w = x_CO2w*MCO2/(x_CO2w*MCO2 + (1-x_CO2w)*Mw); /* conversion: mole fraction to mass fraction */
435
436 return x_CO2w;
437 }
438
439private:
445 static Scalar computeA_(Scalar T, Scalar pg)
446 {
447 static const Scalar c[10] = {
448 28.9447706,
449 -0.0354581768,
450 -4770.67077,
451 1.02782768E-5,
452 33.8126098,
453 9.04037140E-3,
454 -1.14934031E-3,
455 -0.307405726,
456 -0.0907301486,
457 9.32713393E-4,
458 };
459
460 const Scalar pg_bar = pg / 1.0E5; /* conversion from Pa to bar */
461 const Scalar Tr = 630.0 - T;
462
463 using std::log;
464 return
465 c[0] +
466 c[1]*T +
467 c[2]/T +
468 c[3]*T*T +
469 c[4]/Tr +
470 c[5]*pg_bar +
471 c[6]*pg_bar*log(T) +
472 c[7]*pg_bar/T +
473 c[8]*pg_bar/Tr +
474 c[9]*pg_bar*pg_bar/(Tr*Tr);
475 }
476
483 static Scalar computeB_(Scalar T, Scalar pg)
484 {
485 const Scalar c1 = -0.411370585;
486 const Scalar c2 = 6.07632013E-4;
487 const Scalar c3 = 97.5347708;
488 const Scalar c8 = -0.0237622469;
489 const Scalar c9 = 0.0170656236;
490 const Scalar c11 = 1.41335834E-5;
491
492 const Scalar pg_bar = pg / 1.0E5; /* conversion from Pa to bar */
493
494 using std::log;
495 return
496 c1 +
497 c2*T +
498 c3/T +
499 c8*pg_bar/T +
500 c9*pg_bar/(630.0-T) +
501 c11*T*log(pg_bar);
502 }
503
510 static Scalar computeC_(Scalar T, Scalar pg)
511 {
512 const Scalar c1 = 3.36389723E-4;
513 const Scalar c2 = -1.98298980E-5;
514 const Scalar c8 = 2.12220830E-3;
515 const Scalar c9 = -5.24873303E-3;
516
517 const Scalar pg_bar = pg / 1.0E5; /* conversion from Pa to bar */
518
519 return
520 c1 +
521 c2*T +
522 c8*pg_bar/T +
523 c9*pg_bar/(630.0-T);
524 }
525
536 static Scalar partialPressureCO2_(Scalar temperature, Scalar pg)
537 {
539 }
540
548 static Scalar fugacityCoeffCO2_(Scalar temperature,
549 Scalar pg,
550 Scalar rhoCO2)
551 {
552 static const Scalar a[15] = {
553 8.99288497E-2,
554 -4.94783127E-1,
555 4.77922245E-2,
556 1.03808883E-2,
557 -2.82516861E-2,
558 9.49887563E-2,
559 5.20600880E-4,
560 -2.93540971E-4,
561 -1.77265112E-3,
562 -2.51101973E-5,
563 8.93353441E-5,
564 7.88998563E-5,
565 -1.66727022E-2,
566 1.3980,
567 2.96000000E-2
568 };
569
570 // reduced temperature
571 const Scalar Tr = temperature / CO2::criticalTemperature();
572 // reduced pressure
573 const Scalar pr = pg / CO2::criticalPressure();
574
575 // reduced molar volume. ATTENTION: Vc is _NOT_ the critical
576 // molar volume of CO2. See the reference!
577 const Scalar Vc = IdealGas::R*CO2::criticalTemperature()/CO2::criticalPressure();
578 const Scalar Vr =
579 // molar volume of CO2 at (temperature, pg)
580 CO2::molarMass() / rhoCO2
581 *
582 // "pseudo-critical" molar volume
583 1.0 / Vc;
584
585 // the Z coefficient
586 const Scalar Z = pr * Vr / Tr;
587
588 const Scalar A = a[0] + a[1] / (Tr * Tr) + a[2] / (Tr * Tr * Tr);
589 const Scalar B = a[3] + a[4] / (Tr * Tr) + a[5] / (Tr * Tr * Tr);
590 const Scalar C = a[6] + a[7] / (Tr * Tr) + a[8] / (Tr * Tr * Tr);
591 const Scalar D = a[9] + a[10] / (Tr * Tr) + a[11] / (Tr * Tr * Tr);
592
593 using std::log;
594 using std::exp;
595 const Scalar lnphiCO2 =
596 Z - 1 -
597 log(Z) +
598 A/Vr +
599 B/(2*Vr*Vr) +
600 C/(4*Vr*Vr*Vr*Vr) +
601 D/(5*Vr*Vr*Vr*Vr*Vr)
602 +
603 a[12]/(2*Tr*Tr*Tr*a[14])*
604 (
605 a[13] + 1 -
606 ( a[13] + 1 +
607 a[14]/(Vr*Vr)
608 )*exp(-a[14]/(Vr*Vr)));
609
610 return exp(lnphiCO2);
611 }
612
613};
614
615} // end namespace Dumux::BinaryCoeff
616
617#endif
Old version of binary coefficients for CO2 and brine. Calculates molfraction of CO2 in brine accordin...
Definition: brine_co2.hh:379
static Scalar moleFracCO2InBrine(Scalar temperature, Scalar pg, Scalar rhoCO2)
Returns the mole (!) fraction of CO2 in the liquid phase at a given temperature, pressure and density...
Definition: brine_co2.hh:394
Binary coefficients for brine and CO2.
Definition: brine_co2.hh:33
static Scalar fugacityCoefficientH2O(Scalar T, Scalar pg)
Returns the fugacity coefficient of the H2O component in a water-CO2 mixture (given in Spycher,...
Definition: brine_co2.hh:180
static Scalar liquidDiffCoeff(Scalar temperature, Scalar pressure)
Binary diffusion coefficient of CO2 in the brine phase.
Definition: brine_co2.hh:79
static void calculateMoleFractions(const Scalar temperature, const Scalar pg, const Scalar salinity, const int knownPhaseIdx, Scalar &xlCO2, Scalar &ygH2O)
Returns the mol (!) fraction of CO2 in the liquid phase and the mol (!) fraction of H2O in the gas ph...
Definition: brine_co2.hh:109
static Scalar fugacityCoefficientCO2(Scalar T, Scalar pg)
Returns the fugacity coefficient of the CO2 component in a water-CO2 mixture (given in Spycher,...
Definition: brine_co2.hh:154
static Scalar gasDiffCoeff(Scalar temperature, Scalar pressure)
Binary diffusion coefficient of water in the CO2 phase.
Definition: brine_co2.hh:53
A class for the brine fluid properties.
Definition: components/brine.hh:44
static Scalar salinity()
Return the constant salinity.
Definition: components/brine.hh:61
static Scalar vaporPressure(Scalar temperature)
The vapor pressure in of pure brine at a given temperature.
Definition: components/brine.hh:117
A class for the CO2 fluid properties.
Definition: co2.hh:45
Material properties of pure water .
Definition: h2o.hh:49
static constexpr Scalar molarMass()
The molar mass in of water.
Definition: h2o.hh:69
Relations valid for an ideal gas.
Definition: idealgas.hh:25
static constexpr Scalar R
The ideal gas constant .
Definition: idealgas.hh:28
A class for the CO2 fluid properties.
A class for the brine fluid properties,.
Helpers for deprecation.
Material properties of pure water .
Relations valid for an ideal gas.
Definition: air_mesitylene.hh:19
std::string temperature() noexcept
I/O name of temperature for equilibrium models.
Definition: name.hh:39
std::string pressure(int phaseIdx) noexcept
I/O name of pressure for multiphase systems.
Definition: name.hh:22
bool hasParam(const std::string &param)
Check whether a key exists in the parameter tree.
Definition: parameters.hh:157
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.