diff --git a/include/AbstractState.h b/include/AbstractState.h index c9f7df45..9fa7baa0 100644 --- a/include/AbstractState.h +++ b/include/AbstractState.h @@ -71,19 +71,19 @@ protected: //~ return true; //~ } - + /// Two important points SimpleState _critical, _reducing; /// Molar mass [mol/kg] CachedElement _molar_mass; - + /// Universal gas constant [J/mol/K] CachedElement _gas_constant; /// Bulk values double _rhomolar, _T, _p, _Q, _R; - + CachedElement _tau, _delta; /// Transport properties @@ -161,7 +161,7 @@ protected: virtual long double calc_d2alphar_dDelta_dTau(void){throw NotImplementedError("calc_d2alphar_dDelta_dTau is not implemented for this backend");}; /// Using this backend, calculate the residual Helmholtz energy term \f$\alpha^r_{\tau\tau}\f$ (dimensionless) virtual long double calc_d2alphar_dTau2(void){throw NotImplementedError("calc_d2alphar_dTau2 is not implemented for this backend");}; - + // Derivatives of ideal-gas helmholtz energy /// Using this backend, calculate the ideal-gas Helmholtz energy term \f$\alpha^0\f$ (dimensionless) virtual long double calc_alpha0(void){throw NotImplementedError("calc_alpha0 is not implemented for this backend");}; @@ -197,7 +197,7 @@ protected: virtual long double calc_health_hazard(void){throw NotImplementedError("calc_health_hazard is not implemented for this backend");}; /// Using this backend, calculate the physical hazard virtual long double calc_physical_hazard(void){throw NotImplementedError("calc_physical_hazard is not implemented for this backend");}; - + /// Calculate the first partial derivative for the desired derivative virtual long double calc_first_partial_deriv(int Of, int Wrt, int Constant){throw NotImplementedError("calc_first_partial_deriv is not implemented for this backend");}; @@ -217,7 +217,7 @@ protected: /// Using this backend, get the name of the fluid virtual std::string calc_name(void){throw NotImplementedError("calc_name is not implemented for this backend");}; - + /// Using this backend, get the triple point temperature in K virtual long double calc_Ttriple(void){throw NotImplementedError("calc_Ttriple is not implemented for this backend");}; @@ -228,6 +228,8 @@ protected: /// Using this backend, get the critical point molar density in mol/m^3 virtual long double calc_rhomolar_critical(void){throw NotImplementedError("calc_rhomolar_critical is not implemented for this backend");}; + /// Using this backend, construct the phase envelope, the variable type describes the type of phase envelope to be built. + virtual void calc_phase_envelope(const std::string &type){throw NotImplementedError("calc_phase_envelope is not implemented for this backend");}; public: virtual long double calc_melt_p_T(long double T){throw NotImplementedError("calc_melt_p_T is not implemented for this backend");}; @@ -236,13 +238,13 @@ public: AbstractState(){}; virtual ~AbstractState(){}; - + /// A factory function to return a pointer to a new-allocated instance of one of the backends. /** Very Important!! : Use a smart pointer to manage the pointer returned. In older versions of C++, you can use std::tr1::smart_ptr. In C++2011 you can use std::shared_ptr Several backends are possible: - + 1. "?" : The backend is unknown, we will parse the fluid string to determine the backend to be used. Probably will use HEOS backend (see below) 2. "HEOS" : The Helmholtz Equation of State backend for use with pure and pseudo-pure fluids, and mixtures, all of which are based on multi-parameter Helmholtz Energy equations of state. The fluid part of the string should then either be 1. A pure or pseudo-pure fluid name (eg. "PROPANE" or "R410A"), yielding a HelmholtzEOSBackend instance. @@ -251,14 +253,14 @@ public: 3. "REFPROP" : The REFPROP backend will be used. The fluid part of the string should then either be 1. A pure or pseudo-pure fluid name (eg. "PROPANE" or "R410A"), yielding a REFPROPBackend instance. 2. A string that encodes the components of the mixture with a "&" between them (e.g. "R32&R125"), yielding a REFPROPMixtureBackend instance. - + 4. "TTSE&XXXX": The TTSE backend will be used, and the tables will be generated using the XXXX backend where XXXX is one of the base backends("HEOS", "REFPROP", etc. ) 5. "BICUBIC&XXXX": The Bicubic backend will be used, and the tables will be generated using the XXXX backend where XXXX is one of the base backends("HEOS", "REFPROP", etc. ) 6. "INCOMP": The incompressible backend will be used 7. "BRINE": The brine backend will be used */ static AbstractState * factory(const std::string &backend, const std::string &fluid_string); - + // The derived classes must implement this function to define whether they use mole fractions (true) or mass fractions (false) virtual bool using_mole_fractions(void) = 0; @@ -268,7 +270,7 @@ public: /// Clear all the cached values bool clear(); - + void set_mole_fractions(const std::vector &mole_fractions){set_mole_fractions(std::vector(mole_fractions.begin(), mole_fractions.end()));}; void set_mass_fractions(const std::vector &mass_fractions){set_mass_fractions(std::vector(mass_fractions.begin(), mass_fractions.end()));}; @@ -360,6 +362,7 @@ public: /// Return the isobaric expansion coefficient \f$ \beta = \frac{1}{v}\left.\frac{\partial v}{\partial T}\right|_p = -\frac{1}{\rho}\left.\frac{\partial \rho}{\partial T}\right|_p\f$ in 1/K double isobaric_expansion_coefficient(void); double fugacity_coefficient(int i); + void build_phase_envelope(const std::string &type); //double fundamental_derivative_of_gas_dynamics(void); // ---------------------------------------- diff --git a/src/AbstractState.cpp b/src/AbstractState.cpp index d00d64d2..7299f86f 100644 --- a/src/AbstractState.cpp +++ b/src/AbstractState.cpp @@ -302,6 +302,10 @@ double AbstractState::fugacity_coefficient(int i){ // TODO: Cache the fug. coeff for each component return calc_fugacity_coefficient(i); } +void AbstractState::build_phase_envelope(const std::string &type) +{ + calc_phase_envelope(type); +} double AbstractState::isothermal_compressibility(void){ return 1.0/_rhomolar*first_partial_deriv(iDmolar, iP, iT); } diff --git a/src/Backends/REFPROP/REFPROPMixtureBackend.cpp b/src/Backends/REFPROP/REFPROPMixtureBackend.cpp index d5671183..d77fd2e4 100644 --- a/src/Backends/REFPROP/REFPROPMixtureBackend.cpp +++ b/src/Backends/REFPROP/REFPROPMixtureBackend.cpp @@ -181,6 +181,7 @@ static char default_reference_state[] = "DEF"; SATPdll_POINTER SATPdll; SATSdll_POINTER SATSdll; SATTdll_POINTER SATTdll; + SATSPLNdll_POINTER SATSPLNdll; SETAGAdll_POINTER SETAGAdll; SETKTVdll_POINTER SETKTVdll; SETMIXdll_POINTER SETMIXdll; @@ -307,6 +308,7 @@ double setFunctionPointers() SATPdll = (SATPdll_POINTER) getFunctionPointer((char *)SATPdll_NAME); SATSdll = (SATSdll_POINTER) getFunctionPointer((char *)SATSdll_NAME); SATTdll = (SATTdll_POINTER) getFunctionPointer((char *)SATTdll_NAME); + SATSPLNdll = (SATSPLNdll_POINTER) getFunctionPointer((char *)SATSPLNdll_NAME); SETAGAdll = (SETAGAdll_POINTER) getFunctionPointer((char *)SETAGAdll_NAME); SETKTVdll = (SETKTVdll_POINTER) getFunctionPointer((char *)SETKTVdll_NAME); SETMIXdll = (SETMIXdll_POINTER) getFunctionPointer((char *)SETMIXdll_NAME); @@ -550,7 +552,8 @@ void REFPROPMixtureBackend::set_REFPROP_fluids(const std::vector &f } else if (ierr > 0) // Error { - if (k==0) continue; + if (k==0 && N > 1) + continue; // Allow us to use PPF if a pure fluid else throw ValueError(format("%s",herr)); } @@ -603,11 +606,6 @@ long double REFPROPMixtureBackend::calc_melt_p_T(long double T) long ierr; char herr[255]; - if (T > calc_melt_Tmax()) - { - throw ValueError(format("Melting temperature [%g] is out of range",T)); - } - MELTTdll(&_T, &(mole_fractions[0]), &p_kPa, &ierr,herr,errormessagelength); // Error message @@ -672,6 +670,15 @@ long double REFPROPMixtureBackend::calc_fugacity_coefficient(int i) return static_cast(fug_cof[i]); } +void REFPROPMixtureBackend::calc_phase_envelope(const std::string &type) +{ + long ierr; + char herr[255]; + SATSPLNdll(&(mole_fractions[0]), // Inputs + &ierr, herr, errormessagelength); // Error message + if (ierr > 0) { throw ValueError(format("%s",herr).c_str()); } +} + void REFPROPMixtureBackend::update(long input_pair, double value1, double value2) { double rho_mol_L=_HUGE, rhoLmol_L=_HUGE, rhoVmol_L=_HUGE, diff --git a/src/Backends/REFPROP/REFPROPMixtureBackend.h b/src/Backends/REFPROP/REFPROPMixtureBackend.h index d38af71a..f82113fd 100644 --- a/src/Backends/REFPROP/REFPROPMixtureBackend.h +++ b/src/Backends/REFPROP/REFPROPMixtureBackend.h @@ -24,7 +24,7 @@ protected: std::vector mole_fractions_liq, mole_fractions_vap; public: REFPROPMixtureBackend(){}; - + /// The instantiator /// @param fluid_names The vector of strings of the fluid components, without file ending REFPROPMixtureBackend(const std::vector& fluid_names); @@ -34,10 +34,10 @@ public: bool using_mole_fractions(){return true;} /// Updating function for REFPROP - /** + /** 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. REFPROP calculates - a lot of other state variables each time you use a flash routine so we cache all the + a lot of other state variables each time you use a flash routine so we cache all the outputs that we can, which saves on computational time. @param input_pair Integer key from CoolProp::input_pairs to the two inputs that will be passed to the function @@ -59,17 +59,19 @@ public: void set_REFPROP_fluids(const std::vector &fluid_names); /// Set the mole fractions - /** + /** @param mole_fractions The vector of mole fractions of the components */ void set_mole_fractions(const std::vector &mole_fractions); - + /// Set the mass fractions - /** + /** @param mass_fractions The vector of mass fractions of the components */ void set_mass_fractions(const std::vector &mass_fractions); + void calc_phase_envelope(const std::string &type); + /// Check if the mole fractions have been set, etc. void check_status(); @@ -81,7 +83,7 @@ public: long double calc_surface_tension(void); long double calc_fugacity_coefficient(int i); - + long double calc_melt_p_T(long double T); long double calc_melt_T_p(long double p); long double calc_melt_rho_T(long double T); diff --git a/src/Backends/REFPROP/REFPROP_lib.h b/src/Backends/REFPROP/REFPROP_lib.h index 6741433c..372f896a 100644 --- a/src/Backends/REFPROP/REFPROP_lib.h +++ b/src/Backends/REFPROP/REFPROP_lib.h @@ -95,6 +95,7 @@ # define SATPdll SATPdll # define SATSdll SATSdll # define SATTdll SATTdll +# define SATSPLNdll SATSPLNdll # define SETAGAdll SETAGAdll # define SETKTVdll SETKTVdll # define SETMIXdll SETMIXdll @@ -210,6 +211,7 @@ # define SATPdll satpdll_ # define SATSdll satsdll_ # define SATTdll sattdll_ +# define SATSPLNdll satsplndll_ # define SETAGAdll setagadll_ # define SETKTVdll setktvdll_ # define SETMIXdll setmixdll_ @@ -316,6 +318,7 @@ # define SATPdll satpdll_ # define SATSdll satsdll_ # define SATTdll sattdll_ +# define SATSPLNdll satsplndll_ # define SETAGAdll setagadll_ # define SETKTVdll setktvdll_ # define SETMIXdll setmixdll_ @@ -420,6 +423,7 @@ # define SATPdll satpdll # define SATSdll satsdll # define SATTdll sattdll +# define SATSPLNdll satsplndll # define SETAGAdll setagadll # define SETKTVdll setktvdll # define SETMIXdll setmixdll @@ -536,6 +540,7 @@ #define SATPdll_NAME FUNCTION_NAME(SATPdll) #define SATSdll_NAME FUNCTION_NAME(SATSdll) #define SATTdll_NAME FUNCTION_NAME(SATTdll) +#define SATSPLNdll_NAME FUNCTION_NAME(SATSPLNdll) #define SETAGAdll_NAME FUNCTION_NAME(SETAGAdll) #define SETKTVdll_NAME FUNCTION_NAME(SETKTVdll) #define SETMIXdll_NAME FUNCTION_NAME(SETMIXdll) @@ -649,6 +654,7 @@ extern "C" { typedef void (CALLCONV SATPdll_TYPE)(double *,double *,long *,double *,double *,double *,double *,double *,long *,char*,long ); typedef void (CALLCONV SATSdll_TYPE)(double *,double *,long *,long *,long *,double *,double *,double *,long *,double *,double *,double *,long *,double *,double *,double *,long *,char*,long ); typedef void (CALLCONV SATTdll_TYPE)(double *,double *,long *,double *,double *,double *,double *,double *,long *,char*,long ); + typedef void (CALLCONV SATSPLNdll_TYPE)(double *,long *,char*,long ); typedef void (CALLCONV SETAGAdll_TYPE)(long *,char*,long ); typedef void (CALLCONV SETKTVdll_TYPE)(long *,long *,char*,double *,char*,long *,char*,long ,long ,long ); typedef void (CALLCONV SETMIXdll_TYPE)(char*,char*,char*,long *,char*,double *,long *,char*,long ,long ,long ,long ,long ); @@ -857,6 +863,7 @@ extern "C" { typedef SATPdll_TYPE * SATPdll_POINTER; typedef SATSdll_TYPE * SATSdll_POINTER; typedef SATTdll_TYPE * SATTdll_POINTER; + typedef SATSPLNdll_TYPE * SATSPLNdll_POINTER; typedef SETAGAdll_TYPE * SETAGAdll_POINTER; typedef SETKTVdll_TYPE * SETKTVdll_POINTER; typedef SETMIXdll_TYPE * SETMIXdll_POINTER;