21#ifndef DUMUX_PENG_ROBINSON_HH
22#define DUMUX_PENG_ROBINSON_HH
24#include <dune/common/math.hh>
46template <
class Scalar>
53 static void init(Scalar aMin, Scalar aMax,
int na,
54 Scalar bMin, Scalar bMax,
int nb)
61 Scalar VmCrit = 18e-6;
64 for (
int i = 0; i < na; ++i) {
66 for (
int j = 0; j < nb; ++j) {
88 template <
class Params>
91 using Component =
typename Params::Component;
92 if (T >= Component::criticalTemperature())
93 return Component::criticalPressure();
97 const Scalar eps = Component::criticalPressure()*1e-10;
104 for (
int i = 0; i < 5; ++i) {
106 assert(molarVolumes(Vm, params, T, pVap) == 3);
115 Scalar delta = f/df_dp;
118 if (abs(delta/pVap) < 1e-10)
143 template <
class Flu
idState,
class Params>
148 bool handleUnphysicalPhase =
true)
152 Scalar T = fs.temperature(phaseIdx);
153 Scalar p = fs.pressure(phaseIdx);
155 Scalar a = params.a(phaseIdx);
156 Scalar b = params.b(phaseIdx);
159 Scalar Astar = a*p/(RT*RT);
160 Scalar Bstar = b*p/RT;
163 Scalar a2 = - (1 - Bstar);
164 Scalar a3 = Astar - Bstar*(3*Bstar + 2);
165 Scalar a4 = Bstar*(- Astar + Bstar*(1 + Bstar));
175 if (numSol > 1 && Z[0] <= 0.0) {
176 Z[0] = Z[numSol - 1];
180 if (numSol > 0 && Z[0] <= 0)
192 else if (numSol == 1) {
198 if (handleUnphysicalPhase)
202 DUNE_THROW(
NumericalProblem,
"Unexpected number of roots in the equation for compressibility factor: " << numSol);
206 if (!isfinite(Vm) || Vm <= 0)
218 template <
class Params>
236 template <
class Params>
239 Scalar T = params.temperature();
240 Scalar p = params.pressure();
241 Scalar Vm = params.molarVolume();
245 Scalar Bstar = p*params.b() / RT;
248 (Vm + params.b()*(1 + sqrt(2))) /
249 (Vm + params.b()*(1 - sqrt(2)));
250 Scalar expo = - params.a()/(RT * 2 * params.b() * sqrt(2));
254 exp(Z - 1) / (Z - Bstar) *
270 template <
class Params>
272 {
return params.pressure()*computeFugacityCoeff(params); }
282 template <
class Flu
idState,
class Params>
284 const FluidState &fs,
285 const Params ¶ms,
289 Scalar T = fs.temperature(phaseIdx);
300 Scalar Vmin, Vmax, pmin, pmax;
304 params.a(phaseIdx), params.b(phaseIdx), T))
305 return isGasPhase ? max(Vmax, Vm) : min(Vmin, Vm);
310 template <
class Flu
idState,
class Params>
312 const FluidState &fs,
313 const Params ¶ms,
321 return isGasPhase ? max(Vm, Vcrit) : min(Vm, Vcrit);
339 for (
int i = 0; i < 30; ++i) {
340 bool hasExtrema =
findExtrema_(minVm, maxVm, minP, maxP, a, b, Tmin);
350 for (
int i = 0; i < 25; ++i) {
352 Scalar f = maxVm - minVm;
357 pcrit = (minP + maxP)/2;
358 Vcrit = (maxVm + minVm)/2;
366 const Scalar eps = - 1e-8;
367 [[maybe_unused]]
bool hasExtrema =
findExtrema_(minVm, maxVm, minP, maxP, a, b, T + eps);
369 Scalar fStar = maxVm - minVm;
374 Scalar fPrime = (fStar - f)/eps;
377 Scalar delta = f/fPrime;
383 for (
int j = 0; ; ++j) {
386 "Could not determine the critical point for a=" << a <<
", b=" << b);
389 if (
findExtrema_(minVm, maxVm, minP, maxP, a, b, T - delta)) {
419 Scalar a2 = 2*RT*u*b - 2*a;
420 Scalar a3 = 2*RT*w*b*b + RT*u*u*b*b + 4*a*b - u*a*b;
421 Scalar a4 = 2*RT*u*w*b*b*b + 2*u*a*b*b - 2*a*b*b;
422 Scalar a5 = RT*w*w*b*b*b*b - u*a*b*b*b;
432 for (
int i = 0; abs(delta) > 1e-9; ++i) {
433 Scalar f = a5 + V*(a4 + V*(a3 + V*(a2 + V*a1)));
434 Scalar fPrime = a4 + V*(2*a3 + V*(3*a2 + V*4*a1));
436 if (abs(fPrime) < 1e-20) {
457 Scalar b2 = a2 + V*b1;
458 Scalar b3 = a3 + V*b2;
459 Scalar b4 = a4 + V*b3;
467 std::sort(allV + 0, allV + numSol);
470 if (allV[numSol - 2] < b) {
478 Vmin = allV[numSol - 2];
479 Vmax = allV[numSol - 1];
493 template <
class Params>
496 using Component =
typename Params::Component;
498 Scalar Tr = T / Component::criticalTemperature();
500 Scalar omega = Component::acentricFactor();
503 Scalar f0 = (tau*(-5.97616 + sqrt(tau)*(1.29874 - tau*0.60394)) - 1.06841*power(tau, 5))/Tr;
504 Scalar f1 = (tau*(-5.03365 + sqrt(tau)*(1.11505 - tau*5.41217)) - 7.46628*power(tau, 5))/Tr;
505 Scalar f2 = (tau*(-0.64771 + sqrt(tau)*(2.41539 - tau*4.26979)) + 3.25259*power(tau, 5))/Tr;
507 return Component::criticalPressure()*exp(f0 + omega * (f1 + omega*f2));
520 template <
class Params>
526 {
return fugacity(params, T, p, VmLiquid) - fugacity(params, T, p, VmGas); }
533template <
class Scalar>
536template <
class Scalar>
539template <
class Scalar>
A central place for various physical constants occurring in some equations.
Definition: constants.hh:27
Exception thrown if a fixable numerical problem occurs.
Definition: exceptions.hh:27
Implements the Peng-Robinson equation of state for liquids and gases.
Definition: pengrobinson.hh:48
static Scalar criticalTemperature(const Params ¶ms)
Returns the critical temperature for a given mix.
Definition: pengrobinson.hh:219
static Scalar handleSingleRoot_(Scalar Vm, const FluidState &fs, const Params ¶ms, int phaseIdx, bool isGasPhase)
Definition: pengrobinson.hh:283
static Scalar fugacityDifference_(const Params ¶ms, Scalar T, Scalar p, Scalar VmLiquid, Scalar VmGas)
Returns the difference between the liquid and the gas phase fugacities in [bar].
Definition: pengrobinson.hh:521
static Scalar computeMolarVolume(const FluidState &fs, Params ¶ms, int phaseIdx, bool isGasPhase, bool handleUnphysicalPhase=true)
Computes molar volumes where the Peng-Robinson EOS is true.
Definition: pengrobinson.hh:144
static Tabulated2DFunction< Scalar > criticalPressure_
Definition: pengrobinson.hh:529
static void init(Scalar aMin, Scalar aMax, int na, Scalar bMin, Scalar bMax, int nb)
Definition: pengrobinson.hh:53
static Tabulated2DFunction< Scalar > criticalMolarVolume_
Definition: pengrobinson.hh:530
static bool findExtrema_(Scalar &Vmin, Scalar &Vmax, Scalar &pMin, Scalar &pMax, Scalar a, Scalar b, Scalar T)
Definition: pengrobinson.hh:403
static void findCriticalPoint_(Scalar &Tcrit, Scalar &pcrit, Scalar &Vcrit, Scalar a, Scalar b)
Definition: pengrobinson.hh:324
static Scalar computeFugacity(const Params ¶ms)
Returns the fugacity coefficient for a given pressure and molar volume.
Definition: pengrobinson.hh:271
static Scalar ambroseWalton_(const Params ¶ms, Scalar T)
The Ambrose-Walton method to estimate the vapor pressure.
Definition: pengrobinson.hh:494
static Scalar handleCriticalFluid_(Scalar Vm, const FluidState &fs, const Params ¶ms, int phaseIdx, bool isGasPhase)
Definition: pengrobinson.hh:311
static Tabulated2DFunction< Scalar > criticalTemperature_
Definition: pengrobinson.hh:528
static Scalar computeVaporPressure(const Params ¶ms, Scalar T)
Predicts the vapor pressure for the temperature given in setTP().
Definition: pengrobinson.hh:89
static Scalar computeFugacityCoeffient(const Params ¶ms)
Returns the fugacity coefficient for a given pressure and molar volume.
Definition: pengrobinson.hh:237
Implements tabulation for a two-dimensional function.
Definition: tabulated2dfunction.hh:36
Some exceptions thrown in DuMux
int invertCubicPolynomial(SolContainer *sol, Scalar a, Scalar b, Scalar c, Scalar d, std::size_t numPostProcessIterations=1)
Invert a cubic polynomial analytically.
Definition: math.hh:240
Relations valid for an ideal gas.
Define some often used mathematical functions.
Implements tabulation for a two-dimensional function.
This is a fluid state which allows to set the fluid temperatures and takes all other quantities from ...