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>
 
static constexpr Scalar R
The ideal gas constant .
Definition constants.hh:32
Exception thrown if a fixable numerical problem occurs.
Definition exceptions.hh:27
static Tabulated2DFunction< Scalar > criticalMolarVolume_
Definition pengrobinson.hh:530
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 Tabulated2DFunction< Scalar > criticalTemperature_
Definition pengrobinson.hh:528
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 void init(Scalar aMin, Scalar aMax, int na, Scalar bMin, Scalar bMax, int nb)
Definition pengrobinson.hh:53
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 Tabulated2DFunction< Scalar > criticalPressure_
Definition pengrobinson.hh:529
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 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:269
Relations valid for an ideal gas.
Define some often used mathematical functions.
const Scalar PengRobinsonMixture< Scalar, StaticParameters >::w
Definition pengrobinsonmixture.hh:140
const Scalar PengRobinsonMixture< Scalar, StaticParameters >::u
Definition pengrobinsonmixture.hh:138
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 ...