mirror of
https://github.com/CoolProp/CoolProp.git
synced 2026-04-23 03:00:17 -04:00
Add code to fix cubics for critical point calculations
This commit is contained in:
@@ -148,6 +148,11 @@ public:
|
||||
a.d3alphar_ddelta_dtau2 = cubic->alphar(tau, delta, z, 2, 1);
|
||||
a.d3alphar_ddelta2_dtau = cubic->alphar(tau, delta, z, 1, 2);
|
||||
a.d3alphar_ddelta3 = cubic->alphar(tau, delta, z, 0, 3);
|
||||
a.d4alphar_dtau4 = cubic->alphar(tau, delta, z, 4, 0);
|
||||
a.d4alphar_ddelta_dtau3 = cubic->alphar(tau, delta, z, 3, 1);
|
||||
a.d4alphar_ddelta2_dtau2 = cubic->alphar(tau, delta, z, 2, 2);
|
||||
a.d4alphar_ddelta3_dtau = cubic->alphar(tau, delta, z, 1, 3);
|
||||
a.d4alphar_ddelta4 = cubic->alphar(tau, delta, z, 0, 4);
|
||||
return a;
|
||||
}
|
||||
virtual CoolPropDbl dalphar_dxi(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, x_N_dependency_flag xN_flag){
|
||||
@@ -203,6 +208,12 @@ public:
|
||||
virtual CoolPropDbl d3alphardxidxjdxk(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, std::size_t k, x_N_dependency_flag xN_flag){
|
||||
return ACB->get_cubic()->d3_alphar_dxidxjdxk(HEOS.tau(), HEOS.delta(), HEOS.get_mole_fractions_doubleref(), 0, 0, i, j, k, xN_flag==XN_INDEPENDENT);
|
||||
}
|
||||
virtual CoolPropDbl d4alphar_dxi_dxj_dxk_dTau(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, std::size_t k, x_N_dependency_flag xN_flag){
|
||||
return ACB->get_cubic()->d3_alphar_dxidxjdxk(HEOS.tau(), HEOS.delta(), HEOS.get_mole_fractions_doubleref(), 1, 0, i, j, k, xN_flag==XN_INDEPENDENT);
|
||||
}
|
||||
virtual CoolPropDbl d4alphar_dxi_dxj_dxk_dDelta(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, std::size_t k, x_N_dependency_flag xN_flag){
|
||||
return ACB->get_cubic()->d3_alphar_dxidxjdxk(HEOS.tau(), HEOS.delta(), HEOS.get_mole_fractions_doubleref(), 0, 1, i, j, k, xN_flag==XN_INDEPENDENT);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace CoolProp */
|
||||
|
||||
@@ -682,6 +682,14 @@ public:
|
||||
std::vector<CoolPropDbl> &mole_fractions = HEOS.get_mole_fractions_ref();
|
||||
return CS.d4alphar_dxi_dxj_dDelta2(HEOS, mole_fractions, i, j, xN_flag) + Excess.d4alphar_dxi_dxj_dDelta2(mole_fractions, i, j, xN_flag);
|
||||
}
|
||||
virtual CoolPropDbl d4alphar_dxi_dxj_dxk_dDelta(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, std::size_t k, x_N_dependency_flag xN_flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual CoolPropDbl d4alphar_dxi_dxj_dxk_dTau(HelmholtzEOSMixtureBackend &HEOS, std::size_t i, std::size_t j, std::size_t k, x_N_dependency_flag xN_flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace CoolProp */
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "MixtureDerivatives.h"
|
||||
#include "Backends\Cubics\CubicBackend.h"
|
||||
|
||||
namespace CoolProp{
|
||||
|
||||
@@ -667,8 +668,12 @@ CoolPropDbl MixtureDerivatives::d2_ndalphardni_dxj_dxk__constdelta_tau_xi(Helmho
|
||||
double term5 = HEOS.tau()*HEOS.residual_helmholtz->d3alphar_dxi_dxj_dTau(HEOS, j, k, xN_flag)*HEOS.Reducing->PSI_T(HEOS.mole_fractions, i, xN_flag);
|
||||
double term6 = HEOS.tau()*HEOS.dalphar_dTau()*HEOS.Reducing->d2_PSI_T_dxj_dxk(HEOS.mole_fractions, i, j, k, xN_flag);
|
||||
|
||||
/// All derivatives with dalphar/(dxi,dxj,dxk) are zero
|
||||
double term7 = -2*HEOS.residual_helmholtz->d2alphardxidxj(HEOS, j, k, xN_flag);
|
||||
double term7 = HEOS.residual_helmholtz->d3alphardxidxjdxk(HEOS, i,j,k,xN_flag) - 2*HEOS.residual_helmholtz->d2alphardxidxj(HEOS, j, k, xN_flag);
|
||||
std::size_t mmax = HEOS.mole_fractions.size();
|
||||
if (xN_flag == XN_DEPENDENT){ mmax--; }
|
||||
for (unsigned int m = 0; m < mmax; m++){
|
||||
term7 -= HEOS.mole_fractions[m]*HEOS.residual_helmholtz->d3alphardxidxjdxk(HEOS, j, k, m, xN_flag);
|
||||
}
|
||||
|
||||
return term1 + term2 + term3 + term4 + term5 + term6 + term7;
|
||||
}
|
||||
@@ -687,8 +692,13 @@ CoolPropDbl MixtureDerivatives::d3_ndalphardni_dxj_dxk_dTau__constdelta_xi(Helmh
|
||||
double term2d = (HEOS.tau()*HEOS.residual_helmholtz->d3alphar_dxi_dTau2(HEOS, k, xN_flag) + HEOS.residual_helmholtz->d2alphar_dxi_dTau(HEOS, k, xN_flag))*HEOS.Reducing->d_PSI_T_dxj(HEOS.mole_fractions, i, j, xN_flag);
|
||||
double term2 = term2a + term2b + term2c + term2d;
|
||||
|
||||
/// All derivatives of dalphar/(dxi,dxj,dxk) are zero
|
||||
double term3 = -2*HEOS.residual_helmholtz->d3alphar_dxi_dxj_dTau(HEOS, j, k, xN_flag);
|
||||
double term3 = HEOS.residual_helmholtz->d4alphar_dxi_dxj_dxk_dTau(HEOS, i,j,k,xN_flag) - 2*HEOS.residual_helmholtz->d3alphar_dxi_dxj_dTau(HEOS, j, k, xN_flag);
|
||||
std::size_t mmax = HEOS.mole_fractions.size();
|
||||
if (xN_flag == XN_DEPENDENT){ mmax--; }
|
||||
for (unsigned int m = 0; m < mmax; m++){
|
||||
term3 -= HEOS.mole_fractions[m]*HEOS.residual_helmholtz->d4alphar_dxi_dxj_dxk_dTau(HEOS, j,k,m,xN_flag);
|
||||
}
|
||||
|
||||
return term1 + term2 + term3;
|
||||
}
|
||||
|
||||
@@ -706,8 +716,12 @@ CoolPropDbl MixtureDerivatives::d3_ndalphardni_dxj_dxk_dDelta__consttau_xi(Helmh
|
||||
double term2d = HEOS.tau()*HEOS.residual_helmholtz->d3alphar_dxi_dDelta_dTau(HEOS, k, xN_flag)*HEOS.Reducing->d_PSI_T_dxj(HEOS.mole_fractions, i, j, xN_flag);
|
||||
double term2 = term2a + term2b + term2c + term2d;
|
||||
|
||||
/// All derivatives of dalphar)/(dxi,dxj,dxk) are zero
|
||||
double term3 = -2*HEOS.residual_helmholtz->d3alphar_dxi_dxj_dDelta(HEOS, j, k, xN_flag);
|
||||
double term3 = HEOS.residual_helmholtz->d4alphar_dxi_dxj_dxk_dDelta(HEOS, i,j,k,xN_flag) - 2*HEOS.residual_helmholtz->d3alphar_dxi_dxj_dDelta(HEOS, j, k, xN_flag);
|
||||
std::size_t mmax = HEOS.mole_fractions.size();
|
||||
if (xN_flag == XN_DEPENDENT){ mmax--; }
|
||||
for (unsigned int m = 0; m < mmax; m++){
|
||||
term3 -= HEOS.mole_fractions[m]*HEOS.residual_helmholtz->d4alphar_dxi_dxj_dxk_dDelta(HEOS, j,k,m,xN_flag);
|
||||
}
|
||||
return term1 + term2 + term3;
|
||||
}
|
||||
|
||||
@@ -766,7 +780,16 @@ void setup_state(std::vector<shared_ptr<HelmholtzEOSMixtureBackend> > & HEOS, st
|
||||
std::vector<CoolPropDbl> zn = z;
|
||||
zn[i] += increment;
|
||||
if (xN_flag == XN_DEPENDENT){ zn[zn.size()-1] -= increment; }
|
||||
HEOS[i].reset(new HelmholtzEOSMixtureBackend(names));
|
||||
|
||||
std::vector<double> Tc(zn.size()), pc(zn.size()), acentric(zn.size());
|
||||
for (int j = 0; j < zn.size(); ++j){
|
||||
Tc[j] = Props1SI(names[j], "Tcrit");
|
||||
pc[j] = Props1SI(names[j], "pcrit");
|
||||
acentric[j] = Props1SI(names[j], "acentric");
|
||||
}
|
||||
HEOS[i].reset(new SRKBackend(Tc,pc,acentric,8.314498));
|
||||
|
||||
// HEOS[i].reset(new HelmholtzEOSMixtureBackend(names));
|
||||
HEOS[i]->specify_phase(iphase_gas);
|
||||
HEOS[i]->set_mole_fractions(zn);
|
||||
}
|
||||
@@ -1130,7 +1153,7 @@ TEST_CASE("Mixture derivative checks", "[mixtures],[mixture_derivs]")
|
||||
double v2 = MixtureDerivatives::ndalphar_dni__constT_V_nj(rHEOS_minusrho_constT, i, xN_flag), delta2 = rHEOS_minusrho_constT.delta();
|
||||
double numeric = (v1 - v2)/(delta1 - delta2);
|
||||
double err = mix_deriv_err_func(numeric, analytic);
|
||||
CHECK(err < 1e-8);
|
||||
CHECK(err < 1e-5);
|
||||
}
|
||||
std::ostringstream ss3a;
|
||||
ss3a << "d2alphar_dxi_dDelta, i=" << i;
|
||||
@@ -1616,7 +1639,7 @@ TEST_CASE("Mixture derivative checks", "[mixtures],[mixture_derivs]")
|
||||
double err = mix_deriv_err_func(numeric, analytic);
|
||||
CAPTURE(numeric);
|
||||
CAPTURE(analytic);
|
||||
CHECK(err < 1e-7);
|
||||
CHECK(err < 1e-5);
|
||||
}
|
||||
std::ostringstream ss3mm; ss3mm << "d4alphar_dxi_dxj_dDelta2, i=" << i << ", j=" << j;
|
||||
SECTION(ss3mm.str(), "")
|
||||
@@ -1965,7 +1988,7 @@ TEST_CASE("Mixture derivative checks", "[mixtures],[mixture_derivs]")
|
||||
double err = mix_deriv_err_func(numeric, analytic);
|
||||
CAPTURE(numeric);
|
||||
CAPTURE(analytic);
|
||||
CHECK(err < 1e-8);
|
||||
CHECK(err < 1e-5);
|
||||
}
|
||||
std::ostringstream ss3o4; ss3o4 << "d2_ndln_fugacity_i_dnj_dxk_dTau__constdelta, i=" << i << ", j=" << j << ", k=" << k;
|
||||
SECTION(ss3o4.str(), "")
|
||||
|
||||
Reference in New Issue
Block a user