def teest_1phase_first_derivatives(): for US in [CoolProp.UNIT_SYSTEM_SI, CoolProp.UNIT_SYSTEM_KSI]: CP.set_standard_unit_system(US) S = State("R134a", dict(T=300, D=1)) l = [ (S.get_rho, "T", S.T, "P", S.p, S.PFC.drhodT_constp), (S.get_rho, "P", S.p, "T", S.T, S.PFC.drhodp_constT), (S.get_p, "D", S.rho, "T", S.T, S.PFC.dpdrho_constT), # (S.get_p,'D',S.rho,'H',S.h,S.PFC.dpdrho_consth), #(these inputs not supported) (S.get_p, "T", S.T, "D", S.rho, S.PFC.dpdT_constrho), # (S.get_p,'T',S.T,'H',S.h,S.PFC.dpdT_consth), #(these inputs not supported) (S.get_h, "D", S.rho, "T", S.T, S.PFC.dhdrho_constT), (S.get_h, "D", S.rho, "P", S.p, S.PFC.dhdrho_constp), (S.get_h, "T", S.T, "D", S.rho, S.PFC.dhdT_constrho), (S.get_h, "T", S.T, "P", S.p, S.PFC.dhdT_constp), (S.get_h, "P", S.p, "T", S.T, S.PFC.dhdp_constT), (S.get_s, "D", S.rho, "T", S.T, S.PFC.dsdrho_constT), (S.get_s, "T", S.T, "D", S.rho, S.PFC.dsdT_constrho), (S.get_s, "D", S.rho, "P", S.p, S.PFC.dsdrho_constp), (S.get_s, "T", S.T, "P", S.p, S.PFC.dsdT_constp), (S.get_s, "P", S.p, "T", S.T, S.PFC.dsdp_constT), ] for args in l: yield (check_1phase_first_derivatives,) + (S,) + args
def params_table(Fluid): params = dict(mm = CP.Props(Fluid,'molemass'), Tt = CP.Props(Fluid,'Ttriple'), pt = CP.Props(Fluid,'ptriple'), Tmin = CP.Props(Fluid,'Tmin'), CAS = CP.get_CAS_code(Fluid), ASHRAE = CP.get_ASHRAE34(Fluid) ) return textwrap.dedent( """ Fluid Data ========== Fluid Parameters ========================= ============================== Mole Mass [kg/kmol] {mm:0.5f} Triple Point Temp. [K] {Tt:0.3f} Triple Point Press. [kPa] {pt:0.10g} Minimum temperature [K] {Tmin:0.3f} CAS number {CAS:s} ASHRAE classification {ASHRAE:s} ========================= ============================== """.format(**params))
def draw_isolines(self, iso_type, iso_range, num=10, rounding=False, units='kSI', line_opts=None, axis_limits=None): """ Create isolines Parameters ---------- iso_type : str Type of the isolines iso_range : list Range between isolines will be created [min, max] num : int Number of the isolines within range, Optional units : str Unit system of the input data ('kSI' or 'SI'), Optional line_opts : dict Line options (please see :func:`matplotlib.pyplot.plot`), Optional axis_limits : list Limits for drawing isolines [[xmin, xmax], [ymin, ymax]], Optional """ # convert input data to SI units for internal use iso_range = CP.toSI(iso_type, iso_range, units) if axis_limits is not None: axis_limits = [CP.toSI(self.graph_type[1].upper(), axis_limits[0], units), CP.toSI(self.graph_type[0].upper(), axis_limits[1], units), ] iso_lines = IsoLines(self.fluid_ref, self.graph_type, iso_type, axis=self.axis) iso_lines.draw_isolines(iso_range, num, rounding, line_opts, axis_limits)
def test_State_PROPS(): for parameter, SI_over_kSI in State_Props_listing: CP.set_standard_unit_system(CoolProp.unit_systems_constants.UNIT_SYSTEM_SI) val_SI = S.Props(parameter) CP.set_standard_unit_system(CoolProp.unit_systems_constants.UNIT_SYSTEM_KSI) val_kSI = S.Props(parameter) yield check, val_SI, val_kSI, SI_over_kSI
def draw_process(self, states, line_opts={'color' : 'r', 'lw' : 1.5}): """ Draw process or cycle from list of State objects Parameters ---------- states : list List of CoolProp.State.State objects line_opts : dict Line options (please see :func:`matplotlib.pyplot.plot`), Optional """ # plot above other lines line_opts['zorder'] = 10 for i, state in enumerate(states): if state.Fluid != self.fluid_ref: raise ValueError('Fluid [{0}] from State object does not match PropsPlot fluid [{1}].'.format(state.Fluid, self.fluid_ref)) if i == 0: continue S2 = states[i] S1 = states[i-1] iso = False y_name, x_name = self.graph_type.lower().replace('t', 'T') x1 = getattr(S1, x_name) x2 = getattr(S2, x_name) y1 = getattr(S1, y_name) y2 = getattr(S2, y_name) # search for equal properties between states for iso_type in ['p', 'T', 's', 'h', 'rho']: if getattr(S1, iso_type) == getattr(S2, iso_type): axis_limits = [[x1, x2], [y1, y2]] self.draw_isolines(iso_type.upper(), [getattr(S1, iso_type)], num=1, units='kSI', line_opts=line_opts, axis_limits=axis_limits) iso = True break # connect states with straight line if not iso: # convert values to SI for plotting x_val = [CP.toSI(x_name.upper(), x1, 'kSI'), CP.toSI(x_name.upper(), x2, 'kSI')] y_val = [CP.toSI(y_name.upper(), y1, 'kSI'), CP.toSI(y_name.upper(), y2, 'kSI')] self.axis.plot(x_val, y_val, **line_opts)
def scale_plot(self, units='kSI'): """ Scale plot axis with units system Fluid properties are calculated in SI units for internal use. Axis ticks of the plot can be scaled to show data in other unit systems. """ xscale = CP.fromSI(self.graph_type[1], 1, units) yscale = CP.fromSI(self.graph_type[0], 1, units) x_fmt = matplotlib.ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x*xscale)) y_fmt = matplotlib.ticker.FuncFormatter(lambda y, pos: '{0:g}'.format(y*yscale)) self.axis.xaxis.set_major_formatter(x_fmt) self.axis.yaxis.set_major_formatter(y_fmt)
def test_sat_second_derivatives(): for US in [CoolProp.UNIT_SYSTEM_SI, CoolProp.UNIT_SYSTEM_KSI]: CP.set_standard_unit_system(US) S = State('R134a',dict(T=300,Q=1)) l = [(S.get_T,'P',S.p,'Q',0,S.PFC.d2Tdp2_along_sat), (S.get_rho,'P',S.p,'Q',0,S.PFC.d2rhodp2_along_sat_liquid), (S.get_rho,'P',S.p,'Q',1,S.PFC.d2rhodp2_along_sat_vapor), (S.get_h,'P',S.p,'Q',0,S.PFC.d2hdp2_along_sat_liquid), (S.get_h,'P',S.p,'Q',1,S.PFC.d2hdp2_along_sat_vapor), (S.get_s,'P',S.p,'Q',0,S.PFC.d2sdp2_along_sat_liquid), (S.get_s,'P',S.p,'Q',1,S.PFC.d2sdp2_along_sat_vapor), ] for args in l: yield (check_sat_second_derivatives,)+(S,)+args
def CriticalIsotherm(Fluid): return textwrap.dedent( """ Along the critical isotherm where T=T\ :sub:`c` ================================================ .. plot:: Fluid = "{Fluid:s}" RPFluid = "{RPFluid:s}" #Critical isotherm from CoolProp.CoolProp import Props from numpy import linspace,array,abs import matplotlib.pyplot as plt Tc = Props(Fluid,'Tcrit') rhoc = Props(Fluid,'rhocrit') rhov = linspace(1e-12,2*rhoc) #All the CoolProp calculations p = array([Props('P','T',Tc,'D',D,Fluid) for D in rhov]) rho = array([Props('D','T',Tc,'D',D,Fluid) for D in rhov]) cp = array([Props('C','T',Tc,'D',D,Fluid) for D in rhov]) cv = array([Props('O','T',Tc,'D',D,Fluid) for D in rhov]) h0 = Props('H','T',0.95*Tc,'Q',1,Fluid) h = array([Props('H','T',Tc,'D',D,Fluid)-h0 for D in rhov]) s0 = Props('S','T',0.95*Tc,'Q',1,Fluid) s = array([Props('S','T',Tc,'D',D,Fluid)-s0 for D in rhov]) visc = array([Props('V','T',Tc,'D',D,Fluid) for D in rhov]) cond = array([Props('L','T',Tc,'D',D,Fluid) for D in rhov]) Rp = array([Props('P','T',Tc,'D',D,RPFluid) for D in rhov]) Rrho = array([Props('D','T',Tc,'D',D,RPFluid) for D in rhov]) Rcp = array([Props('C','T',Tc,'D',D,RPFluid) for D in rhov]) Rcv = array([Props('O','T',Tc,'D',D,RPFluid) for D in rhov]) Rh0 = Props('H','T',0.95*Tc,'Q',1,RPFluid) Rh = array([Props('H','T',Tc,'D',D,RPFluid)-Rh0 for D in rhov]) Rs0 = Props('S','T',0.95*Tc,'Q',1,RPFluid) Rs = array([Props('S','T',Tc,'D',D,RPFluid)-Rs0 for D in rhov]) Rvisc = array([Props('V','T',Tc,'D',D,RPFluid) for D in rhov]) Rcond = array([Props('L','T',Tc,'D',D,RPFluid) for D in rhov]) fig = plt.figure() ax = fig.add_axes((0.15,0.15,0.8,0.8)) ax.semilogy(rhov/rhoc,abs(p/Rp-1)*100,'o',label='Pressure') ax.semilogy(rhov/rhoc,abs(cp/Rcp-1)*100,'o',label='Specific heat (cp)') ax.semilogy(rhov/rhoc,abs(cv/Rcv-1)*100,'o',label='Specific heat (cv)') ax.semilogy(rhov/rhoc,abs(h/Rh-1)*100,'o',label='Enthalpy') ax.semilogy(rhov/rhoc,abs(s/Rs-1)*100,'o',label='Entropy') ax.semilogy(rhov/rhoc,abs(visc/Rvisc-1)*100,'^',label='Viscosity') ax.semilogy(rhov/rhoc,abs(cond/Rcond-1)*100,'s',label='Conductivity') ax.set_ylim(1e-16,100) ax.set_title('Critical isotherm Deviations from REFPROP 9.1') ax.set_xlabel(r'Reduced density $\\rho/\\rho_c$') ax.set_ylabel('Absolute deviation [%]') ax.legend(numpoints=1,loc='best') plt.show() """.format(Fluid=Fluid,RPFluid = 'REFPROP-'+CP.get_REFPROPname(Fluid)))
def _get_index(prop): if is_string(prop): return CP.get_parameter_index(prop) elif isinstance(prop, int): return prop else: raise ValueError("Invalid input, expected a string or an int, not {0:s}.".format(str(prop)))
def draw_isolines(self, iso_type, iso_range, num=10, rounding=False, units='kSI'): # convert range to SI units for internal use iso_range = CP.toSI(iso_type, iso_range, units) iso_lines = IsoLines(self.fluid_ref, self.graph_type, iso_type, axis=self.axis) iso_lines.draw_isolines(iso_range, num, rounding)
def check_Props(parameter, SI_over_kSI): CP.set_standard_unit_system(CoolProp.unit_systems_constants.UNIT_SYSTEM_SI) val_SI = CP.Props(parameter,'T',300.0,'D',1.0,'R134a') CP.set_standard_unit_system(CoolProp.unit_systems_constants.UNIT_SYSTEM_KSI) val_kSI = CP.Props(parameter,'T',300.0,'D',1.0,'R134a') try: val_SI = val_SI() val_kSI = val_kSI() except: pass print val_SI,val_kSI, val_SI/val_kSI - SI_over_kSI if abs(val_SI/val_kSI - SI_over_kSI) > 1e-12: raise ValueError(val_SI/val_kSI-SI_over_kSI)
def check(N=5000,param='D',fluid = 'R245fa'): values = [] CP.enable_TTSE_LUT(fluid) try: CP.Props('D','P',CP.Props(fluid,'ptriple')+1,'Q',1,fluid) except: return [] #CP.set_TTSESinglePhase_LUT_size(fluid,500,500) hmin,hmax,pmin,pmax = CP.get_TTSESinglePhase_LUT_range(fluid) for i in range(N): x1 = random.random() h = x1*hmin+(1-x1)*hmax x2 = random.random() logp = x2*log(pmin)+(1-x2)*log(pmax) p = exp(logp) try: CP.enable_TTSE_LUT(fluid) value_withTTSE = CP.Props(param,'P',p,'H',h,fluid) CP.disable_TTSE_LUT(fluid) value_noTTSE = CP.Props(param,'P',p,'H',h,fluid) values.append((h,p,value_withTTSE,value_noTTSE)) except ValueError: pass return values
def drawIsoLines(Ref, plot, which, iValues=[], num=0, show=False, axis=None, units='kSI', line_opts=None): """ Draw lines with constant values of type 'which' in terms of x and y as defined by 'plot'. 'iMin' and 'iMax' are minimum and maximum value between which 'num' get drawn. :Note: :func:`CoolProps.Plots.drawIsoLines` will be depreciated in future releases and replaced with :func:`CoolProps.Plots.IsoLines` Parameters ----------- Ref : str The given reference fluid plot : str The plot type used which : str The iso line type iValues : list The list of constant iso line values num : int, Optional The number of iso lines (Default: 0 - Use iValues list only) show : bool, Optional Show the current plot (Default: False) axis : :func:`matplotlib.pyplot.gca()`, Optional The current axis system to be plotted to. (Default: create a new axis system) units : str Unit system of the input data ('kSI' or 'SI'), Optional line_opts : dict Line options (please see :func:`matplotlib.pyplot.plot`), Optional Examples -------- >>> from matplotlib import pyplot >>> from CoolProp.Plots import Ts, drawIsoLines >>> >>> Ref = 'n-Pentane' >>> ax = Ts(Ref) >>> ax.set_xlim([-0.5, 1.5]) >>> ax.set_ylim([300, 530]) >>> quality = drawIsoLines(Ref, 'Ts', 'Q', [0.3, 0.5, 0.7, 0.8], axis=ax) >>> isobars = drawIsoLines(Ref, 'Ts', 'P', [100, 2000], num=5, axis=ax) >>> isochores = drawIsoLines(Ref, 'Ts', 'D', [2, 600], num=7, axis=ax) >>> pyplot.show() """ # convert input data to SI units for internal use iValues = CP.toSI(which, iValues, units) isolines = IsoLines(Ref, plot, which, axis=axis) lines = isolines.draw_isolines(iValues, num=num, line_opts=line_opts) if show: isolines.show() return lines
def teest_sat_first_derivatives(): for US in [CoolProp.UNIT_SYSTEM_SI, CoolProp.UNIT_SYSTEM_KSI]: CP.set_standard_unit_system(US) S = State("R134a", dict(T=300, Q=1)) l = [ (S.get_T, "P", S.p, "Q", 0, S.PFC.dTdp_along_sat), (S.get_rho, "P", S.p, "Q", 0, S.PFC.drhodp_along_sat_liquid), (S.get_rho, "P", S.p, "Q", 1, S.PFC.drhodp_along_sat_vapor), (S.get_rho, "T", S.T, "Q", 0, S.PFC.drhodT_along_sat_liquid), (S.get_rho, "T", S.T, "Q", 1, S.PFC.drhodT_along_sat_vapor), (S.get_h, "P", S.p, "Q", 0, S.PFC.dhdp_along_sat_liquid), (S.get_h, "P", S.p, "Q", 1, S.PFC.dhdp_along_sat_vapor), (S.get_s, "P", S.p, "Q", 0, S.PFC.dsdp_along_sat_liquid), (S.get_s, "P", S.p, "Q", 1, S.PFC.dsdp_along_sat_vapor), ] for args in l: yield (check_sat_first_derivatives,) + (S,) + args
def compareProperty(fluid="",p=0,what=""): global c_diff, c_unit, c_exce if p==0: p = 0.75*CP.Props(fluid,"pcrit") Delta_T = 50 T_bub = CP.Props("T","P",p,"Q",0,fluid) T_dew = CP.Props("T","P",p,"Q",1,fluid) h_bub = CP.Props("H","P",p,"Q",0,fluid) h_dew = CP.Props("H","P",p,"Q",1,fluid) T_1 = T_bub-Delta_T if T_1 < CP.Props(fluid,"Tmin"): T_1 = CP.Props(fluid,"Tmin")+0.5*(T_bub-CP.Props(fluid,"Tmin")) T_2 = T_dew+Delta_T h_1 = CP.Props("H","P",p,"T",T_1,fluid) h_2 = CP.Props("H","P",p,"T",T_2,fluid) h_liq = numpy.linspace(h_1,h_bub,num=100) h_vap = numpy.linspace(h_dew,h_2,num=100) T_liq = CP.Props("T","P",p,"H",h_liq,fluid)-T_bub T_vap = CP.Props("T","P",p,"H",h_vap,fluid)-T_dew X_liq_STDV = CP.Props(what,"P",p,"H",h_liq,fluid) X_vap_STDV = CP.Props(what,"P",p,"H",h_vap,fluid) CP.enable_TTSE_LUT(fluid) X_liq_TTSE = CP.Props(what,"P",p,"H",h_liq,fluid) X_vap_TTSE = CP.Props(what,"P",p,"H",h_vap,fluid) if numpy.max([X_liq_STDV/X_liq_TTSE,X_vap_STDV/X_vap_TTSE])>1.25 or numpy.min([X_liq_STDV/X_liq_TTSE,X_vap_STDV/X_vap_TTSE])<0.75: c_diff += 1 print("") print("There were problems with "+what+" for "+fluid) print("Relative difference liquid: "+str(numpy.mean((X_liq_STDV-X_liq_TTSE)/X_liq_STDV))) print("Relative difference vapour: "+str(numpy.mean((X_vap_STDV-X_vap_TTSE)/X_vap_STDV))) print("Average factor liquid: "+str(numpy.mean(X_liq_STDV/X_liq_TTSE))) print("Average factor vapour: "+str(numpy.mean(X_vap_STDV/X_vap_TTSE)))
def fluid_header(Fluid): aliases = CP.get_aliases(str(Fluid)) aliases = ', '.join(['``'+a.strip()+'``' for a in aliases]) BTC = BibTeXerClass() EOSkey = CP.get_BibTeXKey(Fluid, "EOS") CP0key = CP.get_BibTeXKey(Fluid, "CP0") SURFACE_TENSIONkey = CP.get_BibTeXKey(Fluid, "SURFACE_TENSION") VISCOSITYkey = CP.get_BibTeXKey(Fluid, "VISCOSITY") CONDUCTIVITYkey = CP.get_BibTeXKey(Fluid, "CONDUCTIVITY") ECS_LENNARD_JONESkey = CP.get_BibTeXKey(Fluid, "ECS_LENNARD_JONES") ECS_FITSkey = CP.get_BibTeXKey(Fluid, "ECS_FITS") BibInfo = '' if EOSkey: BibInfo += '**Equation of State**: ' + BTC.entry2rst(EOSkey) + '\n\n' if CP0key: BibInfo += '**Ideal-Gas Specific Heat**: ' + BTC.entry2rst(CP0key) + '\n\n' if SURFACE_TENSIONkey: BibInfo += '**Surface Tension**: ' + BTC.entry2rst(SURFACE_TENSIONkey) + '\n\n' if VISCOSITYkey: BibInfo += '**Viscosity**: ' + BTC.entry2rst(VISCOSITYkey) + '\n\n' if CONDUCTIVITYkey: BibInfo += '**Conductivity**: ' + BTC.entry2rst(CONDUCTIVITYkey) + '\n\n' if ECS_LENNARD_JONESkey: BibInfo += '**Lennard-Jones Parameters for ECS**: ' + BTC.entry2rst(ECS_LENNARD_JONESkey) + '\n\n' if ECS_FITSkey: BibInfo += '**ECS Correction Fit**: ' + BTC.entry2rst(ECS_FITSkey) + '\n\n' return textwrap.dedent( """ ******************** {Fluid:s} ******************** Aliases ================================================================================ {Aliases:s} Bibliographic Information ========================= {Reference:s} """.format(Fluid=Fluid, Aliases = aliases, Reference = BibInfo, ) )
def getErrors(p, h, out="D", Ref=""): "Get the relative errors from table-based interpolation" errorTTSE = 1e3 errorBICUBIC = 1e3 try: # Using the EOS CP.disable_TTSE_LUT(Ref) EOS = CP.PropsSI(out, "P", p, "H", h, Ref) # Using the TTSE method CP.enable_TTSE_LUT(Ref) CP.set_TTSE_mode(Ref, "TTSE") TTSE = CP.PropsSI(out, "P", p, "H", h, Ref) # Using the Bicubic method CP.enable_TTSE_LUT(Ref) CP.set_TTSE_mode(Ref, "BICUBIC") BICUBIC = CP.PropsSI(out, "P", p, "H", h, Ref) errorTTSE = abs(TTSE / EOS - 1.0) * 100.0 errorBICUBIC = abs(BICUBIC / EOS - 1.0) * 100.0 except ValueError as VE: print VE pass return errorTTSE, errorBICUBIC
def get_global_param_string(self, param_name, split=False): """Get global parameter string from CoolProp. The split option was added for convenience and can be used to output comma separated values as a column vector in Calc. Thus, the function can be directly used as input for dropdown fields. """ try: param_str = CoolProp.get_global_param_string(param_name) if split: return zip(param_str.split(',')) else: return [[param_str]] except Exception as e: return [[str(e)]]
def get_update_pair(self): """Processes the values for the isoproperty and the graph dimensions to figure which should be used as inputs to the state update. Returns a tuple with the indices for the update call and the property constant. For an isobar in a Ts-diagram it returns the default order and the correct constant for the update pair: get_update_pair(CoolProp.iP,CoolProp.iSmass,CoolProp.iT) -> (0,1,2,CoolProp.PSmass_INPUTS) other values require switching and swapping. """ # Figure out if x or y-dimension should be used switch = self.XY_SWITCH[self.i_index][self.y_index*10+self.x_index] if switch is None: raise ValueError("This isoline cannot be calculated!") elif switch is False: pair, out1, _ = CP.generate_update_pair(self.i_index,0.0,self.x_index,1.0) elif switch is True: pair, out1, _ = CP.generate_update_pair(self.i_index,0.0,self.y_index,1.0) else: raise ValueError("Unknown error!") if out1==0.0: # Correct order swap = False else: # Wrong order swap = True if not switch and not swap: return 0,1,2,pair elif switch and not swap: return 0,2,1,pair elif not switch and swap: return 1,0,2,pair elif switch and swap: return 1,2,0,pair else: raise ValueError("Check the code, this should not happen!")
def check_Trho(N=5000,param='P',fluid='R245fa'): values = [] CP.enable_TTSE_LUT(fluid) try: CP.Props('D','P',CP.Props(fluid,'ptriple')+1,'Q',1,fluid) except: return [] #CP.set_TTSESinglePhase_LUT_size(fluid,500,500) hmin,hmax,pmin,pmax = CP.get_TTSESinglePhase_LUT_range(fluid) for i in range(N): x1 = random.random() h = x1*hmin+(1-x1)*hmax x2 = random.random() logp = x2*log(pmin)+(1-x2)*log(pmax) p = exp(logp) try: try: #Get the T,rho from the EOS directly without the LUT CP.disable_TTSE_LUT(fluid) s = CP.Props('S','P',p,'H',h,fluid) T = CP.Props('T','P',p,'H',h,fluid) rho = CP.Props('D','P',p,'H',h,fluid) except: print 'EOS failed: ', p,h raise #Now get p,h from the T,rho CP.enable_TTSE_LUT(fluid) val = CP.Props(param,'T',T,'D',rho,fluid) CP.disable_TTSE_LUT(fluid) valREFPROP = CP.Props(param,'T',T,'D',rho,fluid) #print T,rho,val,valREFPROP,(val/valREFPROP-1)*100 if abs(val-valREFPROP)>0.00001: raise ValueError except ValueError: print 'TTSE failed: ', T,rho values.append((T,rho,0,0)) pass return values
def phase_dict(): res = [] res.append(cp.get_phase_index('phase_twophase')) res.append('phase_twophase') res.append(cp.get_phase_index('phase_liquid')) res.append('phase_liquid') res.append(cp.get_phase_index('phase_gas')) res.append('phase_gas') res.append(cp.get_phase_index('phase_supercritical_liquid')) res.append('phase_supercritical_liquid') res.append(cp.get_phase_index('phase_supercritical')) res.append('phase_supercritical') res.append(cp.get_phase_index('phase_supercritical_gas')) res.append('phase_supercritical_gas') return res
def check_Pother(N=5000,param='T',other='S',fluid='R245fa'): values = [] CP.enable_TTSE_LUT(fluid) try: CP.Props('D','P',CP.Props(fluid,'ptriple')+1,'Q',1,fluid) except: return [] #CP.set_TTSESinglePhase_LUT_size(fluid,500,500) hmin,hmax,pmin,pmax = CP.get_TTSESinglePhase_LUT_range(fluid) for i in range(N): x1 = random.random() h = x1*hmin+(1-x1)*hmax x2 = random.random() logp = x2*log(pmin)+(1-x2)*log(pmax) p = exp(logp) try: try: #Get the T,rho from the EOS directly without the LUT CP.disable_TTSE_LUT(fluid) s = CP.Props('S','P',p,'H',h,fluid) T = CP.Props('T','P',p,'H',h,fluid) rho = CP.Props('D','P',p,'H',h,fluid) except: print 'EOS failed: ', p,h raise #Now get p,h from the T,rho CP.enable_TTSE_LUT(fluid) if other =='S': other_val = s elif other =='T': other_val = T elif other == 'D': other_val = rho else: raise ValueError val = CP.Props(param,'P',p,other,other_val,fluid) except ValueError: print 'TTSE failed: ', p,other_val values.append((p,other_val,0,0)) pass return values
import CoolProp.CoolProp as CP import matplotlib.pyplot as plt HEOS = CP.AbstractState('HEOS', 'Propane&IsoButane') for x0 in [0.02, 0.2, 0.4, 0.6, 0.8, 0.98]: HEOS.set_mole_fractions([x0, 1 - x0]) try: HEOS.build_phase_envelope("dummy") PE = HEOS.get_phase_envelope_data() PELabel = 'Propane, x = ' + str(x0) plt.plot(PE.T, PE.p, '-', label=PELabel) except ValueError as VE: print(VE) plt.xlabel('Temperature [K]') plt.xlim(300, 700) plt.ylabel('Pressure [Pa]') plt.yscale('log') plt.title('Phase Envelope for Propane/IsoButane Mixtures') plt.legend(loc='lower right', shadow=True) plt.show() plt.savefig('Propane-Isbutane.pdf') plt.savefig('Propane-Isbutane.png') plt.close()
import CoolProp.CoolProp as CoolProp from CoolProp.CoolProp import PropsSI for k in [ 'formula', 'CAS', 'aliases', 'ASHRAE34', 'REFPROP_name', 'pure', 'INCHI', 'INCHI_Key', 'CHEMSPIDER_ID' ]: item = k + ' --> ' + CoolProp.get_fluid_param_string("R134a", k) print(item) # H_L = PropsSI('H','P',101325,'Q',0,'Water'); print(H_L) # J/kg-K # T = 597.9 K and P = 5.0e6 Pa # Q = 1(vapor) =0(liquid) T1 = 7.8 T2 = 51.9 T3 = 34.3 Tc = 35.6 Te = 5.4 Pc = PropsSI('P', 'T', Tc + 273.15, 'Q', 0, 'R134a') h2 = PropsSI('H', 'T', T2 + 273.15, 'P', Pc, 'R134a') print(h2) h3 = PropsSI('H', 'T', T3 + 273.15, 'Q', 0, 'R134a') print(h3) h4 = h3 Pe = PropsSI('P', 'T', Te + 273.15, 'Q', 1, 'R134a') h1 = PropsSI('H', 'T', T1 + 273.15, 'P', Pe, 'R134a')
import CoolProp import CoolProp.CoolProp as CP print 'Fluid | EOS | CP0 | VISCOSITY | CONDUCTIVITY | ECS_LENNARD_JONES | ECS_FITS | SURFACE_TENSION' for fluid in CoolProp.__fluids__: print '{f:20s}'.format(f=fluid),'|', for key in ['EOS','CP0','VISCOSITY','CONDUCTIVITY','ECS_LENNARD_JONES','ECS_FITS','SURFACE_TENSION']: k = CP.get_BibTeXKey(fluid,key) if k and not k.startswith('__'): print 0,'|', elif k and k.startswith('__'): print 'X','|', else: print ' ','|', print '' f = open('fitdata.tex','w') for fluid in CoolProp.__fluids__: print>>f, '{f:20s}'.format(f=fluid),' & ', for i, key in enumerate(['EOS','CP0','VISCOSITY','CONDUCTIVITY','ECS_LENNARD_JONES','ECS_FITS','SURFACE_TENSION']): k = CP.get_BibTeXKey(fluid,key) if k and not k.startswith('__'): print>>f, '\cite{{{k:s}}}'.format(k=k),' & ', else: print>>f, ' ',' & ', print>>f, '\\\\'
import CoolProp.CoolProp as CP fluid = 'Propane' print CP.enable_TTSE_LUT(fluid) print CP.isenabled_TTSE_LUT(fluid) print CP.Props('H','P',300,'Q',0,fluid) print CP.Props('H','P',310,'Q',0,fluid) print CP.Props('H','P',315,'Q',0,fluid) # fluid = 'TestSolution-0.3' print CP.enable_TTSE_LUT(fluid) print CP.isenabled_TTSE_LUT(fluid) print CP.Props('H','P',3000,'T',280,fluid)
T = np.linspace(CP.PropsSI(Ref, "Tmin") + 0.1, CP.PropsSI(Ref, "Tcrit") - 0.01, 300) pV = CP.PropsSI("P", "T", T, "Q", 1, Ref) hL = CP.PropsSI("Hmolar", "T", T, "Q", 0, Ref) hV = CP.PropsSI("Hmolar", "T", T, "Q", 1, Ref) HHH1, PPP1, EEE1 = [], [], [] HHH2, PPP2, EEE2 = [], [], [] cNorm = colors.LogNorm(vmin=1e-12, vmax=10) scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=plt.get_cmap("jet")) for a_useless_counter in range(40000): h = random.uniform(150000 * MM, 590000 * MM) p = 10 ** random.uniform(np.log10(100000), np.log10(7000000)) CP.set_debug_level(0) try: EOS.update(CoolProp.HmolarP_INPUTS, h, p) rhoEOS = EOS.rhomolar() TEOS = EOS.T() TTSE.update(CoolProp.HmolarP_INPUTS, h, p) rhoTTSE = TTSE.rhomolar() TTTSE = TTSE.T() BICUBIC.update(CoolProp.HmolarP_INPUTS, h, p) rhoBICUBIC = BICUBIC.rhomolar() TBICUBIC = BICUBIC.T() errorTTSE = abs(rhoTTSE / rhoEOS - 1) * 100
#Fluid for transport model (viscosity) fluid_transport = 'hydrogen' #**************************************************************************************** #Temperature limits (set within subcritical region for saturation tables) T0 = 32.941 #Temperature start (K) TMax = 100 #Temperature end (K) #Pressure limits p0 = 1e5 #Pa pMax = 1.7e6 #Pa #**************************************************************************************** Tcrit = CP.PropsSI("Tcrit", fluid_thermo) Ts = [] ps = [] pRange = [] rho = [] mu = [] kappa = [] Cp = [] H = [] CpMCv = [] E = [] S = [] c = [] #pSat = []
def getErrors(p, h, out='D', Ref=''): "Get the relative errors from table-based interpolation" errorTTSE = 1e3 errorBICUBIC = 1e3 try: # Using the EOS CP.disable_TTSE_LUT(Ref) EOS = CP.PropsSI(out,'P',p,'H',h,Ref) # Using the TTSE method CP.enable_TTSE_LUT(Ref) CP.set_TTSE_mode(Ref,"TTSE") TTSE = CP.PropsSI(out,'P',p,'H',h,Ref) # Using the Bicubic method CP.enable_TTSE_LUT(Ref) CP.set_TTSE_mode(Ref,"BICUBIC") BICUBIC = CP.PropsSI(out,'P',p,'H',h,Ref) errorTTSE = abs(TTSE /EOS-1.0)*100.0 errorBICUBIC = abs(BICUBIC/EOS-1.0)*100.0 except ValueError as VE: print(VE) pass return errorTTSE,errorBICUBIC
def __init__(self, inputs=get_default_inputs()): """ Initializes a mulit-stage near-isothermal CAES system """ CAES.__init__(self, inputs) # reservoir self.depth = inputs['depth'] # fluid properties self.cp = CP.PropsSI('CPMASS', 'T', self.T_atm, 'P', self.p_atm * 1000.0, 'AIR') / 1000.0 # constant pressure specific heat [kJ/kg-K] self.cv = CP.PropsSI('CVMASS', 'T', self.T_atm, 'P', self.p_atm * 1000.0, 'AIR') / 1000.0 # constant volume specific heat [kJ/kg-K] self.gamma = self.cp / self.cv # heat capacity ratio [-] # machinery - general if inputs['PR_type'] == 'fixed' or inputs['PR_type'] == 'free': self.PR_type = inputs['PR_type'] else: self.PR_type = 'fixed' # ------------------- # compression # ------------------- # number of compression stages, stops at first 0, negative or non-integer entry for n # need to make sure the number of n entries matches the number of stages if inputs['n_cmp1'] < 0: self.n_stages_cmp = 1 self.n_cmp = [1] elif inputs['n_cmp2'] < 0: self.n_stages_cmp = 1 self.n_cmp = [inputs['n_cmp1']] elif inputs['n_cmp3'] < 0: self.n_stages_cmp = 2 self.n_cmp = [inputs['n_cmp1'], inputs['n_cmp2']] elif inputs['n_cmp4'] < 0: self.n_stages_cmp = 3 self.n_cmp = [inputs['n_cmp1'], inputs['n_cmp2'], inputs['n_cmp3']] elif inputs['n_cmp5'] < 0: self.n_stages_cmp = 4 self.n_cmp = [inputs['n_cmp1'], inputs['n_cmp2'], inputs['n_cmp3'], inputs['n_cmp4']] else: self.n_stages_cmp = 5 self.n_cmp = [inputs['n_cmp1'], inputs['n_cmp2'], inputs['n_cmp3'], inputs['n_cmp4'], inputs['n_cmp5']] # interstage pressure drop self.delta_p_cmp = [] for i in range(self.n_stages_cmp): if i == 0 and inputs['delta_p_cmp12'] > 0.0 and self.include_interstage_dp: self.delta_p_cmp.append(inputs['delta_p_cmp12']) elif i == 1 and inputs['delta_p_cmp23'] > 0.0 and self.include_interstage_dp: self.delta_p_cmp.append(inputs['delta_p_cmp23']) elif i == 2 and inputs['delta_p_cmp34'] > 0.0 and self.include_interstage_dp: self.delta_p_cmp.append(inputs['delta_p_cmp34']) elif i == 3 and inputs['delta_p_cmp45'] > 0.0 and self.include_interstage_dp: self.delta_p_cmp.append(inputs['delta_p_cmp45']) else: self.delta_p_cmp.append(0.0) # multiplier for total pressure ratio to account for interstage pressure drops PR_delta_p_cmp = 1.0 for delta_p in self.delta_p_cmp: PR_delta_p_cmp = PR_delta_p_cmp * (1.0 + delta_p) # equally divide pressure ratio for each stage, if pressure ratios are unspecified if len(inputs['PR_cmp']) == self.n_stages_cmp: self.PR_cmp = inputs['PR_cmp'] else: self.PR_cmp = [] PR_equal = (self.p_machine_design / self.p_atm * PR_delta_p_cmp) ** (1. / self.n_stages_cmp) for n in range(self.n_stages_cmp): self.PR_cmp.append(PR_equal) # ------------------- # expansion # ------------------- if inputs['n_exp1'] < 0: self.n_stages_exp = 1 self.n_exp = [1] elif inputs['n_exp2'] < 0: self.n_stages_exp = 1 self.n_exp = [inputs['n_exp1']] elif inputs['N_exp3'] < 0: self.n_stages_exp = 2 self.n_exp = [inputs['n_exp1'], inputs['n_exp2']] elif inputs['n_exp4'] < 0: self.n_stages_exp = 3 self.n_exp = [inputs['n_exp1'], inputs['n_exp2'], inputs['n_exp3']] elif inputs['n_exp5'] < 0: self.n_stages_exp = 4 self.n_exp = [inputs['n_exp1'], inputs['n_exp2'], inputs['n_exp3'], inputs['n_exp4']] else: self.n_stages_exp = 5 self.n_exp = [inputs['n_exp1'], inputs['n_exp2'], inputs['n_exp3'], inputs['n_exp4'], inputs['n_exp5']] # interstage pressure drop self.delta_p_exp = [] for i in range(self.n_stages_exp): if i == 0 and inputs['delta_p_exp12'] > 0.0 and self.include_interstage_dp: self.delta_p_exp.append(inputs['delta_p_exp12']) elif i == 1 and inputs['delta_p_exp23'] > 0.0 and self.include_interstage_dp: self.delta_p_exp.append(inputs['delta_p_exp23']) elif i == 2 and inputs['delta_p_exp34'] > 0.0 and self.include_interstage_dp: self.delta_p_exp.append(inputs['delta_p_exp34']) elif i == 3 and inputs['delta_p_exp45'] > 0.0 and self.include_interstage_dp: self.delta_p_exp.append(inputs['delta_p_exp45']) else: self.delta_p_exp.append(0.0) # multiplier for total pressure ratio to account for interstage pressure drops PR_delta_p_exp = 1.0 for delta_p in self.delta_p_exp: PR_delta_p_exp = PR_delta_p_exp * (1.0 + delta_p) # equally divide pressure ratio for each stage, if pressure ratios are unspecified if len(inputs['PR_exp']) == self.n_stages_exp: self.PR_exp = inputs['PR_exp'] else: self.PR_exp = [] PR_equal = (self.p_machine_design / self.p_atm * PR_delta_p_exp) ** (1. / self.n_stages_exp) for n in range(self.n_stages_exp): self.PR_exp.append(PR_equal) # ------------------- # recreate dataframe to store data (with additional entries) # ------------------- additional_time_series = ['cmp_p_in', 'cmp_T_in', 'exp_p_in', 'exp_T_in'] stage_entries = ['n', 'w_stg'] state_entries = ['p_in', 'T_in', 'p_out', 'T_out'] for n in range(self.n_stages_cmp): for entry in stage_entries: additional_time_series.append('cmp_' + entry + str(n)) for entry in state_entries: additional_time_series.append('cmp_' + entry + str(n)) for n in range(self.n_stages_exp): for entry in stage_entries: additional_time_series.append('exp_' + entry + str(n)) for entry in state_entries: additional_time_series.append('exp_' + entry + str(n)) self.attributes_time_series = self.attributes_time_series + additional_time_series self.data = pd.DataFrame(columns=self.attributes_time_series)
def mixture_props(mixture, P=None, T=None): MW_mix = 0 Pc_mix = 0 Tc_mix = 0 ω_mix = 0 Pr_mix = 0 Tr_mix = 0 Cp0mass_mix = 0 Cp0molar_mix = 0 normalise(mixture) properties = OrderedDict() for component in mixture: fluid = component["fluid"] y_component = component["molefraction"] # Molecular Weight averaging MW_specie = CP.PropsSI('M', fluid) MW_mix += MW_specie * y_component #Critical Pressure averaging Pc_specie = CP.PropsSI('Pcrit', fluid) Pc_mix += Pc_specie * y_component #Critical Temperature averaging Tc_specie = CP.PropsSI('Tcrit', fluid) Tc_mix += Tc_specie * y_component ω_specie = CP.PropsSI("acentric", fluid) ω_mix += ω_specie * y_component if (P is not None) and (T is not None): Cp0mass = CP.PropsSI("Cp0mass", "P", P, "T", T, fluid) Cp0mass_mix += Cp0mass * y_component Cp0molar = CP.PropsSI("Cp0molar", "P", P, "T", T, fluid) Cp0molar_mix += Cp0molar * y_component MW_mix = round(MW_mix, 6) Pc_mix = round(Pc_mix, 1) Tc_mix = round(Tc_mix, 1) ω_mix = round(ω_mix, 4) if (Pc_mix == 0): Pc_mix = math.nan if (Tc_mix == 0): Tc_mix = math.nan if (MW_mix == 0): MW_mix = math.nan if (Cp0mass_mix == 0): Cp0mass_mix = math.nan if (Cp0molar_mix == 0): Cp0molar_mix = math.nan properties.update({"MW": MW_mix}) properties.update({"Pcritical": Pc_mix}) properties.update({"Tcritical": Tc_mix}) properties.update({"acentric": ω_mix}) if (P is not None) and (T is not None): try: Pr_mix = P / Pc_mix Tr_mix = T / Tc_mix Cv0mass_mix = Cp0mass_mix - (R / MW_mix) Cv0molar_mix = Cp0molar_mix - R k_mix = Cp0molar_mix / Cv0molar_mix except Exception as e: Pr_mix = math.nan Tr_mix = math.nan Cv0mass_mix = math.nan Cv0molar_mix = math.nan k_mix = math.nan try: Z_mix_PR = Z_PengRobinson_mixture(mixture=mixture, P=P, T=T) except Exception: Z_mix_PR = math.nan try: Z_mix_LKP = Z_LeeKesler_mixture(mixture=mixture, P=P, T=T) except Exception: Z_mix_LKP = math.nan try: Z_mix_NO = Z_NelsonObert_mixture(mixture=mixture, P=P, T=T) except Exception: Z_mix_NO = math.nan Pr_mix = round(Pr_mix, 4) Tr_mix = round(Tr_mix, 4) Z_mix_PR = round(Z_mix_PR, 4) Z_mix_LKP = round(Z_mix_LKP, 4) Z_mix_NO = round(Z_mix_NO, 4) Cp0mass_mix = round(Cp0mass_mix, 1) Cv0mass_mix = round(Cv0mass_mix, 1) Cp0molar_mix = round(Cp0molar_mix, 1) Cv0molar_mix = round(Cv0molar_mix, 1) k = Cp0molar_mix / (Cp0molar_mix - 8.314) k = round(k, 2) properties.update({"Pr": Pr_mix}) properties.update({"Tr": Tr_mix}) properties.update({"Cp0mass": Cp0mass_mix}) properties.update({"Cp0molar": Cp0molar_mix}) properties.update({"Cv0mass": Cv0mass_mix}) properties.update({"Cv0molar": Cv0molar_mix}) properties.update({"k": k}) properties.update({"Z_PR": Z_mix_PR}) properties.update({"Z_LKP": Z_mix_LKP}) properties.update({"Z_NO": Z_mix_NO}) return properties
import numpy as np import matplotlib.pyplot as plt from scipy.odr import * import textwrap # #fluid = 'Propane' #Rfluid = 'REFPROP-propane' #e_k = 263.88 #sigma = 0.49748 # fluid = 'DimethylEther' Rfluid = 'REFPROP-DME' e_k = 329.72 sigma = 0.5529 molemass = CP.Props(fluid, 'molemass') Ttriple = CP.Props(fluid, 'Ttriple') Tcrit = CP.Props(fluid, 'Tcrit') rhocrit = CP.Props(fluid, 'rhocrit') n = 6 m = 3 NP = 1 Nb = 0 N = (n - 1) * (m + 1) + 3 + Nb mu, mu_dilute, RHO, TTT = Collector(), Collector(), Collector(), Collector() rhomax = CP.Props('D', 'T', Ttriple, 'Q', 0, fluid) #Build a database of "experimental" data for T in np.linspace(Ttriple, Tcrit + 30, 400):
Created on Tue Apr 21 10:44:37 2020 @author: hdb3uc """ import matplotlib.pyplot as plt import numpy as np import CoolProp.CoolProp as cp # solving a complex rankine cycle for fixed mass flow to water heater fl = 'water' # state 1 P1 = 200e5 T1 = 923.15 H1 = cp.PropsSI('H', 'P', P1, 'T', T1, fl) S1 = cp.PropsSI('S', 'P', P1, 'T', T1, fl) #state 3 P3 = 60e5 T3 = 943.15 H3 = cp.PropsSI('H', 'P', P3, 'T', T3, fl) S3 = cp.PropsSI('S', 'P', P3, 'T', T3, fl) #state 2 P2 = 60e5 H2s = cp.PropsSI('H', 'P', P2, 'S', S1, fl) H2 = (H2s - H1) * (0.92) + H1 T2 = cp.PropsSI('T', 'P', P2, 'H', H2, fl) S2 = cp.PropsSI('S', 'P', P2, 'H', H2, fl) #state 4 P4 = 15e5 H4s = cp.PropsSI('H', 'P', P4, 'S', S3, fl)
# vector length nT = 2000 nP = 100 T_min = 100 T_max = 160 # ANN parameters dim = 1 batch_size = 2 epochs = 100 fluid = 'nitrogen' # get critical pressure p_c = CP.PropsSI(fluid, 'pcrit') p_vec = np.linspace(1, 3, nP) p_vec = (p_vec) * p_c T_vec = np.zeros((nT)) T_vec[:] = np.linspace(T_min, T_max, nT) rho_vec = np.zeros((nT)) # density cp_vec = np.zeros((nT)) # cp mu_vec = np.zeros((nT)) # viscosity lamb_vec = np.zeros((nT)) # lambda A_vec = np.zeros((nT)) # speed of sound Z_vec = np.zeros((nT)) # compressibility print('Generate data ...')
from CoolProp.Plots import Ph import CoolProp.CoolProp as CP import matplotlib.pyplot as plt import matplotlib.colors as colors import matplotlib.cm as cmx import matplotlib.ticker import numpy as np import random fig = plt.figure(figsize=(10,5)) ax1 = fig.add_axes((0.08,0.1,0.32,0.83)) ax2 = fig.add_axes((0.50,0.1,0.32,0.83)) Ref = 'R245fa' T = np.linspace(CP.Props(Ref,'Tmin')+0.1,CP.Props(Ref,'Tcrit')-0.01,300) pV = CP.Props('P','T',T,'Q',1,Ref) hL = CP.Props('H','T',T,'Q',0,Ref) hV = CP.Props('H','T',T,'Q',1,Ref) HHH1, PPP1, EEE1 = [], [], [] HHH2, PPP2, EEE2 = [], [], [] cNorm = colors.LogNorm(vmin=1e-12, vmax=10) scalarMap = cmx.ScalarMappable(norm = cNorm, cmap = plt.get_cmap('jet')) for a_useless_counter in range(40000): h = random.uniform(100,590) p = 10**random.uniform(np.log10(100),np.log10(7000))
def __init__(self, spec, throws=True): self.spec = spec self.html_opts = dict(inputs=True, limits=True, mapped=True, constraints=True, warnings=True) # Constraints C = pandas.Series(index=constraint_columns) calc = pandas.Series(index=calc_columns) mapped = spec.copy() messages = [] self.C = C self.calc = calc self.mapped = mapped self.messages = messages try: # Todo: implement the constraints on T_rect. # eg C[9] to enforce T_cond < T_rect, # C[10] to enforce T_rect <= T(P=Pcond,x=xrefrig,Qu=1). # Todo: Do we need a lower bound for T_abs? # A trivial constraint that is always satisfied C[0] = 0 # Basics C[1] = spec.x_refrig - self.x_refrig_min if C[1] < 0: messages.append( "x_refrig ({:g}) should be greater than {:g} but is not.". format(spec.x_refrig, self.x_refrig_min)) mapped.x_refrig = self.x_refrig_min C[2] = self.x_refrig_max - spec.x_refrig if C[2] < 0: messages.append( "x_refrig ({:g}) should be less than {:g} but is not.". format(spec.x_refrig, self.x_refrig_max)) mapped.x_refrig = self.x_refrig_max calc.T_evap_min = amm.props2(P=0.01, x=mapped.x_refrig, Qu=self.Qu_evap, out="T") C[3] = (spec.T_evap - calc.T_evap_min) if C[3] < 0: messages.append( "T_evap ({:g}) should be greater than {:g} but is not.". format(self.T_evap, calc.T_evap_min)) mapped.T_evap = calc.T_evap_min # convert mass fraction to molar only for Refprop x_molar_refrig = massFractionToMolar(mapped.x_refrig) T_lookup_max_bounds = [] T_lookup_max_bounds.append( CP.PropsSI( 'Tcrit', 'REFPROP::ammonia[{}]&water[{}]'.format( x_molar_refrig, 1.0 - x_molar_refrig))) #T_lookup_max_bounds.append(550) T_lookup_max_bounds.append( amm.props2(P=80, x=mapped.x_refrig, Qu=0, out='T')) calc.T_cond_max = numpy.min(T_lookup_max_bounds) C[4] = (calc.T_cond_max - spec.T_cond) if C[4] < 0: messages.append( "T_cond ({:g}) should be less than {:g} but is not.". format(spec.T_cond, calc.T_cond_max)) mapped.T_cond = calc.T_cond_max C[5] = (spec.T_cond - spec.T_evap) if C[5] < 0: messages.append( "T_cond ({:g}) should be greater than T_evap ({:g}) but is not." .format(spec.T_cond, spec.T_evap)) if mapped.T_evap < calc.T_cond_max: mapped.T_cond = mapped.T_evap elif mapped.T_cond > calc.T_evap_min: mapped.T_evap = mapped.T_cond else: mapped.T_evap = calc.T_cond_max mapped.T_cond = mapped.T_evap calc.P_cond = amm.props2(T=mapped.T_cond, x=mapped.x_refrig, Qu=0, out="P") calc.P_evap = amm.props2(T=mapped.T_evap, x=mapped.x_refrig, Qu=self.Qu_evap, out="P") # TODO: explain in write-up above # I had started off with constraint 'x_rich_max > 0', # but it appears that an equivalent statement is 'T_abs < T(x=0, ...)'. # This seems preferrable since following calculations depend on T_abs, # so we can adjust T_abs to the allowed limit, # whereas violation of limit on x_rich_max is not as easy to correct/override(?) calc.T_abs_max1 = amm.props2(x=self.x_rich_min, P=calc.P_evap, Qu=0, out="T") C[6] = (calc.T_abs_max1 - spec.T_abs) if C[6] < 0: messages.append( "T_abs ({:}) should be less than {:g} but is not.".format( spec.T_abs, calc.T_abs_max1)) mapped.T_abs = calc.T_abs_max1 # Also, enforce 'x_rich_max < 1' # First determine maximum equilibrium pressure at this temperature, # that is, when x_rich is 1, so that we don't call State function with invalid inputs. # If evaporator pressure is higher, no problem; even pure ammonia can absorb # by simple condensation. P_max = amm.props2(T=mapped.T_abs, x=self.x_rich_max_max, Qu=0, out="P") if P_max < calc.P_evap: calc.x_rich_max = self.x_rich_max_max calc.x_rich = calc.x_rich_max else: # This must be guarded by the above if-statement. # For P_evap slightly in excess of max, the function # returns x slightly greater than 1. For larger values, it fails altogether. calc.x_rich_max = amm.props2(T=mapped.T_abs, P=calc.P_evap, Qu=0, out="x") calc.x_rich = calc.x_rich_max if calc.x_rich > self.x_rich_max_max: calc.x_rich = self.x_rich_max_max calc.T_abs_max2 = T_abs_max_func( calc.x_rich, P_abs_ammonia(calc.x_rich, mapped.x_refrig, calc.P_evap)) C[7] = (calc.T_abs_max2 - spec.T_abs) if C[7] < 0: messages.append( "T_abs ({:g}) should be less than {:g} but is not.".format( spec.T_abs, calc.T_abs_max2)) # Should already have been fixed by previous constraint ... get rid of this one # self.T_abs_mapped = self.T_abs_max2 # TODO: fix this ... should map T_cond sooner, above. # Sometimes, the given pressure exceeds what the function can handle (see benchmarks). # A guaranteed level of pressure is substantially lower, about 80 bar. # But to use that pressure, we should also need a lower T_cond. try: calc.T_gen_min = amm.props2(P=calc.P_cond, x=calc.x_rich, Qu=0).T except KeyError as e: calc.T_gen_min = amm.props2(P=self.P_cond_max, x=calc.x_rich, Qu=0).T C[8] = (spec.T_gen - calc.T_gen_min) if C[8] < 0: messages.append( "T_gen ({:g}) should be greater than {:g} but is not.". format(spec.T_gen, calc.T_gen_min)) mapped.T_gen = calc.T_gen_min # TODO: reorder newly added constraint. # Enforces T_rect - T_cond > 0. C[9] = (spec.T_rect - spec.T_cond) if C[9] < 0: messages.append( "T_rect ({:g}) should be greater than T_cond ({:g}) but is not." .format(spec.T_rect, spec.T_cond)) # Todo: decide what to do next. # Corrective Action, Case 1 # mapped.T_rect = spec.T_cond + 1 # Now we would have to go back and update variables depending on T_rect. # Corrective Action, Case 2 # mapped.T_cond = spec.T_rect - 1 # Now we would have to go back and update variables depending on T_cond. except KeyError as e: messages.append(e.__repr__()) if throws: raise except ValueError as e: messages.append(e.__repr__()) if throws: raise except: raise
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Sun Oct 8 01:52:18 2017 @author: wei """ import CoolProp.CoolProp as CP fluid = 'Water' pressure_at_critical_point = CP.PropsSI(fluid, 'pcrit') # Massic volume (in m^3/kg) is the inverse of density # (or volumic mass in kg/m^3). Let's compute the massic volume of liquid # at 1bar (1e5 Pa) of pressure vL = 1 / CP.PropsSI('D', 'P', 1e5, 'Q', 0, fluid) # Same for saturated vapor vG = 1 / CP.PropsSI('D', 'P', 1e5, 'Q', 1, fluid)
import numpy as np import random fig = plt.figure(figsize=(10,5)) ax1 = fig.add_axes((0.08,0.1,0.32,0.83)) ax2 = fig.add_axes((0.50,0.1,0.32,0.83)) Ref = 'R245fa' BICUBIC = CoolProp.AbstractState('BICUBIC&HEOS',Ref) TTSE = CoolProp.AbstractState('TTSE&HEOS',Ref) EOS = CoolProp.AbstractState('HEOS',Ref) MM = EOS.molar_mass() print MM T = np.linspace(CP.PropsSI(Ref,'Tmin')+0.1, CP.PropsSI(Ref,'Tcrit')-0.01, 300) pV = CP.PropsSI('P','T',T,'Q',1,Ref) hL = CP.PropsSI('Hmolar','T',T,'Q',0,Ref) hV = CP.PropsSI('Hmolar','T',T,'Q',1,Ref) HHH1, PPP1, EEE1 = [], [], [] HHH2, PPP2, EEE2 = [], [], [] cNorm = colors.LogNorm(vmin=1e-12, vmax=10) scalarMap = cmx.ScalarMappable(norm = cNorm, cmap = plt.get_cmap('jet')) for a_useless_counter in range(40000): h = random.uniform(150000*MM,590000*MM) p = 10**random.uniform(np.log10(100000),np.log10(7000000)) CP.set_debug_level(0)
def CalcProp(self): self.Psat = CP.PropsSI("P", 'T', self.T_vec, "Q", 1, self.fluid) self.Hl = CP.PropsSI("H", 'T', self.T_vec, "Q", 0, self.fluid) self.cpl = CP.PropsSI("CPMASS", 'T', self.T_vec, "Q", 0, self.fluid) self.dDdPl = CP.PropsSI("d(D)/d(P)|T", 'T', self.T_vec, "Q", 0, self.fluid) self.Sl = CP.PropsSI("S", 'T', self.T_vec, "Q", 0, self.fluid) self.Cvl = CP.PropsSI("CVMASS", 'T', self.T_vec, "Q", 0, self.fluid) self.Al = CP.PropsSI("A", 'T', self.T_vec, "Q", 0, self.fluid) self.Vl = CP.PropsSI("V", 'T', self.T_vec, "Q", 0, self.fluid) self.Ll = CP.PropsSI("L", 'T', self.T_vec, "Q", 0, self.fluid) self.Hg = CP.PropsSI("H", 'T', self.T_vec, "Q", 1, self.fluid) self.cpg = CP.PropsSI("CPMASS", 'T', self.T_vec, "Q", 1, self.fluid) self.dDdPg = CP.PropsSI("d(D)/d(P)|T", 'T', self.T_vec, "Q", 1, self.fluid) self.Sg = CP.PropsSI("S", 'T', self.T_vec, "Q", 1, self.fluid) self.Cvg = CP.PropsSI("CVMASS", 'T', self.T_vec, "Q", 1, self.fluid) self.Ag = CP.PropsSI("A", 'T', self.T_vec, "Q", 1, self.fluid) self.Vg = CP.PropsSI("V", 'T', self.T_vec, "Q", 1, self.fluid) self.Lg = CP.PropsSI("L", 'T', self.T_vec, "Q", 1, self.fluid)
def init(): global hasInited global liquidDensityInterpolator, gasDensityInterpolator, liquidInternalEnergyInterpolator, gasInternalEnergyInterpolator global liquidViscosityInterpolator, gasViscosityInterpolator, liquidThermalConductivityInterpolator, gasThermalConductivityInterpolator if options.enableTankTemperatureInterpolation and not hasInited: hasInited = True tankInterpolationValues = np.linspace( 183, 309, options.tankInterpolantPointCount) interpolant = options.tankInterpolant print("computing liquidDensities") liquidDensities = CP.PropsSI('D', 'T', tankInterpolationValues, 'Q', 0, 'N2O') liquidDensityInterpolator = scipy.interpolate.interp1d( tankInterpolationValues, liquidDensities, kind=interpolant, bounds_error=True, copy=False) print("computing gasDensities") gasDensities = CP.PropsSI('D', 'T', tankInterpolationValues, 'Q', 1, 'N2O') gasDensityInterpolator = scipy.interpolate.interp1d( tankInterpolationValues, gasDensities, kind=interpolant, bounds_error=True, copy=False) print("computing liquidSpecificInternalEnergies") liquidSpecificInternalEnergies = CP.PropsSI('U', 'T', tankInterpolationValues, 'Q', 0, 'N2O') liquidInternalEnergyInterpolator = scipy.interpolate.interp1d( tankInterpolationValues, liquidSpecificInternalEnergies, kind=interpolant, bounds_error=True, copy=False) print("computing gasSpecificInternalEnergies") gasSpecificInternalEnergies = CP.PropsSI('U', 'T', tankInterpolationValues, 'Q', 1, 'N2O') gasInternalEnergyInterpolator = scipy.interpolate.interp1d( tankInterpolationValues, gasSpecificInternalEnergies, kind=interpolant, bounds_error=True, copy=False) # https://github.com/aesirkth/mjollnir-propulsion-simulations/blob/master/combustion/properties/oxidizerProperties_create_interpolationtables.m propertiesInterpolant = "cubic" T_mu = np.concatenate(([182.33, 184.69], np.arange(185, 305, 5))) mu_l = 1e-3 * np.array([ 0.4619, 0.4306, 0.4267, 0.3705, 0.3244, 0.2861, 0.2542, 0.2272, 0.2042, 0.1846, 0.1676, 0.1528, 0.1399, 0.1284, 0.1183, 0.1093, 0.1012, 0.0939, 0.0872, 0.0810, 0.0754, 0.0700, 0.0650, 0.0601, 0.0552, 0.0501 ]) mu_g = 1e-6 * np.array([ 9.4, 9.6, 9.6, 9.8, 10.1, 10.3, 10.6, 10.9, 11.1, 11.4, 11.7, 12.0, 12.3, 12.6, 12.9, 13.3, 13.7, 14.0, 14.4, 14.9, 15.4, 15.9, 16.5, 17.2, 18.1, 19.2 ]) liquidViscosityInterpolator = scipy.interpolate.interp1d( T_mu, mu_l, kind=propertiesInterpolant, fill_value="extrapolate") gasViscosityInterpolator = scipy.interpolate.interp1d( T_mu, mu_g, kind=propertiesInterpolant, fill_value="extrapolate") T_k = np.concatenate(([182.33, 184.69], np.arange(185, 285, 5))) k_l = 1e-3 * np.array([ 146.9, 145.6, 145.5, 142.8, 140.2, 137.6, 135.1, 132.6, 130.0, 127.6, 125.1, 122.7, 120.3, 117.9, 115.6, 113.3, 111.0, 108.7, 106.5, 104.4, 102.2, 100.1 ]) k_g = 1e-3 * np.array([ 8.2, 8.4, 8.4, 8.9, 9.3, 9.7, 10.2, 10.7, 11.2, 11.7, 12.2, 12.8, 13.4, 14.0, 14.7, 15.3, 16.1, 16.8, 17.6, 18.5, 19.5, 20.6 ]) liquidThermalConductivityInterpolator = scipy.interpolate.interp1d( T_k, k_l, kind=propertiesInterpolant, fill_value="extrapolate") gasThermalConductivityInterpolator = scipy.interpolate.interp1d( T_k, k_g, kind=propertiesInterpolant, fill_value="extrapolate")
def Compressor(Te = 273, Tc = 300, f = None,TTSE = False, OneCycle = False): if TTSE: CP.set_TTSESinglePhase_LUT_size("Propane", 500, 500) CP.enable_TTSE_LUT('Propane') global Injection ScrollComp=Scroll() #This runs if the module code is run directly ScrollComp.set_scroll_geo(83e-6, 3.3, 0.005, 0.006) #Set the scroll wrap geometry ScrollComp.set_disc_geo('2Arc',r2 = 0) ScrollComp.geo.delta_flank = 10e-6 ScrollComp.geo.delta_radial = 10e-6 ScrollComp.geo.delta_suction_offset = 0.0e-3 ScrollComp.geo.phi_ie_offset = 0.0 ScrollComp.omega = 3000/60*2*pi ScrollComp.Tamb = 298.0 #Temporarily set the bearing dimensions ScrollComp.mech = struct() ScrollComp.mech.D_upper_bearing = 0.04 ScrollComp.mech.L_upper_bearing = 0.04 ScrollComp.mech.c_upper_bearing = 20e-6 ScrollComp.mech.D_crank_bearing = 0.04 ScrollComp.mech.L_crank_bearing = 0.04 ScrollComp.mech.c_crank_bearing = 20e-6 ScrollComp.mech.D_lower_bearing = 0.025 ScrollComp.mech.L_lower_bearing = 0.025 ScrollComp.mech.c_lower_bearing = 20e-6 ScrollComp.mech.thrust_ID = 0.05 ScrollComp.mech.thrust_friction_coefficient = 0.028 #From Chen thesis ScrollComp.mech.orbiting_scroll_mass = 2.5 ScrollComp.mech.L_ratio_bearings = 3 ScrollComp.mech.mu_oil = 0.008 ScrollComp.h_shell = 0.02 ScrollComp.A_shell = 0.05 ScrollComp.HTC = 1.0 ScrollComp.motor = Motor() ScrollComp.motor.set_eta(0.9) ScrollComp.motor.suction_fraction = 1.0 Ref = 'Propane' #Ref = 'REFPROP-MIX:R410A.mix' Te = -20 + 273.15 Tc = 20 + 273.15 Tin = Te + 11.1 DT_sc = 7 pe = CP.PropsSI('P','T',Te,'Q',1.0,Ref)/1000.0 pc = CP.PropsSI('P','T',Tc,'Q',1.0,Ref)/1000.0 inletState = State.State(Ref,{'T':Tin,'P':pe}) T2s = ScrollComp.guess_outlet_temp(inletState,pc) outletState = State.State(Ref,{'T':T2s,'P':pc}) mdot_guess = inletState.rho*ScrollComp.Vdisp*ScrollComp.omega/(2*pi) ScrollComp.add_tube(Tube(key1='inlet.1', key2='inlet.2', L=0.3, ID=0.02, mdot=mdot_guess, State1=inletState.copy(), fixed=1, TubeFcn=ScrollComp.TubeCode)) ScrollComp.add_tube(Tube(key1='outlet.1', key2='outlet.2', L=0.3, ID=0.02, mdot=mdot_guess, State2=outletState.copy(), fixed=2, TubeFcn=ScrollComp.TubeCode)) ScrollComp.auto_add_CVs(inletState, outletState) ScrollComp.auto_add_leakage(flankFunc = ScrollComp.FlankLeakage, radialFunc = ScrollComp.RadialLeakage) FP = FlowPath(key1='inlet.2', key2='sa', MdotFcn=IsentropicNozzleWrapper(), ) FP.A = pi*0.01**2/4 ScrollComp.add_flow(FP) ScrollComp.add_flow(FlowPath(key1='sa', key2='s1', MdotFcn=ScrollComp.SA_S1, MdotFcn_kwargs = dict(X_d = 0.7) ) ) ScrollComp.add_flow(FlowPath(key1 = 'sa', key2 = 's2', MdotFcn = ScrollComp.SA_S2, MdotFcn_kwargs = dict(X_d = 0.7) ) ) ScrollComp.add_flow(FlowPath(key1 = 'outlet.1', key2 = 'dd', MdotFcn = ScrollComp.DISC_DD, MdotFcn_kwargs = dict(X_d = 0.7) ) ) ScrollComp.add_flow(FlowPath(key1 = 'outlet.1', key2 = 'ddd', MdotFcn = ScrollComp.DISC_DD, MdotFcn_kwargs = dict(X_d = 0.7) ) ) # ScrollComp.add_flow(FlowPath(key1 = 'outlet.1', # key2 = 'd1', # MdotFcn = ScrollComp.DISC_D1, # MdotFcn_kwargs = dict(X_d = 0.7) # ) # ) # # FP = FlowPath(key1='outlet.1', # key2='dd', # MdotFcn=IsentropicNozzleWrapper(), # ) # FP.A = pi*0.006**2/4 # ScrollComp.add_flow(FP) # # FP = FlowPath(key1='outlet.1', # key2='ddd', # MdotFcn=IsentropicNozzleWrapper(), # ) # FP.A = pi*0.006**2/4 # ScrollComp.add_flow(FP) ScrollComp.add_flow(FlowPath(key1='d1', key2='dd', MdotFcn=ScrollComp.D_to_DD)) ScrollComp.add_flow(FlowPath(key1='d2', key2='dd', MdotFcn=ScrollComp.D_to_DD)) #Connect the callbacks for the step, endcycle, heat transfer and lump energy balance ScrollComp.connect_callbacks(step_callback = ScrollComp.step_callback, endcycle_callback = ScrollComp.endcycle_callback, heat_transfer_callback = ScrollComp.heat_transfer_callback, lumps_energy_balance_callback = ScrollComp.lump_energy_balance_callback ) from time import clock t1=clock() ScrollComp.RK45_eps = 1e-6 ScrollComp.eps_cycle = 3e-3 try: ScrollComp.precond_solve(key_inlet='inlet.1', key_outlet='outlet.2', solver_method='RK45', OneCycle = OneCycle, plot_every_cycle= False, #hmin = 1e-3 eps_cycle = 3e-3 ) except BaseException as E: print(E) raise print 'time taken',clock()-t1 del ScrollComp.FlowStorage from PDSim.misc.hdf5 import HDF5Writer h5 = HDF5Writer() import CoolProp h5.write_to_file(ScrollComp, 'CPgit_'+CoolProp.__gitrevision__+'.h5') return ScrollComp
def apply_line_terms(attrs, vals): def is_int(i): """ Returns True if it is an integer """ try: i = int(i) return True except ValueError: return False def is_line_term(attr): """ Check if it is a line type term of the form injection_xxxxx_1' and is not a port term of the form injection_xxxxx_1_1 """ if not attr.startswith('injection'): return False #If there are no underscores, return false if len(attr.rsplit('_', 1)) == 1: return False #Try to split twice attr, i, j = attr.rsplit('_', 2) # If the far right one is an integer and the left part isn't you are # ok, its an injection line if not is_int(i) and is_int(j): return True else: return False # First check about the injection state; if two state related terms are # provided, use them to fix the injection state inj_state_params = [(par, val) for par, val in zip(attrs, vals) if is_line_term(par)] num_inj_state_params = len(inj_state_params) for i in range(len(self.Lines)): #Find the injection state terms that apply for this line state_params = [ (par, val) for par, val in zip(attrs, vals) if par.find('state') > -1 and par.endswith(str(i + 1)) ] num_state_params = len(state_params) #Get a copy of the state from the StatePanel inletState = self.Lines[i].state.GetState() if num_state_params > 0: #Unzip the parameters (List of tuples -> tuple of lists) state_attrs, state_vals = zip(*state_params) if num_state_params == 2: # Remove all the entries that correspond to the injection state - # we need them and don't want to set them in the conventional way for a in state_attrs: vals.pop(attrs.index(a)) attrs.pop(attrs.index(a)) #: The string representation of the index (1-based) I = str(i + 1) #Temperature and pressure provided if 'injection_state_temp_' + I in state_attrs and 'injection_state_pressure_' + I in state_attrs: injection_temp = state_vals[state_attrs.index( 'injection_state_temp_' + I)] injection_pressure = state_vals[state_attrs.index( 'injection_state_pressure_' + I)] self.Lines[i].state.set_state(inletState.Fluid, T=injection_temp, P=injection_pressure) #Dew temperature and superheat provided elif 'injection_state_sat_temp_' + I in state_attrs and 'injection_state_superheat_' + I in state_attrs: injection_sat_temp = state_vals[state_attrs.index( 'injection_state_sat_temp_' + I)] injection_superheat = state_vals[state_attrs.index( 'injection_state_superheat_' + I)] injection_temp = injection_sat_temp + injection_superheat import CoolProp.CoolProp as CP injection_pressure = CP.PropsSI( 'P', 'T', injection_sat_temp, 'Q', 1.0, inletState.Fluid) / 1000.0 self.Lines[i].state.set_state(inletState.Fluid, T=injection_temp, P=injection_pressure) else: raise ValueError( 'Invalid combination of injection states: ' + str(state_attrs)) elif num_inj_state_params == 1: import textwrap string = textwrap.dedent(""" Sorry but you need to provide two variables for the injection state in parametric table to fix the state. If you want to just modify the saturated temperature, add the superheat as a variable and give it one element in the parametric table """) dlg = wx.MessageDialog(None, string) dlg.ShowModal() dlg.Destroy() raise ValueError( 'Must provide two state variables in the parametric table for injection line' ) elif num_inj_state_params > 2: raise ValueError( 'Only two inlet state parameters can be provided in parametric table' ) return attrs, vals
Tcrit = CP.Props(fluid, "Tcrit") rhocrit = CP.Props(fluid, "rhocrit") n = 6 m = 3 NP = 1 Nb = 0 N = (n - 1) * (m + 1) + 3 + Nb mu, mu_dilute, RHO, TTT = Collector(), Collector(), Collector(), Collector() rhomax = CP.Props("D", "T", Ttriple, "Q", 0, fluid) # Build a database of "experimental" data for T in np.linspace(Ttriple, Tcrit + 30, 400): for rho in np.linspace(1e-10, rhomax, 400): muval = CP.Props("V", "T", T, "D", rho, Rfluid) mudilute = CP.viscosity_dilute(fluid, T, rho, e_k, sigma) # Want positive value, and single-phase if muval > 0 and T > Tcrit or rho > CP.rhosatL_anc(fluid, T) or rho < CP.rhosatV_anc(fluid, T): mu << muval mu_dilute << mudilute TTT << T RHO << rho from CoolProp.Plots.Plots import Trho Trho(fluid) plt.plot(RHO.vec, TTT.vec, ".") plt.show() # tau = np.array(TTT.vec)/Tcrit
import numpy as np import CoolProp.CoolProp as CP import CoolProp.Plots as CPP import matplotlib.pyplot as plt # Propiedades criticas fluid = 'R113' Tc = CP.PropsSI(fluid, 'Tcrit') rhoc = CP.PropsSI(fluid, 'rhocrit') Pc = CP.PropsSI(fluid, 'Pcrit') Dens = np.logspace(0, 4) for T in [321]: P = CP.PropsSI('P', 'T', T, 'D', Dens, fluid) dsl = CP.PropsSI('D', 'T', T, 'Q', 0, fluid) dsg = CP.PropsSI('D', 'T', T, 'Q', 1, fluid) print(dsl) print(dsg) print(dsl / dsg)
l.append("{:23.16e}".format(self.P_crit)) l.append("P_TRIPLE") l.append("{:23.16e}".format(self.P_triple)) l.append("T_CRITICAL") l.append("{:23.16e}".format(self.T_crit)) l.append("T_TRIPLE") l.append("{:23.16e}".format(self.T_triple)) for i in range(1, 10): l.append("TABLE_" + str(i)) l.append("{:10d}".format(self.nT) + "{:10d}".format(self.nP)) l.append("SAT_TABLE") l.append("{:10d}".format(5) + "{:10d}".format(4) + "{:10d}".format(9)) return l def WriteTable(self, filename): table = self.GetTable() with open(filename, 'w') as f: for line in table: f.write(line + os.linesep) if __name__ == "__main__": table = RGPTable(900, 300, 1e3, 50e5, \ CP.PropsSI("T","P",41e5, 'Q',1, "Toluene"), \ CP.PropsSI("T","P",1e4, 'Q',1, "Toluene"), \ 900, 900,10, "Toluene") table.WriteTable(table.fluid + ".rgp") # table = RGPTable(400, 240, 55000, 400000,350,240, 5, 5,5, "R134a") # table.WriteTable(table.fluid+".rgp")
def SatLiquidParity(Fluid): return textwrap.dedent( """ Saturated Liquid Deviations =========================== .. plot:: Fluid = "{Fluid:s}" RPFluid = "{RPFluid:s}" #Saturated Liquid from CoolProp.CoolProp import Props from numpy import linspace,array,abs import matplotlib.pyplot as plt Tt = Props(Fluid,'Tmin') Tc = Props(Fluid,'Tcrit') Tv = linspace(Tt+0.01,0.95*Tc,20) #All the CoolProp calculations p = array([Props('P','T',T,'Q',0,Fluid) for T in Tv]) rho = array([Props('D','T',T,'Q',0,Fluid) for T in Tv]) cp = array([Props('C','T',T,'Q',0,Fluid) for T in Tv]) cv = array([Props('O','T',T,'Q',0,Fluid) for T in Tv]) h0 = Props('H','T',(Tt+Tc)/2.0,'Q',0,Fluid) h = array([Props('H','T',T,'Q',0,Fluid)-h0 for T in Tv]) s0 = Props('S','T',(Tt+Tc)/2.0,'Q',0,Fluid) s = array([Props('S','T',T,'Q',0,Fluid)-s0 for T in Tv]) visc = array([Props('V','T',T,'Q',0,Fluid) for T in Tv]) cond = array([Props('L','T',T,'Q',0,Fluid) for T in Tv]) sigma = array([Props('I','T',T,'Q',0,Fluid) for T in Tv]) Rp = array([Props('P','T',T,'Q',0,RPFluid) for T in Tv]) Rrho = array([Props('D','T',T,'Q',0,RPFluid) for T in Tv]) Rcp = array([Props('C','T',T,'Q',0,RPFluid) for T in Tv]) Rcv = array([Props('O','T',T,'Q',0,RPFluid) for T in Tv]) Rh0 = Props('H','T',(Tt+Tc)/2.0,'Q',0,RPFluid) Rh = array([Props('H','T',T,'Q',0,RPFluid)-Rh0 for T in Tv]) Rs0 = Props('S','T',(Tt+Tc)/2.0,'Q',0,RPFluid) Rs = array([Props('S','T',T,'Q',0,RPFluid)-Rs0 for T in Tv]) Rvisc = array([Props('V','T',T,'Q',0,RPFluid) for T in Tv]) Rcond = array([Props('L','T',T,'Q',0,RPFluid) for T in Tv]) Rsigma = array([Props('I','T',T,'Q',0,RPFluid) for T in Tv]) fig = plt.figure() ax = fig.add_axes((0.15,0.15,0.8,0.8)) ax.semilogy(Tv/Tc,abs(p/Rp-1)*100,'o',label='Pressure') ax.semilogy(Tv/Tc,abs(rho/Rrho-1)*100,'o',label='Density') ax.semilogy(Tv/Tc,abs(cp/Rcp-1)*100,'o',label='Specific heat (cp)') ax.semilogy(Tv/Tc,abs(cv/Rcv-1)*100,'o',label='Specific heat (cv)') ax.semilogy(Tv/Tc,abs(h/Rh-1)*100,'o',label='Enthalpy') ax.semilogy(Tv/Tc,abs(s/Rs-1)*100,'o',label='Entropy') ax.semilogy(Tv/Tc,abs(visc/Rvisc-1)*100,'^',label='Viscosity') ax.semilogy(Tv/Tc,abs(cond/Rcond-1)*100,'s',label='Conductivity') ax.semilogy(Tv/Tc,abs(sigma/Rsigma-1)*100,'p',label='Surface tension') ax.set_ylim(1e-16,100) ax.set_title('Saturated Liquid Deviations from REFPROP 9.1') ax.set_xlabel('Reduced temperature T/Tc') ax.set_ylabel('Absolute deviation [%]') ax.legend(numpoints=1,loc='best') plt.show() """.format(Fluid=Fluid,RPFluid = 'REFPROP-'+CP.get_REFPROPname(Fluid)))
from __future__ import division from CoolProp import CoolProp as CP Fluid = 'CO2' R = 8.314472/CP.Props(Fluid,'molemass') Tc = CP.Props(Fluid,'Tcrit') pc = CP.Props(Fluid,'pcrit') w = CP.Props(Fluid,'accentric') a = 0.457235*R**2*Tc**2/pc b = 0.077796*R*Tc/pc kappa = 0.37464+1.54226*w-0.26992*w**2 T = 298.15 rho = 1000 v = 1/rho Tr = T/Tc alpha = (1+kappa*(1-Tr**0.5))**2 p = R*T/(v-b)-a*alpha/(v**2+2*b*v-b**2) print p, CP.Props('P', 'T', T, 'D', rho, Fluid)
def computeDerivedVariables(self, t, state, models): from models.flight import FlightModel from rellipsoid import earth from ambiance import Atmosphere surfaceAltitude = assumptions.launchSeaLevelAltitude.get( ) + models["flight"]["state"][FlightModel.states_z] if surfaceAltitude < 0: surfaceAltitude = 0 if surfaceAltitude > 80000: surfaceAltitude = 80000 atmosphere = Atmosphere(surfaceAltitude) pressure = atmosphere.pressure[0] density = atmosphere.density[0] speedOfSound = atmosphere.speed_of_sound[0] temperature = atmosphere.temperature[0] pressure = pressure * (assumptions.initialAtmosphericPressure.get() / seaLevelPressure) density = density * (assumptions.initialAtmosphericPressure.get() / seaLevelPressure) speedOfSound = speedOfSound * ( assumptions.initialAtmosphericPressure.get() / seaLevelPressure) temperature = temperature * ( assumptions.initialAtmosphericTemperature.get() / seaLevelTemperature) viscosity = atmosphere.dynamic_viscosity[0] thermalConductivity = atmosphere.thermal_conductivity[0] velocityThroughAir = np.linalg.norm([ models["flight"]["state"][FlightModel.states_vx], models["flight"]["state"][FlightModel.states_vy], models["flight"]["state"][FlightModel.states_vz] ]) dynamicPressure = 0.5 * density * velocityThroughAir * velocityThroughAir stagnationPressure = pressure - dynamicPressure airCp = CP.PropsSI('CPMASS', 'T', temperature, 'P', pressure, 'air') airCv = CP.PropsSI('CVMASS', 'T', temperature, 'P', pressure, 'air') airGamma = airCp / airCv mach = velocityThroughAir / speedOfSound # This is the adiabatic stagnation temperature on the surface of the rocket stagnationTemperature = temperature * ( 1 + (airGamma - 1) / 2 * mach * mach) launchLatitudeRadians = assumptions.launchLatitudeDegrees.get( ) / 180 * math.pi # todo for future: take into account the present latitude, not just the starting one verticalGravity, northwardGravity = earth.get_analytic_gravity( launchLatitudeRadians, surfaceAltitude) return [ pressure, density, speedOfSound, verticalGravity, northwardGravity, viscosity, thermalConductivity, temperature, dynamicPressure, stagnationPressure, stagnationTemperature ]
RPdata = CP.PropsSI(key, 'T', T, 'Dmolar', rho, RPfluid) - CP.PropsSI(key, 'T', T, 'Dmolar', 1, RPfluid) CPdata = CP.PropsSI(key, 'T', T, 'Dmolar', rho, fluid) - CP.PropsSI(key, 'T', T, 'Dmolar', 1, fluid) plt.plot(rho/rhoc, np.abs(RPdata/CPdata-1)*100, lw = 0, label = key, marker = symbols[(i+len(normalkeys))%len(symbols)]) ax.legend(loc='best', ncol = 2) plt.xlabel(r'Reduced density [$\\rho/\\rho_c$]') plt.ylabel(r'Relative deviation $(y_{{CP}}/y_{{RP}}-1)\\times 100$ [%]') ax.set_yscale('log') plt.title('Comparison between CoolProp and REFPROP({rpv:s}) along T = 1.01*Tc') plt.savefig(fluid+'.png', dpi = 100) plt.savefig(fluid+'.pdf') plt.close('all') """ if not os.path.exists(plots_path): os.makedirs(plots_path) with open(os.path.join(plots_path, 'matplotlibrc'), 'w') as fp: fp.write("backend : agg\n") for fluid in CoolProp.__fluids__: print('fluid:', fluid) file_string = template.format(fluid = fluid, rpv = CP.get_global_param_string("REFPROP_version")) file_path = os.path.join(plots_path, fluid + '.py') print('Writing to', file_path) with open(file_path, 'w') as fp: fp.write(file_string) subprocess.check_call('python "' + fluid + '.py"', cwd = plots_path, stdout = sys.stdout, stderr = sys.stderr, shell = True)
Rinput = 0.5 pressure_ratio = 2 ############################ SAME FROM THIS POINT ###################### # Call TcritEval function to determine operating conditions bnds = ((0.5, 5)) res = minimize_scalar(TcritEval, bounds=bnds, args=( FLUID, Z, ), tol=1e-3, method='bounded') Tr = res.x # Critical temperatures and pressures for the fluid Tcrit = CP.PropsSI('Tcrit', FLUID) # in K Pcrit = CP.PropsSI('Pcrit', FLUID) / 1e5 # in bars # Inlet conditions inletP = Pcrit inletT = Tr * Tcrit # Gas properties Rgas = CP.PropsSI('gas_constant', FLUID) / CP.PropsSI('M', FLUID) Gamma = CP.PropsSI('Cpmass', 'T', Tr * Tcrit, 'P', Pcrit * 1e5, FLUID) / CP.PropsSI( 'Cvmass', 'T', Tr * Tcrit, 'P', Pcrit * 1e5, FLUID) Cp = CP.PropsSI('Cpmass', 'T', Tr * Tcrit, 'P', Pcrit * 1e5, FLUID) # Velocity triangles phi = PHI psi = PSI R = Rinput # Machine efficiency
# -*- coding: utf-8 -*- """ Spyder Editor This is a temporary script file. """ import CoolProp.CoolProp as CP import numpy as NP import matplotlib.pyplot as PL #fluid = input ('Enter fluid name: ') fluid = 'R134a' pc = CP.PropsSI(fluid, 'pcrit') pt = CP.PropsSI(fluid, 'ptriple') # Create lists of properties on saturation line with GP variation in p pr = (0.9999 * pc / pt) pr = NP.power(pr, 0.001) plt_pp = [] plt_hf = [] plt_hg = [] p = pt p1 = 100000 p3 = 800000 #p1=1.0*p
def computeDerivedVariables(self, t, state, models): totalMass = state[self.states_oxidizerMass] totalEnergy = state[self.states_totalEnergy] if options.currentlySolvingWithDAE and options.solveTankVolumeContraintWithDAE: temperature = state[self.states_temperature] else: def tempFn(temperature): return self.derivePropellantVolume( totalMass, totalEnergy, temperature) - assumptions.tankVolume.get() try: if options.rootFindingType == "bisect": temperature = scipy.optimize.bisect(tempFn, 183, 309) if options.rootFindingType == "brentq": temperature = scipy.optimize.brentq(tempFn, 183, 309) if options.rootFindingType == "toms748": temperature = scipy.optimize.toms748(tempFn, 183, 309, k=2) if options.rootFindingType == "newton": temperature = scipy.optimize.newton(tempFn, 293) except: temperature = 183 volume = self.derivePropellantVolume(totalMass, totalEnergy, temperature) pressure = CP.PropsSI('P', 'T', temperature, 'Q', 0, 'N2O') vaporQuality = self.deriveVaporQuality(totalMass, totalEnergy, temperature) if vaporQuality < 0: vaporQuality = 0 if vaporQuality > 1: vaporQuality = 1 gasMass = totalMass * vaporQuality liquidMass = totalMass - gasMass gasDensity = gasDensityInterpolator( temperature ) if options.enableTankTemperatureInterpolation else CP.PropsSI( 'D', 'T', temperature, 'Q', 1, 'N2O') liquidDensity = liquidDensityInterpolator( temperature ) if options.enableTankTemperatureInterpolation else CP.PropsSI( 'D', 'T', temperature, 'Q', 0, 'N2O') gasVolume = gasMass / liquidDensity liquidVolume = liquidMass / liquidDensity liquidLevel = liquidVolume / assumptions.tankVolume.get() # outlet is liquid unless vapor quality is 1 # 0 if liquidLevel > bottomFalloff else (1 - max(0, liquidLevel / bottomFalloff)) outletPhase = outletPhaseFalloff(liquidLevel) #top is gas if there is some vapor in the tank # 1 if liquidLevel < (1 - topFalloff) else min(1, (liquidLevel - (1 - topFalloff)) / topFalloff) topPhase = inletPhaseFalloff(liquidLevel) densityOutlet = CP.PropsSI('D', 'T', temperature, 'Q', outletPhase, 'N2O') densityTop = CP.PropsSI('D', 'T', temperature, 'Q', topPhase, 'N2O') hOutlet = CP.PropsSI('H', 'T', temperature, 'Q', outletPhase, 'N2O') hTop = CP.PropsSI('H', 'T', temperature, 'Q', topPhase, 'N2O') # dLiquidWallTemperature_dt = tankWallHeatTransfer() return [ pressure, densityOutlet, densityTop, temperature, hOutlet, hTop, liquidMass, gasMass, vaporQuality, liquidLevel, gasDensity, liquidDensity, gasVolume, liquidVolume, outletPhase, topPhase, volume ]
def query(self, what, **queries): keys = queries.keys() assert len(keys) == 2 return CP.PropsSI(what, keys[0], queries[keys[0]], keys[1], queries[keys[1]], self.fluid)
# de la commande # # recode l1..utf8 monfichier.py # # Il faudra alors modifier la première ligne en # coding: utf8 # pour que Python s'y retrouve. """ Fabrication d'un diagramme (T,s) avec les iso-choses adéquates. """ import numpy as np # Les outils mathématiques import CoolProp.CoolProp as CP # Les outils thermodynamiques import CoolProp.Plots as CPP # Les outils thermographiques import matplotlib.pyplot as plt # Les outils graphiques print(CP.FluidsList()) # Pour regarder les fluides disponibles fluide = 'Water' # Le choix du fluide iso_P = True # Veut-on des isobares ? iso_x = True # et les isotitres ? iso_h = True # et les isenthalpiques ? iso_v = True # et les isochores ? Ttriple = CP.PropsSI(fluide, 'Ttriple') # Valeur de la température au point triple Tcrit = CP.PropsSI(fluide, 'Tcrit') # et au point critique # Données pour les isotitres val_x = np.linspace(0.1, 0.9, 9) # Les valeurs des isotitres # Données pour les isenthalpiques dh = 100e3
def set_axis_limits(self, limits, units='kSI'): # convert limits to SI units for internal use limits[0:2] = CP.toSI(self.graph_type[1], limits[0:2], units) limits[2:] = CP.toSI(self.graph_type[0], limits[2:], units) self.axis.set_xlim([limits[0], limits[1]]) self.axis.set_ylim([limits[2], limits[3]])
'depth', 'd', 'm_dot', 'rho', 'mu', # inputs 'dp_grav', 'dp_fric', 'f' ] # results df = pd.DataFrame(columns=attributes) # perform parameter sweep for m_dot in m_dots: for p in pressures: # fluid properties, inputs are degrees K and Pa rho = CP.PropsSI('D', 'T', T, 'P', p * 1e6, "Air.mix") # density [kg/m3] mu = CP.PropsSI('V', 'T', T, 'P', p * 1e6, "Air.mix") # viscosity [Pa*s] # pressure drop dp_grav = pipe_grav_dp(m_dot=m_dot, rho=rho, z=depth) dp_fric, f = pipe_fric_dp(epsilon=epsilon, d=d, depth=depth, m_dot=m_dot, rho=rho, mu=mu) # save results s = pd.Series(index=attributes) s['T'] = T
def computeDerivatives(self, t, state, derived, models): from models.tank import TankModel from models.nozzle import NozzleModel from models.injector import InjectorModel from models.combustion import CombustionModel from models.passiveVent import PassiveVentModel from models.environment import EnvironmentModel from models.flight import FlightModel massFlowTop = models["passiveVent"]["derived"][ PassiveVentModel.derived_massFlow] massFlowOutlet = models["injector"]["derived"][ InjectorModel.derived_massFlow] hOutlet = derived[self.derived_hOutlet] hTop = derived[self.derived_hTop] massFlow = -massFlowTop - massFlowOutlet gasDensity = derived[self.derived_gasDensity] liquidDensity = derived[self.derived_liquidDensity] temperature = derived[self.derived_temperature] pressure = derived[self.derived_pressure] liquidLevel = derived[self.derived_liquidLevel] airThermalConductivity = models["environment"]["derived"][ EnvironmentModel.derived_ambientThermalConductivity] airPressure = models["environment"]["derived"][ EnvironmentModel.derived_ambientPressure] airTemperature = models["environment"]["derived"][ EnvironmentModel.derived_stagnationTemperature] airViscosity = models["environment"]["derived"][ EnvironmentModel.derived_ambientViscosity] airDensity = models["environment"]["derived"][ EnvironmentModel.derived_ambientDensity] airCp = CP.PropsSI('CPMASS', 'T', airTemperature, 'P', airPressure, 'air') gasThermalConductivity = gasThermalConductivityInterpolator( temperature) gasCp = CP.PropsSI('CPMASS', 'T', temperature, 'Q', 1, 'N2O') gasViscosity = gasViscosityInterpolator(temperature) liquidThermalConductivity = liquidThermalConductivityInterpolator( temperature) liquidCp = CP.PropsSI('CPMASS', 'T', temperature, 'Q', 0, 'N2O') liquidViscosity = liquidViscosityInterpolator(temperature) gasWallHeight = (1 - liquidLevel) * assumptions.tankLength.get() liquidWallHeight = liquidLevel * assumptions.tankLength.get() gasWallTemperature = state[self.states_gasWallTankTemperature] liquidWallTemperature = state[self.states_liquidWallTankTemperature] # Using isobaric_expansion_coefficient resulted in results that is closest to the ideal gas assumption 1 / temperature. # Using isentropic_expansion_coefficient lead to results that were far off... gasVolumetricThermalExpansionCoefficient = CP.PropsSI( "isobaric_expansion_coefficient", "T", temperature, "Q", 1, "N2O") liquidVolumetricThermalExpansionCoefficient = CP.PropsSI( "isobaric_expansion_coefficient", "T", temperature, "Q", 0, "N2O") airVolumetricThermalExpansionCoefficient = CP.PropsSI( "isobaric_expansion_coefficient", "T", temperature, "P", pressure, "air") g = models["flight"]["derived"][FlightModel.derived_perceivedGravity] energyFlowIntoGasPhaseFromTank = tankTransfer.tankWallHeatTransfer( gasVolumetricThermalExpansionCoefficient, gasThermalConductivity, gasCp, gasViscosity, gasDensity, g, temperature, gasWallTemperature, gasWallHeight, assumptions.tankInsideRadius.get(), 2 / 5, 0.021) energyFlowIntoGasPartOfTankFromAmbient = tankTransfer.tankWallHeatTransfer( airVolumetricThermalExpansionCoefficient, airThermalConductivity, airCp, airViscosity, airDensity, g, gasWallTemperature, airTemperature, gasWallHeight, assumptions.tankInsideRadius.get(), 1 / 4, 0.59) energyFlowIntoLiquidPhaseFromTank = tankTransfer.tankWallHeatTransfer( liquidVolumetricThermalExpansionCoefficient, liquidThermalConductivity, liquidCp, liquidViscosity, liquidDensity, g, temperature, liquidWallTemperature, liquidWallHeight, assumptions.tankInsideRadius.get(), 2 / 5, 0.021) energyFlowIntoLiquidPartOfTankFromAmbient = tankTransfer.tankWallHeatTransfer( airVolumetricThermalExpansionCoefficient, airThermalConductivity, airCp, airViscosity, airDensity, g, liquidWallTemperature, airTemperature, liquidWallHeight, assumptions.tankInsideRadius.get(), 1 / 4, 0.59) energyFlowIntoGasPartOfTankFromLiquidPartOfTank = tankTransfer.tankWallHeatConduction( assumptions.tankWallThermalConductivity.get(), assumptions.tankInsideRadius.get(), assumptions.tankInsideRadius.get() + assumptions.tankThickness.get(), gasWallTemperature, liquidWallTemperature, assumptions.tankLength.get(), liquidWallHeight) massPerLength = tankTransfer.massPerLength( assumptions.tankInsideRadius.get(), assumptions.tankInsideRadius.get() + assumptions.tankThickness.get(), assumptions.tankWallDensity.get()) gasPartOfTankMass = gasWallHeight * massPerLength liquidPartOfTankMass = liquidWallHeight * massPerLength # Replace with DAE liquidLevelChangeDerivative = tankTransfer.estimate_liquidLevelChangeDerivative( -massFlow, liquidDensity, assumptions.tankInsideRadius.get()) boundaryTransferFromLiquidToGasPartOfTank = tankTransfer.tankWallControlVolumeBoundaryTransfer( assumptions.tankInsideRadius.get(), assumptions.tankThickness.get() + assumptions.tankInsideRadius.get(), assumptions.tankWallDensity.get(), liquidLevelChangeDerivative, assumptions.tankWallSpecificHeatCapacity.get(), gasWallTemperature, liquidWallTemperature) tankHeatCapacity = assumptions.tankWallSpecificHeatCapacity.get() dGasWallTemperature_dt = 1 / (gasPartOfTankMass * tankHeatCapacity) * ( -energyFlowIntoGasPhaseFromTank + energyFlowIntoGasPartOfTankFromAmbient + energyFlowIntoGasPartOfTankFromLiquidPartOfTank - boundaryTransferFromLiquidToGasPartOfTank ) if gasPartOfTankMass > 1e-6 else 0 dLiquidWallTemperature_dt = 1 / ( liquidPartOfTankMass * tankHeatCapacity) * ( -energyFlowIntoLiquidPhaseFromTank + energyFlowIntoLiquidPartOfTankFromAmbient - energyFlowIntoGasPartOfTankFromLiquidPartOfTank + boundaryTransferFromLiquidToGasPartOfTank ) if liquidPartOfTankMass > 1e-6 else 0 energyFlow = -massFlowOutlet * hOutlet - massFlowTop * hTop + energyFlowIntoGasPhaseFromTank + energyFlowIntoLiquidPhaseFromTank printMessages = False if printMessages: print("") print("t = {:.2f} s".format(t)) print("masses:") print(" {:45s} = {:8.2f} kg".format("gas", derived[self.derived_gasMass])) print(" {:45s} = {:8.2f} kg".format( "liquid", derived[self.derived_liquidMass])) print(" {:45s} = {:8.2f} kg".format("tank (gas part)", gasPartOfTankMass)) print(" {:45s} = {:8.2f} kg".format("tank (liquid part)", liquidPartOfTankMass)) print("energy:") print(" {:45s} = {:8.2f} kJ".format( "oxidizer (total)", state[self.states_totalEnergy] / 1e3)) print(" {:45s} = {:8.2f} kJ".format( "tank (gas part)", state[self.states_gasWallTankTemperature] * gasPartOfTankMass * tankHeatCapacity / 1e3)) print(" {:45s} = {:8.2f} kJ".format( "tank (liquid part)", state[self.states_liquidWallTankTemperature] * liquidPartOfTankMass * tankHeatCapacity / 1e3)) print("heat capacity:") print(" {:45s} = {:8.2f} kJ/K".format( "gas", derived[self.derived_gasMass] * gasCp / 1e3)) print(" {:45s} = {:8.2f} kJ/K".format( "liquid", derived[self.derived_liquidMass] * liquidCp / 1e3)) print(" {:45s} = {:8.2f} kJ/K".format( "tank (gas part)", gasPartOfTankMass * tankHeatCapacity / 1e3)) print(" {:45s} = {:8.2f} kJ/K".format( "tank (liquid part)", liquidPartOfTankMass * tankHeatCapacity / 1e3)) print("heat flux:") print(" {:45s} = {:8.2f} kW".format( "tank (gas part) -> gas", energyFlowIntoGasPhaseFromTank / 1e3)) print(" {:45s} = {:8.2f} kW".format( "ambient -> tank (gas part)", energyFlowIntoGasPartOfTankFromAmbient / 1e3)) print(" {:45s} = {:8.2f} kW".format( "tank (liquid part) -> liquid", energyFlowIntoLiquidPhaseFromTank / 1e3)) print(" {:45s} = {:8.2f} kW".format( "ambient -> tank (liquid part)", energyFlowIntoLiquidPartOfTankFromAmbient / 1e3)) print(" {:45s} = {:8.2f} kW".format( "tank (liquid part) -> tank (gas part)", energyFlowIntoGasPartOfTankFromLiquidPartOfTank / 1e3)) print(" {:45s} = {:8.2f} kW".format( "energy leaving oxidizer through top", -massFlowTop * hTop / 1e3)) print(" {:45s} = {:8.2f} kW".format( "energy leaving oxidizer through bottom", -massFlowOutlet * hOutlet / 1e3)) volumeConstraint = 0 if options.currentlySolvingWithDAE and options.solveTankVolumeContraintWithDAE: volumeConstraint = derived[ self.derived_volume] - assumptions.tankVolume.get() return [ massFlow, energyFlow, dGasWallTemperature_dt, dLiquidWallTemperature_dt, volumeConstraint ]
#ax1 = fig.add_axes((0.175,0.575,0.575,0.375)) #ax2 = fig.add_axes((0.175,0.075,0.575,0.375)) #cbar_ax = fig.add_axes([0.80, 0.075, 0.05, 0.875]) #ax1 = fig.add_subplot(241,colspan=3) #ax2 = fig.add_subplot(245,colspan=3) #cbar_ax = fig.add_subplot(244,rowspan=2) ax1 = plt.subplot2grid((2,8), (0,0), colspan=7) ax2 = plt.subplot2grid((2,8), (1,0), colspan=7) cbar_ax = plt.subplot2grid((2,8), (0,7), colspan=1, rowspan=2) #Ref = 'R245fa' #Ref = 'Isopentane' Ref = 'Air' T = np.linspace(CP.PropsSI(Ref,'Tmin')+0.1,CP.PropsSI(Ref,'Tcrit')-0.01,300) pV = CP.PropsSI('P','T',T,'Q',1,Ref) hL = CP.PropsSI('H','T',T,'Q',0,Ref) hV = CP.PropsSI('H','T',T,'Q',1,Ref) hTP= np.append(hL,[hV[::-1]]) pTP= np.append(pV,[pV[::-1]]) HHH1, PPP1, EEE1 = [], [], [] HHH2, PPP2, EEE2 = [], [], [] cNorm = colors.LogNorm(vmin=1e-10, vmax=1e-1) scalarMap = cmx.ScalarMappable(norm = cNorm, cmap = plt.get_cmap(colourmap)) # Setting the limits for enthalpy and pressure p_min = CP.PropsSI(Ref,'ptriple') p_max = 60e5
Changelog: 11/2017 - Integration of CoolProp 06/2018 - Update to OpenFOAM-5.x (Mass-based thermodynamics (for example: cpMcv to CpMCv)) 03/2019 - Update to include orthohydrogen extrapolated thermal conductivity 10/2019 - Update to Python 3 (for example: print p to print(p) ) """ import CoolProp.CoolProp as CP import numpy as np import matplotlib.pyplot as plt #Fluid for thermodynamic properties (rho, Cp, CpMcv, H, E, S, c, thermal conductivity) #Custom refernce state for orthohydrogen to capture enthalpy offset of orthohydrogen CP.set_reference_state('orthohydrogen', 20.3800689304, 35150.6373702, 1417.12332, 0.036828) fluid_thermo = 'orthohydrogen' #Fluid for transport model (viscosity) fluid_transport = 'hydrogen' #**************************************************************************************** #Temperature limits T0 = 30 #Temperature start (K) TMax = 32 #Temperature end (K) #Pressure limits p0 = 1e5 #Pa pMax = 1.7e6 #Pa
#axPH.set_title("p-h Diagram for : " + fluid) #axPH.set_yscale("log") #axPH.set_xlabel("Enthalpy (kJ/kg)") #axPH.set_ylabel('log(P/Pa)') #axTS.plot(plt_sfg,plt_TT,'k') # #axTS.set_title("T-s Diagram for : " + fluid) #axTS.set_xlabel("Specific entropy (kJ/(K.kg))") #axTS.set_ylabel('Temperature (deg. C)') # Plot cycle states ##curve between state 2,3 exp_Pr = np.linspace(states[1].p, states[2].p, 1000).tolist() exp_Hr = np.linspace(states[1].h, states[2].h, 1000) exp_Tr = (CP.PropsSI('T', 'P', exp_Pr, 'H', exp_Hr, fluid) - 273.15).tolist() exp_Sr = (CP.PropsSI('S', 'P', exp_Pr, 'H', exp_Hr, fluid) / 1000).tolist() exp_Hr = (exp_Hr / 1000).tolist() exp_plt_hc = [states[i].h / 1000.0 for i in range(4)] exp_plt_pc = [states[i].p for i in range(4)] exp_plt_sc = [states[i].s / 1000.0 for i in range(4)] exp_plt_tc = [(states[i].t - 273.15) for i in range(4)] exp_plt_hc[2:2] = exp_Hr exp_plt_pc[2:2] = exp_Pr exp_plt_tc[2:2] = exp_Tr exp_plt_sc[2:2] = exp_Sr exp_plt_hc.append(states[0].h / 1000.0) exp_plt_pc.append(states[0].p) exp_plt_sc.append(states[0].s / 1000.0)