def get_psi(fluid, ref_fluid, eta, T, rhomolar, e_k, sigma_nm): THIS = CoolProp.AbstractState('HEOS', fluid) REF = CoolProp.AbstractState('HEOS', ref_fluid) THIS.update(CoolProp.DmolarT_INPUTS, rhomolar, T) def residual_for_psi(psi, REF): # Calculate the conformal state conformal_state = THIS.conformal_state(ref_fluid, -1, -1) # Calculate ESRR (which are based on the CONFORMAL state values) f = THIS.T() / conformal_state['T'] h = conformal_state['rhomolar'] / THIS.rhomolar() # Must be the ratio of MOLAR densities!! # The F factor F_eta = sqrt(f) * pow(h, -2.0 / 3.0) * sqrt( THIS.molar_mass() / REF.molar_mass()) # Dilute viscosity of fluid of interest eta_dilute = viscosity_dilute(fluid, T, e_k, sigma_nm) # Required background contribution from reference fluid viscosity_background_required = (eta - eta_dilute) / F_eta REF.update(CoolProp.DmolarT_INPUTS, conformal_state['rhomolar'] * psi, conformal_state['T']) visc_ref = REF.viscosity_contributions() residual = visc_ref['initial_density'] + visc_ref['residual'] return residual - viscosity_background_required psi = scipy.optimize.newton(residual_for_psi, 1.0, args=(REF, )) return psi
def calc_Tmax_curve(self): HEOS = CP.AbstractState(self.additional_backend, self.fluid) PCSAFT = CP.AbstractState(self.backend, self.fluid) # rhomolar, smolar, hmolar, T, p, umolar = [], [], [], [], [], [] rhomolar, T, p = [], [], [] for _p in np.logspace(np.log10(HEOS.keyed_output(CP.iP_min) * 1.01), np.log10(HEOS.keyed_output(CP.iP_max)), 300): try: PCSAFT.update(CP.PT_INPUTS, _p, HEOS.keyed_output(CP.iT_max)) except ValueError as VE: print(1, 'Tmax', _p, VE) print('T', PCSAFT.T()) print('p', PCSAFT.p()) print('rhomolar', PCSAFT.rhomolar()) myprint(1, 'Tmax', _p, VE) continue try: T.append(PCSAFT.T()) p.append(PCSAFT.p()) rhomolar.append(PCSAFT.rhomolar()) # hmolar.append(PCSAFT.hmolar()) # smolar.append(PCSAFT.smolar()) # umolar.append(PCSAFT.umolar()) except ValueError as VE: myprint(1, 'Tmax access', VE) self.Tmax = dict(T=np.array(T), P=np.array(p), Dmolar=np.array(rhomolar))
def Initialize(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 # 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] # Define critical pressure and temperature self.Pcr = AS.p_critical() #[Pa] self.Tcr = AS.T_critical() #[K] 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]
def Calculate(self): #AbstractState if hasattr(self, 'Backend_g'): #check if backend is given AS_g = CP.AbstractState(self.Backend_g, self.Ref_g) if hasattr(self, 'MassFrac_g'): AS_g.set_mass_fractions([self.MassFrac_g]) else: #otherwise, use the defualt backend AS_g = CP.AbstractState('HEOS', self.Ref_g) self.AS_g = AS_g AS_g.update(CP.PT_INPUTS, self.pin_g, self.Tin_g) rho = AS_g.rhomass() #[kg/m^3] self.W = abs(self.DP_g) * (self.mdot_g / rho) / self.eta
def __init__(self, fluid, unit_system="kSI_C"): self.fluid = fluid self.HEOS = CoolProp.AbstractState("HEOS", self.fluid) self.HEOS.update(CoolProp.PT_INPUTS, 101325, 300) try: self.BICU = CoolProp.AbstractState("BICUBIC&HEOS", self.fluid) self.BICU.update(CoolProp.PT_INPUTS, 101325, 300) except Exception as e: pass self.unit_system = unit_system # legacy definitions/aliases self.Cp = self.cp self.Cv = self.cv self.mu = self.viscosity self.nu = self.kinematic_viscosity
def __init__(self, substance, **kwargs): if substance.upper() in self._allowed_subs: self.sub = substance.upper() else: raise ValueError( "{} is not an allowed substance. Choose one of {}.".format( substance, self._allowed_subs)) self._abstract_state = CoolProp.AbstractState("HEOS", self.sub) input_props = "" for arg in kwargs: if arg not in self._all_props: raise ValueError("The argument {} is not allowed.".format(arg)) else: input_props += arg if len(input_props) > 2 or len(input_props) == 1: raise ValueError( "Incorrect number of properties specified. Must be 2 or 0.") if len(input_props) > 0 and input_props not in self._allowed_pairs: raise StateError( "The pair of input properties entered ({}) isn't supported yet. " "Sorry!".format(input_props)) if len(input_props) > 0: setattr(self, input_props, (kwargs[input_props[0]], kwargs[input_props[1]]))
def __call__(self, **kwargs): self.kwargs.update(kwargs) if self.calculable: # try: self.calculo() # except ValueError as e: # self.msg = e # self.status = 0 # else: self.status = 1 self.msg = "Solved" elif self._definition and not self._multicomponent and "ids" in kwargs: if os.environ["CoolProp"] == "True": fluido = self._name() estado = CP.AbstractState("HEOS", fluido) self.Tc = unidades.Temperature(estado.T_critical()) self.Pc = unidades.Pressure(estado.p_critical()) self.rhoc = unidades.Density(estado.rhomass_critical()) self.M = unidades.Dimensionless(estado.molar_mass()*1000) self.R = unidades.SpecificHeat(estado.gas_constant()/self.M) self.Tt = unidades.Temperature(estado.Ttriple()) self.f_accent = unidades.Dimensionless( estado.acentric_factor()) 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.eq = self._limit(fluido, estado)
def __init__(self, composition, state): self.composition=composition self.state=state comp_name='&'.join(list(self.composition.keys())) comp_values=list(self.composition.values()) # defining thermodynamic state for CoolProp system = CP.AbstractState("HEOS",comp_name) system.set_mole_fractions(comp_values) system.update(CP.PT_INPUTS, self.state['pres'], self.state['temp']) #self.tp_para = [system.keyed_output(k) for k in [CP.iQ, CP.iDmass , CP.iDmolar, CP.iHmass, CP.iHmolar, CP.iSmolar, CP.iCpmolar, CP.iviscosity, CP.iconductivity]] # Getting property parameter from CoolProp self.Phase=system.keyed_output(CP.iPhase) # vapor fraction self.Q=system.keyed_output(CP.iQ) # vapor fraction self.Dmass=system.keyed_output(CP.iDmass) # mass density self.Dmolar=system.keyed_output(CP.iDmolar) # molar density self.Hmass=system.keyed_output(CP.iHmass) # specific enthalpy mass self.Hmolar=system.keyed_output(CP.iHmolar) # specific enthalpy molar self.Cpmass=system.keyed_output(CP.iCpmass) # specific heat mass self.Cpmolar=system.keyed_output(CP.iCpmolar) # specific heat molar try: self.Vis=system.keyed_output(CP.iviscosity) # viscosity except: self.Vis=[] try: self.cond=system.keyed_output(CP.iconductivity) # thermla conductivity except: self.cond=[] # thermla conductivity
def calc_Tmax_curve(self): HEOS = CP.AbstractState(self.backend, self.fluid) rhomolar, smolar, hmolar, T, p, umolar = [], [], [], [], [], [] for _p in np.logspace(np.log10(HEOS.keyed_output(CP.iP_min) * 1.01), np.log10(HEOS.keyed_output(CP.iP_max)), 300): try: HEOS.update(CP.PT_INPUTS, _p, HEOS.keyed_output(CP.iT_max)) except ValueError as VE: print('Tmax', _p, VE) continue try: T.append(HEOS.T()) p.append(HEOS.p()) rhomolar.append(HEOS.rhomolar()) hmolar.append(HEOS.hmolar()) smolar.append(HEOS.smolar()) umolar.append(HEOS.umolar()) except ValueError as VE: print('Tmax access', VE) self.Tmax = dict(T=np.array(T), P=np.array(p), Dmolar=np.array(rhomolar), Hmolar=np.array(hmolar), Smolar=np.array(smolar), Umolar=np.array(umolar))
def calc_melting_curve(self): state = CP.AbstractState('HEOS', self.fluid) rhomolar, smolar, hmolar, T, p, umolar = [], [], [], [], [], [] # Melting line if it has it if state.has_melting_line(): pmelt_min = max(state.melting_line(CP.iP_min, -1, -1), state.keyed_output(CP.iP_triple)) * 1.01 pmelt_max = min(state.melting_line(CP.iP_max, -1, -1), state.keyed_output(CP.iP_max)) * 0.99 for _p in np.logspace(np.log10(pmelt_min), np.log10(pmelt_max), 100): try: Tm = state.melting_line(CP.iT, CP.iP, _p) state.update(CP.PT_INPUTS, _p, Tm) T.append(state.T()) p.append(state.p()) rhomolar.append(state.rhomolar()) hmolar.append(state.hmolar()) smolar.append(state.smolar()) umolar.append(state.umolar()) except ValueError as VE: print('melting', VE) self.melt = dict(T=np.array(T), P=np.array(p), Dmolar=np.array(rhomolar), Hmolar=np.array(hmolar), Smolar=np.array(smolar), Umolar=np.array(umolar))
def Update(self): ''' Update cycle class with selected HX type Update cycle class with Abstract State ''' if self.EvapSolver == 'Moving-Boundary': if self.EvapType == 'Fin-tube': self.Evaporator = EvaporatorClass() self.Evaporator.Fins = FinInputs() elif self.EvapType == 'Micro-channel': raise else: raise elif self.EvapSolver == 'Finite-Element': raise else: raise if self.CondSolver == 'Moving-Boundary': if self.CondType == 'Fin-tube': self.Condenser = CondenserClass() self.Condenser.Fins = FinInputs() elif self.CondType == 'Micro-channel': self.Condenser = MicroCondenserClass() self.Condenser.Fins = MicroFinInputs() else: raise elif self.CondSolver == 'Finite-Element': raise else: raise #Abstract State self.AS = CP.AbstractState(self.Backend, self.Ref)
def __init__(self,P,h_in,mdot,fluid='water'): import CoolProp self.P = P self.h_in = h_in self.mdot = mdot self.fluid = fluid f = CoolProp.AbstractState('HEOS',fluid) f.update(CoolProp.PQ_INPUTS,self.P,0) h_liq = f.hmass() f.update(CoolProp.PQ_INPUTS,self.P,1) h_vap = f.hmass() # Determine what enthalpy to give at saturation temperature, since # at saturation temperature, rounding depends whether # the user intends heating or cooling. if h_in < h_liq: self.h_sat = h_liq elif h_in > h_vap: self.h_sat = h_vap else: self.h_sat = h_in #f.update(CoolProp.QT_INPUTS,0,f.Ttriple()) f.update(CoolProp.PT_INPUTS,P,f.Tmin()) h_min = f.hmass() f.update(CoolProp.PT_INPUTS,P,f.Tmax()) h_max = f.hmass() qlim1,qlim2 = self.mdot * (h_max - self.h_in), self.mdot * (h_min - self.h_in) self.qmin = min(qlim1,qlim2) self.qmax = max(qlim1,qlim2) self.Tmin = K2C(f.Tmin()) self.Tmax = K2C(f.Tmax()) self.q = np.vectorize(self._q) self.T = np.vectorize(self._T)
def calc_saturation_curves(self): """ Calculate all the saturation curves in one shot using the state class to save computational time """ HEOS = CP.AbstractState(self.backend, self.fluid) self.dictL, self.dictV = {}, {} for Q, dic in zip([0, 1], [self.dictL, self.dictV]): rhomolar,smolar,hmolar,T,p,umolar = [],[],[],[],[],[] for _T in np.logspace(np.log10(HEOS.keyed_output(CP.iT_triple)), np.log10(HEOS.keyed_output(CP.iT_critical)), 500): try: HEOS.update(CP.QT_INPUTS, Q, _T) if (HEOS.p() < 0): raise ValueError('P is negative:'+str(HEOS.p())) HEOS.T(), HEOS.p(), HEOS.rhomolar(), HEOS.hmolar(), HEOS.smolar() HEOS.umolar() T.append(HEOS.T()) p.append(HEOS.p()) rhomolar.append(HEOS.rhomolar()) hmolar.append(HEOS.hmolar()) smolar.append(HEOS.smolar()) umolar.append(HEOS.umolar()) except ValueError as VE: print('satT error:', VE, '; T:', '{T:0.16g}'.format(T=_T), 'T/Tc:', _T/HEOS.keyed_output(CP.iT_critical)) dic.update(dict(T = np.array(T), P = np.array(p), Dmolar = np.array(rhomolar), Hmolar = np.array(hmolar), Smolar = np.array(smolar), Umolar = np.array(umolar)))
def backend(self): """Return the CoolProp state associated with the fluid.""" if not self._backend_mode or self._backend_mode != pygaps.COOLPROP_BACKEND: self._backend_mode = pygaps.COOLPROP_BACKEND self._state = CoolProp.AbstractState( pygaps.COOLPROP_BACKEND, self.backend_name()) return self._state
def Update(self): ''' Update cycle class with selected HX type Update cyle class with Abstract State ''' if self.EvapSolver == 'Moving-Boundary': if self.EvapType == 'Fin-tube': self.Evaporator = EvaporatorClass() self.Evaporator.Fins = FinInputs() elif self.EvapType == 'Micro-channel': self.Evaporator = MicroChannelEvaporatorClass() self.Evaporator.Fins = MicroFinInputs() else: raise elif self.EvapSolver == 'Finite-Element': self.Evaporator = DiscretizeEvaporatorClass() else: raise if self.CondSolver == 'Moving-Boundary': if self.CondType == 'Fin-tube': self.Condenser = CondenserClass() self.Condenser.Fins = FinInputs() elif self.CondType == 'Micro-channel': self.Condenser = MicroCondenserClass() self.Condenser.Fins = MicroFinInputs() else: raise elif self.CondSolver == 'Finite-Element': self.Condenser = DiscretizeCondenserClass() else: raise #Abstract State self.AS = CP.AbstractState(self.Backend, self.Ref) if hasattr(self, 'MassFrac'): self.AS.set_mass_fractions([self.MassFrac]) elif hasattr(self, 'VoluFrac'): self.AS.set_volu_fractions([self.VoluFrac]) #Abstract State for SecLoopFluid self.AS_SLF = CP.AbstractState(self.Backend_SLF, self.SecLoopFluid) if hasattr(self, 'MassFrac_SLF'): self.AS_SLF.set_mass_fractions([self.MassFrac_SLF]) elif hasattr(self, 'VoluFrac_SLF'): self.AS_SLF.set_volu_fractions([self.VoluFrac_SLF])
def next(): """ """ fluid = request.vars.fluid # Create the state HEOS = CoolProp.AbstractState("HEOS", fluid) # Convert input strings to keys key1 = CoolProp.CoolProp.get_parameter_index( input_longname_to_key[request.vars.name1]) key2 = CoolProp.CoolProp.get_parameter_index( input_longname_to_key[request.vars.name2]) # Update it using the input pair that was selected # Upstream the input pair will be checked to make sure it is valid, so when it gets here there should not be a problem HEOS.update(*CoolProp.CoolProp.generate_update_pair( key1, float(request.vars.value1), key2, float(request.vars.value2))) entries = [ TR("Temperature [K]", HEOS.T()), TR("Pressure [Pa]", HEOS.p()), TR("Vapor quality [kg/kg]", HEOS.keyed_output(CoolProp.iQ)), TR("Speed of sound [m/s]", HEOS.speed_sound()) ] if request.vars.unit_system == 'Mole-based': entries += [ TR("Density [mol/m3]", HEOS.rhomolar()), TR("Enthalpy [J/mol]", HEOS.hmolar()), TR("Entropy [J/mol/K]", HEOS.smolar()), TR("Constant-pressure specific heat [J/mol/K]", HEOS.cpmolar()), TR("Constant-volume specific heat [J/mol/K]", HEOS.cvmolar()) ] elif request.vars.unit_system == 'Mass-based': entries += [ TR("Density [kg/m3]", HEOS.rhomass()), TR("Enthalpy [J/kg]", HEOS.hmass()), TR("Entropy [J/kg/K]", HEOS.smass()), TR("Constant-pressure specific heat [J/kg/K]", HEOS.cpmass()), TR("Constant-volume specific heat [J/kg/K]", HEOS.cvmass()) ] else: raise ValueError form = TABLE(entries) T = np.linspace( CoolProp.CoolProp.PropsSI(fluid, "Ttriple") + 0.1, CoolProp.CoolProp.PropsSI(fluid, "Tcrit") - 0.1) p = CoolProp.CoolProp.PropsSI("P", "T", T, "Q", [0] * len(T), fluid) fig, ax = plt.subplots() ax.plot(T, p, 'k-', lw=2) ax.set_xlabel('Temperature [K]') ax.set_ylabel('Pressure [Pa]') ax.set_yscale('log') fig_html = XML( mpld3.fig_to_html(fig, no_extras=True, template_type='simple')) plt.close('all') return dict(form=form, fig=fig_html, fluid=fluid)
def display(self, fig=None): import matplotlib.pyplot as plt if fig is None: fig = plt.figure() for stream, ii in [ ("refrig", [9, 10, 11]), ("mix", [7, 8, 9]), #6, ... ("motive", [9, 1, 2, 3, 4]), #... ,5 ("pump", [9, "1'"]), ]: #("nozzle", [4,"5'"]), #("diffuser", [6, "7'"])]: hh, TT = zip(*[(self.points[i].hmass(), self.points[i].T()) for i in ii]) plt.plot(hh, TT) state = CP.AbstractState("HEOS", "Water") # Fix nozzle stream for i1, i2, c in [(4, 5, 'r'), (4, "5'", 'r--'), (6, 7, 'g'), (6, "7'", 'g--')]: p1, p2 = self.points[i1], self.points[i2] ds = p2.smass() - p1.smass() dp = p2.p() - p1.p() HH = [] TT = [] for x in np.linspace(0, 1): s = ds * x + p1.smass() p = dp * x + p1.p() state.update(CP.PSmass_INPUTS, p, s) HH.append(state.hmass()) TT.append(state.T()) plt.plot(HH, TT, c) # Saturation curves #state.update(CP.QT_INPUTS,0,state.Tmin()) #pmin = state.p() #pmax = state.p_critical() tmin = state.Tmin() tmax = state.T_critical() lh, lT = [], [] vh, vT = [], [] #for P in np.linspace(pmin, pmax): for T in np.linspace(tmin, tmax): #state.update(CP.PQ_INPUTS, P, 0) state.update(CP.QT_INPUTS, 0, T) lh.append(state.hmass()) lT.append(state.T()) #state.update(CP.PQ_INPUTS, P, 1) state.update(CP.QT_INPUTS, 1, T) vh.append(state.hmass()) vT.append(state.T()) plt.plot(lh, lT, '--') plt.plot(vh, vT, '--') return fig
def get_offset_NBP(name): # CPmod.set_debug_level(10) CPmod.set_reference_state(name, "RESET") HEOS = CoolProp.AbstractState('HEOS', name) HEOS.update(CoolProp.PQ_INPUTS, 101325, 0) gas_constant = HEOS.gas_constant() / HEOS.molar_mass() delta_a1 = HEOS.smass() / (gas_constant) delta_a2 = -HEOS.hmass() / (gas_constant * HEOS.keyed_output(CoolProp.iT_reducing)) return delta_a1, delta_a2
def caching_state_CoolProp(backend, fluid, spec0, spec1, spec_set, phase, zs): # Pretty sure about as optimized as can get! # zs should be a tuple, not a list key = (backend, fluid, spec0, spec1, spec_set, phase, zs) if key in caching_states_CoolProp: AS = caching_states_CoolProp[key] try: caching_states_CoolProp.move_to_end(key) except: # Move to end the old fashioned way del caching_states_CoolProp[key] caching_states_CoolProp[key] = AS elif len(caching_states_CoolProp) < max_CoolProp_states: # Always make a new item until the cache is full AS = CoolProp.AbstractState(backend, fluid) AS.specify_phase(phase) if zs is not None: AS.set_mole_fractions(zs) AS.update(spec_set, spec0, spec1) # A failed call here takes ~400 us. caching_states_CoolProp[key] = AS return AS else: # Reuse an item if not in the cache, making the value go to the end of # the ordered dict if not SORTED_DICT: old_key, AS = caching_states_CoolProp.popitem(False) else: # Hack - get first item in dict old_key = next(iter(caching_states_CoolProp)) AS = caching_states_CoolProp.pop(old_key) if old_key[1] != fluid or old_key[0] != backend: # Handle different components - other will be gc AS = CoolProp.AbstractState(backend, fluid) AS.specify_phase(phase) if zs is not None: AS.set_mole_fractions(zs) AS.update(spec_set, spec0, spec1) caching_states_CoolProp[key] = AS return AS
def SampleMicroChannelGasCooler(): Fins = MicroFinInputs() Fins.Tubes.NTubes = 61.354 #Number of tubes (per bank for now!) Fins.Tubes.Nbank = 1 #Number of banks (set to 1 for now!) Fins.Tubes.Npass = 3 #Number of passes (per bank-averaged) Fins.Tubes.Nports = 1 #Number of rectangular ports Fins.Tubes.Ltube = 0.30213 #length of a single tube Fins.Tubes.Td = 0.0333 #Tube outside width (depth) Fins.Tubes.Ht = 0.002 #Tube outside height (major diameter) Fins.Tubes.b = 0.00635 #Tube spacing Fins.Tubes.tw = 0.0003 #Tube wall thickness Fins.Tubes.twp = 0.0003 #Port (channel) wall thickness Fins.Tubes.beta = 1 #Port (channel) aspect ratio (=width/height) Fins.Tubes.kw = 117 #wall thermal conductivity Fins.Fins.FPI = 11.0998 #Fin per inch Fins.Fins.Lf = 0.0333 #Fin length Fins.Fins.t = 0.000152 #Fin thickness Fins.Fins.k_fin = 117 #Fin thermal conductivity Fins.Air.Vdot_ha = 0.281 #rated volumetric flowrate (m^3/s) Fins.Air.Tmean = 29.4 + 273.15 Fins.Air.Tdb = 29.4 + 273.15 #Dry Bulb Temperature Fins.Air.p = 101325 #Air pressure in Pa Fins.Air.RH = 0.5 #Relative Humidity Fins.Air.RHmean = 0.5 Fins.Air.FanPower = 160 Fins.Louvers.Lalpha = 20 #Louver angle, in degree Fins.Louvers.lp = 0.001 #Louver pitch Fins.Louvers.Llouv = 0.005737 #Louver cut length #Abstract State Ref = 'R744' Backend = 'HEOS' #choose between: 'HEOS','TTSE&HEOS','BICUBIC&HEOS','REFPROP','SRK','PR' AS = CP.AbstractState(Backend, Ref) params = { 'AS': AS, 'mdot_r': 0.076, 'Tin_r': 110.6 + 273.15, 'psat_r': 11000000, 'Fins': Fins, 'FinsType': 'MultiLouveredMicroFins', 'Verbosity': 0, 'h_a_tuning': 1, 'h_r_tuning': 1, 'DP_tuning': 1, } GasCool = MicroChannelGasCoolerClass(**params) GasCool.Calculate() return GasCool
def __add__(self, other): self_flow=self.state['flow'] other_flow=other.state['flow'] new_flow=self_flow+other_flow self_comp=self.composition other_comp=other.composition try: self_comp = {key: comp * self_flow for key, comp in self_comp.items()} other_comp = {key: comp * other_flow for key, comp in other_comp.items()} new = self_comp.copy() new.update(other_comp) for key in new.keys(): first=self_comp.get(key,0) second=other_comp.get(key,0) new[key]=(first+second)/(new_flow) # State calculation new_state = self.state.copy() new_state['flow'] = new_flow # total flow # pressure = lowest pressure among streams if self.state['pres'] <= other.state['pres']: new_state['pres'] = self.state['pres'] else: new_state['pres'] = other.state['pres'] # temperature from energy balance--isenthalpic mixing # Note: heat of mixing is not considered here # Specific molar enthalpy of mixture new_Hmolar = (self.Hmolar*self.state['flow'] + other.Hmolar*other.state['flow'])/new_flow # State of mixture new_comp_name='&'.join(list(new.keys())) new_comp_values=list(new.values()) new_system = CP.AbstractState("HEOS",new_comp_name) new_system.set_mole_fractions(new_comp_values) # Make phase envelop new_system.build_phase_envelope("dummy") PE = new_system.get_phase_envelope_data() val=self.takeClosest(PE.hmolar_liq, new_Hmolar) ind=PE.hmolar_liq.index(val) new_state['temp']=PE.T[ind] # State with enthalpy and pressure as inputs #new_system.update(CP.HmolarP_INPUTS , new_Hmolar, new_state['pres']) #New temp #new_state['temp'] = new_system.keyed_output(CP.iT) except: ValueError return material_stream(new, new_state)
def Initialize(self): #AbstractState if hasattr(self, 'Backend_g'): #check if backend is given AS_g = CP.AbstractState(self.Backend_g, self.Ref_g) if hasattr(self, 'MassFrac_g'): AS_g.set_mass_fractions([self.MassFrac_g]) else: #otherwise, use the defualt backend AS_g = CP.AbstractState('HEOS', self.Ref_g) self.AS_g = AS_g #Update self.Update() # 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 self.pin_a = self.Fins.Air.p self.RHin_a = self.Fins.Air.RH # 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 glycol side self.A_g_wetted = self.Ncircuits * pi * self.ID * self.Lcircuit # Evaluate the air-side heat transfer and pressure drop if self.FinsType == 'WavyLouveredFins': WavyLouveredFins(self.Fins) elif self.FinsType == 'HerringboneFins': HerringboneFins(self.Fins) elif self.FinsType == 'PlainFins': PlainFins(self.Fins)
def __init__(self, backend, fluid, p0, T0): """ p0 : Initial pressure [Pa] T0 : Initial temperatrure [K] """ self.P = [p0] self.T = [] self.AS = CoolProp.AbstractState(backend, fluid) # Solve for Temperature for first point T = scipy.optimize.newton(self.objective_T, T0, args=(p0, -1)) self.T.append(T)
def __init__(self, fluid, figsize=(15, 23), backend='HEOS', additional_skips=[], mole_fractions=None, p_limits_1phase=None, T_limits_1phase=None, NT_1phase=40, Np_1phase=40, NT_2phase=20, NQ_2phase=20): self.fluid = fluid self.backend = backend print('***********************************************************************************') print('*************** ' + backend + '::' + fluid + ' ************************') print('***********************************************************************************') self.fig, self.axes = plt.subplots(nrows=5, ncols=3, figsize=figsize) self.pairs = all_solvers pairs_generator = iter(self.pairs) states = [CP.AbstractState(backend, fluid) for _ in range(3)] if mole_fractions is not None: for state in states: state.set_mole_fractions(mole_fractions) self.axes_list = [] for row in self.axes: for ax in row: pair = six.next(pairs_generator) kwargs = dict(p_limits_1phase=p_limits_1phase, T_limits_1phase=T_limits_1phase, NT_1phase=NT_1phase, Np_1phase=Np_1phase, NT_2phase=NT_2phase, NQ_2phase=NQ_2phase) self.axes_list.append(ConsistencyAxis(ax, self, pair, self.fluid, self.backend, *states, **kwargs)) ax.set_title(pair) self.calc_saturation_curves() self.plot_saturation_curves() self.calc_Tmax_curve() self.plot_Tmax_curve() self.calc_melting_curve() self.plot_melting_curve() self.tight_layout() self.fig.subplots_adjust(top=0.95) self.fig.suptitle('Consistency plots for ' + self.fluid, size=14) errors = [] for i, (ax, pair) in enumerate(zip(self.axes_list, self.pairs)): if pair not in not_implemented_solvers and pair not in additional_skips: errors.append(ax.consistency_check_singlephase()) if pair not in no_two_phase_solvers: ax.consistency_check_twophase() else: ax.cross_out_axis() self.errors = pandas.concat(errors, sort=True)
def __init__(self, fluid, figsize=(15, 23), backend='HEOS', additional_skips=[], mole_fractions=None): self.fluid = fluid self.backend = backend self.fig, self.axes = plt.subplots(nrows=5, ncols=3, figsize=figsize) self.pairs = all_solvers pairs_generator = iter(self.pairs) states = [CP.AbstractState(backend, fluid) for _ in range(3)] if mole_fractions is not None: for state in states: state.set_mole_fractions(mole_fractions) self.axes_list = [] for row in self.axes: for ax in row: pair = pairs_generator.next() self.axes_list.append( ConsistencyAxis(ax, self, pair, self.fluid, self.backend, *states)) ax.set_title(pair) self.calc_saturation_curves() self.plot_saturation_curves() self.calc_Tmax_curve() self.plot_Tmax_curve() self.calc_melting_curve() self.plot_melting_curve() self.tight_layout() self.fig.subplots_adjust(top=0.95) self.fig.suptitle('Consistency plots for ' + self.fluid, size=14) for i, (ax, pair) in enumerate(zip(self.axes_list, self.pairs)): if pair not in not_implemented_solvers and pair not in additional_skips: ax.consistency_check_singlephase() if pair not in no_two_phase_solvers: ax.consistency_check_twophase() else: ax.cross_out_axis()
def __init__(self, T_hot, T_reject, T_cold, m_dot, eta_nozzle=0.85, eta_mixer=0.70, eta_diffuser=0.70, superheat=20, eta_pump=0.8): vars = """Q_condenser,W Q_boiler,W Q_evaporator,W W_pump,W COP,W/W m_dot,kg/s m_refrig,kg/s""".split() self.vars = [var.split(',')[0] for var in vars] self.units = [var.split(',')[1] for var in vars] for var in self.vars: self.__setattr__(var, 0) self.T_hot = T_hot self.T_reject = T_reject self.T_cold = T_cold self.m_dot = m_dot self.eta_nozzle = eta_nozzle self.eta_mixer = eta_mixer self.eta_diffuser = eta_diffuser self.superheat = superheat self.eta_pump = eta_pump self.labels = range(1, 12) + ["1'", "5'", "7'"] self.points = {} for i in self.labels: self.points[i] = CP.AbstractState("HEOS", "Water")
def add_fluids(fluids): r""" Add list of fluids to fluid memorisation class. - Generate arrays for fluid property lookup. - Calculate/set fluid property value ranges for convergence checks. Parameters ---------- fluids : list List of fluid for fluid property memorization. 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 num_fl > 0: fl = tuple(fluids) # fluid property tables memorise.T_ph[fl] = np.empty((0, num_fl + 3), float) memorise.T_ps[fl] = np.empty((0, num_fl + 4), float) memorise.v_ph[fl] = np.empty((0, num_fl + 3), float) memorise.visc_ph[fl] = np.empty((0, num_fl + 3), float) memorise.s_ph[fl] = np.empty((0, num_fl + 3), float) # lists for memory cache, values not in these lists will be deleted # from the table after every tespy.networks.network.solve call. memorise.T_ph_f[fl] = [] memorise.T_ps_f[fl] = [] memorise.v_ph_f[fl] = [] memorise.visc_ph_f[fl] = [] memorise.s_ph_f[fl] = [] memorise.count = 0 msg = 'Added fluids ' + str(fl) + ' to memorise lookup tables.' logging.debug(msg) for f in fluids: if 'TESPy::' in f: if f in tespy_fluid.fluids.keys(): pmin = tespy_fluid.fluids[f].p_range[0] pmax = tespy_fluid.fluids[f].p_range[1] Tmin = tespy_fluid.fluids[f].T_range[0] Tmax = tespy_fluid.fluids[f].T_range[1] msg = ('Loading fluid property ranges for TESPy-fluid ' + f + '.') logging.debug(msg) # value range for fluid properties memorise.vrange[f] = [pmin, pmax, Tmin, Tmax] msg = ('Specifying fluid property ranges for pressure and ' 'temperature for convergence check.') logging.debug(msg) else: memorise.vrange[f] = [2000, 2000000, 300, 2000] elif 'INCOMP::' in f: # temperature range available only for incompressibles Tmin, Tmax = CPPSI('TMIN', f), CPPSI('TMAX', f) memorise.vrange[f] = [2000, 2000000, Tmin, Tmax] else: if f not in memorise.heos.keys(): # abstractstate object memorise.heos[f] = CP.AbstractState('HEOS', f) msg = ('Created CoolProp.AbstractState object for fluid ' + f + ' in memorise class.') logging.debug(msg) # pressure range pmin, pmax = CPPSI('PMIN', f), CPPSI('PMAX', f) # temperature range Tmin, Tmax = CPPSI('TMIN', f), CPPSI('TMAX', f) # value range for fluid properties memorise.vrange[f] = [pmin, pmax, Tmin, Tmax] msg = ('Specifying fluid property ranges for pressure and ' 'temperature for convergence check of fluid ' + f + '.') logging.debug(msg)
Ts = np.linspace(Tt, Tc) ps = CoolProp.CoolProp.PropsSI('P', 'T', Ts, 'Q', 0, 'Water') plt.plot(T, p, '.', color='gray') plt.plot(Ts, ps, 'k', lw=2) plt.yscale('log') plt.xlabel('Temperature / K') plt.ylabel('Pressure / Pa') plt.show() # coding: utf-8 # In[ ]: import CoolProp, numpy as np AS = CoolProp.AbstractState('BICUBIC&HEOS', 'CO2') print(AS.rhomolar_critical()) pt = AS.keyed_output(CoolProp.iP_triple) pc = AS.p_critical() verbose = False dTs = np.power(10.0, -np.arange(-1, 4)) for p in np.logspace(np.log10(pt * 1.05), np.log10(pc * 0.95)): AS.update(CoolProp.PQ_INPUTS, p, 0) rhoL = AS.rhomolar() Ts = AS.T() # Liquid side for specify_phase in [False, True]: if specify_phase: AS.specify_phase(CoolProp.iphase_liquid)
import numpy as np import CoolProp import matplotlib.pyplot as plt AS = CoolProp.AbstractState('HEOS', 'Water') steps = 100 # Saturated liquid AS.update(CoolProp.PQ_INPUTS, 101325, 0) Ts = AS.T() h_fg = AS.saturated_vapor_keyed_output( CoolProp.iHmass) - AS.saturated_liquid_keyed_output(CoolProp.iHmass) cl = AS.cpmass() # Subcooled liquid x, y = [], [] for T in np.linspace(Ts - 30, Ts - 0.1, steps): AS.update(CoolProp.PT_INPUTS, 101325, T) x.append(-cl * (Ts - T) / h_fg) y.append( AS.first_partial_deriv(CoolProp.iDmass, CoolProp.iHmass, CoolProp.iP)) plt.plot(x, y, label='Subcooled', color='gray') # Two-phase derivatives (splined) x, y1 = [], [] for Q in np.linspace(0, 0.3, steps): AS.update(CoolProp.PQ_INPUTS, 101325, Q) x.append(AS.Q()) y1.append( AS.first_two_phase_deriv_splined(CoolProp.iDmass, CoolProp.iHmass,
def DXPreconditioner(Cycle,epsilon=0.96): #Assume the heat exchangers are highly effective #Condensing heat transfer rate from enthalpies rho_air=1.1 Cp_air =1005 #[J/kg/K] #AbstractState if hasattr(Cycle,'Backend'): #check if backend is given AS = CP.AbstractState(Cycle.Backend, Cycle.Ref) else: #otherwise, use the defualt backend AS = CP.AbstractState('HEOS', Cycle.Ref) Cycle.Backend = 'HEOS' Cycle.AS = AS def OBJECTIVE(x): Tevap=x[0] Tcond=x[1] #Use fixed effectiveness to get a guess for the condenser capacity Qcond=epsilon*Cycle.Condenser.Fins.Air.Vdot_ha*rho_air*(Cycle.Condenser.Fins.Air.Tdb-Tcond)*Cp_air Cycle.AS.update(CP.QT_INPUTS,1.0,Tevap) pevap=Cycle.AS.p() #[pa] Cycle.AS.update(CP.QT_INPUTS,1.0,Tcond) pcond=Cycle.AS.p() #[pa] Cycle.Compressor.pin_r=pevap Cycle.Compressor.pout_r=pcond Cycle.Compressor.Tin_r=Tevap+Cycle.Evaporator.DT_sh Cycle.Compressor.Ref=Cycle.Ref Cycle.Compressor.Calculate() W=Cycle.Compressor.W # Evaporator fully-dry analysis Qevap_dry=epsilon*Cycle.Evaporator.Fins.Air.Vdot_ha*rho_air*(Cycle.Evaporator.Fins.Air.Tdb-Tevap)*Cp_air #Air-side heat transfer UA Evap=Cycle.Evaporator Evap.mdot_r=Cycle.Compressor.mdot_r Evap.psat_r=pevap Evap.Ref=Cycle.Ref Evap.Initialize() UA_a=Evap.Fins.h_a*Evap.Fins.A_a*Evap.Fins.eta_a Tin_a=Evap.Fins.Air.Tdb Tout_a=Tin_a+Qevap_dry/(Evap.Fins.mdot_da*Evap.Fins.cp_da) #Refrigerant-side heat transfer UA UA_r=Evap.A_r_wetted*Correlations.ShahEvaporation_Average(0.5,0.5,Cycle.AS,Evap.G_r,Evap.ID,Evap.psat_r,Qevap_dry/Evap.A_r_wetted,Evap.Tbubble_r,Evap.Tdew_r) #Get wall temperatures at inlet and outlet from energy balance T_so_a=(UA_a*Evap.Tin_a+UA_r*Tevap)/(UA_a+UA_r) T_so_b=(UA_a*Tout_a+UA_r*Tevap)/(UA_a+UA_r) Tdewpoint=HAPropsSI('D','T',Cycle.Evaporator.Fins.Air.Tdb, 'P',101325, 'R',Evap.Fins.Air.RH) #Now calculate the fully-wet analysis #Evaporator is bounded by saturated air at the refrigerant temperature. h_ai=HAPropsSI('H','T',Cycle.Evaporator.Fins.Air.Tdb, 'P',101325, 'R', Cycle.Evaporator.Fins.Air.RH) #[J/kg_da] h_s_w_o=HAPropsSI('H','T',Tevap, 'P',101325, 'R', 1.0) #[J/kg_da] Qevap_wet=epsilon*Cycle.Evaporator.Fins.Air.Vdot_ha*rho_air*(h_ai-h_s_w_o) #Coil is either fully-wet, fully-dry or partially wet, partially dry if T_so_a>Tdewpoint and T_so_b>Tdewpoint: #Fully dry, use dry Q f_dry=1.0 elif T_so_a<Tdewpoint and T_so_b<Tdewpoint: #Fully wet, use wet Q f_dry=0.0 else: f_dry=1-(Tdewpoint-T_so_a)/(T_so_b-T_so_a) Qevap=f_dry*Qevap_dry+(1-f_dry)*Qevap_wet if Cycle.ImposedVariable == 'Subcooling': #if Subcooling impose Cycle.AS.update(CP.PT_INPUTS,pcond,Tcond-Cycle.DT_sc_target) h_target = Cycle.AS.hmass() #[J/kg] Qcond_enthalpy=Cycle.Compressor.mdot_r*(Cycle.Compressor.hout_r-h_target) else: #otherwise, if Charge impose Cycle.AS.update(CP.PT_INPUTS,pcond,Tcond-5) h_target = Cycle.AS.hmass() #[J/kg] Qcond_enthalpy=Cycle.Compressor.mdot_r*(Cycle.Compressor.hout_r-h_target) resids=[Qevap+W+Qcond,Qcond+Qcond_enthalpy]#,Qevap,f_dry] return resids Tevap_init=Cycle.Evaporator.Fins.Air.Tdb-15 Tcond_init=Cycle.Condenser.Fins.Air.Tdb+8 x=fsolve(OBJECTIVE,[Tevap_init,Tcond_init]) DT_evap=Cycle.Evaporator.Fins.Air.Tdb-x[0] DT_cond=x[1]-Cycle.Condenser.Fins.Air.Tdb return DT_evap-1, DT_cond+1