From f43a0b792bc37abe0ec1a97b25f66f8465cd2932 Mon Sep 17 00:00:00 2001 From: Ian Bell Date: Tue, 19 Aug 2014 21:55:23 +0200 Subject: [PATCH] Humid air properties now use string instead of char* Signed-off-by: Ian Bell --- include/HumidAirProp.h | 2 +- src/CoolPropLib.cpp | 6 ++- src/HumidAirProp.cpp | 41 ++++++++++++------- wrappers/Python/CoolProp/CoolProp.pxd | 17 ++++---- wrappers/Python/CoolProp/HumidAirProp.pyx | 24 ++++------- wrappers/Python/CoolProp/Plots/PsychScript.py | 16 ++++---- 6 files changed, 56 insertions(+), 50 deletions(-) diff --git a/include/HumidAirProp.h b/include/HumidAirProp.h index f16e495b..ec455602 100644 --- a/include/HumidAirProp.h +++ b/include/HumidAirProp.h @@ -10,7 +10,7 @@ namespace HumidAir // ----------------------- // Standard I/O function // ----------------------- -double HAPropsSI(const char *OutputName, const char *Input1Name, double Input1, const char *Input2Name, double Input2, const char *Input3Name, double Input3); +double HAPropsSI(const std::string &OutputName, const std::string &Input1Name, double Input1, const std::string &Input2Name, double Input2, const std::string &Input3Name, double Input3); // ----------------------- // Extra I/O function diff --git a/src/CoolPropLib.cpp b/src/CoolPropLib.cpp index 07dbe838..b0fe63af 100644 --- a/src/CoolPropLib.cpp +++ b/src/CoolPropLib.cpp @@ -181,9 +181,11 @@ EXPORT_CODE long CONVENTION get_parameter_information_string(const char *param, EXPORT_CODE double CONVENTION HAPropsSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * Name3, double Prop3) { - return HumidAir::HAPropsSI(Output, Name1, Prop1, Name2, Prop2, Name3, Prop3); + std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _Name3 = Name3; + return HumidAir::HAPropsSI(Output, _Name1, Prop1, _Name2, Prop2, _Name3, Prop3); } EXPORT_CODE void CONVENTION hapropssi_(const char *Output, const char *Name1, double *Prop1, const char *Name2, double *Prop2, const char * Name3, double * Prop3, double *output) { - *output = HumidAir::HAPropsSI(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3); + std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _Name3 = Name3; + *output = HumidAir::HAPropsSI(_Output, _Name1, *Prop1, _Name2, *Prop2, _Name3, *Prop3); } diff --git a/src/HumidAirProp.cpp b/src/HumidAirProp.cpp index 95a06649..fac7ceeb 100644 --- a/src/HumidAirProp.cpp +++ b/src/HumidAirProp.cpp @@ -19,12 +19,22 @@ #include #include +/// This is a stub overload to help with all the strcmp calls below and avoid needing to rewrite all of them +std::size_t strcmp(const std::string &s, const std::string e){ + return s.compare(e); +} + +// This is a lazy stub function to avoid recoding all the strcpy calls below +void strcpy(std::string &s, const std::string e){ + s = e; +} shared_ptr Water, Air; namespace HumidAir { + void check_fluid_instantiation() { if (!Water.get()){ @@ -134,16 +144,16 @@ void UseIdealGasEnthalpyCorrelations(int flag) printf("UseIdealGasEnthalpyCorrelations takes an integer, either 0 (no) or 1 (yes)\n"); } } -static double Brent_HAProps_T(char *OutputName, char *Input1Name, double Input1, char *Input2Name, double Input2, double TargetVal, double T_min, double T_max) +static double Brent_HAProps_T(const std::string &OutputName, const std::string &Input1Name, double Input1, const std::string &Input2Name, double Input2, double TargetVal, double T_min, double T_max) { double T; class BrentSolverResids : public CoolProp::FuncWrapper1D { private: double Input1,Input2,TargetVal; - char *OutputName,*Input1Name,*Input2Name; + std::string OutputName, Input1Name, Input2Name; public: - BrentSolverResids(char *OutputName, char *Input1Name, double Input1, char *Input2Name, double Input2, double TargetVal) + BrentSolverResids(std::string OutputName, std::string Input1Name, double Input1, std::string Input2Name, double Input2, double TargetVal) { this->OutputName = OutputName; this->Input1Name = Input1Name; @@ -155,7 +165,7 @@ static double Brent_HAProps_T(char *OutputName, char *Input1Name, double Input1, ~BrentSolverResids(){}; double call(double T){ - return HAPropsSI(OutputName,(char *)"T",T,Input1Name,Input1,Input2Name,Input2)-TargetVal; + return HAPropsSI(OutputName,"T",T,Input1Name,Input1,Input2Name,Input2)-TargetVal; } }; @@ -167,18 +177,19 @@ static double Brent_HAProps_T(char *OutputName, char *Input1Name, double Input1, return T; } -static double Secant_HAProps_T(char *OutputName, char *Input1Name, double Input1, char *Input2Name, double Input2, double TargetVal, double T_guess) +static double Secant_HAProps_T(const std::string &OutputName, const std::string &Input1Name, double Input1, const std::string &Input2Name, double Input2, double TargetVal, double T_guess) { // Use a secant solve in order to yield a target output value for HAProps by altering T double x1=0,x2=0,x3=0,y1=0,y2=0,eps=5e-7,f=999,T=300,change; int iter=1; + std::string sT = "T"; while ((iter<=3 || (fabs(f)>eps && fabs(change)>1e-10)) && iter<100) { if (iter==1){x1=T_guess; T=x1;} if (iter==2){x2=T_guess+0.001; T=x2;} if (iter>2) {T=x2;} - f=HAPropsSI(OutputName,(char *)"T",T,Input1Name,Input1,Input2Name,Input2)-TargetVal; + f=HAPropsSI(OutputName,sT,T,Input1Name,Input1,Input2Name,Input2)-TargetVal; if (iter==1){y1=f;} if (iter>1) { @@ -192,7 +203,7 @@ static double Secant_HAProps_T(char *OutputName, char *Input1Name, double Input1 return T; } -static double Secant_HAProps_W(const char *OutputName, const char *Input1Name, double Input1, const char *Input2Name, double Input2, double TargetVal, double W_guess) +static double Secant_HAProps_W(const std::string &OutputName, const std::string &Input1Name, double Input1, const std::string &Input2Name, double Input2, double TargetVal, double W_guess) { // Use a secant solve in order to yield a target output value for HAProps by altering humidity ratio double x1=0,x2=0,x3=0,y1=0,y2=0,eps=1e-8,f=999,W=0.0001; @@ -1009,7 +1020,7 @@ double WetbulbTemperature(double T, double p, double psi_w) } return return_val; } -static int Name2Type(const char *Name) +static int Name2Type(const std::string &Name) { if (!strcmp(Name,"Omega") || !strcmp(Name,"HumRat") || !strcmp(Name,"W")) return GIVEN_HUMRAT; @@ -1032,10 +1043,10 @@ static int Name2Type(const char *Name) else if (!strcmp(Name,"k") || !strcmp(Name,"Conductivity") || !strcmp(Name,"K")) return GIVEN_COND; else - printf("Sorry, your input [%s] was not understood to Name2Type in HumAir.c. Acceptable values are T,P,R,W,D,B,H,M,K and aliases thereof\n",Name); + printf("Sorry, your input [%s] was not understood to Name2Type in HumAir.c. Acceptable values are T,P,R,W,D,B,H,M,K and aliases thereof\n",Name.c_str()); return -1; } -int TypeMatch(int TypeCode, const char *Input1Name, const char *Input2Name, const char *Input3Name) +int TypeMatch(int TypeCode, const std::string &Input1Name, const std::string &Input2Name, const std::string &Input3Name) { // Return the index of the input variable that matches the input, otherwise return -1 for failure if (TypeCode==Name2Type(Input1Name)) @@ -1128,7 +1139,7 @@ double RelativeHumidity(double T, double p, double psi_w) // Find relative humidity using W/e=phi*p_s/(p-phi*p_s) return W/epsilon*p/(p_s*(1+W/epsilon)); } -double HAPropsSI(const char *OutputName, const char *Input1Name, double Input1, const char *Input2Name, double Input2, const char *Input3Name, double Input3) +double HAPropsSI(const std::string &OutputName, const std::string &Input1Name, double Input1, const std::string &Input2Name, double Input2, const std::string &Input3Name, double Input3) { try { @@ -1138,16 +1149,16 @@ double HAPropsSI(const char *OutputName, const char *Input1Name, double Input1, int In1Type, In2Type, In3Type,iT,iW,iTdp,iRH,ip,Type1,Type2; double vals[3],p,T,RH,W,Tdp,psi_w,M_ha,v_bar,h_bar,s_bar,MainInputValue,SecondaryInputValue,T_guess; double Value1,Value2,W_guess; - char MainInputName[100], SecondaryInputName[100],Name1[100],Name2[100]; + std::string MainInputName, SecondaryInputName, Name1, Name2; vals[0]=Input1; vals[1]=Input2; vals[2]=Input3; // First figure out what kind of inputs you have, convert names to Macro expansions - In1Type=Name2Type(Input1Name); - In2Type=Name2Type(Input2Name); - In3Type=Name2Type(Input3Name); + In1Type=Name2Type(Input1Name.c_str()); + In2Type=Name2Type(Input2Name.c_str()); + In3Type=Name2Type(Input3Name.c_str()); // Pressure must be included ip=TypeMatch(GIVEN_P,Input1Name,Input2Name,Input3Name); diff --git a/wrappers/Python/CoolProp/CoolProp.pxd b/wrappers/Python/CoolProp/CoolProp.pxd index 35db7535..90fbc44f 100644 --- a/wrappers/Python/CoolProp/CoolProp.pxd +++ b/wrappers/Python/CoolProp/CoolProp.pxd @@ -14,30 +14,29 @@ cdef extern from "DataStructures.h" namespace "CoolProp": int _get_parameter_index "CoolProp::get_parameter_index"(string) except + cdef extern from "CoolProp.h" namespace "CoolProp": + double _Props1SI "CoolProp::Props1SI"(string Ref, string Output) double _PropsSI "CoolProp::PropsSI"(string Output, string Name1, double Prop1, string Name2, double Prop2, string FluidName) vector[double] _PropsSI "CoolProp::PropsSI"(string Output, string Name1, vector[double] Prop1, string Name2, vector[double] Prop2, string FluidName, vector[double] fractions) vector[double] _PropsSII "CoolProp::PropsSI"(string Output, string Name1, vector[double] Prop1, string Name2, vector[double] Prop2, string FluidName) string _get_global_param_string "CoolProp::get_global_param_string"(string ParamName) except + - double _Props1SI "CoolProp::Props1SI"(string Ref, string Output) - -# double _IProps "CoolProp::IProps"(long Output, long Name1, double Prop1, long Name2, double Prop2, long Ref) # double _Props "CoolProp::Props"(string Output, string Name1, double Prop1, string Name2, double Prop2, string Ref) # double _Props1 "CoolProp::Props1"(string Ref, string Output) # string _get_fluid_param_string "CoolProp::get_fluid_param_string"(string ParamName, string FluidName) -# long _get_Fluid_index "CoolProp::get_Fluid_index" (string Fluid) #long _get_parameter_index "CoolProp::get_parameter_index" (string param) int _get_debug_level "CoolProp::get_debug_level"() void _set_debug_level "CoolProp::set_debug_level"(int level) -# string _get_BibTeXKey "CoolProp::get_BibTeXKey"(string Ref, string key) # Convenience functions # int _IsFluidType "IsFluidType"(char* Ref, char* Type) - -# cdef extern from "HumidAirProp.h": -# double _HAProps "HAProps"(char *OutputName, char *Input1Name, double Input1, char *Input2Name, double Input2, char *Input3Name, double Input3) -# double _HAProps_Aux "HAProps_Aux"(char* Name,double T, double p, double W, char *units) +# string _get_BibTeXKey "CoolProp::get_BibTeXKey"(string Ref, string key) +# long _get_Fluid_index "CoolProp::get_Fluid_index" (string Fluid) +# double _IProps "CoolProp::IProps"(long Output, long Name1, double Prop1, long Name2, double Prop2, long Ref) + +cdef extern from "HumidAirProp.h": + double _HAPropsSI "HumidAir::HAPropsSI"(string OutputName, string Input1Name, double Input1, string Input2Name, double Input2, string Input3Name, double Input3) +# double _HAProps_Aux "HAProps_Aux"(const char* Name,double T, double p, double W, char *units) # double _cair_sat "cair_sat"(double T) cdef class State: diff --git a/wrappers/Python/CoolProp/HumidAirProp.pyx b/wrappers/Python/CoolProp/HumidAirProp.pyx index 54416c16..d2a205d4 100644 --- a/wrappers/Python/CoolProp/HumidAirProp.pyx +++ b/wrappers/Python/CoolProp/HumidAirProp.pyx @@ -1,12 +1,12 @@ #This file gets directly included in CoolProp.pyx, separate here for cleanness of code -cpdef HAProps(str OutputName, str Input1Name, Input1, str Input2Name, Input2, str Input3Name, Input3): +cpdef HAPropsSI(string OutputName, string Input1Name, Input1, string Input2Name, Input2, string Input3Name, Input3): """ Copyright Ian Bell, 2011 email: ian.h.bell@gmail.com The function is called like - HAProps('H','T',298.15,'P',101.325,'R',0.5) + HAPropsSI('H','T',298.15,'P',101325,'R',0.5) which will return the enthalpy of the air for a set of inputs of dry bulb temperature of 25C, atmospheric pressure, and a relative humidity of 50%. @@ -22,29 +22,24 @@ cpdef HAProps(str OutputName, str Input1Name, Input1, str Input2Name, Input2, st T Tdb Dry-Bulb Temperature [K] B Twb Wet-Bulb Temperature [K] D Tdp Dew-Point Temperature [K] - P Pressure [kPa] + P Pressure [Pa] V Vda Mixture volume [m3/kg dry air] R RH Relative humidity in (0,1) [-] W Omega Humidity Ratio [kg water/kg dry air] - H Hda Mixture enthalpy [kJ/kg dry air] - S Sda Mixture entropy [kJ/kg dry air/K] - C cp Mixture specific heat [kJ/kg dry air/K] + H Hda Mixture enthalpy [J/kg dry air] + S Sda Mixture entropy [J/kg dry air/K] + C cp Mixture specific heat [J/kg dry air/K] M Visc Mixture viscosity [Pa-s] - K Mixture thermal conductivity [kW/m/K] + K Mixture thermal conductivity [W/m/K] ======== ======== ======================================== There are also strings for the mixture volume and mixture enthalpy that will return the properties on a total humid air flow rate basis, they are given by 'Vha' [units of m^3/kg humid air] and 'Cha' [units of kJ/kg humid air/K] and 'Hha' [units of kJ/kg humid air] respectively. For more information, go to http://www.coolprop.org """ - #Convert all strings to byte-strings - cdef bytes _OutputName = OutputName.encode('ascii') - cdef bytes _Input1Name = Input1Name.encode('ascii') - cdef bytes _Input2Name = Input2Name.encode('ascii') - cdef bytes _Input3Name = Input3Name.encode('ascii') if isinstance(Input1, (int, long, float, complex)) and isinstance(Input2, (int, long, float, complex)) and isinstance(Input3, (int, long, float, complex)): - val = _HAProps(_OutputName,_Input1Name,Input1,_Input2Name,Input2,_Input3Name,Input3) + val = _HAPropsSI(OutputName, Input1Name, Input1, Input2Name, Input2, Input3Name, Input3) if math.isinf(val) or math.isnan(val): err_string = _get_global_param_string('errstring') @@ -70,7 +65,6 @@ cpdef HAProps(str OutputName, str Input1Name, Input1, str Input2Name, Input2, st raise TypeError("Iterable inputs are not all the same length. Lengths: "+str(iterable_lengths)) else: L = iterable_lengths[0] - if isinstance(Input1, (int, long, float, complex)): Input1vec = [Input1]*L @@ -90,7 +84,7 @@ cpdef HAProps(str OutputName, str Input1Name, Input1, str Input2Name, Input2, st vals = [] for _Input1, _Input2, _Input3 in zip(Input1vec, Input2vec, Input3vec): - val = _HAProps(_OutputName,_Input1Name,_Input1,_Input2Name,_Input2,_Input3Name,_Input3) + val = _HAPropsSI(OutputName, Input1Name, Input1, Input2Name, Input2, Input3Name, Input3) if math.isinf(val) or math.isnan(val): err_string = _get_global_param_string('errstring') diff --git a/wrappers/Python/CoolProp/Plots/PsychScript.py b/wrappers/Python/CoolProp/Plots/PsychScript.py index 51eed94c..e07d5b25 100644 --- a/wrappers/Python/CoolProp/Plots/PsychScript.py +++ b/wrappers/Python/CoolProp/Plots/PsychScript.py @@ -1,6 +1,6 @@ import numpy, matplotlib -from CoolProp.HumidAirProp import HAProps +from CoolProp.HumidAirProp import HAPropsSI from CoolProp.Plots.Plots import InlineLabel p = 101.325 @@ -17,16 +17,16 @@ ax.plot(Tdb-273.15,w,lw=2) # Humidity lines RHValues = [0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9] for RH in RHValues: - w = [HAProps('W','T',T,'P',p,'R',RH) for T in Tdb] + w = [HAPropsSI('W','T',T,'P',p,'R',RH) for T in Tdb] ax.plot(Tdb-273.15,w,'r',lw=1) # Humidity lines for H in [-20, -10, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90]: #Line goes from saturation to zero humidity ratio for this enthalpy - T1 = HAProps('T','H',H,'P',p,'R',1.0)-273.15 - T0 = HAProps('T','H',H,'P',p,'R',0.0)-273.15 - w1 = HAProps('W','H',H,'P',p,'R',1.0) - w0 = HAProps('W','H',H,'P',p,'R',0.0) + T1 = HAPropsSI('T','H',H,'P',p,'R',1.0)-273.15 + T0 = HAPropsSI('T','H',H,'P',p,'R',0.0)-273.15 + w1 = HAPropsSI('W','H',H,'P',p,'R',1.0) + w0 = HAPropsSI('W','H',H,'P',p,'R',0.0) ax.plot(numpy.r_[T1,T0],numpy.r_[w1,w0],'r',lw=1) ax.set_xlim(Tdb[0]-273.15,Tdb[-1]-273.15) @@ -36,8 +36,8 @@ ax.set_ylabel(r"Humidity ratio ($m_{water}/m_{dry\ air}$) [-]") xv = Tdb #[K] for RH in [0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]: - yv = [HAProps('W','T',T,'P',p,'R',RH) for T in Tdb] - y = HAProps('W','P',p,'H',65.000000,'R',RH) + yv = [HAPropsSI('W','T',T,'P',p,'R',RH) for T in Tdb] + y = HAPropsSI('W','P',p,'H',65.000000,'R',RH) T_K,w,rot = InlineLabel(xv, yv, y=y, axis = ax) string = r'$\phi$='+str(RH*100)+'%' bbox_opts = dict(boxstyle='square,pad=0.0',fc='white',ec='None',alpha = 0.5)