def calculable(self): """Check in the class is fully defined""" # Check mix state self._multicomponent = False if len(self.kwargs["ids"]) > 1: self._multicomponent = True # Check supported fluid COOLPROP_available = True for id in self.kwargs["ids"]: if id not in __all__ and id not in noIds: COOLPROP_available = False if not COOLPROP_available: raise(ValueError) # Check correct fluid definition if self._multicomponent: if self.kwargs["ids"] and len(self.kwargs["fraccionMolar"]) == \ len(self.kwargs["ids"]): self._definition = True else: self._definition = False elif self.kwargs["ids"]: self._definition = True else: self._definition = False # Update the kwargs with the special coolprop namespace if self.kwargs["x"] != CoolProp.kwargs["x"]: self.kwargs["Q"] = self.kwargs["x"] if self.kwargs["v"] != CoolProp.kwargs["v"]: self.kwargs["Dmass"] = 1/self.kwargs["v"] if self.kwargs["rho"] != CoolProp.kwargs["rho"]: self.kwargs["Dmass"] = self.kwargs["rho"] if self.kwargs["s"] != CoolProp.kwargs["s"]: self.kwargs["Smass"] = self.kwargs["s"] if self.kwargs["h"] != CoolProp.kwargs["h"]: self.kwargs["Hmass"] = self.kwargs["h"] if self.kwargs["u"] != CoolProp.kwargs["u"]: self.kwargs["Umass"] = self.kwargs["u"] # Check thermo definition self._thermo = "" for def_ in ["P-T", "Q-T", "P-Q", "Dmass-T", "Dmass-P", "Hmass-P", "P-Smass", "Hmass-Smass", "Hmass-T", "T-Umass", "P-Umass", "Dmass-Hmass", "Dmass-Smass", "Dmass-Umass", "Hmass-Umass", "Smass-Umass"]: inputs = def_.split("-") if self.kwargs[inputs[0]] != CoolProp.kwargs[inputs[0]] and \ self.kwargs[inputs[1]] != CoolProp.kwargs[inputs[1]]: self._thermo = def_.replace("-", "") self._inputs = inputs self._par = CP.__getattribute__("%s_INPUTS" % self._thermo) break return self._definition and self._thermo
s_before_condenser = PropsSI('S', 'T', ihe_condenser.T.val + 273.15, 'P', ihe_condenser.p.val * 100000, working_fluid) T_before_condenser = ihe_condenser.T.val s_after_condenser = PropsSI('S', 'T', condenser_pump.T.val + 273.15, 'Q', 0, working_fluid) T_after_condenser = condenser_pump.T.val s_after_pump = PropsSI('S', 'T', pump_ihe.T.val + 273.15, 'P', pump_ihe.p.val * 100000, working_fluid) T_after_pump = pump_ihe.T.val s_after_ihe = PropsSI('S', 'T', ihe_wf_out.T.val + 273.15, 'P', ihe_wf_out.p.val * 100000, working_fluid) T_after_ihe = ihe_wf_out.T.val s_after_preheater = PropsSI('S', 'T', preheater_evaporator.T.val + 273.15, 'P', preheater_evaporator.p.val * 100000, working_fluid) T_after_preheater = preheater_evaporator.T.val state = CP.AbstractState('HEOS', working_fluid) T_crit = state.trivial_keyed_output(CP.iT_critical) df = pd.DataFrame(columns=['s_l', 's_g', 's_iso_P0', 's_iso_P1', 's_iso_P_top', 's_iso_P_bottom']) P0 = condenser_pump.p.val * 100000 P1 = p_before_turbine * 100000 T_range = np.geomspace(273.15, T_crit, 1000) for T in T_range: df.loc[T, 's_l'] = PropsSI('S', 'T', T, 'Q', 0, working_fluid) df.loc[T, 's_g'] = PropsSI('S', 'T', T, 'Q', 1, working_fluid) df.loc[T, 's_iso_P0'] = PropsSI('S', 'T', T, 'P', P0, working_fluid) df.loc[T, 's_iso_P1'] = PropsSI('S', 'T', T, 'P', P1, working_fluid) T_range_evaporator = np.geomspace(preheater_evaporator.T.val + 273.15, evaporator_turbine.T.val + 273.15+0.1, 100) for T in T_range_evaporator: df.loc[T, 's_iso_P_top'] = PropsSI('S', 'T', T, 'P', P1, working_fluid)
def Calculate(self): """ Calculate the PHE For now, only evaporation against glycol is possible Cold: Ref Hot: Glycol """ #AbstractState if hasattr(self,'Backend_c'): #check if backend is given AS_c = CP.AbstractState(self.Backend_c, self.Ref_c) if hasattr(self,'MassFrac_c'): AS_c.set_mass_fractions([self.MassFrac_c]) elif hasattr(self, 'VoluFrac_c'): AS_c.set_volu_fractions([self.VoluFrac_c]) else: #otherwise, use the defualt backend AS_c = CP.AbstractState('HEOS', self.Ref_c) self.AS_c =AS_c if hasattr(self,'Backend_h'): #check if backend is given AS_h = CP.AbstractState(self.Backend_h, self.Ref_h) if hasattr(self,'MassFrac_h'): AS_h.set_mass_fractions([self.MassFrac_h]) elif hasattr(self, 'VoluFrac_h'): AS_h.set_volu_fractions([self.VoluFrac_h]) else: #otherwise, use the defualt backend AS_h = CP.AbstractState('HEOS', self.Ref_h) self.AS_h =AS_h # Allocate channels between hot and cold streams if not hasattr(self,'MoreChannels') or self.MoreChannels not in ['Hot','Cold']: raise KeyError("MoreChannels not found, options are 'Hot' or 'Cold'") #There are (Nplates - 1) gaps between the plates if self.MoreChannels=='Hot': #Hot stream gets the extra channel self.NgapsHot=(self.Nplates-1)//2+1 self.NgapsCold=self.Nplates-1-self.NgapsHot else: #Cold stream gets the extra channel self.NgapsCold=(self.Nplates-1)//2+1 self.NgapsHot=self.Nplates-1-self.NgapsCold #Saturation temperatures for cold fluid if 'IncompressibleBackend' in AS_c.backend_name(): self.rhosatL_c= None self.rhosatV_c= None self.Tbubble_c = None self.Tdew_c = None self.Tsat_c = None else: AS_c.update(CP.PQ_INPUTS, self.pin_c, 0.0) self.Tbubble_c=AS_c.T() #[K] self.rhosatL_c=AS_c.rhomass() #[kg/m^3] AS_c.update(CP.PQ_INPUTS, self.pin_c, 1.0) self.Tdew_c=AS_c.T() #[K] self.rhosatV_c=AS_c.rhomass() #[kg/m^3] self.Tsat_c=(self.Tbubble_c+self.Tdew_c)/2.0 if 'IncompressibleBackend' in AS_h.backend_name(): self.Tbubble_h=None self.Tdew_h=None self.Tsat_h=None self.rhosatL_h=None self.rhosatV_h=None else: #Saturation temperatures for hot fluid AS_h.update(CP.PQ_INPUTS, self.pin_h, 0.0) self.Tbubble_h=AS_h.T() #[K] self.rhosatL_h=AS_h.rhomass() #[kg/m^3] AS_h.update(CP.PQ_INPUTS, self.pin_h, 1.0) self.Tdew_h=AS_h.T() #[K] self.rhosatV_h=AS_h.rhomass() #[kg/m^3] self.Tsat_h=(self.Tbubble_h+self.Tdew_h)/2.0 #The rest of the inlet states self.Tin_h,self.rhoin_h=TrhoPhase_ph(self.AS_h,self.pin_h,self.hin_h,self.Tbubble_h,self.Tdew_h,self.rhosatL_h,self.rhosatV_h)[0:2] self.Tin_c,self.rhoin_c=TrhoPhase_ph(self.AS_c,self.pin_c,self.hin_c,self.Tbubble_c,self.Tdew_c,self.rhosatL_c,self.rhosatV_c)[0:2] if 'IncompressibleBackend' in AS_c.backend_name(): AS_c.update(CP.PT_INPUTS, self.pin_c, self.Tin_c) self.sin_c=AS_c.smass() #[J/kg-K] else: AS_c.update(CP.DmassT_INPUTS, self.rhoin_c,self.Tin_c) self.sin_c=AS_c.smass() #[J/kg-K] if 'IncompressibleBackend' in AS_h.backend_name(): AS_h.update(CP.PT_INPUTS, self.pin_h, self.Tin_h) self.sin_h=AS_h.smass() #[J/kg-K] else: AS_h.update(CP.DmassT_INPUTS, self.rhoin_h, self.Tin_h) self.sin_h=AS_h.smass() #[J/kg-K] # Find HT and Delta P on the hot side #--------------- #Mean values for the hot side based on average of inlet temperatures HotPlateInputs={ 'PlateAmplitude': self.PlateAmplitude, 'PlateWavelength' : self.PlateWavelength, 'InclinationAngle': self.InclinationAngle, 'Bp': self.Bp, 'Lp': self.Lp } HotPlateOutputs=PHE_1phase_hdP(HotPlateInputs,JustGeo=True) #There are (Nplates-2) active plates (outer ones don't do anything) self.A_h_wetted=HotPlateOutputs['Ap']*(self.Nplates-2) self.V_h=HotPlateOutputs['Vchannel']*self.NgapsHot self.A_h_flow=HotPlateOutputs['Aflow']*self.NgapsHot self.Dh_h=HotPlateOutputs['Dh'] # Find geometric parameters for cold side of plates ColdPlateInputs={ 'PlateAmplitude': self.PlateAmplitude, 'PlateWavelength' : self.PlateWavelength, 'InclinationAngle': self.InclinationAngle, 'Bp': self.Bp, 'Lp': self.Lp } ColdPlateOutputs=PHE_1phase_hdP(ColdPlateInputs,JustGeo=True) #There are (Nplates-2) active plates (outer ones don't do anything) self.A_c_wetted=ColdPlateOutputs['Ap']*(self.Nplates-2) self.V_c=ColdPlateOutputs['Vchannel']*self.NgapsCold self.A_c_flow=ColdPlateOutputs['Aflow']*self.NgapsCold self.Dh_c=ColdPlateOutputs['Dh'] #Figure out the limiting rate of heat transfer self.Qmax=self.DetermineHTBounds() def GivenQ(Q): """ In this function, the heat transfer rate is imposed. Therefore the outlet states for both fluids are known, and each element can be solved analytically in one shot without any iteration. """ EnthalpyList_c,EnthalpyList_h=self.BuildEnthalpyLists(Q) # #Plot temperature versus enthalpy profiles # for i in range(len(EnthalpyList_c)-1): # hc=np.linspace(EnthalpyList_c[i],EnthalpyList_c[i+1]) # Tc=np.zeros_like(hc) # for j in range(len(hc)): # Tc[j],r,Ph=TrhoPhase_ph(self.Ref_c,self.pin_c,hc[j],self.Tbubble_c,self.Tdew_c,self.rhosatL_c,self.rhosatV_c) # pylab.plot(self.mdot_c*(hc-EnthalpyList_c[0])/1000,Tc,'b') # # for i in range(len(EnthalpyList_h)-1): # hh=np.linspace(EnthalpyList_h[i],EnthalpyList_h[i+1]) # Th=np.zeros_like(hh) # for j in range(len(hh)): # Th[j],r,Ph=TrhoPhase_ph(self.Ref_h,self.pin_h,hh[j],self.Tbubble_h,self.Tdew_h,self.rhosatL_h,self.rhosatV_h) # pylab.plot(self.mdot_h*(hh-EnthalpyList_h[0])/1000,Th,'r') # pylab.show() # Ph(self.Ref_h) # pylab.plot(np.array(EnthalpyList_h)/1000,self.pin_h/1000*np.ones_like(EnthalpyList_h)) # pylab.show() I_h=0 I_c=0 wList=[] cellList=[] while I_h<len(EnthalpyList_h)-1: #Try to figure out whether the next phase transition is on the hot or cold side Qbound_h=self.mdot_h*(EnthalpyList_h[I_h+1]-EnthalpyList_h[I_h]) Qbound_c=self.mdot_c*(EnthalpyList_c[I_c+1]-EnthalpyList_c[I_c]) if Qbound_h<Qbound_c-1e-9: # Minimum amount of heat transfer is on the hot side, # add another entry to EnthalpyList_c Qbound=Qbound_h EnthalpyList_c.insert(I_c+1, EnthalpyList_c[I_c]+Qbound/self.mdot_c) elif Qbound_h>Qbound_c+1e-9: # Minimum amount of heat transfer is on the cold side, # add another entry to EnthalpyList_h at the interface Qbound=Qbound_c EnthalpyList_h.insert(I_h+1, EnthalpyList_h[I_h]+Qbound/self.mdot_h) else: Qbound=Qbound_h #Figure out the inlet and outlet enthalpy for this cell hout_h=EnthalpyList_h[I_h] hin_h=hout_h+Qbound/self.mdot_h hin_c=EnthalpyList_c[I_c] hout_c=hin_c+Qbound/self.mdot_c # Figure out what combination of phases you have: # ------------------------------------------------- # Hot stream is either single phase or condensing (two phase) # Cold stream is either single phase or evaporating (two phase) #Use midpoint enthalpies to figure out the phase in the cell Phase_h=Phase_ph(self.AS_h,self.pin_h,(hin_h+hout_h)/2,self.Tbubble_h,self.Tdew_h,self.rhosatL_h,self.rhosatV_h) Phase_c=Phase_ph(self.AS_c,self.pin_c,(hin_c+hout_c)/2,self.Tbubble_c,self.Tdew_c,self.rhosatL_c,self.rhosatV_c) #Determine inlet and outlet temperatures to the cell ([0] gives the first element of the tuple which is temeperature) Tin_h=TrhoPhase_ph(self.AS_h,self.pin_h,hin_h,self.Tbubble_h,self.Tdew_h,self.rhosatL_h,self.rhosatV_h)[0] Tin_c=TrhoPhase_ph(self.AS_c,self.pin_c,hin_c,self.Tbubble_c,self.Tdew_c,self.rhosatL_c,self.rhosatV_c)[0] Tout_h=TrhoPhase_ph(self.AS_h,self.pin_h,hout_h,self.Tbubble_h,self.Tdew_h,self.rhosatL_h,self.rhosatV_h)[0] Tout_c=TrhoPhase_ph(self.AS_c,self.pin_c,hout_c,self.Tbubble_c,self.Tdew_c,self.rhosatL_c,self.rhosatV_c)[0] if Phase_h in ['Subcooled','Superheated'] and Phase_c in ['Subcooled','Superheated']: # Both are single-phase Inputs={ 'Q':Qbound, 'cp_h':(hin_h-hout_h)/(Tin_h-Tout_h), 'cp_c':(hin_c-hout_c)/(Tin_c-Tout_c), 'Tmean_h':(Tin_h+Tout_h)/2, 'Tmean_c':(Tin_c+Tout_c)/2, 'Tin_h':Tin_h, 'Tin_c':Tin_c, 'pin_h':self.pin_h, 'pin_c':self.pin_c, 'Phase_c':Phase_c, 'Phase_h':Phase_h } Outputs=self._OnePhaseH_OnePhaseC_Qimposed(Inputs) wList.append(Outputs['w']) cellList.append(Outputs) if self.Verbosity>6: print('w[1-1]: ', Outputs['w']) elif Phase_h=='TwoPhase' and Phase_c in ['Subcooled','Superheated']: # Hot stream is condensing, and cold stream is single-phase (SH or SC) # TODO: bounding state can be saturated state if hot stream is condensing #Must be two-phase so quality is defined xin_h=(hin_h-self.hsatL_h)/(self.hsatV_h-self.hsatL_h) xout_h=(hout_h-self.hsatL_h)/(self.hsatV_h-self.hsatL_h) Inputs={ 'Q':Qbound, 'xin_h':xin_h, 'xout_h':xout_h, 'Tsat_h':self.Tsat_h, 'Tmean_c':(Tin_c+Tout_c)/2, 'cp_c':(hin_c-hout_c)/(Tin_c-Tout_c), 'Tin_c':Tin_c, 'pin_h':self.pin_h, 'pin_c':self.pin_c, 'Phase_c':Phase_c, 'Phase_h':Phase_h } Outputs=self._TwoPhaseH_OnePhaseC_Qimposed(Inputs) if self.Verbosity>6: print('w[2-1]: ', Outputs['w']) wList.append(Outputs['w']) cellList.append(Outputs) elif Phase_c=='TwoPhase' and Phase_h in ['Subcooled','Superheated']: # Cold stream is evaporating, and hot stream is single-phase (SH or SC) #Must be two-phase so quality is defined xin_c=(hin_c-self.hsatL_c)/(self.hsatV_c-self.hsatL_c) xout_c=(hout_c-self.hsatL_c)/(self.hsatV_c-self.hsatL_c) Inputs={ 'Q':Qbound, 'xin_c':xin_c, 'xout_c':xout_c, 'Tsat_c':self.Tsat_c, 'cp_h':(hin_h-hout_h)/(Tin_h-Tout_h), 'Tmean_h':(Tin_h+Tout_h)/2, 'Tin_h':Tin_h, 'pin_h':self.pin_h, 'pin_c':self.pin_c, 'Phase_c':Phase_c, 'Phase_h':Phase_h } Outputs=self._OnePhaseH_TwoPhaseC_Qimposed(Inputs) if self.Verbosity>6: print('w[1-2]: ', Outputs['w']) wList.append(Outputs['w']) cellList.append(Outputs) I_h+=1 I_c+=1 self.cellList=cellList if self.Verbosity>6: print('wsum:', np.sum(wList)) return np.sum(wList)-1.0 try: brentq(GivenQ,0.0000001*self.Qmax,0.999999999*self.Qmax,xtol=0.000001*self.Qmax)#,xtol=0.000001*self.Qmax) is commented except ValueError: print(GivenQ(0.0000001*self.Qmax),GivenQ(0.999999999*self.Qmax)) raise # Collect parameters from all the pieces self.PostProcess(self.cellList)
import CoolProp import pandas grouping = dict() grouping2 = [] # Group aliases for parameter in CoolProp.get('parameter_list').split(','): index = CoolProp.CoolProp.get_parameter_index(parameter) units = CoolProp.CoolProp.get_parameter_information(index, 'units').replace('-',' ') IO = CoolProp.CoolProp.get_parameter_information(index, 'IO') long = CoolProp.CoolProp.get_parameter_information(index, 'long') short = CoolProp.CoolProp.get_parameter_information(index, 'short') RHS = (units, IO, long) if RHS not in grouping: grouping[RHS] = [parameter] else: grouping[RHS].append(parameter) for k, v in grouping.iteritems(): grouping2.append([', '.join(['``'+_+'``' for _ in v])] + list(k)) headers = ['Parameter','Units','Input/Output','Description'] df3 = pandas.DataFrame(grouping2, columns = headers) df4 = df3.sort_index(by = ['Input/Output', 'Parameter']) grouping2 = [row for row in df4.values] N = [] for i in range(len(grouping2[0])): N.append(max([len(el[i]) for el in grouping2]))
embedsignature = True), cython_c_in_temp=True ) ) package_data = package_pxd_files setup( name = 'PDSim', version = version, author = "Ian Bell", author_email='*****@*****.**', url='http://pdsim.sourceforge.net', description = """A flexible open-source framework for the quasi-steady-state simulation of positive displacement machines including compressors and expanders""", packages = ['PDSim','PDSim.core','PDSim.flow','PDSim.plot','PDSim.scroll','PDSim.misc','PDSim.recip','PDSim.misc.clipper'], cmdclass={'build_ext': build_ext}, ext_modules = ext_module_list, package_dir = {'PDSim':'PDSim',}, package_data = package_data, include_dirs = [numpy.get_include(), CoolProp.get_include_directory(), "PDSim/misc/clipper"], ) try: import quantities print('quantities package found, no need to install from source') except ImportError: print('quantities package not found, will install from sources in externals/quantities. Please hold on.') import subprocess subprocess.check_output('python setup.py install', shell = True, cwd=os.path.join('externals','quantities'))
plt.savefig(fn + '_ORC_Ts_plot.png') # plt.show() fluids = [ 'R600', 'R245fa', 'R245CA', 'R11', 'Isopentane', 'n-Pentane', 'R123', 'R141B', 'R113' ] # Isobutane Td_bp_conds = [2, 4, 6, 8, 10] for fluid in fluids: try: # for some testing print('+' * 75) PowerPlantWithIHE = PowerPlant(working_fluid=fluid) print('Working fluid:', fluid) state = CP.AbstractState('HEOS', fluid) T_crit = state.trivial_keyed_output(CP.iT_critical) - 273.15 print('Critical temperature: {} °C'.format(round(T_crit, 4))) # for Td_bp_cond in Td_bp_conds: eff = PowerPlantWithIHE.calculate_efficiency(200, 0.1, 70, 2) if not np.isnan(eff): # PowerPlantWithIHE.generate_diagram() # PowerPlantWithIHE.plot_process(fn=fluid) PowerPlantWithIHE.print_result() PowerPlantWithIHE.plot_Ts(fn=fluid) else: print('+' * 75) print(fluid) print('+' * 75) except: print('+' * 75)
def Calculate(self): #AbstractState if hasattr(self, 'Backend'): #check if backend is given AS = CP.AbstractState(self.Backend, self.Ref) else: #otherwise, use the defualt backend AS = CP.AbstractState('HEOS', self.Ref) self.AS = AS #Check that the length of lists of mdot_r and FinsTubes.Air.Vdot_ha #match the number of circuits or are all equal to 1 (standard evap) Ncircuits = int(self.Fins.Tubes.Ncircuits) # Make Ncircuits copies of evaporator classes defined # by the inputs to the MCE superclass EvapDict = self.__dict__ self.Evaps = [] for i in range(Ncircuits): # Make a deep copy to break all the links between the Fins structs # of each of the evaporator instances ED = copy.deepcopy(EvapDict) #Create new evaporator instanciated with new deep copied dictionary E = EvaporatorClass(**ED) #Add to list of evaporators self.Evaps.append(E) #Upcast single values to lists, and convert numpy arrays to lists self.Fins.Air.Vdot_ha = np.atleast_1d(self.Fins.Air.Vdot_ha).tolist() self.mdot_r = np.atleast_1d(self.mdot_r).tolist() if Ncircuits != len(self.mdot_r) and len(self.mdot_r) > 1: print("Problem with length of vector for mdot_r for MCE") else: if len(self.mdot_r) == 1: #Single value passed in for mdot_r if hasattr(self, 'mdot_r_coeffs'): if len(self.mdot_r_coeffs) != Ncircuits: raise AttributeError("Size of array mdot_r_coeffs: " + str(len(self.mdot_r_coeffs)) + " does not equal Ncircuits: " + str(Ncircuits)) elif abs(np.sum(self.mdot_r_coeffs) - 1) >= 100 * np.finfo(float).eps: raise AttributeError( "mdot_r_coeffs must sum to 1.0. Sum *100000 is: " + str(100000 * np.sum(self.mdot_r_coeffs))) else: # A vector of weighting factors multiplying the total mass flow rate is provided with the right length for i in range(Ncircuits): self.Evaps[i].mdot_r = self.mdot_r[ -1] * self.mdot_r_coeffs[i] else: # Refrigerant flow is evenly distributed between circuits, # give each evaporator an equal portion of the refrigerant for i in range(Ncircuits): self.Evaps[i].mdot_r = self.mdot_r[-1] / Ncircuits else: for i in range(Ncircuits): self.Evaps[i].mdot_r = self.mdot_r[i] # Deal with the possibility that the quality might be varied among circuits if hasattr(self, 'mdot_v_coeffs'): if len(self.mdot_v_coeffs) != Ncircuits: raise AttributeError("Size of array mdot_v_coeffs: " + str(len(self.mdot_v_coeffs)) + " does not equal Ncircuits: " + str(Ncircuits)) elif abs(np.sum(self.mdot_v_coeffs) - 1) >= 10 * np.finfo(float).eps: raise AttributeError( "mdot_v_coeffs must sum to 1.0. Sum is: " + str(np.sum(self.mdot_v_coeffs))) else: AS.update(CP.PQ_INPUTS, self.psat_r, 0.0) hsatL = AS.hmass() #[J/kg] AS.update(CP.PQ_INPUTS, self.psat_r, 1.0) hsatV = AS.hmass() #[J/kg] x_inlet = (self.hin_r - hsatL) / (hsatV - hsatL) mdot_v = x_inlet * sum(self.mdot_r) for i in range(Ncircuits): mdot_v_i = self.mdot_v_coeffs[i] * mdot_v x_i = mdot_v_i / self.Evaps[i].mdot_r AS.update(CP.PQ_INPUTS, self.psat_r, x_i) self.Evaps[i].hin_r = AS.hmass() #[J/kg] #For backwards compatibility, if the coefficients are provided in the FinInputs class, copy them to the base class if hasattr(self.Fins.Air, 'Vdot_ha_coeffs'): self.Vdot_ha_coeffs = self.Fins.Air.Vdot_ha_coeffs print( "Warning: please put the vector Vdot_ha_coeffs in the base MCE class, accesssed as MCE.Vdot_ha_coeffs" ) if Ncircuits != len(self.Fins.Air.Vdot_ha) and len( self.Fins.Air.Vdot_ha) > 1: print("Problem with length of vector for Vdot_ha for MCE") else: if len(self.Fins.Air.Vdot_ha) == 1: if hasattr(self, 'Vdot_ha_coeffs'): if len(self.Vdot_ha_coeffs) != Ncircuits: raise AttributeError("Size of array Vdot_ha_coeffs: " + str(len(self.Vdot_ha_coeffs)) + " does not equal Ncircuits: " + str(Ncircuits)) elif abs(np.sum(self.Vdot_ha_coeffs) - 1) >= 10 * np.finfo(float).eps: raise AttributeError( "Vdot_ha_coeffs does not sum to 1.0! Sum is: " + str(np.sum(self.Vdot_ha_coeffs))) else: # A vector of factors multiplying the total volume flow rate is provided for i in range(Ncircuits): self.Evaps[ i].Fins.Air.Vdot_ha = self.Fins.Air.Vdot_ha[ -1] * self.Vdot_ha_coeffs[i] else: # Air flow is evenly distributed between circuits, # give each circuit an equal portion of the air flow for i in range(Ncircuits): self.Evaps[i].Fins.Air.Vdot_ha = self.Fins.Air.Vdot_ha[ -1] / Ncircuits else: for i in range(Ncircuits): self.Evaps[i].Fins.Air.Vdot_ha = self.Fins.Air.Vdot_ha[i] # Distribute the tubes of the bank among the different circuits # If Tubes per bank is divisible by the number of circuits, all the # circuits have the same number of tubes per bank # The circuits are ordered from fewer to more if they are not evenly distributed NTubes_min = int(floor(self.Fins.Tubes.NTubes_per_bank / Ncircuits)) NTubes_max = int(ceil(self.Fins.Tubes.NTubes_per_bank / Ncircuits)) if NTubes_min == NTubes_max: #If evenly divisible, use the tubes per circuit from the division A = Ncircuits else: # Total number of tubes per bank is given by A = (self.Fins.Tubes.NTubes_per_bank - Ncircuits * NTubes_max) / (NTubes_min - NTubes_max) for i in range(Ncircuits): if i + 1 <= A: self.Evaps[i].Fins.Tubes.NTubes_per_bank = NTubes_min else: self.Evaps[i].Fins.Tubes.NTubes_per_bank = NTubes_max for i in range(Ncircuits): self.Evaps[i].Fins.Tubes.Ncircuits = 1 #Actually run each Evaporator self.Evaps[i].Calculate() #Collect the outputs from each of the evaporators individually #Try to mirror the outputs of each of the evaporators self.Q = np.sum([self.Evaps[i].Q for i in range(Ncircuits)]) self.Charge = np.sum([self.Evaps[i].Charge for i in range(Ncircuits)]) self.Charge_superheat = np.sum( [self.Evaps[i].Charge_superheat for i in range(Ncircuits)]) self.Charge_2phase = np.sum( [self.Evaps[i].Charge_2phase for i in range(Ncircuits)]) self.DP_r = np.mean([self.Evaps[i].DP_r for i in range(Ncircuits)]) #simplified self.DP_r_superheat = np.mean([ self.Evaps[i].DP_r_superheat for i in range(Ncircuits) ]) #simplified self.DP_r_2phase = np.mean( [self.Evaps[i].DP_r_2phase for i in range(Ncircuits)]) #simplified self.Tin_r = np.mean([self.Evaps[i].Tin_r for i in range(Ncircuits)]) #simplified self.h_r_superheat = np.mean([ self.Evaps[i].h_r_superheat for i in range(Ncircuits) ]) #simplified, really should consider flowrate self.h_r_2phase = np.mean([ self.Evaps[i].h_r_2phase for i in range(Ncircuits) ]) #simplified, really should consider flowrate self.w_superheat = np.sum( [self.Evaps[i].w_superheat for i in range(Ncircuits)]) / float(Ncircuits) self.w_2phase = np.sum( [self.Evaps[i].w_2phase for i in range(Ncircuits)]) / float(Ncircuits) self.hout_r = 0.0 for i in range(Ncircuits): self.hout_r += self.Evaps[i].hout_r * self.Evaps[i].mdot_r self.hout_r = (self.hout_r / sum(self.mdot_r)) self.Tin_a = self.Evaps[ 0].Fins.Air.Tdb #assuming equal temperature for all circuits self.Tout_a = 0.0 for i in range(Ncircuits): self.Tout_a += self.Evaps[i].Tout_a * self.Evaps[i].Fins.Air.Vdot_ha self.Tout_a = (self.Tout_a / sum(self.Fins.Air.Vdot_ha)) Pout_r = self.psat_r + self.DP_r / 1.0 AS.update(CP.PQ_INPUTS, Pout_r, 1.0) hsatV_out = AS.hmass() #[J/kg] AS.update(CP.PQ_INPUTS, Pout_r, 0.0) hsatL_out = AS.hmass() #[J/kg] if self.hout_r > hsatV_out: AS.update(CP.HmassP_INPUTS, self.hout_r, Pout_r) self.Tout_r = AS.T() #superheated temperature at outlet [K] else: xout_r = ((self.hout_r - hsatL_out) / (hsatV_out - hsatL_out)) AS.update(CP.PQ_INPUTS, Pout_r, xout_r) self.Tout_r = AS.T() #saturated temperature at outlet quality [K] self.Capacity = np.sum([self.Evaps[i].Q for i in range(Ncircuits) ]) - self.Fins.Air.FanPower self.SHR = np.mean([self.Evaps[i].SHR for i in range(Ncircuits)]) self.UA_a = np.sum([self.Evaps[i].UA_a for i in range(Ncircuits)]) self.UA_r = np.sum([self.Evaps[i].UA_r for i in range(Ncircuits)]) self.Q_superheat = np.sum( [self.Evaps[i].Q_superheat for i in range(Ncircuits)]) self.Q_2phase = np.sum( [self.Evaps[i].Q_2phase for i in range(Ncircuits)]) #Convert back to a single value for the overall evaporator self.Fins.Air.Vdot_ha = float(self.Fins.Air.Vdot_ha[-1]) if self.Verbosity > 0: print(chr(127), end='') #progress bar
matplotlib.use('Agg') # use a non-interactive backend import CoolProp import os.path web_dir = os.path.abspath(os.path.join(os.path.dirname(__file__),'..')) tar_fil = os.path.join(web_dir,'_static','CoolPropLogo.png') tar_fil_long = os.path.join(web_dir,'_static','CoolPropLogoLong.png') import matplotlib import numpy as np import CoolProp as CP import matplotlib.pyplot as plt import scipy.interpolate # Prepare the constants Water = CP.AbstractState("HEOS", "Water") pc = Water.keyed_output(CP.iP_critical) Tc = Water.keyed_output(CP.iT_critical) T_min = 200 T_max = 1000 p_max = Water.keyed_output(CP.iP_max) p_triple = 611.657 T_triple = 273.16 # Prepare the data for the melting line steps = 2000 TT = [] PP = list(np.logspace(np.log10(p_triple), np.log10(p_max),steps)) for p in PP: TT.append(Water.melting_line(CP.iT, CP.iP, p))
import CoolProp 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' 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'))
def calculo(self): fluido = self._name() args = self.args() estado = CP.AbstractState("HEOS", fluido) self.eq = self._limit(fluido, estado) if self._multicomponent: estado.set_mole_fractions(self.kwargs["fraccionMolar"]) estado.update(self._par, *args) self.M = unidades.Dimensionless(estado.molar_mass() * 1000) if self._multicomponent: # Disabled CoolProp critical properties for multicomponent, # see issue #1087 # Calculate critical properties with mezcla method # Coolprop for mixtures can fail and it's slow Cmps = [Componente(int(i)) for i in self.kwargs["ids"]] # Calculate critic temperature, API procedure 4B1.1 pag 304 V = sum([ xi * cmp.Vc for xi, cmp in zip(self.kwargs["fraccionMolar"], Cmps) ]) k = [ xi * cmp.Vc / V for xi, cmp in zip(self.kwargs["fraccionMolar"], Cmps) ] Tcm = sum([ki * cmp.Tc for ki, cmp in zip(k, Cmps)]) self.Tc = unidades.Temperature(Tcm) # Calculate pseudocritic temperature tpc = sum([ x * cmp.Tc for x, cmp in zip(self.kwargs["fraccionMolar"], Cmps) ]) # Calculate pseudocritic pressure ppc = sum([ x * cmp.Pc for x, cmp in zip(self.kwargs["fraccionMolar"], Cmps) ]) # Calculate critic pressure, API procedure 4B2.1 pag 307 sumaw = 0 for xi, cmp in zip(self.kwargs["fraccionMolar"], Cmps): sumaw += xi * cmp.f_acent pc = ppc + ppc * (5.808 + 4.93 * sumaw) * (self.Tc - tpc) / tpc self.Pc = unidades.Pressure(pc) # Calculate critic volume, API procedure 4B3.1 pag 314 sumaxvc23 = sum([ xi * cmp.Vc**(2. / 3) for xi, cmp in zip(self.kwargs["fraccionMolar"], Cmps) ]) k = [ xi * cmp.Vc**(2. / 3) / sumaxvc23 for xi, cmp in zip(self.kwargs["fraccionMolar"], Cmps) ] # TODO: Calculate C value from component type. # For now it suppose all are hidrycarbon (C=0) C = 0 V = [[ -1.4684 * abs((cmpi.Vc - cmpj.Vc) / (cmpi.Vc + cmpj.Vc)) + C for cmpj in Cmps ] for cmpi in Cmps] v = [[ V[i][j] * (cmpi.Vc + cmpj.Vc) / 2. for j, cmpj in enumerate(Cmps) ] for i, cmpi in enumerate(Cmps)] suma1 = sum([ki * cmp.Vc for ki, cmp in zip(k, Cmps)]) suma2 = sum([ ki * kj * v[i][j] for j, kj in enumerate(k) for i, ki in enumerate(k) ]) self.rhoc = unidades.Density((suma1 + suma2) * self.M) else: self.Tc = unidades.Temperature(estado.T_critical()) self.Pc = unidades.Pressure(estado.p_critical()) self.rhoc = unidades.Density(estado.rhomass_critical()) self.R = unidades.SpecificHeat(estado.gas_constant() / self.M) self.Tt = unidades.Temperature(estado.Ttriple()) estado2 = CP.AbstractState("HEOS", fluido) if self._multicomponent: estado2.set_mole_fractions(self.kwargs["fraccionMolar"]) estado2.update(CP.PQ_INPUTS, 101325, 1) self.Tb = unidades.Temperature(estado2.T()) self.f_accent = unidades.Dimensionless(estado.acentric_factor()) # Dipole moment only available for REFPROP backend # self.momentoDipolar(estado.keyed_output(CP.idipole_moment)) self.phase, x = self.getphase(estado) self.x = unidades.Dimensionless(x) if self._multicomponent: string = fluido.replace("&", " (%0.2f), ") string += " (%0.2f)" self.name = string % tuple(self.kwargs["fraccionMolar"]) self.CAS = "" self.synonim = "" self.formula = "" else: self.name = fluido self.CAS = estado.fluid_param_string("CAS") self.synonim = estado.fluid_param_string("aliases") self.formula = estado.fluid_param_string("formula") self.P = unidades.Pressure(estado.p()) self.T = unidades.Temperature(estado.T()) self.Tr = unidades.Dimensionless(self.T / self.Tc) self.Pr = unidades.Dimensionless(self.P / self.Pc) self.rho = unidades.Density(estado.rhomass()) self.v = unidades.SpecificVolume(1. / self.rho) cp0 = self._prop0(estado) self._cp0(cp0) self.Liquido = ThermoAdvanced() self.Gas = ThermoAdvanced() if self.x == 0: # liquid phase self.fill(self.Liquido, estado) self.fill(self, estado) self.fillNone(self.Gas) elif self.x == 1: # vapor phase self.fill(self.Gas, estado) self.fill(self, estado) self.fillNone(self.Liquido) else: # Two phase liquido = CP.AbstractState("HEOS", fluido) if self._multicomponent: xi = estado.mole_fractions_liquid() liquido.set_mole_fractions(xi) liquido.specify_phase(CP.iphase_liquid) liquido.update(CP.QT_INPUTS, 0, self.T) self.fill(self.Liquido, liquido) vapor = CP.AbstractState("HEOS", fluido) if self._multicomponent: yi = estado.mole_fractions_vapor() vapor.set_mole_fractions(yi) vapor.specify_phase(CP.iphase_gas) vapor.update(CP.QT_INPUTS, 1, self.T) self.fill(self.Gas, vapor) self.fill(self, estado) # Calculate special properties useful only for one phase if self._multicomponent: self.sigma = unidades.Tension(None) elif x < 1 and self.Tt <= self.T <= self.Tc: self.sigma = unidades.Tension(estado.surface_tension()) else: self.sigma = unidades.Tension(None) self.virialB = unidades.SpecificVolume(estado.Bvirial()) self.virialC = unidades.SpecificVolume_square(estado.Cvirial()) self.invT = unidades.InvTemperature(-1 / self.T) if 0 < self.x < 1: self.Hvap = unidades.Enthalpy(self.Gas.h - self.Liquido.h) self.Svap = unidades.SpecificHeat(self.Gas.s - self.Liquido.s) else: self.Hvap = unidades.Enthalpy(None) self.Svap = unidades.SpecificHeat(None)
import CoolProp import matplotlib.pyplot as plt import math from CoolProp.Plots import StateContainer refrigerant = 'R600' # setting the gasses HEOS = CoolProp.AbstractState('HEOS', refrigerant) # Setting the variables evaporation_temp = 4 + 273.15 condensation_temp = 70 + 273.15 superheat_evap = 5 superheat_intercooler = 5 subcooling_intercooler = 23 isentropic_eff = 0.7 compressor_loss = 0.1 condensor_capacity = 50000 DP_sup = 2500 DP_cond = 5000 DP_sub = 5000 DP_evap = 500 DP_int = 5000 """----Evaporation----""" T1 = evaporation_temp HEOS.update(CoolProp.QT_INPUTS, 1, T1) HEOS.specify_phase(CoolProp.iphase_gas)
return u':raw-html:`<span title="{1}">{0}</span>`'.format(short, long) class Dossier: def __init__(self): self.data = {} def add(self, key, value): if key not in self.data: self.data[key] = [] self.data[key].append(value) d = Dossier() pairs = CoolProp.get('mixture_binary_pairs_list') print(len(pairs.split(','))) for pair in pairs.split(','): CAS1, CAS2 = pair.split('&') d.add('CAS1', CAS1) d.add('CAS2', CAS2) for key in [ 'name1', 'name2', 'F', 'function', 'BibTeX', 'xi', 'zeta', 'betaT', 'betaV', 'gammaT', 'gammaV' ]: try: d.add( key, CoolProp.CoolProp.get_mixture_binary_pair_data( CAS1, CAS2, key)) except BaseException as BE:
# -*- coding: utf-8 -*- """ Created on Thu Apr 23 15:27:45 2020 @author: TrungNguyen """ import CoolProp from CoolProp.CoolProp import PropsSI from CoolProp.Plots import PropertyPlot from CoolProp.Plots import StateContainer #Evaporator chracteristics gas = 'R290' HEOS = CoolProp.AbstractState('HEOS', 'Propane&IsoButane') HEOS.set_mass_fractions([0.99999, 0.00001]) isentropic_eff=0.7 evaporation_temp = 0 + 273.15 # R290 condensation_temp = 55 + 273.15 # Estimation from Aeronamic superheat = 5 # ambient temperature subcooling = 3.1 # estimation from Aeronamic (how to know or calculate the value) #Compressor characteristics compressor_power = 4300 # massflow = 0.04506 # #Aeronamic calculated values Qdot_condensor_expected = 14.3e3 Expected_COP = 3.17
def add_fluids(fluids, memorise_fluid_properties=True): r""" Add list of fluids to fluid memorisation class. - Generate arrays for fluid property lookup if memorisation is activated. - Calculate/set fluid property value ranges for convergence checks. Parameters ---------- fluids : dict Dict of fluid and corresponding CoolProp back end for fluid property memorization. memorise_fluid_properties : boolean Activate or deactivate fluid property value memorisation. Default state is activated (:code:`True`). Note ---- The Memorise class creates globally accessible variables for different fluid property calls as dictionaries: - T(p,h) - T(p,s) - v(p,h) - visc(p,h) - s(p,h) Each dictionary uses the list of fluids passed to the Memorise class as identifier for the fluid property memorisation. The fluid properties are stored as numpy array, where each column represents the mass fraction of the respective fluid and the additional columns are the values for the fluid properties. The fluid property function will then look for identical fluid property inputs (p, h, (s), fluid mass fraction). If the inputs are in the array, the first column of that row is returned, see example. Example ------- T(p,h) for set of fluids ('water', 'air'): - row 1: [282.64527752319697, 10000, 40000, 1, 0] - row 2: [284.3140698256616, 10000, 47000, 1, 0] """ # number of fluids num_fl = len(fluids) if memorise_fluid_properties and num_fl > 0: fl = tuple(fluids.keys()) # fluid property tables Memorise.T_ph[fl] = np.empty((0, num_fl + 4), float) Memorise.T_ps[fl] = np.empty((0, num_fl + 5), float) Memorise.v_ph[fl] = np.empty((0, num_fl + 4), float) Memorise.visc_ph[fl] = np.empty((0, num_fl + 4), float) Memorise.s_ph[fl] = np.empty((0, num_fl + 4), float) msg = ( 'Added fluids ' + ', '.join(fl) + ' to memorise lookup tables.') logging.debug(msg) Memorise.water = None for f, back_end in fluids.items(): # save name for water in memorise if f in get_aliases("H2O"): Memorise.water = f if f in Memorise.state: del Memorise.state[f] # create CoolProp.AbstractState object try: Memorise.state[f] = CP.AbstractState(back_end, f) Memorise.back_end[f] = back_end except ValueError: msg = ( 'Could not find the fluid "' + f + '" in the fluid ' 'property database.' ) logging.warning(msg) continue msg = ( 'Created CoolProp.AbstractState object for fluid ' + f + ' with back end ' + back_end + '.') logging.debug(msg) # pressure range try: pmin = Memorise.state[f].trivial_keyed_output(CP.iP_min) pmax = Memorise.state[f].trivial_keyed_output(CP.iP_max) except ValueError: pmin = 1e4 pmax = 1e8 msg = ( 'Could not find values for maximum and minimum ' 'pressure.') logging.warning(msg) # temperature range Tmin = Memorise.state[f].trivial_keyed_output(CP.iT_min) Tmax = Memorise.state[f].trivial_keyed_output(CP.iT_max) # value range for fluid properties Memorise.value_range[f] = [pmin, pmax, Tmin, Tmax] try: molar_masses[f] = Memorise.state[f].molar_mass() gas_constants[f] = Memorise.state[f].gas_constant() except ValueError: try: molar_masses[f] = CPPSI('M', f) gas_constants[f] = CPPSI('GAS_CONSTANT', f) except ValueError: molar_masses[f] = 1 gas_constants[f] = 1 msg = ( 'Could not find values for molar mass and gas ' 'constant.') logging.warning(msg) msg = ( 'Specifying fluid property ranges for pressure and ' 'temperature for convergence check of fluid ' + f + '.') logging.debug(msg)
ts_plot.show() #%% from CoolProp.Plots import PropertyPlot plot = PropertyPlot("REFPROP::ISOBUTAN[0.8]&PROPANE[0.2]", 'PH', unit_system='EUR', tp_limits='ACHP') plot.calc_isolines() plot.show() #%% import CoolProp state = CoolProp.AbstractState("REFPROP", "ISOBUTAN&PROPANE") state.set_mass_fractions([0.8, 0.2]) from CoolProp.Plots import PropertyPlot plot = PropertyPlot(state, 'TS', unit_system='EUR', tp_limits='ACHP') plot.calc_isolines() plot.show() #%% #from __future__ import print_function import CoolProp from CoolProp.Plots import StateContainer T0 = 300.000 p0 = 200000.000 h0 = 112745.749
import CoolProp as CP from CoolProp.CoolProp import PropsSI import numpy as np import pandas as pd from matplotlib import pyplot as plt state = CP.AbstractState('HEOS', 'Isopentane') T_crit = state.trivial_keyed_output(CP.iT_critical) df = pd.DataFrame(columns=['s_l', 's_g', 's_iso_P0', 's_iso_P1']) P0 = 1000000 P1 = 200000 T_range = np.geomspace(273.15, T_crit, 1000) for T in T_range: df.loc[T, 's_l'] = PropsSI('S', 'T', T, 'Q', 0, 'Isopentane') df.loc[T, 's_g'] = PropsSI('S', 'T', T, 'Q', 1, 'Isopentane') df.loc[T, 's_iso_P0'] = PropsSI('S', 'T', T, 'P', P0, 'Isopentane') df.loc[T, 's_iso_P1'] = PropsSI('S', 'T', T, 'P', P1, 'Isopentane') print(df) fig, ax = plt.subplots() ax.plot(df['s_g'] / 1000, df.index - 273.15, color='black') ax.plot(df['s_l'] / 1000, df.index - 273.15, color='black') ax.plot(df['s_iso_P0'] / 1000, df.index - 273.15, color='green') ax.plot(df['s_iso_P1'] / 1000, df.index - 273.15, color='green') ax.set(xlabel='Specific entropy [kJ/kg K]', ylabel='Temperature [K]', title='T,s Graph for working fluid') ax.grid() plt.savefig('ts_plot_new.png') plt.show()
phi_g_square = 1 + C * sqrt(X_squared) + X_squared #Find Boiling pressure drop griendient if dpdz_g * phi_g_square > dpdz_f * phi_f_square: dpdz = dpdz_g * phi_g_square else: dpdz = dpdz_f * phi_f_square return dpdz if __name__ == '__main__': DP_vals_acc = [] DP_vals_fric = [] x_vals = [] import pylab AS = CP.AbstractState("HEOS", "R410A") for x in np.linspace(0.1, 1.0, 10): DP_vals_acc.append(AccelPressureDrop(x - 0.1, x, AS, 2, 250, 250)) DP_vals_fric.append( LMPressureGradientAvg(x - 0.1, x, AS, 0.1, 0.01, 250, 250) * 1 * 1) x_vals.append(x) print("plot shows accelerational pressure drop as f(x) for 0.1 x segments") pylab.plot(x_vals, DP_vals_acc) pylab.show() print( "plot shows frictional pressure drop as f(x) for 0.1 x segments of a fictional tube with unit length" ) pylab.plot(x_vals, DP_vals_fric) pylab.show()
def Initialize(self): #Input validation the first call of Initialize if False:#not hasattr(self,'IsValidated'): self.Fins.Validate() reqFields=[ ('Ref',str,None,None), ('psat_r',float,0.001,100000000), ('Fins',IsFinsClass,None,None), ('FinsType',str,None,None), ('hin_r',float,-100000,10000000), ('mdot_r',float,0.000001,10), ] optFields=['Verbosity','Backend'] d=self.__dict__ #Current fields in model ValidateFields(d,reqFields,optFields) self.IsValidated=True #AbstractState if hasattr(self,'Backend'): #check if backend is given AS = CP.AbstractState(self.Backend, self.Ref) else: #otherwise, use the defualt backend AS = CP.AbstractState('HEOS', self.Ref) self.AS = AS # Retrieve some parameters from nested structures # for code compactness self.ID=self.Fins.Tubes.ID self.OD=self.Fins.Tubes.OD self.Ltube=self.Fins.Tubes.Ltube self.NTubes_per_bank=self.Fins.Tubes.NTubes_per_bank self.Nbank=self.Fins.Tubes.Nbank self.Ncircuits=self.Fins.Tubes.Ncircuits self.Tin_a=self.Fins.Air.Tdb # Calculate an effective length of circuit if circuits are # not all the same length TotalLength=self.Ltube*self.NTubes_per_bank*self.Nbank self.Lcircuit=TotalLength/self.Ncircuits # Wetted area on the refrigerant side self.A_r_wetted=self.Ncircuits*pi*self.ID*self.Lcircuit self.V_r=self.Ncircuits*self.Lcircuit*pi*self.ID**2/4.0 #Average mass flux of refrigerant in circuit self.G_r = self.mdot_r/(self.Ncircuits*pi*self.ID**2/4.0) #[kg/m^2-s] ## Bubble and dew temperatures (same for fluids without glide) AS.update(CP.PQ_INPUTS, self.psat_r, 0.0) self.Tbubble_r=AS.T() #[K] h_l = AS.hmass() #[J/kg] AS.update(CP.PQ_INPUTS, self.psat_r, 1.0) self.Tdew_r=AS.T() #[K] h_v = AS.hmass() #[J/kg] ## Mean temperature for use in HT relationships self.Tsat_r=(self.Tbubble_r+self.Tdew_r)/2 # Latent heat self.h_fg=h_v - h_l #[J/kg] self.Fins.Air.RHmean=self.Fins.Air.RH #Update with user FinType if self.FinsType == 'WavyLouveredFins': WavyLouveredFins(self.Fins) elif self.FinsType == 'HerringboneFins': HerringboneFins(self.Fins) elif self.FinsType == 'PlainFins': PlainFins(self.Fins) self.mdot_ha=self.Fins.mdot_ha #[kg_ha/s] self.mdot_da=self.Fins.mdot_da #[kg_da/s]
#mu_axis.set_ylim([0,1]) #mu_axis.set_yscale("log") cp_axis.set_xlabel("Temperature $T$ / deg C") cp_axis.set_ylabel("Isobaric Heat Capacity $c_p$ / J/kg/K") #cp_axis.set_ylim([0,5000]) for fluid in CoolProp.__incompressibles_pure__ + CoolProp.__incompressibles_solution__: #for fluid in CoolProp.__incompressibles_solution__: #for fluid in CoolProp.__incompressibles_pure__: skip_fluid = False for ignored in ["example", "iceea", "icena", "icepg"]: if ignored in fluid.lower(): skip_fluid = True if skip_fluid: continue state = CoolProp.AbstractState("INCOMP", fluid) error = "" for frac in [0.5, 0.2, 0.8, 0.1, 0.9]: error = "" try: state.set_mass_fractions([frac]) state.update(CoolProp.PT_INPUTS, p, state.Tmax()) break except Exception as e: error = e.message try: state.set_volu_fractions([frac]) state.update(CoolProp.PT_INPUTS, p, state.Tmax()) break except Exception as e: error = e.message
Nominal compressor power consumption: 3.4 kW Evaporating temperature (K): 247-274 Condensing temperature (K): 316-342 Suction temperature (K): 290-292 Discharge temperature (K): 364-415 Refrigerant type: R22 'a_etav':[1.35,-0.2678,-0.0106,0.7195], #Volumetric eff. coeff. 'a_etais':[1,0.0753,0.2183,0.0015,0.0972], #Isentropic eff. coeff. 'a_etaoi':[1,-0.1642,0.2050,0.0659,0.7669], #Overall eff. coeff. """ #Abstract State Ref = 'R134a' Backend = 'HEOS' #choose between: 'HEOS','TTSE&HEOS','BICUBIC&HEOS','REFPROP','SRK','PR' AS = CP.AbstractState(Backend, Ref) Tsat_ev = 270 #[K] DT_sh = 7 + 8 #[K] AS.update(CP.QT_INPUTS, 1, Tsat_ev) pin_r = AS.p() #[Pa] Tsat_cd = 320 #[K] DT_sc = 8 #[K] AS.update(CP.QT_INPUTS, 1, Tsat_cd) pout_r = AS.p() #[Pa] # Compressor inlet temperature Tin_r = Tsat_ev + DT_sh
def get_speed_data(): H_TP = 350e3 P_TP = 400e3 H_SP = 250e3 P_SP = 1000e3 P_PT = 101325 T_PT = 300 fluid = 'R245fa' number = 50000 repeat = 3 version = CoolProp.__version__ if int(CoolProp.__version__[0]) > 4: loaded = 5 print("Loaded CoolProp version 5") from CoolProp.CoolProp import generate_update_pair, get_parameter_index, set_debug_level TTSE = CoolProp.AbstractState('TTSE&HEOS', fluid) BICUBIC = CoolProp.AbstractState('BICUBIC&HEOS', fluid) HEOS = CoolProp.AbstractState('HEOS', fluid) def two_phase_TTSE(): TTSE.update(CoolProp.HmassP_INPUTS, H_TP, P_TP) TTSE.rhomolar() def single_phase_TTSE(): TTSE.update(CoolProp.HmassP_INPUTS, H_SP, P_SP) TTSE.rhomolar() def single_phase_pT_TTSE(): TTSE.update(CoolProp.PT_INPUTS, P_PT, T_PT) TTSE.rhomolar() def two_phase_BICUBIC(): BICUBIC.update(CoolProp.HmassP_INPUTS, H_TP, P_TP) BICUBIC.rhomolar() def single_phase_BICUBIC(): BICUBIC.update(CoolProp.HmassP_INPUTS, H_SP, P_SP) BICUBIC.rhomolar() def single_phase_pT_BICUBIC(): BICUBIC.update(CoolProp.PT_INPUTS, P_PT, T_PT) BICUBIC.rhomolar() def two_phase_HEOS(): HEOS.update(CoolProp.HmassP_INPUTS, H_TP, P_TP) HEOS.rhomolar() def single_phase_HEOS(): HEOS.update(CoolProp.HmassP_INPUTS, H_SP, P_SP) HEOS.rhomolar() def single_phase_pT_HEOS(): HEOS.update(CoolProp.PT_INPUTS, P_PT, T_PT) HEOS.rhomolar() else: loaded = 4 print("Loaded CoolProp version 4") #from CoolProp.CoolProp import set_debug_level,set_standard_unit_system,enable_TTSE_LUT,disable_TTSE_LUT CoolProp.CoolProp.set_standard_unit_system(CoolProp.UNIT_SYSTEM_SI) state = CoolProp.State.State(fluid, {"H": H_TP * 2, "P": P_TP}) def two_phase_HP(): state.update({"H": H_TP, "P": P_TP}) state.get_rho() def single_phase_HP(): state.update({"H": H_SP, "P": P_SP}) state.get_rho() def single_phase_PT(): state.update({"P": P_PT, "T": T_PT}) state.get_rho() if loaded == 4: CoolProp.CoolProp.disable_TTSE_LUT(fluid) two_phase_hp_heos = min( timeit.Timer(two_phase_HP).repeat(repeat=repeat, number=number)) / number * 1e6 single_phase_hp_heos = min( timeit.Timer(single_phase_HP).repeat(repeat=repeat, number=number)) / number * 1e6 single_phase_pt_heos = min( timeit.Timer(single_phase_PT).repeat(repeat=repeat, number=number)) / number * 1e6 CoolProp.CoolProp.enable_TTSE_LUT(fluid) two_phase_hp_ttse = min( timeit.Timer(two_phase_HP).repeat(repeat=repeat, number=number)) / number * 1e6 single_phase_hp_ttse = min( timeit.Timer(single_phase_HP).repeat(repeat=repeat, number=number)) / number * 1e6 single_phase_pt_ttse = min( timeit.Timer(single_phase_PT).repeat(repeat=repeat, number=number)) / number * 1e6 CoolProp.CoolProp.disable_TTSE_LUT(fluid) elif loaded == 5: two_phase_hp_heos = min( timeit.Timer(two_phase_HEOS).repeat(repeat=repeat, number=number)) / number * 1e6 single_phase_hp_heos = min( timeit.Timer(single_phase_HEOS).repeat( repeat=repeat, number=number)) / number * 1e6 single_phase_pt_heos = min( timeit.Timer(single_phase_pT_HEOS).repeat( repeat=repeat, number=number)) / number * 1e6 two_phase_hp_ttse = min( timeit.Timer(two_phase_TTSE).repeat(repeat=repeat, number=number)) / number * 1e6 single_phase_hp_ttse = min( timeit.Timer(single_phase_TTSE).repeat( repeat=repeat, number=number)) / number * 1e6 single_phase_pt_ttse = min( timeit.Timer(single_phase_pT_TTSE).repeat( repeat=repeat, number=number)) / number * 1e6 two_phase_hp_bicubic = min( timeit.Timer(two_phase_BICUBIC).repeat( repeat=repeat, number=number)) / number * 1e6 single_phase_hp_bicubic = min( timeit.Timer(single_phase_BICUBIC).repeat( repeat=repeat, number=number)) / number * 1e6 single_phase_pt_bicubic = min( timeit.Timer(single_phase_pT_BICUBIC).repeat( repeat=repeat, number=number)) / number * 1e6 else: raise ValueError("Unknown CoolProp version.") return locals()
# ts_plot_water = PropsPlot('Water', 'Ts') # ts_plot_water.title('Ts Graph for Water') # ts_plot_water.xlabel(r's $[{kJ}/{kg K}]$') # ts_plot_water.ylabel(r'T $[K]$') # ts_plot_water.grid() # ts_plot_water.savefig('images/Water_Ts.pdf') # ph_plot_water = PropsPlot('Water', 'Ph') # ax = ph_plot_water.axis # ax.set_yscale('log') # ax.text(400, 5500, 'Saturated Liquid', fontsize=15, rotation=40) # ax.text(2700, 3500, 'Saturated Vapour', fontsize=15, rotation=-100) # ph_plot_water.savefig('images/Water_Ph.pdf') # ref_fluid = 'R600a' # fig = pyplot.figure(1, figsize=(10, 10), dpi=100) # for i, gtype in enumerate(['PT', 'PD', 'PS', 'PH', 'TD', 'TS', 'HS']): # ax = pyplot.subplot(4, 2, i+1) # if gtype.startswith('P'): # ax.set_yscale('log') # props_plot = PropsPlot(ref_fluid, gtype, axis=ax) # props_plot.title(gtype) # props_plot._draw_graph() # fig.set_tight_layout(True) #pyplot.tight_layout() # fig.savefig('images/comined_R600a.pdf') #pyplot.savefig('images/comined_R600a.pdf') print CP.PropsSI("P","T",306.3265564,"Q",0,"R407C") print CP.PhaseSI("T",306.3265564,"P",100000,"R407C") print CP.PropsSI('I', 'T', 200, 'Q', 0, "R407C") print CP.saturation_ancillary("R407C",'I',1,'T', 200) print get_svn_revision(sys.path)
import CoolProp import pandas grouping = dict() grouping2 = [] # Group aliases for parameter in CoolProp.get('parameter_list').split(','): index = CoolProp.CoolProp.get_parameter_index(parameter) units = CoolProp.CoolProp.get_parameter_information(index, 'units').replace( '-', ' ') IO = CoolProp.CoolProp.get_parameter_information(index, 'IO') long = CoolProp.CoolProp.get_parameter_information(index, 'long') short = CoolProp.CoolProp.get_parameter_information(index, 'short') trivial = str(CoolProp.CoolProp.is_trivial_parameter(index)) RHS = (units, IO, trivial, long) if RHS not in grouping: grouping[RHS] = [parameter] else: grouping[RHS].append(parameter) for k, v in grouping.iteritems(): grouping2.append([', '.join(['``' + _ + '``' for _ in v])] + list(k)) headers = ['Parameter', 'Units', 'Input/Output', 'Trivial', 'Description'] df3 = pandas.DataFrame(grouping2, columns=headers) df4 = df3.sort_values(by=['Input/Output', 'Parameter']) grouping2 = [row for row in df4.values]
def Calculate(self): #AbstractState if hasattr(self,'Backend'): #check if backend is given AS = CP.AbstractState(self.Backend, self.Ref) else: #otherwise, use the defualt backend AS = CP.AbstractState('HEOS', self.Ref) self.AS = AS #Local copies of coefficients P=self.P M=self.M #Calculate suction superheat and dew temperatures AS.update(CP.PQ_INPUTS, self.pin_r, 1.0) self.Tsat_s_K=AS.T() #[K] AS.update(CP.PQ_INPUTS, self.pout_r, 1.0) self.Tsat_d_K=AS.T() #[K] self.DT_sh_K=self.Tin_r-self.Tsat_s_K #Convert saturation temperatures in K to F Tsat_s = self.Tsat_s_K * 9/5 - 459.67 Tsat_d = self.Tsat_d_K * 9/5 - 459.67 #Apply the 10 coefficient ARI map to saturation temps in F power_map = P[0] + P[1] * Tsat_s + P[2] * Tsat_d + P[3] * Tsat_s**2 + P[4] * Tsat_s * Tsat_d + P[5] * Tsat_d**2 + P[6] * Tsat_s**3 + P[7] * Tsat_d * Tsat_s**2 + P[8] * Tsat_d**2*Tsat_s + P[9] * Tsat_d**3 mdot_map = M[0] + M[1] * Tsat_s + M[2] * Tsat_d + M[3] * Tsat_s**2 + M[4] * Tsat_s * Tsat_d + M[5] * Tsat_d**2 + M[6] * Tsat_s**3 + M[7] * Tsat_d * Tsat_s**2 + M[8] * Tsat_d**2*Tsat_s + M[9] * Tsat_d**3 # Convert mass flow rate to kg/s from lbm/h mdot_map *= 0.000125998 # Add more mass flow rate to scale mdot_map*=self.Vdot_ratio power_map*=self.Vdot_ratio P1 = self.pin_r P2 = self.pout_r T1_actual = self.Tsat_s_K + self.DT_sh_K T1_map = self.Tsat_s_K + 20 * 5 / 9 AS.update(CP.PT_INPUTS, P1, T1_map) v_map = 1 / AS.rhomass() #[m^3/kg] s1_map = AS.smass() #[J/kg-K] h1_map = AS.hmass() #[J/kg] AS.update(CP.PT_INPUTS, P1, T1_actual) s1_actual = AS.smass() #[J/kg-K] h1_actual = AS.hmass() #[J/kg] v_actual = 1 / AS.rhomass() #[m^3/kg] F = 0.75 mdot = (1 + F * (v_map / v_actual - 1)) * mdot_map AS.update(CP.PSmass_INPUTS, P2, s1_map) h2s_map = AS.hmass() #[J/kg] AS.update(CP.PSmass_INPUTS, P2, s1_actual) h2s_actual = AS.hmass() #[J/kg] #Shaft power based on 20F superheat calculation from fit overall isentropic efficiency power = power_map * (mdot / mdot_map) * (h2s_actual - h1_actual) / (h2s_map - h1_map) h2 = power * (1 - self.fp) / mdot + h1_actual self.eta_oi=mdot*(h2s_actual-h1_actual)/(power) AS.update(CP.HmassP_INPUTS, h2, P2) self.Tout_r = AS.T() #[K] self.sout_r = AS.smass() #[J/kg-K] self.sin_r = s1_actual self.hout_r = h2 self.hin_r = h1_actual self.mdot_r=mdot self.W=power self.CycleEnergyIn=power*(1-self.fp) self.Vdot_pumped= mdot*v_actual self.Q_amb=-self.fp*power
import CoolProp as CP import pylab, numpy as np from ACHP.Correlations import ShahEvaporation_Average x = np.linspace(0, 1, 1000) h = np.zeros_like(x) TsatL, TsatV = 300., 300. AS = CP.AbstractState('HEOS', 'R134a') AS.update(CP.QT_INPUTS, 0.0, TsatL) p = AS.p() #[Pa] for i in range(len(x)): h[i] = ShahEvaporation_Average(x[i], x[i], AS, 300, 0.01, p, 200, TsatL, TsatV) havg = np.trapz(h, x=x) pylab.figure(figsize=(7, 5)) pylab.axhline(havg, ls='--') pylab.text(0.2, havg, r'$\alpha_{avg}$', ha='center', va='bottom') pylab.text( 0.7, 1300, 'R134a\nG=300 kg/m$^2$\nD=0.01 m\nq\"=200 W/m$^2$\np=%0.1f kPa' % (p / 1000)) pylab.gca().set_xlabel('x [-]') pylab.gca().set_ylabel(r'$\alpha$ [W/m$^2$/K]') pylab.plot(x, h) pylab.title('Shah Evaporation HTC as a function of quality') pylab.show()
number = float(number) short = "{0:.4e}".format(number) long = "{0:.14e}".format(number) return u':raw-html:`<span title="{1}">{0}</span>`'.format(short,long) class Dossier: def __init__(self): self.data = {} def add(self, key, value): if key not in self.data: self.data[key] = [] self.data[key].append(value) d = Dossier() pairs = CoolProp.get('mixture_binary_pairs_list') for pair in pairs.split(','): CAS1, CAS2 = pair.split('&') d.add('CAS1', CAS1) d.add('CAS2', CAS2) for key in ['name1','name2','F','function','BibTeX','xi','zeta','betaT','betaV','gammaT','gammaV']: try: d.add(key, CoolProp.CoolProp.get_mixture_binary_pair_data(CAS1, CAS2, key)) except BaseException as BE: d.add(key, '') import pandas df = pandas.DataFrame(d.data) df = df.sort(['BibTeX','name1'], ascending = [0, 1]) bibtexer = getBibtexParser()#filename = '../../../CoolPropBibTeXLibrary.bib')
def Calculate(self): #Only validate the first time if not hasattr(self, 'IsValidated'): self.Fins.Validate() reqFields = [('Ref', str, None, None), ('Fins', IsFinsClass, None, None), ('FinsType', str, None, None), ('mdot_r', float, 0.00001, 20), ('Tin_r', float, 200, 500), ('psat_r', float, 0.01, 20000000)] optFields = ['Verbosity', 'Backend'] ValidateFields(self.__dict__, reqFields, optFields) self.IsValidated = True #AbstractState if hasattr(self, 'Backend'): #check if backend is given AS = CP.AbstractState(self.Backend, self.Ref) else: #otherwise, use the defualt backend AS = CP.AbstractState('HEOS', self.Ref) self.AS = AS # Retrieve some parameters from nested structures # for code compactness self.ID = self.Fins.Tubes.ID self.OD = self.Fins.Tubes.OD self.Ltube = self.Fins.Tubes.Ltube self.NTubes_per_bank = self.Fins.Tubes.NTubes_per_bank self.Nbank = self.Fins.Tubes.Nbank self.Ncircuits = self.Fins.Tubes.Ncircuits self.Tin_a = self.Fins.Air.Tdb ## Bubble and dew temperatures (same for fluids without glide) AS.update(CP.PQ_INPUTS, self.psat_r, 0.0) self.Tbubble = AS.T() #[K] self.h_l = AS.hmass() #[J/kg] self.cp_satL = AS.cpmass() #[J/kg-K] AS.update(CP.PQ_INPUTS, self.psat_r, 1.0) self.Tdew = AS.T() #[K] self.h_v = AS.hmass() #[J/kg] # Calculate an effective length of circuit if circuits are # not all the same length TotalLength = self.Ltube * self.NTubes_per_bank * self.Nbank self.Lcircuit = TotalLength / self.Ncircuits self.V_r = pi * self.ID**2 / 4.0 * self.Lcircuit * self.Ncircuits self.A_r_wetted = pi * self.ID * self.Ncircuits * self.Lcircuit self.G_r = self.mdot_r / (self.Ncircuits * pi * self.ID**2 / 4.0) #define known parameters AS.update(CP.PT_INPUTS, self.psat_r, self.Tin_r) self.hin_r = AS.hmass() #[J/kg] self.sin_r = AS.smass() #[J/kg-K] #Definitely have a superheated portion self._Superheat_Forward() #Maybe have a full two-phase section #First try to run with a full two-phase section from quality of 1 to quality of 0 self._TwoPhase_Forward() #If we have already used too much of the HX (max possible sum of w is 1.0) if self.w_2phase + self.w_superheat > 1: #There is no subcooled portion, solve for outlet quality brentq(self._TwoPhase_Forward, 0.0000001, 0.9999999) #Zero out all the subcooled parameters self.Q_subcool = 0.0 self.DP_r_subcool = 0.0 self.Charge_subcool = 0.0 self.w_subcool = 0.0 self.h_r_subcool = 0.0 self.existsSubcooled = False else: #By definition then we have a subcooled portion, solve for it self.existsSubcooled = True self._Subcool_Forward() #Overall calculations self.Q = self.Q_superheat + self.Q_2phase + self.Q_subcool self.DP_r = self.DP_r_superheat + self.DP_r_2phase + self.DP_r_subcool self.Charge = self.Charge_2phase + self.Charge_subcool + self.Charge_superheat if self.existsSubcooled == True: AS.update(CP.PT_INPUTS, self.psat_r, self.Tout_r) self.hout_r = AS.hmass() #[J/kg] self.sout_r = AS.smass() #[J/kg-K] else: self.Tout_r = self.xout_2phase * self.Tdew + ( 1 - self.xout_2phase) * self.Tbubble AS.update(CP.QT_INPUTS, 0.0, self.Tout_r) h_l = AS.hmass() #[J/kg] s_l = AS.smass() #[J/kg-K] AS.update(CP.QT_INPUTS, 1.0, self.Tout_r) h_v = AS.hmass() #[J/kg] s_v = AS.smass() #[J/kg-K] self.hout_r = h_l + self.xout_2phase * (h_v - h_l) self.sout_r = s_l + self.xout_2phase * (s_v - s_l) #Use the effective subcooling self.DT_sc = self.DT_sc_2phase #Calculate the mean outlet air temperature [K] self.Tout_a = self.Tin_a - self.Q / (self.Fins.cp_da * self.Fins.mdot_da) self.hmean_r = self.w_2phase * self.h_r_2phase + self.w_superheat * self.h_r_superheat + self.w_subcool * self.h_r_subcool self.UA_r = self.hmean_r * self.A_r_wetted self.UA_a = self.Fins.h_a * self.Fins.A_a * self.Fins.eta_a