mirror of
https://github.com/CoolProp/CoolProp.git
synced 2026-02-08 12:55:16 -05:00
Merge branch 'master' into eigenPolynomials
Conflicts: CMakeLists.txt
This commit is contained in:
@@ -19,7 +19,7 @@ AbstractState * AbstractState::factory(const std::string &backend, const std::st
|
||||
static std::string HEOS_string = "HEOS";
|
||||
if (!backend.compare("HEOS"))
|
||||
{
|
||||
if (fluid_string.find('&') == -1){
|
||||
if (fluid_string.find('&') == std::string::npos){
|
||||
return new HelmholtzEOSBackend(&get_fluid(fluid_string));
|
||||
}
|
||||
else{
|
||||
@@ -31,7 +31,7 @@ AbstractState * AbstractState::factory(const std::string &backend, const std::st
|
||||
}
|
||||
else if (!backend.compare("REFPROP"))
|
||||
{
|
||||
if (fluid_string.find('&') == -1){
|
||||
if (fluid_string.find('&') == std::string::npos){
|
||||
return new REFPROPBackend(fluid_string);
|
||||
}
|
||||
else{
|
||||
@@ -57,7 +57,7 @@ AbstractState * AbstractState::factory(const std::string &backend, const std::st
|
||||
{
|
||||
std::size_t idel = fluid_string.find("::");
|
||||
// Backend has not been specified, and we have to figure out what the backend is by parsing the string
|
||||
if (idel == -1) // No '::' found, no backend specified, try HEOS, otherwise a failure
|
||||
if (idel == std::string::npos) // No '::' found, no backend specified, try HEOS, otherwise a failure
|
||||
{
|
||||
// Figure out what backend to use
|
||||
return factory(HEOS_string, fluid_string);
|
||||
@@ -196,6 +196,8 @@ double AbstractState::keyed_output(int key)
|
||||
return get_reducing().T;
|
||||
case irhomolar_reducing:
|
||||
return get_reducing().rhomolar;
|
||||
case ispeed_sound:
|
||||
return speed_sound();
|
||||
//case iT_critical:
|
||||
// return get_critical().T;
|
||||
//case irhomolar_critical:
|
||||
|
||||
@@ -52,7 +52,7 @@ void FlashRoutines::QT_flash(HelmholtzEOSMixtureBackend &HEOS)
|
||||
|
||||
rhoLsat = HEOS.solver_rho_Tp(HEOS._T, psatLanc, rhoLanc);
|
||||
rhoVsat = HEOS.solver_rho_Tp(HEOS._T, psatVanc, rhoLanc);
|
||||
if (!ValidNumber(rhoLsat) || !ValidNumber(rhoVsat) ||
|
||||
if (!ValidNumber(rhoLsat) || !ValidNumber(rhoVsat) ||
|
||||
fabs(rhoLsat/rhoLanc-1) > 0.1 || fabs(rhoVanc/rhoVsat-1) > 0.1)
|
||||
{
|
||||
throw ValueError("pseudo-pure failed");
|
||||
@@ -79,7 +79,7 @@ void FlashRoutines::QT_flash(HelmholtzEOSMixtureBackend &HEOS)
|
||||
|
||||
// Use Wilson iteration to obtain updated guess for pressure
|
||||
pguess = SaturationSolvers::saturation_Wilson(&HEOS, HEOS._Q, HEOS._T, SaturationSolvers::imposed_T, HEOS.mole_fractions, pguess);
|
||||
|
||||
|
||||
// Actually call the successive substitution solver
|
||||
SaturationSolvers::successive_substitution(&HEOS, HEOS._Q, HEOS._T, pguess, HEOS.mole_fractions, HEOS.K, options);
|
||||
}
|
||||
@@ -109,7 +109,7 @@ void FlashRoutines::PQ_flash(HelmholtzEOSMixtureBackend &HEOS)
|
||||
options.use_logdelta = false;
|
||||
// Actually call the solver
|
||||
SaturationSolvers::saturation_PHSU_pure(&HEOS, HEOS._p, options);
|
||||
|
||||
|
||||
// Load the outputs
|
||||
HEOS._p = HEOS._Q*HEOS.SatV->p() + (1 - HEOS._Q)*HEOS.SatL->p();
|
||||
HEOS._rhomolar = 1/(HEOS._Q/HEOS.SatV->rhomolar() + (1 - HEOS._Q)/HEOS.SatL->rhomolar());
|
||||
@@ -128,10 +128,10 @@ void FlashRoutines::PQ_flash(HelmholtzEOSMixtureBackend &HEOS)
|
||||
|
||||
// Use Wilson iteration to obtain updated guess for temperature
|
||||
Tguess = SaturationSolvers::saturation_Wilson(&HEOS, HEOS._Q, HEOS._p, SaturationSolvers::imposed_p, HEOS.mole_fractions, Tguess);
|
||||
|
||||
|
||||
// Actually call the successive substitution solver
|
||||
SaturationSolvers::successive_substitution(&HEOS, HEOS._Q, Tguess, HEOS._p, HEOS.mole_fractions, HEOS.K, io);
|
||||
|
||||
|
||||
PhaseEnvelope::PhaseEnvelope_GV ENV_GV;
|
||||
ENV_GV.build(&HEOS, HEOS.mole_fractions, HEOS.K, io);
|
||||
}
|
||||
@@ -143,7 +143,7 @@ void FlashRoutines::PHSU_D_flash(HelmholtzEOSMixtureBackend &HEOS, int other)
|
||||
class solver_resid : public FuncWrapper1D
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
HelmholtzEOSMixtureBackend *HEOS;
|
||||
long double r, eos, rhomolar, value, T;
|
||||
int other;
|
||||
@@ -164,15 +164,15 @@ void FlashRoutines::PHSU_D_flash(HelmholtzEOSMixtureBackend &HEOS, int other)
|
||||
default:
|
||||
throw ValueError(format("Input not supported"));
|
||||
}
|
||||
|
||||
|
||||
r = eos - value;
|
||||
return r;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
std::string errstring;
|
||||
|
||||
if (HEOS.imposed_phase_index > -1)
|
||||
if (HEOS.imposed_phase_index > -1)
|
||||
{
|
||||
// Use the phase defined by the imposed phase
|
||||
HEOS._phase = HEOS.imposed_phase_index;
|
||||
@@ -182,17 +182,17 @@ void FlashRoutines::PHSU_D_flash(HelmholtzEOSMixtureBackend &HEOS, int other)
|
||||
if (HEOS.is_pure_or_pseudopure)
|
||||
{
|
||||
CoolPropFluid * component = HEOS.components[0];
|
||||
|
||||
|
||||
shared_ptr<HelmholtzEOSMixtureBackend> Sat;
|
||||
long double rhoLtriple = component->pEOS->rhoLtriple;
|
||||
long double rhoVtriple = component->pEOS->rhoVtriple;
|
||||
long double rhoLtriple = component->triple_liquid.rhomolar;
|
||||
long double rhoVtriple = component->triple_vapor.rhomolar;
|
||||
// Check if in the "normal" region
|
||||
if (HEOS._rhomolar >= rhoVtriple && HEOS._rhomolar <= rhoLtriple)
|
||||
{
|
||||
long double yL, yV, value, y_solid;
|
||||
long double TLtriple = component->pEOS->Ttriple; //TODO: separate TL and TV for ppure
|
||||
long double TVtriple = component->pEOS->Ttriple; //TODO: separate TL and TV for ppure
|
||||
|
||||
long double TLtriple = component->triple_liquid.T; ///TODO: separate TL and TV for ppure
|
||||
long double TVtriple = component->triple_vapor.T;
|
||||
|
||||
// First check if solid (below the line connecting the triple point values) - this is an error for now
|
||||
switch (other)
|
||||
{
|
||||
@@ -246,10 +246,10 @@ void FlashRoutines::PHSU_D_flash(HelmholtzEOSMixtureBackend &HEOS, int other)
|
||||
|
||||
}
|
||||
// Check if vapor/solid region below triple point vapor density
|
||||
else if (HEOS._rhomolar < component->pEOS->rhoVtriple)
|
||||
else if (HEOS._rhomolar < component->triple_vapor.rhomolar)
|
||||
{
|
||||
long double y, value;
|
||||
long double TVtriple = component->pEOS->Ttriple; //TODO: separate TL and TV for ppure
|
||||
long double TVtriple = component->triple_vapor.T; //TODO: separate TL and TV for ppure
|
||||
|
||||
// If value is above the value calculated from X(Ttriple, _rhomolar), it is vapor
|
||||
switch (other)
|
||||
@@ -275,15 +275,15 @@ void FlashRoutines::PHSU_D_flash(HelmholtzEOSMixtureBackend &HEOS, int other)
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ValueError(format("D < DLtriple"));
|
||||
throw ValueError(format("D < DLtriple %g %g", value, y));
|
||||
}
|
||||
|
||||
}
|
||||
// Check in the liquid/solid region above the triple point density
|
||||
else
|
||||
else
|
||||
{
|
||||
long double y, value;
|
||||
long double TLtriple = component->pEOS->Ttriple; //TODO: separate TL and TV for ppure
|
||||
long double TLtriple = component->pEOS->Ttriple;
|
||||
|
||||
// If value is above the value calculated from X(Ttriple, _rhomolar), it is vapor
|
||||
switch (other)
|
||||
@@ -309,11 +309,11 @@ void FlashRoutines::PHSU_D_flash(HelmholtzEOSMixtureBackend &HEOS, int other)
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ValueError(format("D < DLtriple"));
|
||||
throw ValueError(format("D < DLtriple %g %g", value, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
throw NotImplementedError("PHSU_D_flash not ready for mixtures");
|
||||
}
|
||||
}
|
||||
@@ -323,7 +323,7 @@ void FlashRoutines::HSU_P_flash(HelmholtzEOSMixtureBackend &HEOS, int other)
|
||||
}
|
||||
void FlashRoutines::DHSU_T_flash(HelmholtzEOSMixtureBackend &HEOS, int other)
|
||||
{
|
||||
if (HEOS.imposed_phase_index > -1)
|
||||
if (HEOS.imposed_phase_index > -1)
|
||||
{
|
||||
// Use the phase defined by the imposed phase
|
||||
HEOS._phase = HEOS.imposed_phase_index;
|
||||
@@ -370,9 +370,9 @@ void FlashRoutines::DHSU_T_flash(HelmholtzEOSMixtureBackend &HEOS, int other)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
HEOS.calc_pressure();
|
||||
HEOS.calc_pressure();
|
||||
HEOS._Q = -1;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace CoolProp */
|
||||
} /* namespace CoolProp */
|
||||
|
||||
@@ -16,8 +16,8 @@ extern int get_debug_level();
|
||||
|
||||
/// A container for the fluid parameters for the CoolProp fluids
|
||||
/**
|
||||
This container holds copies of all of the fluid instances for the fluids that are loaded in CoolProp.
|
||||
New fluids can be added by passing in a rapidjson::Value instance to the add_one function, or
|
||||
This container holds copies of all of the fluid instances for the fluids that are loaded in CoolProp.
|
||||
New fluids can be added by passing in a rapidjson::Value instance to the add_one function, or
|
||||
a rapidjson array of fluids to the add_many function.
|
||||
*/
|
||||
class JSONFluidLibrary
|
||||
@@ -31,9 +31,9 @@ protected:
|
||||
|
||||
/// Parse the contributions to the residual Helmholtz energy
|
||||
void parse_alphar(rapidjson::Value &alphar, EquationOfState &EOS)
|
||||
{
|
||||
{
|
||||
for (rapidjson::Value::ValueIterator itr = alphar.Begin(); itr != alphar.End(); ++itr)
|
||||
{
|
||||
{
|
||||
// A reference for code cleanness
|
||||
rapidjson::Value &contribution = *itr;
|
||||
|
||||
@@ -140,7 +140,7 @@ protected:
|
||||
{
|
||||
if (!alpha0.IsArray()){throw ValueError();}
|
||||
for (rapidjson::Value::ValueIterator itr = alpha0.Begin(); itr != alpha0.End(); ++itr)
|
||||
{
|
||||
{
|
||||
// A reference for code cleanness
|
||||
rapidjson::Value &contribution = *itr;
|
||||
|
||||
@@ -172,7 +172,7 @@ protected:
|
||||
// Retrieve the values
|
||||
std::vector<long double> n = cpjson::get_long_double_array(contribution["n"]);
|
||||
std::vector<long double> t = cpjson::get_long_double_array(contribution["t"]);
|
||||
|
||||
|
||||
std::vector<long double> c = cpjson::get_long_double_array(contribution["c"]);
|
||||
std::vector<long double> d = cpjson::get_long_double_array(contribution["d"]);
|
||||
if (EOS.alpha0.PlanckEinstein.is_enabled() == true){
|
||||
@@ -217,7 +217,7 @@ protected:
|
||||
}
|
||||
else if (!type.compare("IdealGasHelmholtzCP0AlyLee"))
|
||||
{
|
||||
|
||||
|
||||
std::vector<long double> constants = cpjson::get_long_double_array(contribution["c"]);
|
||||
long double Tc = cpjson::get_double(contribution, "Tc");
|
||||
long double T0 = cpjson::get_double(contribution, "T0");
|
||||
@@ -249,7 +249,7 @@ protected:
|
||||
c.push_back(1);
|
||||
d.push_back(1);
|
||||
}
|
||||
|
||||
|
||||
if (EOS.alpha0.PlanckEinstein.is_enabled() == true){
|
||||
EOS.alpha0.PlanckEinstein.extend(n, t, c, d);
|
||||
}
|
||||
@@ -297,38 +297,41 @@ protected:
|
||||
EOS.R_u = cpjson::get_double(EOS_json,"gas_constant");
|
||||
EOS.molar_mass = cpjson::get_double(EOS_json,"molar_mass");
|
||||
EOS.accentric = cpjson::get_double(EOS_json,"accentric");
|
||||
EOS.Ttriple = cpjson::get_double(EOS_json, "Ttriple");
|
||||
EOS.ptriple = cpjson::get_double(EOS_json, "ptriple");
|
||||
EOS.rhoLtriple = cpjson::get_double(EOS_json, "rhoLtriple");
|
||||
EOS.rhoVtriple = cpjson::get_double(EOS_json, "rhoVtriple");
|
||||
|
||||
EOS.pseudo_pure = cpjson::get_bool(EOS_json, "pseudo_pure");
|
||||
EOS.limits.Tmax = cpjson::get_double(EOS_json, "T_max");
|
||||
EOS.limits.pmax = cpjson::get_double(EOS_json, "p_max");
|
||||
|
||||
rapidjson::Value &reducing_state = EOS_json["reducing_state"];
|
||||
|
||||
rapidjson::Value &reducing_state = EOS_json["STATES"]["reducing"];
|
||||
rapidjson::Value &satminL_state = EOS_json["STATES"]["sat_min_liquid"];
|
||||
rapidjson::Value &satminV_state = EOS_json["STATES"]["sat_min_vapor"];
|
||||
|
||||
// Reducing state
|
||||
EOS.reduce.T = cpjson::get_double(reducing_state,"T");
|
||||
EOS.reduce.rhomolar = cpjson::get_double(reducing_state,"rhomolar");
|
||||
EOS.reduce.p = cpjson::get_double(reducing_state,"p");
|
||||
|
||||
/// \todo: define limits of EOS better
|
||||
EOS.limits.Tmin = cpjson::get_double(satminL_state, "T");
|
||||
EOS.Ttriple = EOS.limits.Tmin;
|
||||
|
||||
// BibTex keys
|
||||
EOS.BibTeX_EOS = cpjson::get_string(EOS_json,"BibTeX_EOS");
|
||||
EOS.BibTeX_CP0 = cpjson::get_string(EOS_json,"BibTeX_CP0");
|
||||
|
||||
|
||||
parse_alphar(EOS_json["alphar"], EOS);
|
||||
parse_alpha0(EOS_json["alpha0"], EOS);
|
||||
|
||||
|
||||
// Validate the equation of state that was just created
|
||||
EOS.validate();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Parse the list of possible equations of state
|
||||
void parse_EOS_listing(rapidjson::Value &EOS_array, CoolPropFluid & fluid)
|
||||
{
|
||||
for (rapidjson::Value::ValueIterator itr = EOS_array.Begin(); itr != EOS_array.End(); ++itr)
|
||||
{
|
||||
{
|
||||
parse_EOS(*itr,fluid);
|
||||
}
|
||||
|
||||
@@ -436,7 +439,7 @@ protected:
|
||||
if (!type.compare("modified_Batschinski_Hildebrand")){
|
||||
// Get a reference to the entry in the fluid instance to simplify the code that follows
|
||||
CoolProp::ViscosityModifiedBatschinskiHildebrandData &BH = fluid.transport.viscosity_higher_order.modified_Batschinski_Hildebrand;
|
||||
|
||||
|
||||
// Set the flag for the type of this model
|
||||
fluid.transport.viscosity_higher_order.type = CoolProp::ViscosityHigherOrderVariables::VISCOSITY_HIGHER_ORDER_BATSCHINKI_HILDEBRAND;
|
||||
|
||||
@@ -467,7 +470,7 @@ protected:
|
||||
else if (!type.compare("friction_theory")){
|
||||
// Get a reference to the entry in the fluid instance to simplify the code that follows
|
||||
CoolProp::ViscosityFrictionTheoryData &F = fluid.transport.viscosity_higher_order.friction_theory;
|
||||
|
||||
|
||||
// Set the flag for the type of this model
|
||||
fluid.transport.viscosity_higher_order.type = CoolProp::ViscosityHigherOrderVariables::VISCOSITY_HIGHER_ORDER_FRICTION_THEORY;
|
||||
|
||||
@@ -476,7 +479,7 @@ protected:
|
||||
F.Aa = cpjson::get_long_double_array(higher["Aa"]);
|
||||
F.Aaa = cpjson::get_long_double_array(higher["Aaa"]);
|
||||
F.Ar = cpjson::get_long_double_array(higher["Ar"]);
|
||||
|
||||
|
||||
|
||||
F.Na = cpjson::get_integer(higher,"Na");
|
||||
F.Naa = cpjson::get_integer(higher,"Naa");
|
||||
@@ -487,7 +490,7 @@ protected:
|
||||
assert(F.Aa.size() == 3);
|
||||
assert(F.Aaa.size() == 3);
|
||||
assert(F.Ar.size() == 3);
|
||||
|
||||
|
||||
F.T_reduce = cpjson::get_double(higher,"T_reduce");
|
||||
|
||||
if (higher.HasMember("Arr") && !higher.HasMember("Adrdr")){
|
||||
@@ -581,7 +584,7 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Load dilute viscosity term
|
||||
if (viscosity.HasMember("dilute")){
|
||||
@@ -596,7 +599,7 @@ protected:
|
||||
parse_higher_order_viscosity(viscosity["higher_order"], fluid);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Parse the transport properties
|
||||
void parse_dilute_conductivity(rapidjson::Value &dilute, CoolPropFluid & fluid)
|
||||
{
|
||||
@@ -639,7 +642,7 @@ protected:
|
||||
|
||||
// Load up the values
|
||||
data.A = cpjson::get_long_double_array(dilute["A"]);
|
||||
data.t = cpjson::get_long_double_array(dilute["t"]);
|
||||
data.t = cpjson::get_long_double_array(dilute["t"]);
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("type [%s] is not understood for fluid %s",type.c_str(),fluid.name.c_str()));
|
||||
@@ -732,7 +735,7 @@ protected:
|
||||
throw ValueError(format("type [%s] is not understood for fluid %s",type.c_str(),fluid.name.c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Parse the thermal conductivity data
|
||||
void parse_thermal_conductivity(rapidjson::Value &conductivity, CoolPropFluid & fluid)
|
||||
{
|
||||
@@ -784,7 +787,7 @@ protected:
|
||||
parse_viscosity(transport["viscosity"],fluid);
|
||||
}
|
||||
|
||||
// Parse thermal conductivity
|
||||
// Parse thermal conductivity
|
||||
if (transport.HasMember("conductivity")){
|
||||
parse_thermal_conductivity(transport["conductivity"],fluid);
|
||||
}
|
||||
@@ -794,19 +797,115 @@ protected:
|
||||
{
|
||||
// Use the method of Chung to approximate the values for epsilon_over_k and sigma_eta
|
||||
// Chung, T.-H.; Ajlan, M.; Lee, L. L.; Starling, K. E. Generalized Multiparameter Correlation for Nonpolar and Polar Fluid Transport Properties. Ind. Eng. Chem. Res. 1988, 27, 671-679.
|
||||
// rhoc needs to be in mol/L to yield a sigma in nm,
|
||||
// rhoc needs to be in mol/L to yield a sigma in nm,
|
||||
long double rho_crit_molar = fluid.pEOS->reduce.rhomolar/1000.0;// [mol/m3 to mol/L]
|
||||
long double Tc = fluid.pEOS->reduce.T;
|
||||
fluid.transport.sigma_eta = 0.809/pow(rho_crit_molar, static_cast<long double>(1.0/3.0))/1e9; // 1e9 is to convert from nm to m
|
||||
fluid.transport.epsilon_over_k = Tc/1.3593; // [K]
|
||||
}
|
||||
|
||||
/// Parse the critical state for the given EOS
|
||||
void parse_crit_state(rapidjson::Value &crit, CoolPropFluid & fluid)
|
||||
void parse_melting_line(rapidjson::Value &melting_line, CoolPropFluid & fluid)
|
||||
{
|
||||
fluid.crit.T = cpjson::get_double(crit,"T");
|
||||
fluid.crit.p = cpjson::get_double(crit,"p");
|
||||
fluid.crit.rhomolar = cpjson::get_double(crit,"rhomolar");
|
||||
fluid.ancillaries.melting_line.T_m = cpjson::get_double(melting_line, "T_m");
|
||||
fluid.ancillaries.melting_line.BibTeX = cpjson::get_string(melting_line, "BibTeX");
|
||||
|
||||
if (melting_line.HasMember("type"))
|
||||
{
|
||||
std::string type = cpjson::get_string(melting_line, "type");
|
||||
if (!type.compare("Simon"))
|
||||
{
|
||||
rapidjson::Value &parts = melting_line["parts"];
|
||||
for (rapidjson::Value::ValueIterator itr = parts.Begin(); itr != parts.End(); ++itr)
|
||||
{
|
||||
MeltingLinePiecewiseSimonSegment data;
|
||||
data.a = cpjson::get_double((*itr),"a");
|
||||
data.c = cpjson::get_double((*itr),"c");
|
||||
data.T_min = cpjson::get_double((*itr),"T_min");
|
||||
data.T_max = cpjson::get_double((*itr),"T_max");
|
||||
data.T_0 = cpjson::get_double((*itr),"T_0");
|
||||
data.p_0 = cpjson::get_double((*itr),"p_0");
|
||||
fluid.ancillaries.melting_line.simon.parts.push_back(data);
|
||||
}
|
||||
fluid.ancillaries.melting_line.type = MeltingLineVariables::MELTING_LINE_SIMON_TYPE;
|
||||
}
|
||||
else if (!type.compare("polynomial_in_Tr"))
|
||||
{
|
||||
rapidjson::Value &parts = melting_line["parts"];
|
||||
for (rapidjson::Value::ValueIterator itr = parts.Begin(); itr != parts.End(); ++itr)
|
||||
{
|
||||
MeltingLinePiecewisePolynomialInTrSegment data;
|
||||
data.a = cpjson::get_long_double_array((*itr),"a");
|
||||
data.t = cpjson::get_long_double_array((*itr),"t");
|
||||
data.T_min = cpjson::get_double((*itr),"T_min");
|
||||
data.T_max = cpjson::get_double((*itr),"T_max");
|
||||
data.T_0 = cpjson::get_double((*itr),"T_0");
|
||||
data.p_0 = cpjson::get_double((*itr),"p_0");
|
||||
fluid.ancillaries.melting_line.polynomial_in_Tr.parts.push_back(data);
|
||||
}
|
||||
fluid.ancillaries.melting_line.type = MeltingLineVariables::MELTING_LINE_POLYNOMIAL_IN_TR_TYPE;
|
||||
}
|
||||
else if (!type.compare("polynomial_in_Theta"))
|
||||
{
|
||||
rapidjson::Value &parts = melting_line["parts"];
|
||||
for (rapidjson::Value::ValueIterator itr = parts.Begin(); itr != parts.End(); ++itr)
|
||||
{
|
||||
MeltingLinePiecewisePolynomialInThetaSegment data;
|
||||
data.a = cpjson::get_long_double_array((*itr),"a");
|
||||
data.t = cpjson::get_long_double_array((*itr),"t");
|
||||
data.T_min = cpjson::get_double((*itr),"T_min");
|
||||
data.T_max = cpjson::get_double((*itr),"T_max");
|
||||
data.T_0 = cpjson::get_double((*itr),"T_0");
|
||||
data.p_0 = cpjson::get_double((*itr),"p_0");
|
||||
fluid.ancillaries.melting_line.polynomial_in_Theta.parts.push_back(data);
|
||||
}
|
||||
fluid.ancillaries.melting_line.type = MeltingLineVariables::MELTING_LINE_POLYNOMIAL_IN_THETA_TYPE;
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("melting line type [%s] is not understood for fluid %s", type.c_str(), fluid.name.c_str()));
|
||||
}
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("melting line does not have \"type\" for fluid %s", fluid.name.c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
/// Parse the critical state for the given EOS
|
||||
void parse_states(rapidjson::Value &states, CoolPropFluid & fluid)
|
||||
{
|
||||
if (!states.HasMember("critical")){ throw ValueError(format("fluid[\"STATES\"] [%s] does not have \"critical\" member",fluid.name.c_str())); }
|
||||
rapidjson::Value &crit = states["critical"];
|
||||
fluid.crit.T = cpjson::get_double(crit, "T");
|
||||
fluid.crit.p = cpjson::get_double(crit, "p");
|
||||
fluid.crit.rhomolar = cpjson::get_double(crit, "rhomolar");
|
||||
|
||||
if (!states.HasMember("triple_liquid")){ throw ValueError(format("fluid[\"STATES\"] [%s] does not have \"triple_liquid\" member",fluid.name.c_str())); }
|
||||
rapidjson::Value &triple_liquid = states["triple_liquid"];
|
||||
if (triple_liquid.ObjectEmpty()){
|
||||
// State is empty - probably because the triple point temperature is below the minimum saturation temperature
|
||||
fluid.triple_liquid.T = -1;
|
||||
fluid.triple_liquid.p = -1;
|
||||
fluid.triple_liquid.rhomolar = -1;
|
||||
}
|
||||
else{
|
||||
fluid.triple_liquid.T = cpjson::get_double(triple_liquid, "T");
|
||||
fluid.triple_liquid.p = cpjson::get_double(triple_liquid, "p");
|
||||
fluid.triple_liquid.rhomolar = cpjson::get_double(triple_liquid, "rhomolar");
|
||||
}
|
||||
|
||||
if (!states.HasMember("triple_vapor")){ throw ValueError(format("fluid[\"STATES\"] [%s] does not have \"triple_vapor\" member",fluid.name.c_str())); }
|
||||
rapidjson::Value &triple_vapor = states["triple_vapor"];
|
||||
if (triple_vapor.ObjectEmpty()){
|
||||
// State is empty - probably because the triple point temperature is below the minimum saturation temperature
|
||||
fluid.triple_vapor.T = -1;
|
||||
fluid.triple_vapor.p = -1;
|
||||
fluid.triple_vapor.rhomolar = -1;
|
||||
}
|
||||
else{
|
||||
fluid.triple_vapor.T = cpjson::get_double(triple_vapor, "T");
|
||||
fluid.triple_vapor.p = cpjson::get_double(triple_vapor, "p");
|
||||
fluid.triple_vapor.rhomolar = cpjson::get_double(triple_vapor, "rhomolar");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// Parse the critical state for the given EOS
|
||||
@@ -833,7 +932,7 @@ protected:
|
||||
assert(fluid.name.length() > 0);
|
||||
}
|
||||
public:
|
||||
|
||||
|
||||
// Default constructor;
|
||||
JSONFluidLibrary(){
|
||||
_is_empty = true;
|
||||
@@ -844,14 +943,14 @@ public:
|
||||
void add_many(rapidjson::Value &listing)
|
||||
{
|
||||
for (rapidjson::Value::ValueIterator itr = listing.Begin(); itr != listing.End(); ++itr)
|
||||
{
|
||||
{
|
||||
add_one(*itr);
|
||||
}
|
||||
};
|
||||
void add_one(rapidjson::Value &fluid_json)
|
||||
{
|
||||
_is_empty = false;
|
||||
|
||||
|
||||
// Get the next index for this fluid
|
||||
std::size_t index = fluid_map.size();
|
||||
|
||||
@@ -863,73 +962,93 @@ public:
|
||||
|
||||
// Fluid name
|
||||
fluid.name = fluid_json["NAME"].GetString(); name_vector.push_back(fluid.name);
|
||||
// CAS number
|
||||
fluid.CAS = fluid_json["CAS"].GetString();
|
||||
// REFPROP alias
|
||||
fluid.REFPROPname = fluid_json["REFPROP_NAME"].GetString();
|
||||
// Critical state
|
||||
parse_crit_state(fluid_json["CRITICAL"], fluid);
|
||||
|
||||
if (get_debug_level() > 5){
|
||||
std::cout << format("Loading fluid %s with CAS %s; %d fluids loaded\n", fluid.name.c_str(), fluid.CAS.c_str(), index);
|
||||
}
|
||||
try{
|
||||
// CAS number
|
||||
if (!fluid_json.HasMember("CAS")){ throw ValueError(format("fluid [%s] does not have \"CAS\" member",fluid.name.c_str())); }
|
||||
fluid.CAS = fluid_json["CAS"].GetString();
|
||||
// REFPROP alias
|
||||
if (!fluid_json.HasMember("REFPROP_NAME")){ throw ValueError(format("fluid [%s] does not have \"REFPROP_NAME\" member",fluid.name.c_str())); }
|
||||
fluid.REFPROPname = fluid_json["REFPROP_NAME"].GetString();
|
||||
// Critical state
|
||||
if (!fluid_json.HasMember("STATES")){ throw ValueError(format("fluid [%s] does not have \"STATES\" member",fluid.name.c_str())); }
|
||||
parse_states(fluid_json["STATES"], fluid);
|
||||
|
||||
// Aliases
|
||||
fluid.aliases = cpjson::get_string_array(fluid_json["ALIASES"]);
|
||||
|
||||
// EOS
|
||||
parse_EOS_listing(fluid_json["EOS"], fluid);
|
||||
|
||||
// Validate the fluid
|
||||
validate(fluid);
|
||||
|
||||
// Ancillaries for saturation
|
||||
if (!fluid_json.HasMember("ANCILLARIES")){throw ValueError(format("Ancillary curves are missing for fluid [%s]",fluid.name.c_str()));};
|
||||
parse_ancillaries(fluid_json["ANCILLARIES"],fluid);
|
||||
|
||||
// Surface tension
|
||||
if (!(fluid_json["ANCILLARIES"].HasMember("surface_tension"))){
|
||||
if (get_debug_level() > 0){
|
||||
std::cout << format("Surface tension curves are missing for fluid [%s]\n", fluid.name.c_str()) ;
|
||||
if (get_debug_level() > 5){
|
||||
std::cout << format("Loading fluid %s with CAS %s; %d fluids loaded\n", fluid.name.c_str(), fluid.CAS.c_str(), index);
|
||||
}
|
||||
}
|
||||
else{
|
||||
parse_surface_tension(fluid_json["ANCILLARIES"]["surface_tension"], fluid);
|
||||
}
|
||||
|
||||
// Parse the environmental parameters
|
||||
if (!(fluid_json.HasMember("ENVIRONMENTAL"))){
|
||||
if (get_debug_level() > 0){
|
||||
std::cout << format("Environmental data are missing for fluid [%s]\n", fluid.name.c_str()) ;
|
||||
// Aliases
|
||||
fluid.aliases = cpjson::get_string_array(fluid_json["ALIASES"]);
|
||||
|
||||
// EOS
|
||||
parse_EOS_listing(fluid_json["EOS"], fluid);
|
||||
|
||||
// Validate the fluid
|
||||
validate(fluid);
|
||||
|
||||
// Ancillaries for saturation
|
||||
if (!fluid_json.HasMember("ANCILLARIES")){throw ValueError(format("Ancillary curves are missing for fluid [%s]",fluid.name.c_str()));};
|
||||
parse_ancillaries(fluid_json["ANCILLARIES"],fluid);
|
||||
|
||||
// Surface tension
|
||||
if (!(fluid_json["ANCILLARIES"].HasMember("surface_tension"))){
|
||||
if (get_debug_level() > 0){
|
||||
std::cout << format("Surface tension curves are missing for fluid [%s]\n", fluid.name.c_str()) ;
|
||||
}
|
||||
}
|
||||
else{
|
||||
parse_surface_tension(fluid_json["ANCILLARIES"]["surface_tension"], fluid);
|
||||
}
|
||||
}
|
||||
else{
|
||||
parse_environmental(fluid_json["ENVIRONMENTAL"], fluid);
|
||||
}
|
||||
|
||||
// Parse the environmental parameters
|
||||
if (!(fluid_json.HasMember("TRANSPORT"))){
|
||||
default_transport(fluid);
|
||||
}
|
||||
else{
|
||||
parse_transport(fluid_json["TRANSPORT"], fluid);
|
||||
}
|
||||
|
||||
// If the fluid is ok...
|
||||
// Melting line
|
||||
if (!(fluid_json["ANCILLARIES"].HasMember("melting_line"))){
|
||||
if (get_debug_level() > 0){
|
||||
std::cout << format("Melting line curves are missing for fluid [%s]\n", fluid.name.c_str()) ;
|
||||
}
|
||||
}
|
||||
else{
|
||||
parse_melting_line(fluid_json["ANCILLARIES"]["melting_line"], fluid);
|
||||
}
|
||||
|
||||
// Add CAS->index mapping
|
||||
string_to_index_map[fluid.CAS] = index;
|
||||
// Parse the environmental parameters
|
||||
if (!(fluid_json.HasMember("ENVIRONMENTAL"))){
|
||||
if (get_debug_level() > 0){
|
||||
std::cout << format("Environmental data are missing for fluid [%s]\n", fluid.name.c_str()) ;
|
||||
}
|
||||
}
|
||||
else{
|
||||
parse_environmental(fluid_json["ENVIRONMENTAL"], fluid);
|
||||
}
|
||||
|
||||
// Parse the environmental parameters
|
||||
if (!(fluid_json.HasMember("TRANSPORT"))){
|
||||
default_transport(fluid);
|
||||
}
|
||||
else{
|
||||
parse_transport(fluid_json["TRANSPORT"], fluid);
|
||||
}
|
||||
|
||||
// If the fluid is ok...
|
||||
|
||||
// Add CAS->index mapping
|
||||
string_to_index_map[fluid.CAS] = index;
|
||||
|
||||
// Add name->index mapping
|
||||
string_to_index_map[fluid.name] = index;
|
||||
|
||||
// Add the aliases
|
||||
for (std::size_t i = 0; i < fluid.aliases.size(); ++i)
|
||||
{
|
||||
string_to_index_map[fluid.aliases[i]] = index;
|
||||
}
|
||||
|
||||
if (get_debug_level() > 5){ std::cout << format("Loaded.\n"); }
|
||||
|
||||
// Add name->index mapping
|
||||
string_to_index_map[fluid.name] = index;
|
||||
|
||||
// Add the aliases
|
||||
for (std::size_t i = 0; i < fluid.aliases.size(); ++i)
|
||||
{
|
||||
string_to_index_map[fluid.aliases[i]] = index;
|
||||
}
|
||||
|
||||
if (get_debug_level() > 5){ std::cout << format("Loaded.\n"); }
|
||||
catch (const std::exception &e){
|
||||
throw ValueError(format("Unable to load fluid [%s] due to error: %s",fluid.name.c_str(),e.what()));
|
||||
}
|
||||
};
|
||||
/// Get a CoolPropFluid instance stored in this library
|
||||
/**
|
||||
@@ -982,4 +1101,4 @@ std::string get_fluid_list(void);
|
||||
CoolPropFluid& get_fluid(std::string fluid_string);
|
||||
|
||||
} /* namespace CoolProp */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -115,6 +115,17 @@ long double HelmholtzEOSMixtureBackend::calc_molar_mass(void)
|
||||
}
|
||||
return summer;
|
||||
}
|
||||
long double HelmholtzEOSMixtureBackend::calc_melt_p_T(long double T)
|
||||
{
|
||||
if (is_pure_or_pseudopure)
|
||||
{
|
||||
return components[0]->ancillaries.melting_line.evaluate(iP, iT, T);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw NotImplementedError(format("calc_melt_p_T not implemented for mixtures"));
|
||||
}
|
||||
}
|
||||
long double HelmholtzEOSMixtureBackend::calc_surface_tension(void)
|
||||
{
|
||||
if (is_pure_or_pseudopure)
|
||||
@@ -1174,8 +1185,8 @@ long double HelmholtzEOSMixtureBackend::solver_for_rho_given_T_oneof_HSU(long do
|
||||
// Supercritical temperature
|
||||
if (_T > _crit.T)
|
||||
{
|
||||
long double rhomelt = components[0]->pEOS->rhoLtriple;
|
||||
long double rhoc = components[0]->pEOS->reduce.rhomolar;
|
||||
long double rhomelt = components[0]->triple_liquid.rhomolar;
|
||||
long double rhoc = components[0]->crit.rhomolar;
|
||||
long double rhomin = 1e-10;
|
||||
|
||||
switch(other)
|
||||
@@ -1228,7 +1239,7 @@ long double HelmholtzEOSMixtureBackend::solver_for_rho_given_T_oneof_HSU(long do
|
||||
else if (_phase == iphase_liquid)
|
||||
{
|
||||
long double ymelt, yL, y;
|
||||
long double rhomelt = components[0]->pEOS->rhoLtriple;
|
||||
long double rhomelt = components[0]->triple_liquid.rhomolar;
|
||||
long double rhoL = static_cast<double>(_rhoLanc);
|
||||
|
||||
switch(other)
|
||||
@@ -1591,8 +1602,8 @@ long double HelmholtzEOSMixtureBackend::calc_speed_sound(void)
|
||||
long double d2ar_dDelta2 = d2alphar_dDelta2();
|
||||
long double d2ar_dDelta_dTau = d2alphar_dDelta_dTau();
|
||||
long double d2ar_dTau2 = d2alphar_dTau2();
|
||||
long double R_u = static_cast<long double>(_gas_constant);
|
||||
long double mm = static_cast<long double>(_molar_mass);
|
||||
long double R_u = gas_constant();
|
||||
long double mm = molar_mass();
|
||||
|
||||
// Get speed of sound
|
||||
_speed_sound = sqrt(R_u*_T/mm*(1+2*_delta.pt()*dar_dDelta+pow(_delta.pt(),2)*d2ar_dDelta2 - pow(1+_delta.pt()*dar_dDelta-_delta.pt()*_tau.pt()*d2ar_dDelta_dTau,2)/(pow(_tau.pt(),2)*(d2ar_dTau2 + d2a0_dTau2))));
|
||||
|
||||
@@ -17,10 +17,10 @@ class FlashRoutines;
|
||||
class HelmholtzEOSMixtureBackend : public AbstractState {
|
||||
protected:
|
||||
std::vector<CoolPropFluid*> components; ///< The components that are in use
|
||||
|
||||
|
||||
bool is_pure_or_pseudopure; ///< A flag for whether the substance is a pure or pseudo-pure fluid (true) or a mixture (false)
|
||||
std::vector<long double> mole_fractions; ///< The mole fractions of the components
|
||||
std::vector<long double> mole_fractions_liq, ///< The mole fractions of the saturated liquid
|
||||
std::vector<long double> mole_fractions_liq, ///< The mole fractions of the saturated liquid
|
||||
mole_fractions_vap, ///< The mole fractions of the saturated vapor
|
||||
K, ///< The K factors for the components
|
||||
lnK; ///< The natural logarithms of the K factors of the components
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
|
||||
friend class FlashRoutines; // Allows the static methods in the FlashRoutines class to have access to all the protected members and methods of this class
|
||||
friend class TransportRoutines; // Allows the static methods in the TransportRoutines class to have access to all the protected members and methods of this class
|
||||
//friend class MixtureDerivatives; //
|
||||
//friend class MixtureDerivatives; //
|
||||
|
||||
// Helmholtz EOS backend uses mole fractions
|
||||
bool using_mole_fractions(){return true;}
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
std::vector<long double> &get_K(){return K;};
|
||||
std::vector<long double> &get_lnK(){return lnK;};
|
||||
|
||||
shared_ptr<HelmholtzEOSMixtureBackend> SatL, SatV; ///<
|
||||
shared_ptr<HelmholtzEOSMixtureBackend> SatL, SatV; ///<
|
||||
|
||||
void update(long input_pair, double value1, double value2);
|
||||
|
||||
@@ -69,19 +69,19 @@ public:
|
||||
void set_excess_term();
|
||||
|
||||
/// Set the mole fractions
|
||||
/**
|
||||
/**
|
||||
@param mole_fractions The vector of mole fractions of the components
|
||||
*/
|
||||
void set_mole_fractions(const std::vector<long double> &mole_fractions);
|
||||
|
||||
const std::vector<long double> &get_mole_fractions(){return mole_fractions;};
|
||||
|
||||
|
||||
/// Set the mass fractions
|
||||
/**
|
||||
/**
|
||||
@param mass_fractions The vector of mass fractions of the components
|
||||
*/
|
||||
void set_mass_fractions(const std::vector<long double> &mass_fractions){throw std::exception();};
|
||||
|
||||
|
||||
long double calc_molar_mass(void);
|
||||
long double calc_gas_constant(void);
|
||||
|
||||
@@ -118,6 +118,7 @@ public:
|
||||
long double calc_d2alpha0_dDelta_dTau(void);
|
||||
long double calc_d2alpha0_dTau2(void);
|
||||
|
||||
long double calc_melt_p_T(long double T);
|
||||
long double calc_surface_tension(void);
|
||||
long double calc_viscosity(void);
|
||||
long double calc_viscosity_dilute(void);
|
||||
@@ -137,7 +138,7 @@ public:
|
||||
std::string calc_name(void);
|
||||
|
||||
long double calc_alphar_deriv_nocache(const int nTau, const int nDelta, const std::vector<long double> & mole_fractions, const long double &tau, const long double &delta);
|
||||
|
||||
|
||||
/**
|
||||
\brief Take derivatives of the ideal-gas part of the Helmholtz energy, don't use any cached values, or store any cached values
|
||||
|
||||
@@ -163,7 +164,7 @@ public:
|
||||
\sa Table B5, GERG 2008 from Kunz Wagner, JCED, 2012
|
||||
*/
|
||||
long double calc_alpha0_deriv_nocache(const int nTau, const int nDelta, const std::vector<long double> & mole_fractions, const long double &tau, const long double &delta, const long double &Tr, const long double &rhor);
|
||||
|
||||
|
||||
void calc_reducing_state(void);
|
||||
SimpleState calc_reducing_state_nocache(const std::vector<long double> & mole_fractions);
|
||||
|
||||
@@ -183,11 +184,11 @@ public:
|
||||
|
||||
void mass_to_molar_inputs(long &input_pair, double &value1, double &value2);
|
||||
|
||||
// ***************************************************************
|
||||
// ***************************************************************
|
||||
// ***************************************************************
|
||||
// ************* PHASE DETERMINATION ROUTINES ******************
|
||||
// ***************************************************************
|
||||
// ***************************************************************
|
||||
// ***************************************************************
|
||||
void T_phase_determination_pure_or_pseudopure(int other, long double value);
|
||||
void p_phase_determination_pure_or_pseudopure(int other, long double value);
|
||||
void DmolarP_phase_determination();
|
||||
@@ -197,8 +198,8 @@ public:
|
||||
// ***************************************************************
|
||||
// ******************* SOLVER ROUTINES *************************
|
||||
// ***************************************************************
|
||||
// ***************************************************************
|
||||
|
||||
// ***************************************************************
|
||||
|
||||
long double solver_rho_Tp(long double T, long double p, long double rho_guess = -1);
|
||||
long double solver_rho_Tp_SRK(long double T, long double p, int phase);
|
||||
long double solver_for_rho_given_T_oneof_HSU(long double T, long double value, int other);
|
||||
@@ -310,7 +311,7 @@ public:
|
||||
\f[
|
||||
n\left(\frac{\partial \ln \phi_i}{\partial n_j}\right)_{T,p} = n\left(\frac{\partial^2n\alpha^r}{\partial n_j \partial n_i} \right)_{T,V}+1+\frac{n}{RT}\frac{\left(\frac{\partial p}{\partial n_j}\right)_{T,V,n_i}\left(\frac{\partial p}{\partial n_i}\right)_{T,V,n_j}}{\left(\frac{\partial p}{\partial V}\right)_{T,\bar n}}
|
||||
\f]
|
||||
which is also equal to
|
||||
which is also equal to
|
||||
\f[
|
||||
n\left(\frac{\partial \ln \phi_i}{\partial n_j}\right)_{T,p} = n\left(\frac{\partial^2n\alpha^r}{\partial n_j \partial n_i} \right)_{T,V}+1-\frac{\hat v_i}{RT}\left[n\left(\frac{\partial p}{\partial n_j}\right)_{T,V,n_i}\right]
|
||||
\f]
|
||||
@@ -320,7 +321,7 @@ public:
|
||||
/// Gernert Equation 3.115
|
||||
/// Catch test provided
|
||||
long double mixderiv_dln_fugacity_coefficient_dxj__constT_p_xi(int i, int j);
|
||||
|
||||
|
||||
/// Gernert Equation 3.130
|
||||
/// Catch test provided
|
||||
long double mixderiv_dpdxj__constT_V_xi(int j);
|
||||
@@ -390,7 +391,7 @@ public:
|
||||
\f]
|
||||
GERG 2004 Monograph equation 7.47:
|
||||
\f{eqnarray*}{
|
||||
n\left( \frac{\partial}{\partial n_j}\left(n\left(\frac{\partial \alpha^r}{\partial n_i}\right)_{T,V,n_j} \right) \right)_{T,V,n_i} &=& \left( \frac{\partial}{\partial \delta}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\tau,\bar x}\cdot n\left(\frac{\partial\delta}{\partial n_j}\right)_{T,V,n_i}\\
|
||||
n\left( \frac{\partial}{\partial n_j}\left(n\left(\frac{\partial \alpha^r}{\partial n_i}\right)_{T,V,n_j} \right) \right)_{T,V,n_i} &=& \left( \frac{\partial}{\partial \delta}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\tau,\bar x}\cdot n\left(\frac{\partial\delta}{\partial n_j}\right)_{T,V,n_i}\\
|
||||
&+& \left( \frac{\partial}{\partial \tau}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\tau,\bar x}\cdot n\left(\frac{\partial\tau}{\partial n_j}\right)_{T,V,n_i}\\
|
||||
&+& \left( \frac{\partial}{\partial x_j}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\delta,\tau,x_i}-\sum_{k=1}^{N}x_k \left( \frac{\partial}{\partial x_k}\left(n\left(\frac{\partial\alpha^r}{\partial n_i}\right)_{T,V,n_j}\right)\right)_{\delta,\tau,x_i}\\
|
||||
\f}
|
||||
@@ -404,7 +405,7 @@ public:
|
||||
\f]
|
||||
*/
|
||||
long double mixderiv_nddeltadni__constT_V_nj(int i);
|
||||
|
||||
|
||||
/// GERG 2004 Monograph equation 7.49
|
||||
/** The derivative term
|
||||
\f[
|
||||
|
||||
@@ -11,13 +11,13 @@ long double TransportRoutines::viscosity_dilute_kinetic_theory(HelmholtzEOSMixtu
|
||||
long double Tstar = HEOS.T()/HEOS.components[0]->transport.epsilon_over_k;
|
||||
long double sigma_nm = HEOS.components[0]->transport.sigma_eta*1e9; // 1e9 to convert from m to nm
|
||||
long double molar_mass_kgkmol = HEOS.molar_mass()*1000; // 1000 to convert from kg/mol to kg/kmol
|
||||
|
||||
// The nondimensional empirical collision integral from Neufeld
|
||||
// Neufeld, P. D.; Janzen, A. R.; Aziz, R. A. Empirical Equations to Calculate 16 of the Transport Collision Integrals (l,s)*
|
||||
|
||||
// The nondimensional empirical collision integral from Neufeld
|
||||
// Neufeld, P. D.; Janzen, A. R.; Aziz, R. A. Empirical Equations to Calculate 16 of the Transport Collision Integrals (l,s)*
|
||||
// for the Lennard-Jones (12-6) Potential. J. Chem. Phys. 1972, 57, 1100-1102
|
||||
long double OMEGA22 = 1.16145*pow(Tstar, static_cast<long double>(-0.14874))+0.52487*exp(-0.77320*Tstar)+2.16178*exp(-2.43787*Tstar);
|
||||
|
||||
// The dilute gas component -
|
||||
// The dilute gas component -
|
||||
return 26.692e-9*sqrt(molar_mass_kgkmol*HEOS.T())/(pow(sigma_nm, 2)*OMEGA22); // Pa-s
|
||||
}
|
||||
else{
|
||||
@@ -40,8 +40,8 @@ long double TransportRoutines::viscosity_dilute_collision_integral(HelmholtzEOSM
|
||||
const long double sigma_nm = HEOS.components[0]->transport.sigma_eta*1e9; // 1e9 to convert from m to nm
|
||||
const long double molar_mass_kgkmol = molar_mass*1000; // 1000 to convert from kg/mol to kg/kmol
|
||||
|
||||
/// Both the collision integral \f$\mathfrak{S}^*\f$ and effective cross section \f$\Omega^{(2,2)}\f$ have the same form,
|
||||
/// in general we don't care which is used. The are related through \f$\Omega^{(2,2)} = (5/4)\mathfrak{S}^*\f$
|
||||
/// Both the collision integral \f$\mathfrak{S}^*\f$ and effective cross section \f$\Omega^{(2,2)}\f$ have the same form,
|
||||
/// in general we don't care which is used. The are related through \f$\Omega^{(2,2)} = (5/4)\mathfrak{S}^*\f$
|
||||
/// see Vesovic(JPCRD, 1990) for CO\f$_2\f$ for further information
|
||||
long double summer = 0, lnTstar = log(Tstar);
|
||||
for (std::size_t i = 0; i < a.size(); ++i)
|
||||
@@ -49,7 +49,7 @@ long double TransportRoutines::viscosity_dilute_collision_integral(HelmholtzEOSM
|
||||
summer += a[i]*pow(lnTstar,t[i]);
|
||||
}
|
||||
S = exp(summer);
|
||||
|
||||
|
||||
// The dilute gas component
|
||||
return C*sqrt(molar_mass_kgkmol*HEOS.T())/(pow(sigma_nm, 2)*S); // Pa-s
|
||||
}
|
||||
@@ -148,7 +148,7 @@ long double TransportRoutines::viscosity_initial_density_dependence_Rainwater_Fr
|
||||
long double B_eta, B_eta_star;
|
||||
long double Tstar = HEOS.T()/HEOS.components[0]->transport.epsilon_over_k; // [no units]
|
||||
long double sigma = HEOS.components[0]->transport.sigma_eta; // [m]
|
||||
|
||||
|
||||
long double summer = 0;
|
||||
for (unsigned int i = 0; i < b.size(); ++i){
|
||||
summer += b[i]*pow(Tstar, t[i]);
|
||||
@@ -225,7 +225,7 @@ long double TransportRoutines::viscosity_water_hardcoded(HelmholtzEOSMixtureBack
|
||||
double x_mu=0.068,qc=1/1.9,qd=1/1.1,nu=0.630,gamma=1.239,zeta_0=0.13,LAMBDA_0=0.06,Tbar_R=1.5, pstar, Tstar, rhostar;
|
||||
double delta,tau,mubar_0,mubar_1,mubar_2,drhodp,drhodp_R,DeltaChibar,zeta,w,L,Y,psi_D,Tbar,rhobar;
|
||||
double drhobar_dpbar,drhobar_dpbar_R,R_Water;
|
||||
|
||||
|
||||
pstar = 22.064e6; // [Pa]
|
||||
Tstar = 647.096; // [K]
|
||||
rhostar = 322; // [kg/m^3]
|
||||
@@ -246,7 +246,7 @@ long double TransportRoutines::viscosity_water_hardcoded(HelmholtzEOSMixtureBack
|
||||
tau=1/Tbar_R;
|
||||
drhodp_R=1/(R_Water*Tbar_R*Tstar*(1+2*rhobar*HEOS.calc_alphar_deriv_nocache(0,1,HEOS.mole_fractions,tau,delta)+delta*delta*HEOS.calc_alphar_deriv_nocache(0,2,HEOS.mole_fractions,tau, delta)));
|
||||
drhobar_dpbar_R = pstar/rhostar*drhodp_R;
|
||||
|
||||
|
||||
DeltaChibar=rhobar*(drhobar_dpbar-drhobar_dpbar_R*Tbar_R/Tbar);
|
||||
if (DeltaChibar<0)
|
||||
DeltaChibar=0;
|
||||
@@ -330,7 +330,7 @@ long double TransportRoutines::viscosity_higher_order_friction_theory(HelmholtzE
|
||||
double deltapr = pr - pid;
|
||||
|
||||
double eta_f = ka*pa + kr*deltapr + ki*pid + kaa*pa*pa + kdrdr*deltapr*deltapr + krr*pr*pr + kii*pid*pid + krrr*pr*pr*pr + kaaa*pa*pa*pa;
|
||||
|
||||
|
||||
return eta_f; //[Pa-s]
|
||||
}
|
||||
else{
|
||||
@@ -345,10 +345,10 @@ long double TransportRoutines::viscosity_helium_hardcoded(HelmholtzEOSMixtureBac
|
||||
double eta_0,eta_0_slash, eta_E_slash, B,C,D,ln_eta,x;
|
||||
//
|
||||
// Arp, V.D., McCarty, R.D., and Friend, D.G.,
|
||||
// "Thermophysical Properties of Helium-4 from 0.8 to 1500 K with Pressures to 2000 MPa",
|
||||
// "Thermophysical Properties of Helium-4 from 0.8 to 1500 K with Pressures to 2000 MPa",
|
||||
// NIST Technical Note 1334 (revised), 1998.
|
||||
//
|
||||
// Using Arp NIST report
|
||||
//
|
||||
// Using Arp NIST report
|
||||
// Report is not clear on viscosity, referring to REFPROP source code for clarity
|
||||
|
||||
// Correlation wants density in g/cm^3; kg/m^3 --> g/cm^3, divide by 1000
|
||||
@@ -391,9 +391,6 @@ long double TransportRoutines::viscosity_R23_hardcoded(HelmholtzEOSMixtureBacken
|
||||
rhocbar = 7.5114,
|
||||
Tc = 299.2793,
|
||||
DELTAeta_max = 3.967,
|
||||
k = 1.380658e-23,
|
||||
N_A = 6.022137e23, // 1/mol
|
||||
pi = 3.141592654, //
|
||||
Ru = 8.31451,
|
||||
molar_mass = 70.014;
|
||||
|
||||
@@ -418,7 +415,7 @@ long double TransportRoutines::viscosity_R23_hardcoded(HelmholtzEOSMixtureBacken
|
||||
long double TransportRoutines::viscosity_dilute_ethane(HelmholtzEOSMixtureBackend &HEOS)
|
||||
{
|
||||
double C[] = {0, -3.0328138281, 16.918880086, -37.189364917, 41.288861858, -24.615921140, 8.9488430959, -1.8739245042, 0.20966101390, -9.6570437074e-3};
|
||||
double OMEGA_2_2 = 0, e_k = 245, sigma = 0.43682, Tstar;
|
||||
double OMEGA_2_2 = 0, e_k = 245, Tstar;
|
||||
|
||||
Tstar = HEOS.T()/e_k;
|
||||
for (int i = 1; i<= 9; i++)
|
||||
@@ -572,7 +569,7 @@ long double TransportRoutines::conductivity_critical_hardcoded_R123(HelmholtzEOS
|
||||
long double TransportRoutines::conductivity_critical_hardcoded_CO2_ScalabrinJPCRD2006(HelmholtzEOSMixtureBackend &HEOS){
|
||||
long double nc = 0.775547504e-3*4.81384, Tr = HEOS.T()/304.1282, alpha, rhor = HEOS.keyed_output(iDmass)/467.6;
|
||||
static long double a[] = {0.0, 3.0, 6.70697, 0.94604, 0.30, 0.30, 0.39751, 0.33791, 0.77963, 0.79857, 0.90, 0.02, 0.20};
|
||||
|
||||
|
||||
// Equation 6 from Scalabrin
|
||||
alpha = 1-a[10]*acosh(1+a[11]*pow(pow(1-Tr,2),a[12]));
|
||||
|
||||
@@ -598,8 +595,8 @@ long double TransportRoutines::conductivity_dilute_hardcoded_CO2(HelmholtzEOSMix
|
||||
//Vesovic Eq. 12 [no units]
|
||||
double r = sqrt(2.0/5.0*cint_k);
|
||||
|
||||
// According to REFPROP, 1+r^2 = cp-2.5R. This is unclear to me but seems to suggest that cint/k is the difference
|
||||
// between the ideal gas specific heat and a monatomic specific heat of 5/2*R. Using the form of cint/k from Vesovic
|
||||
// According to REFPROP, 1+r^2 = cp-2.5R. This is unclear to me but seems to suggest that cint/k is the difference
|
||||
// between the ideal gas specific heat and a monatomic specific heat of 5/2*R. Using the form of cint/k from Vesovic
|
||||
// does not yield exactly the correct values
|
||||
|
||||
Tstar = HEOS.T()/e_k;
|
||||
@@ -670,15 +667,14 @@ long double TransportRoutines::conductivity_hardcoded_water(HelmholtzEOSMixtureB
|
||||
// Finite density contribution
|
||||
lambdabar_1=exp(rhobar*sum);
|
||||
|
||||
double nu=0.630,GAMMA =177.8514,gamma=1.239,xi_0=0.13,Lambda_0=0.06,Tr_bar=1.5,tau_ref = Tr_bar*Tstar/HEOS.T(),
|
||||
double nu=0.630,GAMMA =177.8514,gamma=1.239,xi_0=0.13,Lambda_0=0.06,Tr_bar=1.5,
|
||||
qd_bar=1/0.4,pi=3.141592654, delta = HEOS.delta(), R=461.51805;//J/kg/K
|
||||
tau=1/Tbar;
|
||||
|
||||
|
||||
double drhodp = 1/(R*HEOS.T()*(1+2*rhobar*HEOS.dalphar_dDelta()+rhobar*rhobar*HEOS.d2alphar_dDelta2()));
|
||||
double drhobar_dpbar = pstar/rhostar*drhodp;
|
||||
double drhodp_Trbar = 1/(R*Tr_bar*Tstar*(1+2*rhobar*HEOS.calc_alphar_deriv_nocache(0,1,HEOS.mole_fractions,1/Tr_bar,delta)+delta*delta*HEOS.calc_alphar_deriv_nocache(0,2,HEOS.mole_fractions,1/Tr_bar,delta)));
|
||||
double drhobar_dpbar_Trbar = pstar/rhostar*drhodp_Trbar;
|
||||
double cpmol = HEOS.cpmolar(); // [J/mol/K]
|
||||
double cp = HEOS.cpmass(); // [J/kg/K]
|
||||
double cv = HEOS.cvmass(); // [J/kg/K]
|
||||
double cpbar = cp/R; //[-]
|
||||
@@ -731,17 +727,17 @@ long double TransportRoutines::conductivity_hardcoded_R23(HelmholtzEOSMixtureBac
|
||||
|
||||
long double TransportRoutines::conductivity_critical_hardcoded_ammonia(HelmholtzEOSMixtureBackend &HEOS){
|
||||
|
||||
/*
|
||||
From "Thermal Conductivity of Ammonia in a Large
|
||||
/*
|
||||
From "Thermal Conductivity of Ammonia in a Large
|
||||
Temperature and Pressure Range Including the Critical Region"
|
||||
by R. Tufeu, D.Y. Ivanov, Y. Garrabos, B. Le Neindre,
|
||||
by R. Tufeu, D.Y. Ivanov, Y. Garrabos, B. Le Neindre,
|
||||
Bereicht der Bunsengesellschaft Phys. Chem. 88 (1984) 422-427
|
||||
*/
|
||||
|
||||
double T = HEOS.T(), Tc = 405.4, rhoc = 235, rho;
|
||||
double LAMBDA=1.2, nu=0.63, gamma =1.24, DELTA=0.50,t,zeta_0_plus=1.34e-10,a_zeta=1,GAMMA_0_plus=0.423e-8;
|
||||
double pi=3.141592654,a_chi,k_B=1.3806504e-23,X_T,DELTA_lambda,dPdT,eta_B,DELTA_lambda_id,DELTA_lambda_i;
|
||||
|
||||
|
||||
rho = HEOS.keyed_output(CoolProp::iDmass);
|
||||
t = fabs((T-Tc)/Tc);
|
||||
a_chi = a_zeta/0.7;
|
||||
@@ -785,14 +781,14 @@ long double TransportRoutines::conductivity_hardcoded_helium(HelmholtzEOSMixture
|
||||
lambda_e = (c[0]+c[1]*T+c[2]*pow(T,1/3.0)+c[3]*pow(T,2.0/3.0))*rho
|
||||
+(c[4]+c[5]*pow(T,1.0/3.0)+c[6]*pow(T,2.0/3.0))*rho*rho*rho
|
||||
+(c[7]+c[8]*pow(T,1.0/3.0)+c[9]*pow(T,2.0/3.0)+c[10]/T)*rho*rho*log(rho/rhoc);
|
||||
|
||||
|
||||
// Critical component
|
||||
lambda_c = 0.0;
|
||||
|
||||
|
||||
if (3.5 < T && T < 12)
|
||||
{
|
||||
double x0 = 0.392, E1 = 2.8461, E2 = 0.27156, beta = 0.3554, gamma = 1.1743, delta = 4.304, rhoc_crit = 69.158,
|
||||
Tc = 5.18992, pc = 2.2746e5, R = 4.633e-10, m = 6.6455255e-27, k = 1.38066e-23, pi = M_PI;
|
||||
double x0 = 0.392, E1 = 2.8461, E2 = 0.27156, beta = 0.3554, gamma = 1.1743, delta = 4.304, rhoc_crit = 69.158,
|
||||
Tc = 5.18992, pc = 2.2746e5;
|
||||
|
||||
double DeltaT = fabs(1-T/Tc), DeltaRho = fabs(1-rho/rhoc_crit);
|
||||
double eta = HEOS.viscosity(); // [Pa-s]
|
||||
@@ -810,7 +806,7 @@ long double TransportRoutines::conductivity_hardcoded_helium(HelmholtzEOSMixture
|
||||
double x = pow(DeltaT/DeltaRho,1/beta);
|
||||
double h = E1*(1 + x/x0)*pow(1 + E2*pow(1 + x/x0, 2/beta), (gamma-1)/(2*beta));
|
||||
|
||||
/**
|
||||
/**
|
||||
dh/dx derived using sympy:
|
||||
|
||||
E1,x,x0,E2,beta,gamma = symbols('E1,x,x0,E2,beta,gamma')
|
||||
@@ -824,7 +820,7 @@ long double TransportRoutines::conductivity_hardcoded_helium(HelmholtzEOSMixture
|
||||
K_Tbar = W*K_T + (1-W)*K_Tprime;
|
||||
}
|
||||
|
||||
// 3.4685233d-17 and 3.726229668d0 are "magical" coefficients that are present in the REFPROP source to yield the right values. Not clear why these values are needed.
|
||||
// 3.4685233d-17 and 3.726229668d0 are "magical" coefficients that are present in the REFPROP source to yield the right values. Not clear why these values are needed.
|
||||
// Also, the form of the critical term in REFPROP does not agree with Hands paper. EL and MH from NIST are not sure where these coefficients come from.
|
||||
lambda_c = 3.4685233e-17*3.726229668*sqrt(K_Tbar)*pow(T,2)/rho/eta*pow(dpdT,2)*exp(-18.66*pow(DeltaT,2)-4.25*pow(DeltaRho,4));
|
||||
}
|
||||
@@ -843,7 +839,7 @@ long double TransportRoutines::viscosity_ECS(HelmholtzEOSMixtureBackend &HEOS, H
|
||||
|
||||
// Get a reference to the ECS data
|
||||
CoolProp::ViscosityECSVariables &ECS = HEOS.components[0]->transport.viscosity_ecs;
|
||||
|
||||
|
||||
// The correction polynomial psi_eta
|
||||
double psi = 0;
|
||||
for (std::size_t i=0; i < ECS.psi_a.size(); i++){
|
||||
@@ -897,7 +893,7 @@ long double TransportRoutines::conductivity_ECS(HelmholtzEOSMixtureBackend &HEOS
|
||||
|
||||
// Get a reference to the ECS data
|
||||
CoolProp::ConductivityECSVariables &ECS = HEOS.components[0]->transport.conductivity_ecs;
|
||||
|
||||
|
||||
// The correction polynomial psi_eta in rho/rho_red
|
||||
double psi = 0;
|
||||
for (std::size_t i=0; i < ECS.psi_a.size(); ++i){
|
||||
@@ -954,4 +950,4 @@ long double TransportRoutines::conductivity_ECS(HelmholtzEOSMixtureBackend &HEOS
|
||||
}
|
||||
|
||||
|
||||
}; /* namespace CoolProp */
|
||||
}; /* namespace CoolProp */
|
||||
|
||||
@@ -11,23 +11,21 @@
|
||||
//#include "CoolProp.h"
|
||||
|
||||
#include "IncompressibleBackend.h"
|
||||
#include "../Helmholtz/Fluids/FluidLibrary.h"
|
||||
#include "IncompressibleFluid.h"
|
||||
#include "IncompressibleLibrary.h"
|
||||
#include "Solvers.h"
|
||||
#include "MatrixMath.h"
|
||||
|
||||
namespace CoolProp {
|
||||
|
||||
IncompressibleBackend::IncompressibleBackend(const std::string &fluid_name) {
|
||||
throw CoolProp::NotImplementedError("Mixture-style constructor is not implemented yet for incompressible fluids");
|
||||
fluid = &get_incompressible_fluid(fluid_name);
|
||||
}
|
||||
|
||||
IncompressibleBackend::IncompressibleBackend(const std::vector<std::string> &component_names) {
|
||||
throw CoolProp::NotImplementedError("Mixture-style constructor is not implemented yet for incompressible fluids");
|
||||
throw NotImplementedError("Mixture-style constructor is not implemented yet for incompressible fluids");
|
||||
}
|
||||
|
||||
bool IncompressibleBackend::using_mole_fractions(){return false;}
|
||||
|
||||
|
||||
void IncompressibleBackend::update(long input_pair, double value1, double value2) {
|
||||
switch (input_pair) {
|
||||
case PT_INPUTS: {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#ifndef INCOMPRESSIBLEBACKEND_H_
|
||||
#define INCOMPRESSIBLEBACKEND_H_
|
||||
|
||||
#include "IncompressibleFluid.h"
|
||||
#include "AbstractState.h"
|
||||
#include "Exceptions.h"
|
||||
|
||||
@@ -15,6 +16,7 @@ protected:
|
||||
bool _mole_fractions_set;
|
||||
static bool _REFPROP_supported;
|
||||
std::vector<long double> mass_fractions;
|
||||
IncompressibleFluid *fluid;
|
||||
public:
|
||||
IncompressibleBackend(){};
|
||||
virtual ~IncompressibleBackend(){};
|
||||
@@ -27,10 +29,10 @@ public:
|
||||
IncompressibleBackend(const std::vector<std::string> &component_names);
|
||||
|
||||
// Incompressible backend uses mole fractions
|
||||
bool using_mole_fractions();
|
||||
bool using_mole_fractions(){return false;};
|
||||
|
||||
/// Updating function for incompressible fluid
|
||||
/**
|
||||
/**
|
||||
In this function we take a pair of thermodynamic states, those defined in the input_pairs
|
||||
enumeration and update all the internal variables that we can.
|
||||
|
||||
@@ -41,13 +43,13 @@ public:
|
||||
void update(long input_pair, double value1, double value2);
|
||||
|
||||
/// Set the mole fractions
|
||||
/**
|
||||
/**
|
||||
@param mole_fractions The vector of mole fractions of the components
|
||||
*/
|
||||
void set_mole_fractions(const std::vector<long double> &mole_fractions);
|
||||
|
||||
|
||||
/// Set the mass fractions
|
||||
/**
|
||||
/**
|
||||
@param mass_fractions The vector of mass fractions of the components
|
||||
*/
|
||||
void set_mass_fractions(const std::vector<long double> &mass_fractions);
|
||||
|
||||
35
src/Backends/Incompressible/IncompressibleLibrary.cpp
Normal file
35
src/Backends/Incompressible/IncompressibleLibrary.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "IncompressibleLibrary.h"
|
||||
#include "all_incompressibles_JSON.h" // Makes a std::string variable called all_fluids_JSON
|
||||
|
||||
namespace CoolProp{
|
||||
|
||||
static JSONIncompressibleLibrary library;
|
||||
|
||||
void load_incompressible_library()
|
||||
{
|
||||
rapidjson::Document dd;
|
||||
// This json formatted string comes from the all_fluids_JSON.h header which is a C++-escaped version of the JSON file
|
||||
dd.Parse<0>(all_incompressibles_JSON.c_str());
|
||||
if (dd.HasParseError()){
|
||||
throw ValueError("Unable to load all_fluids.json");
|
||||
} else{
|
||||
try{library.add_many(dd);}catch(std::exception &e){std::cout << e.what() << std::endl;}
|
||||
}
|
||||
}
|
||||
|
||||
JSONIncompressibleLibrary & get_incompressible_library(void){
|
||||
if (library.is_empty()){ load_incompressible_library(); }
|
||||
return library;
|
||||
}
|
||||
|
||||
IncompressibleFluid& get_incompressible_fluid(std::string fluid_string){
|
||||
if (library.is_empty()){ load_incompressible_library(); }
|
||||
return library.get(fluid_string);
|
||||
}
|
||||
|
||||
std::string get_incompressible_list(void){
|
||||
if (library.is_empty()){ load_incompressible_library(); }
|
||||
return library.get_fluid_list();
|
||||
};
|
||||
|
||||
} /* namespace CoolProp */
|
||||
203
src/Backends/Incompressible/IncompressibleLibrary.h
Normal file
203
src/Backends/Incompressible/IncompressibleLibrary.h
Normal file
@@ -0,0 +1,203 @@
|
||||
|
||||
#ifndef INCOMPRESSIBLELIBRARY_H
|
||||
#define INCOMPRESSIBLELIBRARY_H
|
||||
|
||||
#include "IncompressibleFluid.h"
|
||||
|
||||
#include "rapidjson/rapidjson_include.h"
|
||||
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
namespace CoolProp{
|
||||
|
||||
// Forward declaration of the necessary debug function to avoid including the whole header
|
||||
extern int get_debug_level();
|
||||
|
||||
/// A container for the fluid parameters for the incompressible fluids
|
||||
/**
|
||||
This container holds copies of all of the fluid instances for the fluids that are loaded in incompressible.
|
||||
New fluids can be added by passing in a rapidjson::Value instance to the add_one function, or
|
||||
a rapidjson array of fluids to the add_many function.
|
||||
*/
|
||||
class JSONIncompressibleLibrary
|
||||
{
|
||||
/// Map from CAS code to JSON instance. For pseudo-pure fluids, use name in place of CAS code since no CASE number is defined for mixtures
|
||||
std::map<std::size_t, IncompressibleFluid> fluid_map;
|
||||
std::vector<std::string> name_vector;
|
||||
std::map<std::string, std::size_t> string_to_index_map;
|
||||
bool _is_empty;
|
||||
protected:
|
||||
|
||||
/// Parse the viscosity
|
||||
void parse_viscosity(rapidjson::Value &viscosity, IncompressibleFluid & fluid)
|
||||
{
|
||||
if (viscosity.HasMember("type")){
|
||||
std::string type = cpjson::get_string(viscosity, "type");
|
||||
if (!type.compare("polynomial")){
|
||||
fluid.viscosity.type = CoolProp::IncompressibleViscosityVariables::INCOMPRESSIBLE_VISCOSITY_POLYNOMIAL;
|
||||
fluid.viscosity.poly.coeffs = cpjson::get_double_array(viscosity["coeffs"]);
|
||||
return;
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("viscosity type [%s] is not understood for fluid %s", type.c_str(), fluid.name.c_str()));
|
||||
}
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("viscosity does not have \"type\" for fluid %s", fluid.name.c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
/// Parse the conductivity
|
||||
void parse_conductivity(rapidjson::Value &conductivity, IncompressibleFluid & fluid)
|
||||
{
|
||||
if (conductivity.HasMember("type")){
|
||||
std::string type = cpjson::get_string(conductivity, "type");
|
||||
if (!type.compare("polynomial")){
|
||||
fluid.conductivity.type = CoolProp::IncompressibleConductivityVariables::INCOMPRESSIBLE_CONDUCTIVITY_POLYNOMIAL;
|
||||
fluid.conductivity.poly.coeffs = cpjson::get_double_array(conductivity["coeffs"]);
|
||||
return;
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("conductivity type [%s] is not understood for fluid %s", type.c_str(), fluid.name.c_str()));
|
||||
}
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("conductivity does not have \"type\" for fluid %s", fluid.name.c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
/// Parse the specific_heat
|
||||
void parse_specific_heat(rapidjson::Value &specific_heat, IncompressibleFluid & fluid)
|
||||
{
|
||||
if (specific_heat.HasMember("type")){
|
||||
std::string type = cpjson::get_string(specific_heat, "type");
|
||||
if (!type.compare("polynomial")){
|
||||
fluid.specific_heat.type = CoolProp::IncompressibleSpecificHeatVariables::INCOMPRESSIBLE_SPECIFIC_HEAT_POLYNOMIAL; return;
|
||||
fluid.specific_heat.poly.coeffs = cpjson::get_double_array(specific_heat["coeffs"]);
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("specific_heat type [%s] is not understood for fluid %s", type.c_str(), fluid.name.c_str()));
|
||||
}
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("specific_heat does not have \"type\" for fluid %s", fluid.name.c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
/// Parse the density
|
||||
void parse_density(rapidjson::Value &density, IncompressibleFluid & fluid)
|
||||
{
|
||||
if (density.HasMember("type")){
|
||||
std::string type = cpjson::get_string(density, "type");
|
||||
if (!type.compare("polynomial")){
|
||||
fluid.density.type = CoolProp::IncompressibleDensityVariables::INCOMPRESSIBLE_DENSITY_POLYNOMIAL; return;
|
||||
fluid.density.poly.coeffs = cpjson::get_double_array(density["coeffs"]);
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("density type [%s] is not understood for fluid %s", type.c_str(), fluid.name.c_str()));
|
||||
}
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("density does not have \"type\" for fluid %s", fluid.name.c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
/// Validate the fluid file that was just constructed
|
||||
void validate(IncompressibleFluid & fluid)
|
||||
{
|
||||
}
|
||||
public:
|
||||
|
||||
// Default constructor;
|
||||
JSONIncompressibleLibrary(){
|
||||
_is_empty = true;
|
||||
};
|
||||
bool is_empty(void){ return _is_empty;};
|
||||
|
||||
/// Add all the fluid entries in the rapidjson::Value instance passed in
|
||||
void add_many(rapidjson::Value &listing)
|
||||
{
|
||||
for (rapidjson::Value::ValueIterator itr = listing.Begin(); itr != listing.End(); ++itr)
|
||||
{
|
||||
add_one(*itr);
|
||||
}
|
||||
};
|
||||
void add_one(rapidjson::Value &fluid_json)
|
||||
{
|
||||
_is_empty = false;
|
||||
|
||||
// Get the next index for this fluid
|
||||
std::size_t index = fluid_map.size();
|
||||
|
||||
// Add index->fluid mapping
|
||||
fluid_map[index] = IncompressibleFluid();
|
||||
|
||||
// Create an instance of the fluid
|
||||
IncompressibleFluid &fluid = fluid_map[index];
|
||||
|
||||
fluid.name = cpjson::get_string(fluid_json, "name");
|
||||
fluid.Tmin = cpjson::get_double(fluid_json, "Tmin");
|
||||
fluid.Tmax = cpjson::get_double(fluid_json, "Tmax");
|
||||
|
||||
parse_conductivity(fluid_json["conductivity"], fluid);
|
||||
parse_density(fluid_json["density"], fluid);
|
||||
parse_viscosity(fluid_json["viscosity"], fluid);
|
||||
parse_specific_heat(fluid_json["specific_heat"], fluid);
|
||||
|
||||
// Add name->index mapping
|
||||
string_to_index_map[fluid.name] = index;
|
||||
|
||||
};
|
||||
/// Get an IncompressibleFluid instance stored in this library
|
||||
/**
|
||||
@param name Name of the fluid
|
||||
*/
|
||||
IncompressibleFluid& get(std::string key)
|
||||
{
|
||||
std::map<std::string, std::size_t>::iterator it;
|
||||
// Try to find it
|
||||
it = string_to_index_map.find(key);
|
||||
// If it is found
|
||||
if (it != string_to_index_map.end()){
|
||||
return get(it->second);
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("key [%s] was not found in string_to_index_map in JSONIncompressibleLibrary",key.c_str()));
|
||||
}
|
||||
};
|
||||
/// Get a CoolPropFluid instance stored in this library
|
||||
/**
|
||||
@param key The index of the fluid in the map
|
||||
*/
|
||||
IncompressibleFluid& get(std::size_t key)
|
||||
{
|
||||
std::map<std::size_t, IncompressibleFluid>::iterator it;
|
||||
// Try to find it
|
||||
it = fluid_map.find(key);
|
||||
// If it is found
|
||||
if (it != fluid_map.end()){
|
||||
return it->second;
|
||||
}
|
||||
else{
|
||||
throw ValueError(format("key [%d] was not found in JSONIncompressibleLibrary",key));
|
||||
}
|
||||
};
|
||||
/// Return a comma-separated list of fluid names
|
||||
std::string get_fluid_list(void)
|
||||
{
|
||||
return strjoin(name_vector, ",");
|
||||
};
|
||||
};
|
||||
|
||||
/// Get a reference to the library instance
|
||||
JSONIncompressibleLibrary & get_incompressible_library(void);
|
||||
|
||||
/// Get a comma-separated-list of incompressible fluids that are included
|
||||
std::string get_incompressible_list(void);
|
||||
|
||||
/// Get the fluid structure returned as a reference
|
||||
IncompressibleFluid& get_incompressible_fluid(std::string fluid_string);
|
||||
|
||||
} /* namespace CoolProp */
|
||||
#endif
|
||||
@@ -50,7 +50,8 @@ parameter_info parameter_info_list[] = {
|
||||
parameter_info(irhomolar_critical, "rhomolar_critical","O","mol/m^3","Molar density at critical point"),
|
||||
parameter_info(iT_reducing, "T_reducing","O","K","Temperature at the reducing point"),
|
||||
parameter_info(iT_critical, "T_critical","O","K","Temperature at the critical point"),
|
||||
parameter_info(iisothermal_compressibility, "isothermal_compressibility","O","1/Pa","Isothermal compressibility")
|
||||
parameter_info(iisothermal_compressibility, "isothermal_compressibility","O","1/Pa","Isothermal compressibility"),
|
||||
parameter_info(ispeed_sound, "speed_of_sound","O","m/s","Speed of sound")
|
||||
};
|
||||
|
||||
class ParameterInformation
|
||||
@@ -157,7 +158,7 @@ input_pair_info input_pair_list[] = {
|
||||
input_pair_info(SmolarT_INPUTS, "SmolarT_INPUTS", "Entropy in J/mol/K, Temperature in K"),
|
||||
input_pair_info(TUmass_INPUTS, "TUmass_INPUTS", "Temperature in K, Internal energy in J/kg"),
|
||||
input_pair_info(TUmolar_INPUTS, "TUmolar_INPUTS", "Temperature in K, Internal energy in J/mol"),
|
||||
|
||||
|
||||
input_pair_info(DmassP_INPUTS, "DmassP_INPUTS", "Mass density in kg/m^3, Pressure in Pa"),
|
||||
input_pair_info(DmolarP_INPUTS, "DmolarP_INPUTS", "Molar density in mol/m^3, Pressure in Pa"),
|
||||
input_pair_info(HmassP_INPUTS, "HmassP_INPUTS", "Enthalpy in J/kg, Pressure in Pa"),
|
||||
@@ -206,4 +207,4 @@ std::string get_input_pair_long_desc(int pair)
|
||||
return input_pair_information.long_desc_map[pair];
|
||||
}
|
||||
|
||||
} /* namespace CoolProp */
|
||||
} /* namespace CoolProp */
|
||||
|
||||
@@ -468,8 +468,8 @@ long double ResidualHelmholtzGaussian::dDelta3(const long double &tau, const lon
|
||||
for (std::size_t i=0; i<N; ++i)
|
||||
{
|
||||
ResidualHelmholtzGaussianElement &el = elements[i];
|
||||
long double psi=exp(-el.eta*pow(delta-el.epsilon,2)-el.beta*pow(tau-el.gamma,2));
|
||||
long double bracket = pow(el.t/tau-2.0*el.beta*(tau-el.gamma),2)-el.t/pow(tau,2)-2.0*el.beta;
|
||||
long double psi = exp(-el.eta*pow(delta-el.epsilon,2)-el.beta*pow(tau-el.gamma,2));
|
||||
long double bracket = (pow(el.d-2*el.eta*delta*(delta-el.epsilon),3)-3*el.d*el.d+2*el.d-6*el.d*el.eta*delta*delta+6*el.eta*delta*(delta-el.epsilon)*(el.d+2*el.eta*delta*delta));
|
||||
s[i] = el.n*pow(tau,el.t)*pow(delta,el.d-3)*psi*bracket;
|
||||
}
|
||||
return std::accumulate(s.begin(), s.end(), 0.0);
|
||||
@@ -725,7 +725,7 @@ long double ResidualHelmholtzLemmon2005::dTau(const long double &tau, const long
|
||||
int li = el.l, mi = el.m;
|
||||
if (li != 0 && mi != 0){
|
||||
long double pow_tau_mi = pow(tau, md);
|
||||
s[i] = ni*(ti-mi*pow_tau_mi)*exp((ti-1)*log_tau+di*log_delta-pow(delta,li)-pow_tau_mi);
|
||||
s[i] = ni*(ti-md*pow_tau_mi)*exp((ti-1)*log_tau+di*log_delta-pow(delta,li)-pow_tau_mi);
|
||||
}
|
||||
else if (li != 0 && mi == 0)
|
||||
s[i] = ni*ti*exp((ti-1)*log_tau+di*log_delta-pow(delta,li));
|
||||
@@ -769,7 +769,7 @@ long double ResidualHelmholtzLemmon2005::dDelta_dTau(const long double &tau, con
|
||||
if (li != 0 && mi != 0){
|
||||
long double pow_delta_li = pow(delta, li);
|
||||
long double pow_tau_mi = pow(tau, md);
|
||||
s[i] = ni*(di-li*pow_delta_li)*(ti-mi*pow_tau_mi)*exp((ti-1)*log_tau+(di-1)*log_delta-pow_delta_li-pow_tau_mi);
|
||||
s[i] = ni*(di-li*pow_delta_li)*(ti-md*pow_tau_mi)*exp((ti-1)*log_tau+(di-1)*log_delta-pow_delta_li-pow_tau_mi);
|
||||
}
|
||||
else if (li != 0 && mi == 0){
|
||||
long double pow_delta_li = pow(delta, li);
|
||||
@@ -791,7 +791,7 @@ long double ResidualHelmholtzLemmon2005::dTau2(const long double &tau, const lon
|
||||
int li = el.l, mi = el.m;
|
||||
if (li != 0 && mi != 0){
|
||||
long double pow_tau_mi = pow(tau, md);
|
||||
long double bracket = (ti-mi*pow_tau_mi)*(ti-1-mi*pow_tau_mi)-mi*mi*pow_tau_mi;
|
||||
long double bracket = (ti-md*pow_tau_mi)*(ti-1.0-md*pow_tau_mi)-md*md*pow_tau_mi;
|
||||
s[i] = ni*bracket*exp((ti-2)*log_tau+di*log_delta-pow(delta,li)-pow_tau_mi);
|
||||
}
|
||||
else if (li != 0 && mi == 0)
|
||||
@@ -839,7 +839,7 @@ long double ResidualHelmholtzLemmon2005::dDelta2_dTau(const long double &tau, co
|
||||
if (li != 0 && mi != 0){
|
||||
long double pow_delta_li = pow(delta,li);
|
||||
long double pow_tau_mi = pow(tau,md);
|
||||
long double bracket = (ti-mi*pow_tau_mi)*(((di-li*pow_delta_li))*(di-1-li*pow_delta_li)-li*li*pow_delta_li);
|
||||
long double bracket = (ti-md*pow_tau_mi)*(((di-li*pow_delta_li))*(di-1-li*pow_delta_li)-li*li*pow_delta_li);
|
||||
s[i] = ni*bracket*exp((ti-1)*log_tau+(di-2)*log_delta-pow_delta_li-pow_tau_mi);
|
||||
}
|
||||
else if (li != 0 && mi == 0){
|
||||
@@ -865,7 +865,7 @@ long double ResidualHelmholtzLemmon2005::dDelta_dTau2(const long double &tau, co
|
||||
long double pow_delta_li = pow(delta,li);
|
||||
long double pow_tau_mi = pow(tau,md);
|
||||
// delta derivative of second tau derivative
|
||||
long double bracket = ((ti-mi*pow_tau_mi)*(ti-1-mi*pow_tau_mi)-mi*mi*pow_tau_mi)*(di-li*pow_delta_li);
|
||||
long double bracket = ((ti-md*pow_tau_mi)*(ti-1-md*pow_tau_mi)-md*md*pow_tau_mi)*(di-li*pow_delta_li);
|
||||
s[i] = ni*bracket*exp((ti-2)*log_tau+(di-1)*log_delta-pow_delta_li-pow_tau_mi);
|
||||
}
|
||||
else if (li != 0 && mi == 0){
|
||||
@@ -879,31 +879,14 @@ long double ResidualHelmholtzLemmon2005::dDelta_dTau2(const long double &tau, co
|
||||
}
|
||||
|
||||
/**
|
||||
\f[
|
||||
\frac{{{\partial ^2}{\alpha ^r}}}{{\partial {\tau ^2}}} = {N_k}{\delta ^{{d_k}}}{\tau ^{{t_k} - 2}}\exp \left( { - {\delta ^{{l_k}}}} \right)\exp \left( { - {\tau ^{{m_k}}}} \right)\left[ {\left( {{t_k} - {m_k}{\tau ^{{m_k}}}} \right)\left( {{t_k} - 1 - {m_k}{\tau ^{{m_k}}}} \right) - m_k^2{\tau ^{{m_k}}}} \right]\\
|
||||
\f]
|
||||
\f[
|
||||
\frac{{{\partial ^2}{\alpha ^r}}}{{\partial {\tau ^2}}} = {N_k}{\delta ^{{d_k}}}\exp \left( { - {\delta ^{{l_k}}}} \right){\tau ^{{t_k} - 2}}\exp \left( { - {\tau ^{{m_k}}}} \right)\left[ {\left( {{t_k} - {m_k}{\tau ^{{m_k}}}} \right)\left( {{t_k} - 1 - {m_k}{\tau ^{{m_k}}}} \right) - m_k^2{\tau ^{{m_k}}}} \right]\\
|
||||
\f]
|
||||
Group all the terms that don't depend on \f$ \tau \f$
|
||||
\f[
|
||||
\frac{{{\partial ^2}{\alpha ^r}}}{{\partial {\tau ^2}}} = A{\tau ^{{t_k} - 2}}\exp \left( { - {\tau ^{{m_k}}}} \right)\left[ {\left( {{t_k} - {m_k}{\tau ^{{m_k}}}} \right)\left( {{t_k} - 1 - {m_k}{\tau ^{{m_k}}}} \right) - m_k^2{\tau ^{{m_k}}}} \right]\\
|
||||
\f]
|
||||
\f[
|
||||
\frac{1}{A}\frac{{{\partial ^3}{\alpha ^r}}}{{\partial {\tau ^3}}} = {\tau ^{{t_k} - 2}}\exp \left( { - {\tau ^{{m_k}}}} \right)\frac{\partial }{{\partial \tau }}\left[ {\left( {{t_k} - {m_k}{\tau ^{{m_k}}}} \right)\left( {{t_k} - 1 - {m_k}{\tau ^{{m_k}}}} \right) - m_k^2{\tau ^{{m_k}}}} \right] + \frac{\partial }{{\partial \tau }}\left[ {{\tau ^{{t_k} - 2}}\exp \left( { - {\tau ^{{m_k}}}} \right)} \right]\left[ {\left( {{t_k} - {m_k}{\tau ^{{m_k}}}} \right)\left( {{t_k} - 1 - {m_k}{\tau ^{{m_k}}}} \right) - m_k^2{\tau ^{{m_k}}}} \right]\\
|
||||
\f]
|
||||
\f[
|
||||
\frac{\partial }{{\partial \tau }}\left[ {{\tau ^{{t_k} - 2}}\exp \left( { - {\tau ^{{m_k}}}} \right)} \right] = ({t_k} - 2){\tau ^{{t_k} - 3}}\exp \left( { - {\tau ^{{m_k}}}} \right) + {\tau ^{{t_k} - 2}}\exp \left( { - {\tau ^{{m_k}}}} \right)( - {m_k}{\tau ^{{m_k} - 1}}) = \exp \left( { - {\tau ^{{m_k}}}} \right)\left( {({t_k} - 2){\tau ^{{t_k} - 3}} - {\tau ^{{t_k} - 2}}{m_k}{\tau ^{{m_k} - 1}}} \right)\\
|
||||
\f]
|
||||
\f[
|
||||
\frac{\partial }{{\partial \tau }}\left[ {\left( {{t_k} - {m_k}{\tau ^{{m_k}}}} \right)\left( {{t_k} - 1 - {m_k}{\tau ^{{m_k}}}} \right) - m_k^2{\tau ^{{m_k}}}} \right] = \left( {{t_k} - {m_k}{\tau ^{{m_k}}}} \right)\left( { - m_k^2{\tau ^{{m_k} - 1}}} \right) + \left( { - m_k^2{\tau ^{{m_k} - 1}}} \right)\left( {{t_k} - 1 - {m_k}{\tau ^{{m_k}}}} \right) - m_k^3{\tau ^{{m_k} - 1}} = - m_k^2{\tau ^{{m_k} - 1}}\left[ {{t_k} - {m_k}{\tau ^{{m_k}}} + {t_k} - 1 - {m_k}{\tau ^{{m_k}}} + {m_k}} \right] = - m_k^2{\tau ^{{m_k} - 1}}\left[ {2{t_k} - 2{m_k}{\tau ^{{m_k}}} - 1 + {m_k}} \right]\\
|
||||
\f]
|
||||
\f[
|
||||
\frac{1}{A}\frac{{{\partial ^3}{\alpha ^r}}}{{\partial {\tau ^3}}} = {\tau ^{{t_k} - 2}}\exp \left( { - {\tau ^{{m_k}}}} \right)\left( { - m_k^2{\tau ^{{m_k} - 1}}\left[ {2{t_k} - 2{m_k}{\tau ^{{m_k}}} - 1 + {m_k}} \right]} \right) + \exp \left( { - {\tau ^{{m_k}}}} \right)\left( {({t_k} - 2){\tau ^{{t_k} - 3}} - {\tau ^{{t_k} - 2}}{m_k}{\tau ^{{m_k} - 1}}} \right)\left[ {\left( {{t_k} - {m_k}{\tau ^{{m_k}}}} \right)\left( {{t_k} - 1 - {m_k}{\tau ^{{m_k}}}} \right) - m_k^2{\tau ^{{m_k}}}} \right]\\
|
||||
\f]
|
||||
\f[
|
||||
\frac{1}{A}\frac{{{\partial ^3}{\alpha ^r}}}{{\partial {\tau ^3}}} = \exp \left( { - {\tau ^{{m_k}}}} \right)\left[ { - {\tau ^{{t_k} - 2}}m_k^2{\tau ^{{m_k} - 1}}\left[ {2{t_k} - 2{m_k}{\tau ^{{m_k}}} - 1 + {m_k}} \right] + \left( {({t_k} - 2){\tau ^{{t_k} - 3}} - {\tau ^{{t_k} - 2}}{m_k}{\tau ^{{m_k} - 1}}} \right)\left[ {\left( {{t_k} - {m_k}{\tau ^{{m_k}}}} \right)\left( {{t_k} - 1 - {m_k}{\tau ^{{m_k}}}} \right) - m_k^2{\tau ^{{m_k}}}} \right]} \right]
|
||||
\f]
|
||||
Derived using sympy:
|
||||
|
||||
from sympy import *
|
||||
init_printing()
|
||||
n_i, d_i, t_i, m_i, l_i, tau, delta, eta, gamma, beta, epsilon = symbols('n_i, d_i, t_i, m_i, l_i, tau, delta, eta, gamma, beta, epsilon')
|
||||
I = n_i*delta**d_i*tau**t_i*exp(-delta**l_i)*exp(-tau**m_i)
|
||||
ccode(simplify(diff(I,tau,3)))
|
||||
|
||||
*/
|
||||
long double ResidualHelmholtzLemmon2005::dTau3(const long double &tau, const long double &delta) throw()
|
||||
{
|
||||
@@ -912,13 +895,13 @@ long double ResidualHelmholtzLemmon2005::dTau3(const long double &tau, const lon
|
||||
for (std::size_t i=0; i<N; ++i)
|
||||
{
|
||||
ResidualHelmholtzLemmon2005Element &el = elements[i];
|
||||
long double ni = el.n, ti = el.t, di = el.d;
|
||||
long double ni = el.n, ti = el.t, di = el.d, md = el.md;
|
||||
int li = el.l, mi = el.m;
|
||||
if (li != 0 && mi != 0){
|
||||
long double pow_delta_li = pow(delta,li);
|
||||
long double pow_tau_mi = pow(tau,mi);
|
||||
//long double bracket = -pow(tau,ti+mi-3)*mi*mi*(2*ti-2*mi*pow_tau_mi-1-mi)+((ti-2)*pow(tau,ti-3)-pow(tau,ti-2)*mi*pow(tau,mi-1))*((ti-mi*pow_tau_mi)*(ti-1-mi*pow_tau_mi)-mi*mi*pow_tau_mi);
|
||||
s[i] = ni*ti*(ti-1)*(ti-2)*exp((ti-3)*log_tau+di*log_delta-pow_delta_li-pow_tau_mi);
|
||||
long double pow_delta_li = pow(delta, li);
|
||||
long double pow_tau_mi = pow(tau, md);
|
||||
long double bracket = (pow(md, 3)*pow_tau_mi*pow_tau_mi*pow_tau_mi - 3*pow(md, 3)*pow_tau_mi*pow_tau_mi + pow(md, 3)*pow_tau_mi - 3*pow(md, 2)*ti*pow_tau_mi*pow_tau_mi + 3*pow(md, 2)*ti*pow_tau_mi + 3*pow(md, 2)*pow_tau_mi*pow_tau_mi - 3*pow(md, 2)*pow_tau_mi + 3*md*pow(ti, 2)*pow_tau_mi - 6*md*ti*pow_tau_mi + 2*md*pow_tau_mi - pow(ti, 3) + 3*pow(ti, 2) - 2*ti);
|
||||
s[i] = -ni*bracket*exp((ti-3)*log_tau+di*log_delta-pow_delta_li-pow_tau_mi);
|
||||
}
|
||||
else if (li != 0 && mi == 0){
|
||||
s[i] = ni*ti*(ti-1)*(ti-2)*exp((ti-3)*log_tau+di*log_delta-pow(delta,li));
|
||||
@@ -1058,7 +1041,7 @@ long double ResidualHelmholtzNonAnalytic::dDelta2(const long double &tau, const
|
||||
dDELTA2_dDelta2 = dDELTA_dDelta_over_delta_minus_1+pow(delta-1.0,2)*(4.0*Bi*ai*(ai-1.0)*pow(pow(delta-1,2),ai-2.0)+2.0*pow(Ai/betai,2)*pow(pow(pow(delta-1,2),1.0/(2.0*betai)-1.0),2)+Ai*theta*4.0/betai*(1.0/(2.0*betai)-1.0)*pow(pow(delta-1.0,2),1.0/(2.0*betai)-2.0));
|
||||
dDELTAbi2_dDelta2 = bi*(pow(DELTA,bi-1.0)*dDELTA2_dDelta2+(bi-1.0)*pow(DELTA,bi-2.0)*pow(dDELTA_dDelta,2));
|
||||
}
|
||||
|
||||
|
||||
// At critical point, DELTA is 0, and 1/0^n is undefined
|
||||
if (fabs(DELTA) < 10*DBL_EPSILON)
|
||||
{
|
||||
@@ -1966,7 +1949,7 @@ TEST_CASE_METHOD(HelmholtzConsistencyFixture, "Helmholtz energy derivatives", "[
|
||||
term = get(terms[i]);
|
||||
for (std::size_t j = 0; j < sizeof(derivs)/sizeof(derivs[0]); ++j)
|
||||
{
|
||||
call(derivs[j], term, 1.3, 0.7, 1e-8);
|
||||
call(derivs[j], term, 1.3, 0.7, 1e-7);
|
||||
CAPTURE(derivs[j]);
|
||||
CAPTURE(numerical);
|
||||
CAPTURE(analytic);
|
||||
|
||||
Reference in New Issue
Block a user