From 896e85d1297e27b6d978fc2344285b98f295afb6 Mon Sep 17 00:00:00 2001 From: Ian Bell Date: Sat, 4 Oct 2025 16:00:30 -0400 Subject: [PATCH] Add Ideal gas methods (#2626) * Add ability to get at the ideal-gas properties directly Also through the python interface * And python interface files * Fixes the missing reference to ideal gas notebook --- Web/coolprop/IdealGas.ipynb | 77 +++++++++++++++---- Web/coolprop/index.rst | 1 + include/AbstractState.h | 12 +++ include/DataStructures.h | 6 ++ src/AbstractState.cpp | 30 ++++++++ .../REFPROP/REFPROPMixtureBackend.cpp | 31 ++++++++ src/Backends/REFPROP/REFPROPMixtureBackend.h | 15 ++++ src/DataStructures.cpp | 10 ++- src/Tests/CoolProp-Tests.cpp | 47 +++++++++++ wrappers/Python/CoolProp/AbstractState.pxd | 7 +- wrappers/Python/CoolProp/AbstractState.pyx | 19 +++++ wrappers/Python/CoolProp/cAbstractState.pxd | 7 ++ 12 files changed, 243 insertions(+), 19 deletions(-) diff --git a/Web/coolprop/IdealGas.ipynb b/Web/coolprop/IdealGas.ipynb index 22afce43..10e86986 100644 --- a/Web/coolprop/IdealGas.ipynb +++ b/Web/coolprop/IdealGas.ipynb @@ -26,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "73e08117", "metadata": {}, "outputs": [], @@ -39,17 +39,7 @@ "execution_count": null, "id": "b3b3722e", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "T: 200 u: 268.7943717754444 h: 326.2041971329565 s: 3.4799573598766878 deltau: 126.2343717754444 deltah: 126.2341971329565 deltas: 2.1843673598766875\n", - "T: 440 u: 441.7087305389626 h: 568.010346325489 s: 4.274344979641025 deltau: 126.40873053896257 deltah: 126.40034632548895 deltas: 2.1856449796410256\n", - "T: 740 u: 670.468780219468 h: 882.8851340422626 s: 4.818538217796705 deltau: 126.44878021946806 deltah: 126.44513404226257 deltas: 2.1857382177967053\n" - ] - } - ], + "outputs": [], "source": [ "# Some check values from Moran & Shapiro, 6th edition, Table A-22\n", "Ts = [200, 440, 740]\n", @@ -59,19 +49,74 @@ "\n", "for T, h0, s0, u0 in zip(Ts, hs, ss, us):\n", " AS = CP.AbstractState(\"HEOS\", \"Air\")\n", - " AS.update(CP.PT_INPUTS, 101325, T)\n", + " # Use the density obtained from Z=1\n", + " rho = 101325/(CP.PropsSI('molemass','Air')*T)\n", + " AS.update(CP.DmolarT_INPUTS, rho, T)\n", " R = AS.gas_constant()/AS.molar_mass()\n", " RT = R*T\n", " ucalc_kJkg = RT*(AS.tau()*AS.dalpha0_dTau())/1000 # kJ/kg\n", " hcalc_kJkg = RT*(1+AS.tau()*AS.dalpha0_dTau())/1000 # kJ/kg\n", - " scalc_kJkgK = R*(AS.tau()*AS.dalpha0_dTau()-AS.alpha0())/1000 # kJ/kg\n", + " scalc_kJkgK = R*(AS.tau()*AS.dalpha0_dTau()-AS.alpha0())/1000 # kJ/kg/K\n", + " print('T:', T, 'u:', ucalc_kJkg, 'h:', hcalc_kJkg, 's:', scalc_kJkgK, 'deltau:', ucalc_kJkg-u0, 'deltah:', hcalc_kJkg-h0, 'deltas:', scalc_kJkgK-s0)" + ] + }, + { + "cell_type": "markdown", + "id": "2990c24c-5c54-4450-a6d1-871d166b1a1c", + "metadata": {}, + "source": [ + "As of version 7.2, you can also get the ideal-gas properties directly from the model without additional work:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3f6353b-4fae-4ed6-8646-3604aed4d0a9", + "metadata": {}, + "outputs": [], + "source": [ + "for T, h0, s0, u0 in zip(Ts, hs, ss, us):\n", + " AS = CP.AbstractState(\"HEOS\", \"Air\")\n", + "\n", + " # Use the density obtained from Z=1\n", + " rho = 101325/(CP.PropsSI('molemass','Air')*T)\n", + " AS.update(CP.DmolarT_INPUTS, rho, T)\n", + " R = AS.gas_constant()/AS.molar_mass()\n", + " RT = R*T\n", + " ucalc_kJkg = AS.umass_idealgas()/1000 # kJ/kg\n", + " hcalc_kJkg = AS.hmass_idealgas()/1000 # kJ/kg\n", + " scalc_kJkgK = AS.smass_idealgas()/1000 # kJ/kg/K\n", + " print('T:', T, 'u:', ucalc_kJkg, 'h:', hcalc_kJkg, 's:', scalc_kJkgK, 'deltau:', ucalc_kJkg-u0, 'deltah:', hcalc_kJkg-h0, 'deltas:', scalc_kJkgK-s0)" + ] + }, + { + "cell_type": "markdown", + "id": "456ee5f6-5939-4c02-8036-e2e099fc0065", + "metadata": {}, + "source": [ + "Or with the high-level interface (less efficient computationally)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "086d4495-69b5-409b-bd5e-355b1356a21e", + "metadata": {}, + "outputs": [], + "source": [ + "for T, h0, s0, u0 in zip(Ts, hs, ss, us):\n", + " # Use the density obtained from Z=1\n", + " rho = 101325/(CP.PropsSI('molemass','Air')*T)\n", + " ucalc_kJkg = CP.PropsSI('Umass_idealgas','T|phase_gas',T,'Dmolar',rho,'Air')/1000 # kJ/kg\n", + " hcalc_kJkg = CP.PropsSI('Hmass_idealgas','T|phase_gas',T,'Dmolar',rho,'Air')/1000 # kJ/kg\n", + " scalc_kJkgK = CP.PropsSI('Smass_idealgas','T|phase_gas',T,'Dmolar',rho,'Air')/1000 # kJ/kg/K\n", " print('T:', T, 'u:', ucalc_kJkg, 'h:', hcalc_kJkg, 's:', scalc_kJkgK, 'deltau:', ucalc_kJkg-u0, 'deltah:', hcalc_kJkg-h0, 'deltas:', scalc_kJkgK-s0)" ] } ], "metadata": { "kernelspec": { - "display_name": "py313", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -85,7 +130,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.1" + "version": "3.13.2" } }, "nbformat": 4, diff --git a/Web/coolprop/index.rst b/Web/coolprop/index.rst index 8381dc91..d13386d1 100644 --- a/Web/coolprop/index.rst +++ b/Web/coolprop/index.rst @@ -18,3 +18,4 @@ This section includes information about the CoolProp software, listings of input examples.rst changelog.rst SuperAncillary.ipynb + IdealGas.ipynb diff --git a/include/AbstractState.h b/include/AbstractState.h index 29e72a35..cb9d81fb 100644 --- a/include/AbstractState.h +++ b/include/AbstractState.h @@ -1099,6 +1099,10 @@ class AbstractState double hmolar(void); /// Return the residual molar enthalpy in J/mol double hmolar_residual(void); + /// Return the ideal gas molar enthalpy in J/mol + double hmolar_idealgas(void); + /// Return the ideal gas specific enthalpy in J/kg + double hmass_idealgas(void); /// Return the mass enthalpy in J/kg double hmass(void) { return calc_hmass(); @@ -1113,6 +1117,10 @@ class AbstractState double smolar(void); /// Return the residual molar entropy (as a function of temperature and density) in J/mol/K double smolar_residual(void); + /// Return the ideal gas molar entropy in J/mol/K + double smolar_idealgas(void); + /// Return the ideal gas specific entropy in J/kg/K + double smass_idealgas(void); /// Return the effective hardness of interaction double neff(void); /// Return the molar entropy in J/kg/K @@ -1137,6 +1145,10 @@ class AbstractState double umass_excess(void) { return calc_umass_excess(); }; + /// Return the ideal gas molar internal energy in J/mol + double umolar_idealgas(void); + /// Return the ideal gas specific internal energy in J/kg + double umass_idealgas(void); /// Return the molar constant pressure specific heat in J/mol/K double cpmolar(void); /// Return the mass constant pressure specific heat in J/kg/K diff --git a/include/DataStructures.h b/include/DataStructures.h index 30ce0fed..1c41fd8e 100644 --- a/include/DataStructures.h +++ b/include/DataStructures.h @@ -105,6 +105,9 @@ enum parameters iHmolar_residual, ///< The residual molar enthalpy iSmolar_residual, ///< The residual molar entropy (as a function of temperature and density) iGmolar_residual, ///< The residual molar Gibbs energy + iHmolar_idealgas, ///< The ideal gas molar enthalpy + iSmolar_idealgas, ///< The ideal gas molar entropy + iUmolar_idealgas, ///< The ideal gas molar internal energy // Mass specific thermodynamic properties iDmass, ///< Mass-based density @@ -116,6 +119,9 @@ enum parameters iUmass, ///< Mass-based internal energy iGmass, ///< Mass-based Gibbs energy iHelmholtzmass, ///< Mass-based Helmholtz energy + iHmass_idealgas, ///< The ideal gas specific enthalpy + iSmass_idealgas, ///< The ideal gas specific entropy + iUmass_idealgas, ///< The ideal gas specific internal energy // Transport properties iviscosity, ///< Viscosity diff --git a/src/AbstractState.cpp b/src/AbstractState.cpp index dec185da..6de8bcaf 100644 --- a/src/AbstractState.cpp +++ b/src/AbstractState.cpp @@ -371,18 +371,30 @@ double AbstractState::keyed_output(parameters key) { return hmolar(); case iHmolar_residual: return hmolar_residual(); + case iHmolar_idealgas: + return hmolar_idealgas(); case iHmass: return hmass(); + case iHmass_idealgas: + return hmass_idealgas(); case iSmolar: return smolar(); case iSmolar_residual: return smolar_residual(); + case iSmolar_idealgas: + return smolar_idealgas(); case iSmass: return smass(); + case iSmass_idealgas: + return smass_idealgas(); case iUmolar: return umolar(); + case iUmolar_idealgas: + return umolar_idealgas(); case iUmass: return umass(); + case iUmass_idealgas: + return umass_idealgas(); case iGmolar: return gibbsmolar(); case iGmolar_residual: @@ -526,6 +538,12 @@ double AbstractState::hmolar_residual(void) { if (!_hmolar_residual) _hmolar_residual = calc_hmolar_residual(); return _hmolar_residual; } +double AbstractState::hmolar_idealgas(void) { + return gas_constant()*T()*(1 + tau()*dalpha0_dTau()); +} +double AbstractState::hmass_idealgas(void) { + return hmolar_idealgas()/molar_mass(); +} double AbstractState::hmolar_excess(void) { if (!_hmolar_excess) calc_excess_properties(); return _hmolar_excess; @@ -538,6 +556,12 @@ double AbstractState::smolar_residual(void) { if (!_smolar_residual) _smolar_residual = calc_smolar_residual(); return _smolar_residual; } +double AbstractState::smolar_idealgas(void) { + return gas_constant()*(tau()*dalpha0_dTau() - alpha0()); +} +double AbstractState::smass_idealgas(void) { + return smolar_idealgas()/molar_mass(); +} double AbstractState::neff(void) { double tau = calc_T_reducing()/_T; double delta = _rhomolar/calc_rhomolar_reducing(); @@ -558,6 +582,12 @@ double AbstractState::umolar_excess(void) { if (!_umolar_excess) calc_excess_properties(); return _umolar_excess; } +double AbstractState::umolar_idealgas(void) { + return gas_constant()*T()*(tau()*dalpha0_dTau()); +} +double AbstractState::umass_idealgas(void) { + return umolar_idealgas()/molar_mass(); +} double AbstractState::gibbsmolar(void) { if (!_gibbsmolar) _gibbsmolar = calc_gibbsmolar(); return _gibbsmolar; diff --git a/src/Backends/REFPROP/REFPROPMixtureBackend.cpp b/src/Backends/REFPROP/REFPROPMixtureBackend.cpp index 6a16e171..72d9d094 100644 --- a/src/Backends/REFPROP/REFPROPMixtureBackend.cpp +++ b/src/Backends/REFPROP/REFPROPMixtureBackend.cpp @@ -2149,6 +2149,37 @@ void REFPROPMixtureBackend::calc_ideal_curve(const std::string& type, std::vecto } }; +THERM0dllOutputs REFPROPMixtureBackend::call_THERM0dll(double T, double rho_mol_dm3, const std::vector &mole_fractions){ + /* + subroutineTHERM0dll(T, D, z, P0, e0, h0, s0, Cv0, Cp00, w0, a0, g0) + Compute ideal-gas thermal quantities as a function of temperature, density, and composition from core functions. + + This routine is the same as THERM, except it only calculates ideal gas properties (Z=1) at any temperature and density. + + Parameters: + T [double ,in] :: Temperature [K] + D [double ,in] :: Molar density [mol/L] + z (20) [double ,in] :: Composition (array of mole fractions) + P0 [double ,out] :: Pressure [kPa] + e0 [double ,out] :: Internal energy [J/mol] + h0 [double ,out] :: Enthalpy [J/mol] + s0 [double ,out] :: Entropy [J/mol-K] + Cv0 [double ,out] :: Isochoric heat capacity [J/mol-K] + Cp00 [double ,out] :: Isobaric heat capacity [J/mol-K] + w0 [double ,out] :: Speed of sound [m/s] + a0 [double ,out] :: Helmholtz energy [J/mol] + g0 [double ,out] :: Gibbs free energy [J/mol] + */ + THERM0dllOutputs o; + if (mole_fractions.size() != 20){ + throw ValueError("mole fractions must be of size 20"); + } + std::vector mf = mole_fractions; + + THERM0dll(&T, &rho_mol_dm3, &(mf[0]), &o.p_kPa, &o.umol_Jmol, &o.hmol_Jmol, &o.smol_JmolK, &o.cvmol_JmolK, &o.cpmol_JmolK, &o.w_ms, &o.amol_Jmol, &o.gmol_Jmol); + return o; +} + bool force_load_REFPROP() { std::string err; if (!load_REFPROP(err)) { diff --git a/src/Backends/REFPROP/REFPROPMixtureBackend.h b/src/Backends/REFPROP/REFPROPMixtureBackend.h index 88bfffd2..7d180127 100644 --- a/src/Backends/REFPROP/REFPROPMixtureBackend.h +++ b/src/Backends/REFPROP/REFPROPMixtureBackend.h @@ -15,6 +15,18 @@ namespace CoolProp { +struct THERM0dllOutputs{ + double p_kPa; /// Pressure [kPa] + double umol_Jmol; /// Internal energy [J/mol] + double hmol_Jmol; /// Enthalpy [J/mol] + double smol_JmolK; /// Entropy [J/mol-K] + double cvmol_JmolK; /// Isochoric heat capacity [J/mol-K] + double cpmol_JmolK; /// Isobaric heat capacity [J/mol-K] + double w_ms; /// Speed of sound [m/s] + double amol_Jmol; ///Helmholtz energy [J/mol] + double gmol_Jmol; /// Gibbs free energy [J/mol] +}; + class REFPROPMixtureBackend : public AbstractState { private: @@ -251,6 +263,9 @@ class REFPROPMixtureBackend : public AbstractState CoolPropDbl calc_Tmax(void); /// Calculate the minimum temperature CoolPropDbl calc_Tmin(void); + + /// Call into the THERM0dll method and return outputs as a struct. REFPROP must already be setup + THERM0dllOutputs call_THERM0dll(double T, double rho_mol_dm3, const std::vector &mole_fractions); /// Calculate the residual entropy in J/mol/K (should be a uniquely negative quantity) CoolPropDbl calc_smolar_residual(void) { diff --git a/src/DataStructures.cpp b/src/DataStructures.cpp index d5ad18b8..11ff028f 100644 --- a/src/DataStructures.cpp +++ b/src/DataStructures.cpp @@ -41,9 +41,15 @@ const std::vector parameter_info_list = { {iCvmass, "Cvmass", "O", "J/kg/K", "Mass specific constant volume specific heat", false}, {iCp0molar, "Cp0molar", "O", "J/mol/K", "Ideal gas molar specific constant pressure specific heat", false}, {iCp0mass, "Cp0mass", "O", "J/kg/K", "Ideal gas mass specific constant pressure specific heat", false}, - {iHmolar_residual, "Hmolar_residual", "O", "J/mol/K", "Residual molar enthalpy", false}, + {iHmolar_residual, "Hmolar_residual", "O", "J/mol", "Residual molar enthalpy", false}, {iSmolar_residual, "Smolar_residual", "O", "J/mol/K", "Residual molar entropy (sr/R = s(T,rho) - s^0(T,rho))", false}, - {iGmolar_residual, "Gmolar_residual", "O", "J/mol/K", "Residual molar Gibbs energy", false}, + {iGmolar_residual, "Gmolar_residual", "O", "J/mol", "Residual molar Gibbs energy", false}, + {iHmolar_idealgas, "Hmolar_idealgas", "O", "J/mol", "Ideal gas molar enthalpy", false}, + {iSmolar_idealgas, "Smolar_idealgas", "O", "J/mol/K", "Ideal gas molar entropy", false}, + {iUmolar_idealgas, "Umolar_idealgas", "O", "J/mol", "Ideal gas molar internal energy", false}, + {iHmass_idealgas, "Hmass_idealgas", "O", "J/kg", "Ideal gas specific enthalpy", false}, + {iSmass_idealgas, "Smass_idealgas", "O", "J/kg/K", "Ideal gas specific entropy", false}, + {iUmass_idealgas, "Umass_idealgas", "O", "J/kg", "Ideal gas specific internal energy", false}, {iGWP20, "GWP20", "O", "-", "20-year global warming potential", true}, {iGWP100, "GWP100", "O", "-", "100-year global warming potential", true}, {iGWP500, "GWP500", "O", "-", "500-year global warming potential", true}, diff --git a/src/Tests/CoolProp-Tests.cpp b/src/Tests/CoolProp-Tests.cpp index 30db25e8..bd9ac6af 100644 --- a/src/Tests/CoolProp-Tests.cpp +++ b/src/Tests/CoolProp-Tests.cpp @@ -4,6 +4,7 @@ #include "DataStructures.h" #include "../Backends/Helmholtz/HelmholtzEOSMixtureBackend.h" #include "../Backends/Helmholtz/HelmholtzEOSBackend.h" +#include "../Backends/REFPROP/REFPROPMixtureBackend.h" #include "superancillary/superancillary.h" #include @@ -2921,6 +2922,52 @@ TEST_CASE_METHOD(SuperAncillaryOnFixture, "Benchmarking caching options", "[cach return opt100; }; } +std::vector> MSA22values = { + {200, 199.97, 142.56, 1.29559}, + {300, 300.19, 214.07, 1.70203}, + {400, 400.98, 286.16, 1.99194}, + {500, 503.02, 359.49, 2.21952}, +}; + +TEST_CASE("Ideal gas thermodynamic properties", "[2589]"){ + shared_ptr AS(CoolProp::AbstractState::factory("HEOS", "Air")); + shared_ptr RP(CoolProp::AbstractState::factory("REFPROP", "Air")); + + auto& rRP = *dynamic_cast(AS.get()); + auto& rHEOS = *dynamic_cast(AS.get()); + + AS->specify_phase(iphase_gas); + RP->specify_phase(iphase_gas); + + double pig = 101325; + + // Moran & Shapiro Table A-22 reference is h(T=0) = 0, but that doesn't play nicely + // with tau=Tc/T = oo and delta = 0/rhor = 0 + + for (auto [T_K, h_kJkg, u_kJkg, s_kJkgK] : MSA22values){ + double rho = pig/(AS->gas_constant()*T_K); // ideal-gas molar density assuming Z=1 + AS->update(DmolarT_INPUTS, rho, T_K); + RP->update(DmolarT_INPUTS, rho, T_K); + + CHECK(AS->smass_idealgas()/AS->gas_constant() == Catch::Approx(RP->smass_idealgas()/AS->gas_constant())); + CHECK(AS->hmass_idealgas()/AS->gas_constant() == Catch::Approx(RP->hmass_idealgas()/AS->gas_constant())); + + std::vector mf(20, 1.0); + auto o = rRP.call_THERM0dll(T_K, rho/1e3, mf); + CHECK(o.hmol_Jmol == Catch::Approx(RP->hmolar_idealgas()).epsilon(1e-12)); + CHECK(o.smol_JmolK == Catch::Approx(RP->smolar_idealgas()).epsilon(1e-12)); + CHECK(o.umol_Jmol == Catch::Approx(RP->umolar_idealgas()).epsilon(1e-12)); + + CAPTURE(T_K); + CAPTURE(AS->hmass_idealgas()); + CAPTURE(AS->hmass_idealgas()-h_kJkg*1e3); + CAPTURE(AS->smass_idealgas()); + CAPTURE(AS->smass_idealgas()-s_kJkgK*1e3); + CAPTURE(AS->umass_idealgas()); + CAPTURE(AS->umass_idealgas()-u_kJkg*1e3); + } + +} /* TEST_CASE("Test that HS solver works for a few fluids", "[HS_solver]") diff --git a/wrappers/Python/CoolProp/AbstractState.pxd b/wrappers/Python/CoolProp/AbstractState.pxd index 1d5dcb92..5824398b 100644 --- a/wrappers/Python/CoolProp/AbstractState.pxd +++ b/wrappers/Python/CoolProp/AbstractState.pxd @@ -163,7 +163,12 @@ cdef class AbstractState: cpdef double smolar_residual(self) except * cpdef double neff(self) except * - + cpdef double hmolar_idealgas(self) except * + cpdef double hmass_idealgas(self) except * + cpdef double smolar_idealgas(self) except * + cpdef double smass_idealgas(self) except * + cpdef double umolar_idealgas(self) except * + cpdef double umass_idealgas(self) except * cpdef double molar_mass(self) except * diff --git a/wrappers/Python/CoolProp/AbstractState.pyx b/wrappers/Python/CoolProp/AbstractState.pyx index 5e008351..4f93aeeb 100644 --- a/wrappers/Python/CoolProp/AbstractState.pyx +++ b/wrappers/Python/CoolProp/AbstractState.pyx @@ -444,6 +444,25 @@ cdef class AbstractState: """ Get the effective hardness of interaction - wrapper of c++ function :cpapi:`CoolProp::AbstractState::neff(void)` """ return self.thisptr.neff() + cpdef double umolar_idealgas(self) except *: + """ Get the mole-specific ideal gas internal energy in J/mol - wrapper of c++ function :cpapi:`CoolProp::AbstractState::umolar_idealgas(void)` """ + return self.thisptr.umolar_idealgas() + cpdef double umass_idealgas(self) except *: + """ Get the mass-specific ideal gas internal energy in J/kg - wrapper of c++ function :cpapi:`CoolProp::AbstractState::umass_idealgas(void)` """ + return self.thisptr.umass_idealgas() + cpdef double hmolar_idealgas(self) except *: + """ Get the mole-specific ideal gas enthalpy in J/mol - wrapper of c++ function :cpapi:`CoolProp::AbstractState::hmolar_idealgas(void)` """ + return self.thisptr.hmolar_idealgas() + cpdef double hmass_idealgas(self) except *: + """ Get the mass-specific ideal gas enthalpy in J/kg - wrapper of c++ function :cpapi:`CoolProp::AbstractState::hmass_idealgas(void)` """ + return self.thisptr.hmass_idealgas() + cpdef double smolar_idealgas(self) except *: + """ Get the mole-specific ideal gas entropy in J/mol/K - wrapper of c++ function :cpapi:`CoolProp::AbstractState::smolar_idealgas(void)` """ + return self.thisptr.smolar_idealgas() + cpdef double smass_idealgas(self) except *: + """ Get the mass-specific ideal gas entropy in J/kg/K - wrapper of c++ function :cpapi:`CoolProp::AbstractState::smass_idealgas(void)` """ + return self.thisptr.smass_idealgas() + ## ---------------------------------------- ## Derivatives diff --git a/wrappers/Python/CoolProp/cAbstractState.pxd b/wrappers/Python/CoolProp/cAbstractState.pxd index f1e1d103..a5ed833e 100644 --- a/wrappers/Python/CoolProp/cAbstractState.pxd +++ b/wrappers/Python/CoolProp/cAbstractState.pxd @@ -160,6 +160,13 @@ cdef extern from "AbstractState.h" namespace "CoolProp": double smolar_residual() except +ValueError double neff() except +ValueError + double hmolar_idealgas() except +ValueError + double hmass_idealgas() except +ValueError + double smolar_idealgas() except +ValueError + double smass_idealgas() except +ValueError + double umolar_idealgas() except +ValueError + double umass_idealgas() except +ValueError + double surface_tension() except +ValueError double Prandtl() except +ValueError double Bvirial() except +ValueError