def TR(self, values): # Set of the temperature value self._temperature = values[0] # Check if the entered value of relative humidity is between 0 and 1 if (values[1] < 0) or (values[1] > 1): raise ValueError("Relative humidity must be between 0% and 100%!") else: self._relative_humidity = values[1] # Calculation of the corresponding specific humidity value self._specific_humidity = HAPropsSI('W', 'P', self.pressure * 1e5, 'T', self.temperature + 273.15, 'R', self.relative_humidity) # Wet bulb temperature self._wet_bulb_temperature = HAPropsSI('B', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'R', self.relative_humidity)\ -273.15 # Dew point temperature self._dew_point_temperature = HAPropsSI('D', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'R', self.relative_humidity)\ -273.15 # Specific enthalpy, in kJ/kg self._specific_enthalpy = HAPropsSI('H', 'P', self.pressure * 1e5, 'T', self.temperature + 273.15, 'R', self.relative_humidity) * 1e-3 # Specific volume, in m^3/kg self._specific_volume = HAPropsSI('V', 'P', self.pressure * 1e5, 'T', self.temperature + 273.15, 'R', self.relative_humidity)
def RW(self, values): # TODO : fast computation must be implemented here. # Check if the entered value of relative humidity is between 0 and 1 if (values[0] < 0) or (values[0] > 1): raise ValueError("Relative humidity must be between 0% and 100%!") else: self._relative_humidity = values[0] # Check if the entered value of specific humidity makes sense if (values[1] < 0): raise ValueError("Specific humidity is positive") else: # Set of the specific humidity value self._specific_humidity = values[1] # Dry temperature self._temperature = HAPropsSI('T', 'P', self.pressure * 1e5, 'R', self.relative_humidity, 'W', self.specific_humidity) - 273.15 # Calculation of the corresponding wet bulb temperature self._wet_bulb_temperature = HAPropsSI('B', 'P', self.pressure*1e5, 'R', self.relative_humidity, 'W', self.specific_humidity)\ -273.15 # Calculation of the corresponding dew point temperature self._dew_point_temperature = HAPropsSI('D', 'P', self.pressure*1e5, 'R', self.relative_humidity, 'W', self.specific_humidity)\ -273.15 # Specific enthalpy, in kJ/kg self._specific_enthalpy = HAPropsSI('H', 'P', self.pressure * 1e5, 'R', self.relative_humidity, 'W', self.specific_humidity) * 1e-3 # Specific volume, in m^3/kg self._specific_volume = HAPropsSI('V', 'P', self.pressure * 1e5, 'R', self.relative_humidity, 'W', self.specific_humidity)
def OBJECTIVE(x): Pair_o = x[0] W = x[1] if W < 0: #to ensure that the humidty ratio is print( 'Microchannel Condensder -- Humidity ratio for air pressure drop is less than zero. Humidity ratio is set to 0.0' ) W = 0.0 v_da = HAPropsSI('V', 'T', self.Tout_a, 'P', Pair_o, 'W', W) W_new = HAPropsSI('W', 'T', self.Tout_a, 'P', Pair_o, 'V', v_da) #outlet air density rho_o = 1 / v_da * (1 + W_new) #[m^3/kg_ha] #mean air density rho_m = pow(0.5 * (1 / self.Fins.rho_i_air + 1 / rho_o), -1) #air-side pressure drop including momentum, expansion and contraction effects DeltaP_air = self.Fins.G_air**2 / 2 / self.Fins.rho_i_air * ( (1 - self.Fins.sigma**2 + self.Fins.Kc_tri) + 2 * (self.Fins.rho_i_air / rho_o - 1) + self.Fins.f_a * self.Fins.A_a / self.Fins.A_a_c * (self.Fins.rho_i_air / rho_m) - (1 - self.Fins.sigma**2 - self.Fins.Ke_tri) * (self.Fins.rho_i_air / rho_o)) resids = [(self.Pin_a - Pair_o) - DeltaP_air, W - W_new] return resids
def BD(self, values): # TODO : fast computation must be implemented here. # Set of the wet bulb temperature value self._wet_bulb_temperature = values[0] # Set of the dew point temperature value self._dew_point_temperature = values[1] # Calculation of the corresponding dry bulb temperature self._temperature = HAPropsSI('T', 'P', self.pressure*1e5, 'B', self.wet_bulb_temperature+273.15, 'D', self.dew_point_temperature+273.15)\ -273.15 # Relative humidity self._relative_humidity = HAPropsSI('R', 'P', self.pressure*1e5, 'B', self.wet_bulb_temperature\ +273.15, 'D', self.dew_point_temperature\ +273.15) # Calculation of the corresponding specific humidity value self._specific_humidity = HAPropsSI('W', 'P', self.pressure*1e5, 'B', self.wet_bulb_temperature\ +273.15, 'D', self.dew_point_temperature\ +273.15) # Specific enthalpy, in kJ/kg self._specific_enthalpy = HAPropsSI('H', 'P', self.pressure*1e5, 'B', self.wet_bulb_temperature\ +273.15, 'D', self.dew_point_temperature\ +273.15)*1e-3 # Specific volume, in m^3/kg self._specific_volume = HAPropsSI('V', 'P', self.pressure*1e5, 'B', self.wet_bulb_temperature+273.15, 'D', self.dew_point_temperature\ +273.15)
def OBJECTIVE(x): Pair_o = x[0] W = x[1] v_da=HAPropsSI('V','T',self.Tout_a,'P',Pair_o,'W',W) W_new = HAPropsSI('W','T',self.Tout_a,'P',Pair_o,'V',v_da) #outlet air density rho_o = 1 / v_da*(1+W_new) #[m^3/kg_ha] #mean air density rho_m = pow(0.5*(1/self.Fins.rho_i_air + 1/rho_o),-1) #air-side pressure drop including momentum, expansion and contraction effects DeltaP_air = self.Fins.G_air**2/2/self.Fins.rho_i_air * ((1 - self.Fins.sigma**2 + self.Fins.Kc_tri) + 2*(self.Fins.rho_i_air/rho_o - 1) + self.Fins.f_a*self.Fins.A_a/self.Fins.A_a_c *(self.Fins.rho_i_air/rho_m) - (1 - self.Fins.sigma**2 -self.Fins.Ke_tri)*(self.Fins.rho_i_air/rho_o)) resids=[(self.Pin_a-Pair_o)-DeltaP_air, W-W_new] return resids
def maximum_specific_humidity(self): """ Maximum value of the humidity content for a given air, corresponding to a 100% relative humidity. """ w0sat = HAPropsSI('W', 'T', self.temperature+273.15, 'R', 1.0,\ 'P', self.pressure*1e5) return w0sat
def __init__(self): # Name of the state self.name = 'State 1' # When the class is involved in computations dealing with a large amount # of data, the below attribute can be switched to True in order to # accelerate the calculation is avoiding as far as possible the use of # the CoolProp package. Obtained results are usually a little bit less # accurate than the ones obtained by Coolprop self.fast_computation = False # Pressure, in bar self.pressure = 1 * ATM # Temperature, in °C self._temperature = 20. # Relative humidity, dimensionless self._relative_humidity = 0.5 # Specific humidity, dimensionless self._specific_humidity = HAPropsSI('W', 'P', self.pressure * 1e5, 'T', self.temperature + 273.15, 'R', self.relative_humidity) # Wet bulb temperature, in °C self._wet_bulb_temperature = HAPropsSI('B', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'R', self.relative_humidity)\ -273.15 # Dew point temperature, in °C self._dew_point_temperature = HAPropsSI('D', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'R', self.relative_humidity)\ -273.15 # Specific enthalpy, in kJ/kg self._specific_enthalpy = HAPropsSI('H', 'P', self.pressure * 1e5, 'T', self.temperature + 273.15, 'R', self.relative_humidity) * 1e-3 # Specific volume, in m3/kg self._specific_volume = HAPropsSI('V', 'P', self.pressure * 1e5, 'T', self.temperature + 273.15, 'R', self.relative_humidity)
def humidity_search(PropsSI_args): desired = PropsSI_args[0] for i, v in enumerate(PropsSI_args): if v == 'P': P = PropsSI_args[i + 1] elif v == 'R': R_target = PropsSI_args[i + 1] elif v == 'W': W = PropsSI_args[i + 1] T = 273.15 # starting guess T_guess = T n_steps = 100 search_steps = [5, -5, 1, -1, 0.1, -0.1, 0.01, -0.01] for step in search_steps: cont = True n_step = 0 while cont: if n_step > 0: T_guess += step try: R = HAPropsSI('R', 'T', T_guess, 'W', W, 'P', P) error = abs(R_target - R) if step > 0: T = T_guess if R < R_target: cont = False elif step < 0 and R < R_target: T = T_guess else: cont = False except ValueError: if step < 0: cont = False n_step += 1 if n_step > n_steps: cont = False if desired == 'Tdb': return T else: return HAPropsSI(desired, 'P', P, 'W', W, 'Tdb', T)
def TD(self, values): # TODO : fast computation must be implemented here. # Set of the temperature value self._temperature = values[0] # Check if the entered dew point temperature value is lower than the dry # one if (values[1] > values[0]): raise ValueError( "Dew point temperature is lower than the dry one!") else: self._dew_point_temperature = values[1] # Calculation of the corresponding relative humidity self._relative_humidity = HAPropsSI('R', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'D', self.dew_point_temperature\ +273.15) # Calculation of the corresponding specific humidity value self._specific_humidity = HAPropsSI('W', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'D', self.dew_point_temperature\ +273.15) # Dew point temperature self._wet_bulb_temperature = HAPropsSI('B', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'D', self.dew_point_temperature\ +273.15)-273.15 # Specific enthalpy, in kJ/kg self._specific_enthalpy = HAPropsSI('H', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'D', self.dew_point_temperature\ +273.15)*1e-3 # Specific volume, in m^3/kg self._specific_volume = HAPropsSI('V', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'D', self.dew_point_temperature\ +273.15)
def DW(self, values): # TODO : fast computation must be implemented here. # Set of the dew point temperature value self._dew_point_temperature = values[0] # Check if the entered value of specific humidity makes sense, so if it # is between 0 and its maximum value when saturation is reached at the # same dry temperature wmax = HAPropsSI('W', 'P', self.pressure*1e5, 'R', 1.0,\ 'D', values[0]+273.15) if (values[1] < 0): raise ValueError("Specific humidity is positive") elif (values[1] > wmax): raise ValueError("Specific humidity is higher than at saturation") else: # Set of the specific humidity value self._specific_humidity = values[1] # Dry temperature self._temperature = HAPropsSI('T', 'P', self.pressure * 1e5, 'D', self.dew_point_temperature + 273.15, 'W', self.specific_humidity) - 273.15 # Relative humidity self._relative_humidity = HAPropsSI('R', 'P', self.pressure*1e5, 'D', self.dew_point_temperature\ +273.15, 'W', self.specific_humidity) # Calculation of the corresponding wet bulb temperature self._wet_bulb_temperature = HAPropsSI('B', 'P', self.pressure*1e5, 'D', self.dew_point_temperature\ +273.15, 'W', self.specific_humidity)\ -273.15 # Specific enthalpy, in kJ/kg self._specific_enthalpy = HAPropsSI('H', 'P', self.pressure*1e5, 'D', self.dew_point_temperature\ +273.15, 'W', self.specific_humidity)*1e-3 # Specific volume, in m^3/kg self._specific_volume = HAPropsSI('V', 'P', self.pressure*1e5, 'D', self.dew_point_temperature\ +273.15, 'W', self.specific_humidity)
def humidAir(outputType: list, inputType1: str, inputValue1: float, inputType2: str, inputValue2: float, inputType3: str, inputValue3: float) -> dict: # 初始化错误输出 errtext = "" # 初始化输出字典 result = dict() if type(outputType) != list: if type(outputType) == str: outputType = set([outputType]) else: errtext += 'Input Error:\nOutput Type key word {%s} is not supported.' % outputType logger.error(errtext) result.update({'error': True, 'message': errtext}) return {'result': result} else: outputType = set(outputType) # 处理输出数据不在范围内的问题。 if "A" not in outputType: if not outputType.issubset(TYPES): errtext += 'Input Error:\nOutput Type {%s} is not in list.' % ( outputType - TYPES) logger.error(errtext) result.update({'error': True, 'message': errtext}) outputType &= TYPES if len(outputType) == 0: return {'result': result} else: outputType = None # 要计算压力水汽数据,必须给出T和P参数,而剩余的一个参数则在输入列表中选取 inputSet = frozenset((inputType1, inputType2, inputType3)) if len(inputSet) == 3 and inputSet.issubset(INTYPES): result.update({ inputType1: inputValue1, inputType2: inputValue2, inputType3: inputValue3 }) if not outputType: outputType = TYPES - inputSet - set(('A', )) else: outputType = outputType - inputSet if not len(outputType): return {"result": result} error_counter = 0 for key in outputType: try: res = HAPropsSI(key, inputType1, inputValue1, inputType2, inputValue2, inputType3, inputValue3) result.update({key: res}) except Exception as e: logger.error("key *%s* failed to calculate: \n %s\n" % (key, str(e))) errtext += "[%s]key *%s* failed to cal.\n" % ( e.__class__.__name__, key) error_counter += 1 else: if error_counter > 0: result.update({'warning': True, 'message': errtext}) else: logger.error( 'Input Error:\nAt lease one of the parameters must in \'BRWD\'') errtext += "input keys [%s, %s, %s] at least has \"T, P, H, S\" and one of \"BWRD\"" % ( inputType1, inputType2, inputType3) result.update({'error': True, 'message': errtext}) return {'result': result}
def OBJECTIVE(x): Tevap=x[0] Tcond=x[1] Tin_CC=x[2] if Cycle.Mode=='AC': #Condenser heat transfer rate Qcond=epsilon*Cycle.Condenser.Fins.Air.Vdot_ha*rho_air*(Cycle.Condenser.Fins.Air.Tdb-Tcond)*Cp_air #Compressor power 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.Compressor.DT_sh Cycle.Compressor.Ref=Cycle.Ref Cycle.Compressor.Calculate() W=Cycle.Compressor.W Qcoolingcoil_dry=epsilon*Cycle.CoolingCoil.Fins.Air.Vdot_ha*rho_air*(Cycle.CoolingCoil.Fins.Air.Tdb-Tin_CC)*Cp_air # Air-side heat transfer UA CC=Cycle.CoolingCoil CC.Initialize() UA_a=CC.Fins.h_a*CC.Fins.A_a*CC.Fins.eta_a #Air outlet temp from dry analysis Tout_a=CC.Tin_a-Qcoolingcoil_dry/(CC.Fins.mdot_a*CC.Fins.cp_a) # Refrigerant side UA f,h,Re=Correlations.f_h_1phase_Tube(Cycle.Pump.mdot_g/CC.Ncircuits, CC.ID, Tin_CC, CC.pin_g, CC.AS_g) UA_r=CC.A_g_wetted*h #Glycol specific heat Cycle.Pump.AS_g.update(CP.PT_INPUTS,Cycle.Pump.pin_g,Tin_CC) cp_g=Cycle.Pump.AS_g.cpmass() #[J/kg-K] #Refrigerant outlet temp Tout_CC=Tin_CC+Qcoolingcoil_dry/(Cycle.Pump.mdot_g*cp_g) #Get wall temperatures at inlet and outlet from energy balance T_so_a=(UA_a*CC.Tin_a+UA_r*Tout_CC)/(UA_a+UA_r) T_so_b=(UA_a*Tout_a+UA_r*Tin_CC)/(UA_a+UA_r) Tdewpoint=HAPropsSI('D','T',CC.Fins.Air.Tdb,'P',101325,'R',CC.Fins.Air.RH) #Now calculate the fully-wet analysis #Evaporator is bounded by saturated air at the refrigerant temperature. h_ai= HAPropsSI('H','T',CC.Fins.Air.Tdb,'P',101325,'R',CC.Fins.Air.RH) h_s_w_o=HAPropsSI('H','T',Tin_CC,'P',101325,'R',1.0) Qcoolingcoil_wet=epsilon*CC.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) Qcoolingcoil=f_dry*Qcoolingcoil_dry+(1-f_dry)*Qcoolingcoil_wet Tin_IHX=Tin_CC+Qcoolingcoil/(Cycle.Pump.mdot_g*cp_g) QIHX=epsilon*Cycle.Pump.mdot_g*cp_g*(Tin_IHX-Tevap) 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) resids=[QIHX+W+Qcond,Qcond+Qcond_enthalpy,Qcoolingcoil-QIHX] return resids elif Cycle.Mode=='HP': #Evaporator heat transfer rate Qevap=epsilon*Cycle.Evaporator.Fins.Air.Vdot_ha*rho_air*(Cycle.Evaporator.Fins.Air.Tdb-Tevap)*Cp_air #Compressor power 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 will be dry Qcoolingcoil=epsilon*Cycle.CoolingCoil.Fins.Air.Vdot_ha*rho_air*(Tin_CC-Cycle.CoolingCoil.Fins.Air.Tdb)*Cp_air #Glycol specifi heat Cycle.Pump.AS_g.update(CP.PT_INPUTS,Cycle.Pump.pin_g,Tin_CC) cp_g=Cycle.Pump.AS_g.cpmass() #[J/kg/K] Tin_IHX=Tin_CC-Qcoolingcoil/(Cycle.Pump.mdot_g*cp_g) QIHX=epsilon*Cycle.Pump.mdot_g*cp_g*(Tin_IHX-Tcond) Cycle.AS.update(CP.PT_INPUTS,pcond,Tcond-Cycle.DT_sc_target) h_target = Cycle.AS.hmass() #[J/kg] QIHX_enthalpy=Cycle.Compressor.mdot_r*(Cycle.Compressor.hout_r-h_target) resids=[QIHX+W+Qevap,QIHX+QIHX_enthalpy,Qcoolingcoil+QIHX] return resids
def MultiLouveredMicroFins(Inputs): """ # The analysis is based on Lee book 2010 "Thermal design:Themoelectric, .." # In addition, correlation from # Man-Hoe Kim and Clark W. Bullard, 2002, "Air-side thermal hydraulic # performance of multi-louvered fin aluminum heat exchanger", International # journal of refrigeration |<------------------- Lf ------------------->| ____________________________________________ | | = | || || || || || || | | | || || || || || || | Llouv | || || || || || || | | | || || || || || || | = |____________________________________________| || -->||<-- lp / / /---------\ \ \ _____/ / / \ \ \____ Lf: Fin length (flow depth) Llouv: Louver cut length Lalpha: Louver angle |- Td -| ________ |________| = | | b | | = ________ |________| Ht Td: tube outside width (depth) Ht: tube outside height (major diameter) b: tube spacing """ Lalpha = Inputs.Louvers.Lalpha #Louver angle, in degree lp = Inputs.Louvers.lp #Louver pitch delta = Inputs.Fins.t #Fin thickness Lf = Inputs.Fins.Lf #Fin length (flow depth) k_fin = Inputs.Fins.k_fin #Thermal conductivity FPI = Inputs.Fins.FPI #Fin per inch (fin density) Ntubes = Inputs.Tubes.NTubes #Number of tubes Nbank = Inputs.Tubes.Nbank #Number of banks L3 = Inputs.Tubes.Ltube #length of a single tube L2 = Inputs.Tubes.Td #Tube outside width (depth) Ht = Inputs.Tubes.Ht #Tube outside height (major diameter) b = Inputs.Tubes.b #Tube spacing Vdot_ha = Inputs.Air.Vdot_ha #Air volume flow rate, m^3/s p = Inputs.Air.p #Air pressure, Pa if hasattr(Inputs.Air,'Tmean'): Temp = Inputs.Air.Tmean else: Temp = Inputs.Air.Tdb if hasattr(Inputs.Air,'RHmean'): RHin = Inputs.Air.RHmean else: RHin = Inputs.Air.RH # Check that cs_cp is defined, if so, set it to the value passed in if (hasattr(Inputs,'cs_cp') and Inputs.cs_cp>0) or (hasattr(Inputs,'WetDry') and Inputs.WetDry=='Wet'): isWet=True cs_cp=Inputs.Air.cs_cp else: isWet=False cs_cp=1.0 #Fins per meter (fin density) [1/m] FPM = FPI / 0.0254 #Fin pitch (distance between centerlines of fins) pf = 1 / FPM #Fin height sf = sqrt(b**2 + pf**2) #Louver cut length if hasattr(Inputs.Louvers,'Llouv'): Llouv = Inputs.Louvers.Llouv else: Llouv = 0.85 *sf #Fin pitch pt = Ht + b #Louver height lh = lp * sin(Lalpha*pi/180) #Air passages Npg = Ntubes + 1 #sometime there are no tubes on the edges of HX, so >>> Npg = Ntubes_bank + 1, otherwise Npg = Ntubes_bank - 1 #Height of heat exchanger (core width) L1 = Npg * b + Ntubes * Ht #Total number of fins (per bank) nf = L3/pf * Npg #Primary area = Tube outside surface area - Fin base area (per bank) Ap = (2*(L2 - Ht) + pi * Ht)*L3 *Ntubes - 2*delta*L2*nf #Total number of louvers (per bank) nlouv = (Lf/lp - 1)*nf #Total fin area = Fin area + Louver edge area (per bank) Af = 2 * (sf*Lf + sf*delta)*nf + 2*Llouv*delta*nlouv #Total surface area on air-side At = (Af + Ap) * Nbank #Minimum free-flow area on air-side = area spacing between tubes - fin and louver edge area Ac = b*L3*Npg - (delta*(sf-Llouv) +Llouv*lh)*nf #Frontal area on air-side Afr = L1*L3 #Hydraulic diameter on air-side Dh = 4*Ac*L2*Nbank / At #Porosity on air-side sigma = Ac/Afr #Volume of HX on air-side Vhx = L2*L3*b*Npg*Nbank #Surface area density on air-side beta = At/Vhx #Evaluate the mass flow rate based on inlet conditions # To convert a parameter from per kg_{humid air} to per kg_{dry air}, divide by (1+W) W=HAPropsSI('W','T',Inputs.Air.Tdb,'P',p,'R',Inputs.Air.RH) v_da=HAPropsSI('V','T',Inputs.Air.Tdb,'P',p,'W',W) h_da=HAPropsSI('H','T',Inputs.Air.Tdb,'P',p,'W',W) rho_ha = 1 / v_da*(1+W) #[m^3/kg_ha] rho_da = 1 / v_da #[m^3/kg_da] mdot_ha = Vdot_ha * rho_ha #[kg_ha/s] mdot_da = Vdot_ha * rho_da #[kg_da/s] #mass flux on air-side G = mdot_ha / Ac #[kg/m^2-s] #maximum velocity on air-side umax = G / rho_ha * Afr/Ac #[m/s] #Use a forward difference to calculate cp from cp=dh/dT dT=0.0001 #[K] cp_da=(HAPropsSI('H','T',Inputs.Air.Tdb+dT,'P', p, 'W',W)-h_da)/dT #*1000 #[J/kg_da/K] cp_ha=cp_da/(1+W) #[J/kg_ha/K] #Transport properties of humid air from CoolProp mu_ha=HAPropsSI('M','T',Inputs.Air.Tdb,'P',p,'W',W) k_ha=HAPropsSI('K','T',Inputs.Air.Tdb,'P',p,'W',W) #Dimensionless Groups Pr = cp_ha * mu_ha / k_ha #Prandlt's number Re_Dh = G * Dh / mu_ha #Reynold's number on air-side Re_lp = rho_ha * umax * lp / mu_ha #Heat transfer #Colburn j-Factor based on Chang & Wang, "A Generalized Heat Transfer #Correlation for Louver Fin Geometry." Int. J. Heat Mass Transfer, 40 (1997): 553-554 #j = pow(Re_lp,-0.49) * pow((Lalpha/90.0),0.27) * pow(pf/lp,-0.14) * pow(b/lp,-0.29) * pow(Lf/lp,-0.23) * pow(Llouv/lp,0.68) * pow(pt/lp,-0.28) * pow(delta/lp,-0.05) #h_a = j * G * cp_ha / pow(Pr,2.0/3.0) #Colburn j-Factor based on Kim & Bullard, "Air-side thermal hydraulic performance #of multi-louvered fin aluminum heat exchanger" Int. J. Refrigeration, 25 (2002): 390-400 j = pow(Re_lp,-0.487) * pow((Lalpha/90.0),0.257) * pow(pf/lp,-0.13) * pow(b/lp,-0.29) * pow(Lf/lp,-0.235) * pow(Llouv/lp,0.68) * pow(pt/lp,-0.279) * pow(delta/lp,-0.05) h_a = j * rho_ha * umax * cp_ha / pow(Pr,2.0/3.0) #Air-side pressure drop correlations based on Chang and el., "A Generalized Friction #Correlation for Louver Fin Geometry." (2000) Int. J. Heat Mass Transfer, 43, 2237-2243 if (Re_lp<150): fa = 14.39 * Re_lp**(-0.805*pf/sf) * pow(log(1.0 + pf/lp),3.04) fb = pow(log((delta/pf)**0.48 + 0.9),-1.453) * pow(Dh/lp,-3.01) * pow(log(0.5*Re_lp),-3.01) fc = pow(pf/Llouv,-0.308) * pow(Lf/Llouv,-0.308) *exp(-0.1167*pt/Ht) * pow(Lalpha,0.35) else: fa = 4.97 * pow(Re_lp,(0.6049 - 1.064/Lalpha**0.2)) * pow(log((delta/pf)**0.5 + 0.9),-0.527) fb = pow((Dh/lp)*log(0.3*Re_lp),-2.966) * pow(pf/Llouv,-0.7931*pt/b) fc = pow(pt/Ht, -0.0446) * pow(log(1.2 + (lp/pf)**1.4),-3.553) * pow(Lalpha,-0.477) #Fanning friction factor f = fa*fb*fc #Air-side pressure drop #neglecting contraction effect, momentum effect, expansion effect (Kc, Ke ,..etc) #this assumption is valid for compact HX based on book of Shah and #Sekulic 2003,"Fundamentals of Heat Exchanger Design" DeltaP_air= f * At/Ac * G**2 / (2.0*rho_ha) #Air-side pressure drop including momentum, expansion and contraction effects #so the coefficients are send back for give structure #Assume Reynold's number is turbulent due to louver fin Re_d = 10**7 #Contraction and expansion coefficient C_tube = 4.374e-4 * exp(6.737*sqrt(sigma)) + 0.621 #Calculate Friction factor, velocity distribution coefficient (triangular tube), if (Re_d >= 2300): f_d = 0.049*Re_d**(-0.2) #Friction factor Kd_tube = 1.09068*(4*f_d) + 0.05884*sqrt(4*f_d) + 1 Kd_tri = 1 + 1.29*(Kd_tube-1) else: f_d = 64/Re_d Kd_tube = 1.33 Kd_tri = 1.43 #Expansion coefficient Ke_tri = 1 - 2*Kd_tri*sigma + sigma**2 #Contraction coefficient Kc_tri = (1 - 2*C_tube + C_tube**2 *(2*Kd_tri - 1))/C_tube**2 #calcs needed for specific fin types (Based on Kim & Bullard 2002 paper) mf = sqrt(2 * h_a * cs_cp / (k_fin * delta) *(1 + delta/Lf) ) #cs_cp is the correction for heat/mass transfer #characteristic length (Based on Kim & Bullard 2002 paper) Ls = sf/2 - delta #Finned surface efficiency eta_f = tanh(mf * Ls) / (mf * Ls) #Can be included for wet surface >>> *cos(0.1 * m * Ls) #overall surface efficiency eta_o = 1 - Af / At * (1 - eta_f) #write necessary values back into the given structure Inputs.Llouv=Llouv Inputs.A_a=At Inputs.A_a_c=Ac Inputs.cp_da=cp_da Inputs.cp_ha=cp_ha if isWet==True: Inputs.eta_a_wet=eta_o else: Inputs.eta_a=eta_o Inputs.h_a=h_a Inputs.mdot_ha=mdot_ha Inputs.mdot_da=mdot_da Inputs.f_a=f Inputs.dP_a=DeltaP_air Inputs.Re=Re_Dh """ADD NEW""" Inputs.G_air = G Inputs.rho_i_air = rho_ha Inputs.sigma = sigma Inputs.Kc_tri = Kc_tri Inputs.Ke_tri = Ke_tri
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), ('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.Ltube = self.Fins.Tubes.Ltube #tube length self.NTubes = self.Fins.Tubes.NTubes #number of tube (per bank) self.Nbank = self.Fins.Tubes.Nbank #number of banks self.Tin_a = self.Fins.Air.Tdb #inlet air temperature self.Pin_a = self.Fins.Air.p #inlet air pressure self.RHin_a = self.Fins.Air.RH #inlet air relative humidity self.Td = self.Fins.Tubes.Td #tube outside width (depth) self.Ht = self.Fins.Tubes.Ht #tube outside height (major diameter) self.b = self.Fins.Tubes.b #tube spacing self.tw = self.Fins.Tubes.tw #tube thickness self.Npass = self.Fins.Tubes.Npass #Number of passes on ref-side (per bank) self.kw = self.Fins.Fins.k_fin #thermal conductivity of tube wall (assume same material as the fin) self.Nports = self.Fins.Tubes.Nports #Number of rectangular ports self.twp = self.Fins.Tubes.twp #Port wall thickness self.beta = self.Fins.Tubes.beta #channel (port) aspect ratio (=width/height) ## 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] # Define Number of circuits (=number of tubes per pass) self.Ncircuits = self.NTubes / self.Npass # Calculate an effective length of circuit if circuits are # not all the same length TotalLength = self.Ltube * self.NTubes * self.Nbank self.Lcircuit = TotalLength / self.Ncircuits # Volume of refrigerant = rectangle of tube + circular part at the ends - thickness between ports self.V_r = ((self.Td - self.Ht) * (self.Ht - 2.0 * self.tw) + (pi / 4.0) * (self.Ht - 2.0 * self.tw)**2 - (self.Ht - 2.0 * self.tw) * self.twp * (self.Nports - 1)) * self.Lcircuit * self.Ncircuits # Tube wetted area = tube straight length + circular shape at the ends - horizontal port thickness + vertical thickness between ports self.A_r_wetted = (2.0 * (self.Td - self.Ht) + pi * (self.Ht - 2.0 * self.tw) - 2.0 * self.twp * (self.Nports - 1) + 2.0 * (self.Ht - 2.0 * self.tw) * (self.Nports - 1)) * self.Lcircuit * self.Ncircuits # Free-flow area on refrigerant-side = area of rectangle tube + circular parts at end - area thickness between ports self.A_c = ((self.Td - self.Ht) * (self.Ht - 2.0 * self.tw) + (pi / 4.0) * (self.Ht - 2.0 * self.tw)**2 - self.twp * (self.Ht - 2.0 * self.tw) * (self.Nports - 1)) * self.Ncircuits # Hydraulic diameter on ref-side self.Dh = 4 * self.A_c * self.Lcircuit / self.A_r_wetted # Mass flux ref-side self.G_r = self.mdot_r / self.A_c # Total conduction area (exclude port's thickness) self.Aw = 2 * (self.Td - self.twp * (self.Nports - 1)) * self.Lcircuit * self.Ncircuits # Thermal resistance at the wall self.Rw = self.tw / (self.kw * self.Aw) #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 #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] 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.Tbubble) h_l = AS.hmass() #[J/kg] s_l = AS.smass() #[J/kg-K] AS.update(CP.QT_INPUTS, 1.0, self.Tdew) 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 self.UA_w = 1 / self.Rw #Upadte air-side pressure drop based on the outlet air temperature #the air-side pressure drop here include momentum, contraction and expansion effects #Objective function def OBJECTIVE(x): Pair_o = x[0] W = x[1] v_da = HAPropsSI('V', 'T', self.Tout_a, 'P', Pair_o, 'W', W) W_new = HAPropsSI('W', 'T', self.Tout_a, 'P', Pair_o, 'V', v_da) #outlet air density rho_o = 1 / v_da * (1 + W_new) #[m^3/kg_ha] #mean air density rho_m = pow(0.5 * (1 / self.Fins.rho_i_air + 1 / rho_o), -1) #air-side pressure drop including momentum, expansion and contraction effects DeltaP_air = self.Fins.G_air**2 / 2 / self.Fins.rho_i_air * ( (1 - self.Fins.sigma**2 + self.Fins.Kc_tri) + 2 * (self.Fins.rho_i_air / rho_o - 1) + self.Fins.f_a * self.Fins.A_a / self.Fins.A_a_c * (self.Fins.rho_i_air / rho_m) - (1 - self.Fins.sigma**2 - self.Fins.Ke_tri) * (self.Fins.rho_i_air / rho_o)) resids = [(self.Pin_a - Pair_o) - DeltaP_air, W - W_new] return resids #Initial guesses P_init = self.Pin_a w_init = HAPropsSI('W', 'T', self.Tin_a, 'P', self.Pin_a, 'R', self.RHin_a) #solve for outlet air pressure and outlet humidity ratio x = fsolve(OBJECTIVE, [P_init, w_init]) #update the air-side pressure drop self.dP_a = self.Pin_a - x[0]
def WavyLouveredFins(Inputs): """ # Correlations from: # Chi-Chuan Wang and Yu-Min Tsai and Ding-Chong Lu, 1998, "Comprehensive # Study of Convex-Louver and Wavy Fin-and-Tube Heat Exchangers", Journal # of Thermophysics and Heat Transfer || - xf -> ^ == == | == | == == Pd == | == == | == | == == = == s == | | | == == == == == == == == == == == == == t: thickness of fin plate Pf: fin pitch (centerline-to-centerline distance between fins) Pd: indentation for waviness (not including fin thickness) s: fin spacing (free space between fins) = Pf-t |-- Pl -| ___ | / \ | = | | | | \ ___ / | | | | ___ | / \ | Pt | | D | \ ___ / | | | ___ | / \ = | | \ ___ / """ Ntubes_bank = Inputs.Tubes.NTubes_per_bank #tubes per bank Nbank = Inputs.Tubes.Nbank #Number of banks Ltube = Inputs.Tubes.Ltube #length of a single tube D = Inputs.Tubes.OD #Outer diameter of tube Pl = Inputs.Tubes.Pl #Horizontal spacing between banks (center to center) Pt = Inputs.Tubes.Pt #Vertical spacing between tubes in a bank (center to center) FPI = Inputs.Fins.FPI pd = Inputs.Fins.Pd xf = Inputs.Fins.xf t = Inputs.Fins.t k_fin = Inputs.Fins.k_fin Vdot_ha = Inputs.Air.Vdot_ha p = Inputs.Air.p if hasattr(Inputs, 'Tmean'): Temp = Inputs.Air.Tmean else: Temp = Inputs.Air.Tdb if hasattr(Inputs, 'RHmean'): RHin = Inputs.Air.RHmean else: RHin = Inputs.Air.RH # Check that cs_cp is defined, if so, set it to the value passed in if (hasattr(Inputs, 'cs_cp') and Inputs.cs_cp > 0) or (hasattr(Inputs, 'WetDry') and Inputs.WetDry == 'Wet'): isWet = True cs_cp = Inputs.Air.cs_cp else: isWet = False cs_cp = 1.0 #Film temperature [K] Tfilm = Temp #Fins per meter [1/m] FPM = FPI / 0.0254 #Fin pitch (distance between centerlines of fins) pf = 1 / FPM #Spacing between fins s = 1 / FPM - t #Height of heat exchanger [m] Height = Pt * ( Ntubes_bank + 1 ) #assuming that fin extends 1/2 pt above/below last tube in bundle #A_duct is the face area [m^2] equivalent to the duct cross-section A_duct = Height * Ltube #neglecting the additional height of the fins above/below the last tubes in the bundle #Number of fins in the tube sheet [-] Nfin = Ltube * FPM #Secant of theta is the area enhancement factor [-] # It captures the increase in area due to the waviness of the fins sec_theta = sqrt(xf * xf + pd * pd) / xf # Duct cross-sectional area that is not fin or tube [m^2] Ac = A_duct - t * Nfin * (Height - D * Ntubes_bank) - Ntubes_bank * D * Ltube # Total outer area of the tubes [m^2] Atube = Ntubes_bank * Nbank * pi * D * Ltube #Wetted Area of a single fin [m^2] A_1fin = 2.0 * ( Height * Pl * (Nbank + 1) * sec_theta - Ntubes_bank * Nbank * pi * D * D / 4 ) #assuming that fin extends 1/2 pt in front/after last tube in bundle # Total wetted area of the fins [m^2] Af = Nfin * A_1fin #Total area including tube and fins [m^2] A = Af + Ntubes_bank * Nbank * pi * D * (Ltube - Nfin * t) #Evaluate the mass flow rate based on inlet conditions # To convert a parameter from per kg_{dry air} to per kg_{humid air}, divide by (1+W) W = HAPropsSI('W', 'T', Inputs.Air.Tdb, 'P', p, 'R', Inputs.Air.RH) v_da = HAPropsSI('V', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) h_da = HAPropsSI('H', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) #[J/kg] rho_ha = 1 / v_da * (1 + W) #[kg_ha/m^3] rho_da = 1 / v_da #[kg_da/m^3] mdot_ha = Vdot_ha * rho_ha #[kg_ha/s] mdot_da = Vdot_ha * rho_da #[kg_da/s] umax = mdot_ha / (rho_ha * Ac) #[m/s] #Use a forward difference to calculate cp from cp=dh/dT dT = 0.0001 #[K] cp_da = (HAPropsSI('H', 'T', Inputs.Air.Tdb + dT, 'P', p, 'W', W) - h_da) / dT #[J/kg_da/K] cp_ha = cp_da / (1 + W) #[J/kg_ha/K] #Transport properties of humid air from CoolProp mu_ha = HAPropsSI('M', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) k_ha = HAPropsSI('K', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) #Dimensionless Groups Pr = cp_ha * mu_ha / k_ha Re_D = rho_ha * umax * D / mu_ha #Heat transfer j = 16.06 * pow(Re_D, -1.02 * (pf / D) - 0.256) * pow(A / Atube, -0.601) * pow( Nbank, -0.069) * pow(pf / D, 0.84) #Colburn j-Factor h_a = j * rho_ha * umax * cp_ha / pow( Pr, 2.0 / 3.0) #air side mean heat transfer coefficient #air side pressure drop correlations if (Re_D < 1e3): fa_total = 0.264 * (0.105 + 0.708 * exp(-Re_D / 225.0)) * pow( Re_D, -0.637) * pow(A / Atube, 0.263) * pow(pf / D, -0.317) else: fa_total = 0.768 * (0.0494 + 0.142 * exp(-Re_D / 1180.0)) * pow( A / Atube, 0.0195) * pow(pf / D, -0.121) #calcs needed for specific fin types r = D / 2 X_D = sqrt(Pl * Pl + Pt * Pt / 4) / 2 X_T = Pt / 2 rf_r = 1.27 * X_T / r * sqrt(X_D / X_T - 0.3) m = sqrt(2 * h_a * cs_cp / (k_fin * t)) #cs_cp is the correction for heat/mass transfer #Using the circular fin correlation of Schmidt phi = (rf_r - 1) * (1 + 0.35 * log(rf_r)) eta_f = tanh(m * r * phi) / (m * r * phi) # Fin efficiency based on analysis in # "FIN EFFICIENCY CALCULATION IN ENHANCED FIN-AND-TUBE HEAT EXCHANGERS IN DRY CONDITIONS" # by Thomas PERROTIN, Denis CLODIC, International Congress of Refrigeration 2006 # In the paper, there is no 0.1 in the cosine term, but if the cosine term is used without # the correction, the results are garbage for wet analysis # Using the offset fins correlation phi = (rf_r - 1) * (1 + (0.3 + pow(m * (rf_r * r - r) / 2.5, 1.5 - rf_r / 12.0) * (0.26 * pow(rf_r, 0.3) - 0.3)) * log(rf_r)) #finned surface efficiency eta_f = tanh(m * r * phi) / (m * r * phi) * cos(0.1 * m * r * phi) #overall surface efficiency eta_o = 1 - Af / A * (1 - eta_f) G_c = mdot_ha / Ac #air mass flux DeltaP_air = A / Ac / rho_ha * G_c**2 / 2.0 * fa_total #airside pressure drop #write necessary values back into the given structure Inputs.A_a = A Inputs.cp_da = cp_da Inputs.cp_ha = cp_ha if isWet == True: Inputs.eta_a_wet = eta_o else: Inputs.eta_a = eta_o Inputs.h_a = h_a Inputs.mdot_ha = mdot_ha Inputs.mdot_da = mdot_da Inputs.f_a = fa_total Inputs.dP_a = DeltaP_air Inputs.Re = Re_D
def Calculate(self): #Initialize self.Initialize() AS = self.AS #assume we have all supercritical region self.Tout_r_cr = self.Tcr #give an intial guess for the inner wall temperature self.T_w = (self.Tout_r_cr + self.Tin_a) / 2 #If we have already used too much of the HX (max possible sum of w is 1.0) if self._Supercritical_Forward(1.0) < 0: self.existsSubcooled = False self.w_supercritical = 1.0 def OBJECTIVE(Tout_r_cr): self.Tout_r_cr = Tout_r_cr AS.update(CP.PT_INPUTS, self.psat_r, self.Tout_r_cr) hout = AS.hmass() Q_target = self.mdot_r * (hout - self.hin_r) self._Supercritical_Forward(self.w_supercritical) return self.Q_supercritical - Q_target brentq(OBJECTIVE, self.Tin_r, self.Tcr) #Zero out all the supercritical_liquid parameters self.Q_supercrit_liq = 0.0 self.DP_r_supercrit_liq = 0.0 self.Charge_supercrit_liq = 0.0 self.w_supercrit_liq = 0.0 self.h_r_supercrit_liq = 0.0 self.Re_r_supercrit_liq = 0.0 self.Tout_a_supercrit_liq = 0.0 self.fdry_supercrit_liq = 0.0 else: #By definition then we have a supercritical_liquid portion, solve for it self.existsSubcooled = True self.w_supercritical = brentq(self._Supercritical_Forward, 0.00000000001, 0.9999999999) def OBJECTIVE(Tout_r_sc): self.Tout_r_sc = Tout_r_sc AS.update(CP.PT_INPUTS, self.psat_r, self.Tout_r_sc) hout = AS.hmass() Q_target = self.mdot_r * (hout - self.hcr) self._Supercrit_liq_Forward(1 - self.w_supercritical) return self.Q_supercrit_liq - Q_target brentq(OBJECTIVE, self.Tcr, self.Ttriple) #Overall calculations self.Q = self.Q_supercritical + self.Q_supercrit_liq self.DP_r = (self.DP_r_supercritical + self.DP_r_supercrit_liq ) * self.DP_tuning #correcting the pressure drop self.Charge = self.Charge_supercritical + self.Charge_supercrit_liq #Average air outlet temperature (area fraction weighted average) [K] self.Tout_a = self.w_supercritical * self.Tout_a_supercritical + self.w_supercrit_liq * self.Tout_a_supercrit_liq #Outlet enthalpy obtained from energy balance self.hout_r = self.hin_r + self.Q / self.mdot_r AS.update(CP.HmassP_INPUTS, self.hout_r, self.psat_r) self.Tout_r = AS.T() #[K] self.sout_r = AS.smass() #[J/kg-K] #Approach temperature self.DT_app = self.Tout_r - self.Tin_a self.hmean_r = self.w_supercritical * self.h_r_supercritical + self.w_supercrit_liq * self.h_r_supercrit_liq self.UA_r = self.hmean_r * self.A_r_wetted self.UA_a = (self.Fins.h_a * self.h_a_tuning) * self.Fins.A_a * self.Fins.eta_a self.UA_w = 1 / self.Rw #Upadte air-side pressure drop based on the outlet air temperature #the air-side pressure drop here include momentum, contraction and expansion effects #Objective function def OBJECTIVE_PD(x): Pair_o = x[0] W = x[1] if W < 0: #to ensure that the humidty ratio is print( 'Microchannel GasCooler -- Humidity ratio for air pressure drop is less than zero. Humidity ratio is set to 0.0' ) W = 0.0 v_da = HAPropsSI('V', 'T', self.Tout_a, 'P', Pair_o, 'W', W) W_new = HAPropsSI('W', 'T', self.Tout_a, 'P', Pair_o, 'V', v_da) #outlet air density rho_o = 1 / v_da * (1 + W_new) #[m^3/kg_ha] #mean air density rho_m = pow(0.5 * (1 / self.Fins.rho_i_air + 1 / rho_o), -1) #air-side pressure drop including momentum, expansion and contraction effects DeltaP_air = self.Fins.G_air**2 / 2 / self.Fins.rho_i_air * ( (1 - self.Fins.sigma**2 + self.Fins.Kc_tri) + 2 * (self.Fins.rho_i_air / rho_o - 1) + self.Fins.f_a * self.Fins.A_a / self.Fins.A_a_c * (self.Fins.rho_i_air / rho_m) - (1 - self.Fins.sigma**2 - self.Fins.Ke_tri) * (self.Fins.rho_i_air / rho_o)) resids = [(self.Pin_a - Pair_o) - DeltaP_air, W - W_new] return resids #Initial guesses P_init = self.Pin_a w_init = HAPropsSI('W', 'T', self.Tin_a, 'P', self.Pin_a, 'R', self.RHin_a) #solve for outlet air pressure and outlet humidity ratio x = fsolve(OBJECTIVE_PD, [P_init, w_init]) #update the air-side pressure drop self.dP_a = self.Pin_a - x[0]
def HerringboneFins(Inputs): #Source: #Empirical correlations for heat transfer and flow friction characteristics of herringbone wavy fin-and-tube heat exchangers #Chi-Chuan Wang, Young-Ming Hwang, Yur-Tsai Lin #International Journal of Refrigeration, 25, 2002, 637-680 #Properties: p = Inputs.Air.p #air pressure W = HAPropsSI('W', 'T', Inputs.Air.Tdb, 'P', p, 'R', Inputs.Air.RH) #Transport properties of humid air from CoolProp mu_ha = HAPropsSI('M', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) k_ha = HAPropsSI('K', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) #Evaluate the mass flow rate based on inlet conditions Vdot_ha = Inputs.Air.Vdot_ha # To convert a parameter from per kg_{dry air} to per kg_{humid air}, divide by (1+W) W = HAPropsSI('W', 'T', Inputs.Air.Tdb, 'P', p, 'R', Inputs.Air.RH) v_da = HAPropsSI('V', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) h_da = HAPropsSI('H', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) #[J/kg] rho_ha = 1 / v_da * (1 + W) #[kg_ha/m^3] rho_da = 1 / v_da #[kg_da/m^3] mdot_ha = Vdot_ha * rho_ha #[kg_ha/s] mdot_da = Vdot_ha * rho_da #[kg_da/s] #Use a forward difference to calculate cp from cp=dh/dT dT = 0.0001 #[K] cp_da = (HAPropsSI('H', 'T', Inputs.Air.Tdb + dT, 'P', p, 'W', W) - h_da) / dT #[J/kg_da/K] cp_ha = cp_da / (1 + W) #[J/kg_ha/K] # Check that cs_cp is defined, if so, set it to the value passed in if (hasattr(Inputs, 'cs_cp') and Inputs.cs_cp > 0) or (hasattr(Inputs, 'WetDry') and Inputs.WetDry == 'Wet'): isWet = True cs_cp = Inputs.Air.cs_cp else: isWet = False cs_cp = 1.0 #Dimensions and values used for both Reynolds number ranges: delta_f = Inputs.Fins.t #fin thickness(m) FPI = Inputs.Fins.FPI #fins per inch FPM = FPI / 0.0254 #Fins per meter [1/m] pf = 1 / FPM #Fin pitch (distance between centerlines of fins) F_s = 1 / FPM - delta_f #Fin spacing(m) P_t = Inputs.Tubes.Pt #transverse tube pitch (m) P_L = Inputs.Tubes.Pl #longitudinal tube pitch (m) D_o = Inputs.Tubes.OD #Outer diameter of tube (m) D_c = D_o + 2 * delta_f #fin collar outside diameter (m) (tube + 2*fin thickness) Ltube = Inputs.Tubes.Ltube #length of a single tube [m] Nfin = Ltube * FPM #Number of fins in the tube sheet [-] Ntubes_bank = Inputs.Tubes.NTubes_per_bank #tubes per bank Height = P_t * ( Ntubes_bank + 1 ) #Height of heat exchanger [m] # assuming that fin extends 1/2 pt above/below last tube in bundle A_duct = Height * Ltube #A_duct is the face area [m^2] - equivalent to the duct cross-section #neglecting the additional height of the fins above/below the last tubes in the bundle Ac = A_duct - delta_f * Nfin * ( Height - D_c * Ntubes_bank ) - Ntubes_bank * D_c * Ltube #Minimum duct cross-sectional area that is not fin or tube(-collar) [m^2] u_max = mdot_ha / (rho_ha * Ac) #maximum airside velocity [m/s] Re_Dc = rho_ha * u_max * D_c / mu_ha #from reference #4 of Wang et all. Slightly different notation used in [4] P_d = Inputs.Fins.Pd #wave height X_f = Inputs.Fins.xf #projected fin length (m) tanTheta = P_d / X_f #tangens of corrugation angle secTheta = sqrt( X_f * X_f + P_d * P_d ) / X_f ###!!used wavy louvered fins definition - there seems to be a bug in the paper !! beta = (pi * D_c**2) / (4.0 * P_t * P_L) oneMbeta = 1.0 - beta #save one operation D_h = 2.0 * F_s * oneMbeta / (oneMbeta * secTheta + 2 * F_s * beta / D_c ) # hydraulic diameter (m) N = Inputs.Tubes.Nbank #number of lomgitudunal tube rows (#Number of banks in ACHP-notation) if Re_Dc < 1000.0: #Heat transfer J1 = 0.0045 - 0.491 * pow(Re_Dc, -0.0316 - 0.0171 * log( N * tanTheta)) * pow(P_L / P_t, -0.109 * log(N * tanTheta)) * pow( D_c / D_h, 0.542 + 0.0471 * N) * pow(F_s / D_c, 0.984) * pow( F_s / P_t, -0.349) J2 = -2.72 + 6.84 * tanTheta J3 = 2.66 * tanTheta j = 0.882 * pow(Re_Dc, J1) * pow(D_c / D_h, J2) * pow( F_s / P_t, J3) * pow(F_s / D_c, -1.58) * pow(tanTheta, -0.2) #Friction F1 = -0.574 - 0.137 * pow(log(Re_Dc) - 5.26, 0.245) * pow( P_t / D_c, -0.765) * pow(D_c / D_h, -0.243) * pow( F_s / D_h, -0.474) * pow(tanTheta, -0.217) * pow(N, 0.035) F2 = -3.05 * tanTheta F3 = -0.192 * N F4 = -0.646 * tanTheta f = 4.37 * pow(Re_Dc, F1) * pow(F_s / D_h, F2) * pow( P_L / P_t, F3) * pow(D_c / D_h, 0.2054) * pow(N, F4) else: #Heat transfer j1 = -0.0545 - 0.0538 * tanTheta - 0.302 * pow(N, -0.24) * pow( F_s / P_L, -1.3) * pow(P_L / P_t, 0.379) * pow( P_L / D_h, -1.35) * pow(tanTheta, -0.256) j2 = -1.29 * pow(P_L / P_t, 1.77 - 9.43 * tanTheta) * pow( D_c / D_h, 0.229 - 1.43 * tanTheta) * pow(N, -0.166 - 1.08 * tanTheta) * pow( F_s / P_t, -0.174 * log(0.5 * N)) j = 0.0646 * pow(Re_Dc, j1) * pow(D_c / D_h, j2) * pow( F_s / P_t, -1.03) * pow(P_L / D_c, 0.432) * pow( tanTheta, -0.692) * pow(N, -0.737) #Friction f1 = -0.141 * pow(F_s / P_L, 0.0512) * pow(tanTheta, -0.472) * pow( P_L / P_t, 0.35) * pow(P_t / D_h, 0.449 * tanTheta) * pow( N, -0.049 + 0.237 * tanTheta) f2 = -0.562 * pow(log(Re_Dc), -0.0923) * pow(N, 0.013) f3 = 0.302 * pow(Re_Dc, 0.03) * pow(P_t / D_c, 0.026) f4 = -0.306 + 3.63 * tanTheta f = 0.228 * pow(Re_Dc, f1) * pow(tanTheta, f2) * pow( F_s / P_L, f3) * pow(P_L / D_c, f4) * pow(D_c / D_h, 0.383) * pow( P_L / P_t, -0.247) Pr = cp_ha * mu_ha / k_ha h_a = j * rho_ha * u_max * cp_ha / pow( Pr, 2.0 / 3.0) #air side mean heat transfer coefficient using colborn j-factor #calcs needed for specific fin types #additional parameters needed k_fin = Inputs.Fins.k_fin Nbank = Inputs.Tubes.Nbank #Number of banks #secTheta=sqrt(X_f*X_f + P_d*P_d) / X_f #secTheta : already calculated, no need to re-calculate it #Wetted Area of a single fin [m^2] A_1fin = 2.0 * ( Height * P_L * (Nbank + 1) * secTheta - Ntubes_bank * Nbank * pi * D_o * D_o / 4 ) #assuming that fin extends 1/2 pt in front/after last tube in bundle # Total wetted area of the fins [m^2] Af = Nfin * A_1fin #Total area including tube and fins [m^2] A = Af + Ntubes_bank * Nbank * pi * D_o * (Ltube - Nfin * delta_f) r = D_o / 2 X_D = sqrt(P_L * P_L + P_t * P_t / 4) / 2 X_T = P_t / 2 rf_r = 1.27 * X_T / r * sqrt(X_D / X_T - 0.3) m = sqrt( 2 * h_a * cs_cp / (k_fin * delta_f)) #cs_cp is the correction for heat/mass transfer #Using the circular fin correlation of Schmidt phi = (rf_r - 1) * (1 + 0.35 * log(rf_r)) eta_f = tanh(m * r * phi) / (m * r * phi) # Fin efficiency based on analysis in # "FIN EFFICIENCY CALCULATION IN ENHANCED FIN-AND-TUBE HEAT EXCHANGERS IN DRY CONDITIONS" # by Thomas PERROTIN, Denis CLODIC, International Congress of Refrigeration 2006 # In the paper, there is no 0.1 in the cosine term, but if the cosine term is used without # the correction, the results are garbage for wet analysis # Using the offset fins correlation phi = (rf_r - 1) * (1 + (0.3 + pow(m * (rf_r * r - r) / 2.5, 1.5 - rf_r / 12.0) * (0.26 * pow(rf_r, 0.3) - 0.3)) * log(rf_r)) #finned surface efficiency eta_f = tanh(m * r * phi) / (m * r * phi) * cos(0.1 * m * r * phi) #overall surface efficiency eta_o = 1 - Af / A * (1 - eta_f) G_c = mdot_ha / Ac #air mass flux Atube = Ntubes_bank * Nbank * pi * D_o * Ltube # Total outer area of the tubes [m^2] DeltaP_air = A / Ac / rho_ha * G_c**2 / 2.0 * f #airside pressure drop #write necessary values back into the given structure Inputs.A_a = A Inputs.cp_da = cp_da Inputs.cp_ha = cp_ha if isWet == True: Inputs.eta_a_wet = eta_o else: Inputs.eta_a = eta_o Inputs.h_a = h_a Inputs.mdot_ha = mdot_ha Inputs.mdot_da = mdot_da Inputs.f_a = f Inputs.dP_a = DeltaP_air Inputs.Re = Re_Dc
def PlainFins(Inputs): #Source: #Heat transfer and friction characteristics of plain fin-and-tube heat exchangers, part II: Correlation #Chi-Chuan Wang, Kuan-Yu Chi, Chun-Jung Chang #Properties: p = Inputs.Air.p #air pressure in kPa W = HAPropsSI('W', 'T', Inputs.Air.Tdb, 'P', p, 'R', Inputs.Air.RH) #Transport properties of humid air from CoolProp mu_ha = HAPropsSI('M', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) k_ha = HAPropsSI('K', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) #Evaluate the mass flow rate based on inlet conditions Vdot_ha = Inputs.Air.Vdot_ha # To convert a parameter from per kg_{dry air} to per kg_{humid air}, divide by (1+W) W = HAPropsSI('W', 'T', Inputs.Air.Tdb, 'P', p, 'R', Inputs.Air.RH) v_da = HAPropsSI('V', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) h_da = HAPropsSI('H', 'T', Inputs.Air.Tdb, 'P', p, 'W', W) rho_ha = 1 / v_da * (1 + W) #[kg_ha/m^3] rho_da = 1 / v_da #[kg_da/m^3] mdot_ha = Vdot_ha * rho_ha #[kg_ha/s] mdot_da = Vdot_ha * rho_da #[kg_da/s] #Use a forward difference to calculate cp from cp=dh/dT dT = 0.0001 #[K] cp_da = (HAPropsSI('H', 'T', Inputs.Air.Tdb + dT, 'P', p, 'W', W) - h_da) / dT #[J/kg_da/K] cp_ha = cp_da / (1 + W) #[J/kg_ha/K] # Check that cs_cp is defined, if so, set it to the value passed in if (hasattr(Inputs, 'cs_cp') and Inputs.cs_cp > 0) or (hasattr(Inputs, 'WetDry') and Inputs.WetDry == 'Wet'): isWet = True cs_cp = Inputs.Air.cs_cp else: isWet = False cs_cp = 1.0 #Dimensions and values used for both Reynolds number ranges: delta_f = Inputs.Fins.t #fin thickness(m) FPI = Inputs.Fins.FPI #fins per inch FPM = FPI / 0.0254 #Fins per meter [1/m] F_p = 1 / FPM #Fin pitch (distance between centerlines of fins) F_s = 1 / FPM - delta_f #Fin spacing(m) P_t = Inputs.Tubes.Pt #transverse tube pitch (m) P_L = Inputs.Tubes.Pl #longitudinal tube pitch (m) D_o = Inputs.Tubes.OD #Outer diameter of tube (m) D_c = D_o + 2 * delta_f #fin collar outside diameter (m) (tube + 2*fin thickness) Ltube = Inputs.Tubes.Ltube #length of a single tube [m] Nfin = Ltube * FPM #Number of fins in the tube sheet [-] Ntubes_bank = Inputs.Tubes.NTubes_per_bank #tubes per bank Height = P_t * ( Ntubes_bank + 1 ) #Height of heat exchanger [m] # assuming that fin extends 1/2 pt above/below last tube in bundle A_duct = Height * Ltube #A_duct is the face area [m^2] - equivalent to the duct cross-section #neglecting the additional height of the fins above/below the last tubes in the bundle A_c = A_duct - delta_f * Nfin * ( Height - D_c * Ntubes_bank ) - Ntubes_bank * D_c * Ltube #Minimum duct cross-sectional area that is not fin or tube(-collar) [m^2] u_max = mdot_ha / (rho_ha * A_c) #maximum airside velocity [m/s] Re_Dc = rho_ha * u_max * D_c / mu_ha #from reference #4 of Wang et all. Slightly different notation used in [4] N = Inputs.Tubes.Nbank #number of lomgitudunal tube rows (#Number of banks in ACHP-notation) L = ( N + 1 ) * P_L #depth of heat exchanger in airflow direction, assuming fins extends 1/2 bank oer the first and last tube Nbank = N #to be able to reuse equations #Wetted Area of a single fin [m^2] A_1fin = 2.0 * ( Height * P_L * (Nbank + 1) - Ntubes_bank * Nbank * pi * D_c * D_c / 4 ) #assuming that fin extends 1/2 pt in front/after last tube in bundle # Total wetted area of the fins [m^2] Af = Nfin * A_1fin #Total area including tube and fins [m^2] A_o = Af + Ntubes_bank * Nbank * pi * D_c * (Ltube - Nfin * delta_f) D_h = 4 * A_c * L / A_o #Hydraulic diameter #heat transfer if N == 1: P1 = 1.9 - 0.23 * log(Re_Dc) P2 = -0.236 + 0.126 * log(Re_Dc) j = 0.108 * pow(Re_Dc, -0.29) * pow(P_t / P_L, P1) * pow( F_p / D_h, -1.084) * pow(F_p / D_h, -0.786) * pow(F_p / P_t, P2) if N >= 2: P3 = -0.361 - 0.042 * N / log(Re_Dc) + 0.158 * log(N * (F_p / D_c)**0.41) P4 = -1.224 - 0.076 * pow(P_L / D_h, 1.42) / log(Re_Dc) P5 = -0.083 + 0.058 * N / log(Re_Dc) P6 = -5.735 + 1.21 * log(Re_Dc / N) j = 0.086 * pow(Re_Dc, P3) * pow(N, P4) * pow(F_p / D_c, P5) * pow( F_p / D_h, P6) * pow(F_p / P_t, -0.93) #pressure drop F1 = -0.764 + 0.739 * P_t / P_L + 0.177 * F_p / D_c - 0.00758 / N F2 = -15.689 + 64.021 / log(Re_Dc) F3 = 1.696 - 15.695 / log(Re_Dc) f = 0.0267 * pow(Re_Dc, F1) * pow(P_t / P_L, F2) * pow(F_p / D_c, F3) Pr = cp_ha * mu_ha / k_ha h_a = j * rho_ha * u_max * cp_ha / pow( Pr, 2.0 / 3.0) #air side mean heat transfer coefficient using colborn j-factor #calcs needed for specific fin types #additional parameters needed k_fin = Inputs.Fins.k_fin #Total area including tube and fins [m^2] A = A_o r = D_o / 2 X_D = sqrt(P_L * P_L + P_t * P_t / 4) / 2 X_T = P_t / 2 rf_r = 1.27 * X_T / r * sqrt(X_D / X_T - 0.3) m = sqrt( 2 * h_a * cs_cp / (k_fin * delta_f)) #cs_cp is the correction for heat/mass transfer #Using the circular fin correlation of Schmidt phi = (rf_r - 1) * (1 + 0.35 * log(rf_r)) eta_f = tanh(m * r * phi) / (m * r * phi) # Fin efficiency based on analysis in # "FIN EFFICIENCY CALCULATION IN ENHANCED FIN-AND-TUBE HEAT EXCHANGERS IN DRY CONDITIONS" # by Thomas PERROTIN, Denis CLODIC, International Congress of Refrigeration 2006 # In the paper, there is no 0.1 in the cosine term, but if the cosine term is used without # the correction, the results are garbage for wet analysis # Using the offset fins correlation phi = (rf_r - 1) * (1 + (0.3 + pow(m * (rf_r * r - r) / 2.5, 1.5 - rf_r / 12.0) * (0.26 * pow(rf_r, 0.3) - 0.3)) * log(rf_r)) #finned surface efficiency eta_f = tanh(m * r * phi) / (m * r * phi) * cos(0.1 * m * r * phi) #overall surface efficiency eta_o = 1 - Af / A * (1 - eta_f) G_c = mdot_ha / A_c #air mass flux Atube = Ntubes_bank * Nbank * pi * D_o * Ltube # Total outer area of the tubes [m^2] DeltaP_air = A / A_c / rho_ha * G_c**2 / 2.0 * f #airside pressure drop #write necessary values back into the given structure Inputs.A_a = A Inputs.cp_da = cp_da Inputs.cp_ha = cp_ha if isWet == True: Inputs.eta_a_wet = eta_o else: Inputs.eta_a = eta_o Inputs.h_a = h_a Inputs.mdot_ha = mdot_ha Inputs.mdot_da = mdot_da Inputs.f_a = f Inputs.dP_a = DeltaP_air Inputs.Re = Re_Dc
def OBJECTIVE(x): Tevap = x[0] Tcond = x[1] #Condensing heat transfer rate from enthalpies rho_air = 1.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 ) * 1005 #Cp_air =1005J/kg/K #Cycle.Condenser.Fins.Air.Vdot_ha/rho_air, division is updated with * pevap = PropsSI('P', 'T', Tevap, 'Q', 1.0, Cycle.Ref) pcond = PropsSI('P', 'T', Tcond, 'Q', 1.0, Cycle.Ref) 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) * 1005 #updated #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.Ref, 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) #*1000 #[J/kg_da] h_s_w_o = HAPropsSI('H', 'T', Tevap, 'P', 101325, 'R', 1.0) #*1000 #[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 Qcond_enthalpy = Cycle.Compressor.mdot_r * ( Cycle.Compressor.hout_r - PropsSI( 'H', 'T', Tcond - Cycle.DT_sc_target, 'P', pcond, Cycle.Ref) ) #*1000) resids = [Qevap + W + Qcond, Qcond + Qcond_enthalpy] #,Qevap,f_dry] return resids
def DryWetSegment(DWS): """ Generic solver function for dry-wet mixed surface conditions for a given element. Can handle superheated, subcooled and two-phase regions. Does not handle the pressure drops, only HT required to get the dry/wet interface """ #List of required parameters RequiredParameters = [ 'Tin_a', 'h_a', 'cp_da', 'eta_a', 'A_a', 'pin_a', 'RHin_a', 'Tin_r', 'pin_r', 'h_r', 'cp_r', 'A_r', 'Rw', 'mdot_r', 'Fins', 'FinsType' ] #Check that all the parameters are included, raise exception otherwise for param in RequiredParameters: if not hasattr(DWS, param): raise AttributeError("Parameter " + param + " is required for DWS class in DryWetSegment") #Retrieve values from structures defined above Tin_a = DWS.Tin_a if DWS.h_a < 0.000000001: print("Warning: Dws.h_a was constrained to 0.001, original value: ", DWS.h_a) h_a = 0.000000001 else: h_a = DWS.h_a cp_da = DWS.cp_da eta_a = DWS.eta_a #from fin correlations, overall airside surface effectiveness A_a = DWS.A_a pin_a = DWS.pin_a RHin_a = DWS.RHin_a mdot_da = DWS.mdot_da Tin_r = DWS.Tin_r pin_r = DWS.pin_r if DWS.h_r < 0.000000001: print("Warning: Dws.h_r was constrained to 0.001, original value: ", DWS.h_r) h_r = 0.000000001 else: h_r = DWS.h_r cp_r = DWS.cp_r A_r = DWS.A_r mdot_r = DWS.mdot_r Rw = DWS.Rw #Calculate the dewpoint (amongst others) omega_in = HAPropsSI('W', 'T', Tin_a, 'P', pin_a, 'R', RHin_a) Tdp = HAPropsSI('D', 'T', Tin_a, 'P', pin_a, 'W', omega_in) hin_a = HAPropsSI('H', 'T', Tin_a, 'P', pin_a, 'W', omega_in) #[J/kg_da] # Internal UA between fluid flow and outside surface (neglecting tube conduction) UA_i = h_r * A_r #[W/K], from Shah or f_h_1phase_Tube-fct -> Correlations.py # External UA between wall and free stream UA_o = eta_a * h_a * A_a #[W/K], from fin correlations # wall UA UA_w = 1 / Rw # Internal Ntu Ntu_i = UA_i / (mdot_r * cp_r) #[-] # External Ntu (multiplied by eta_a since surface is finned and has lower effectiveness) Ntu_o = eta_a * h_a * A_a / (mdot_da * cp_da) #[-] if DWS.IsTwoPhase: #(Two-Phase analysis) UA = 1 / (1 / (h_a * A_a * eta_a) + 1 / (h_r * A_r) + 1 / UA_w) #overall heat transfer coefficient Ntu_dry = UA / (mdot_da * cp_da) #Number of transfer units epsilon_dry = 1 - exp(-Ntu_dry) #since Cr=0, e.g. see Incropera - Fundamentals of Heat and Mass Transfer, 2007, p. 690 Q_dry = epsilon_dry * mdot_da * cp_da * (Tin_a - Tin_r) Tout_a = Tin_a - Q_dry / (mdot_da * cp_da) #outlet temperature, dry fin T_so_a = (UA_o * Tin_a + UA_i * Tin_r) / (UA_o + UA_i) #inlet surface temperature (neglect wall thermal conductance) T_so_b = (UA_o * Tout_a + UA_i * Tin_r) / (UA_o + UA_i) #outlet surface temperature (neglect wall thermal conductance) if T_so_b > Tdp: #All dry, since surface at outlet dry f_dry = 1.0 Q = Q_dry #[W] Q_sensible = Q #[W] hout_a = hin_a - Q / mdot_da #[J/kg_da] # Air outlet humidity ratio DWS.omega_out = omega_in #[kg/kg] else: if T_so_a < Tdp: #All wet, since surface at inlet wet f_dry = 0.0 Q_dry = 0.0 T_ac = Tin_a #temp at onset of wetted wall h_ac = hin_a #enthalpy at onset of wetted surface else: # Partially wet and dry (i.e T_so_b<Tdp<T_so_a) # Air temperature at the interface between wet and dry surface # Based on equating heat fluxes at the wall which is at dew point UA_i*(Tw-Ti)=UA_o*(To-Tw) T_ac = Tdp + UA_i / UA_o * (Tdp - Tin_r) # Dry effectiveness (minimum capacitance on the air side by definition) epsilon_dry = (Tin_a - T_ac) / (Tin_a - Tin_r) # Dry fraction found by solving epsilon=1-exp(-f_dry*Ntu) for known epsilon from above equation f_dry = -1.0 / Ntu_dry * log(1.0 - epsilon_dry) # Enthalpy, using air humidity at the interface between wet and dry surfaces, which is same humidity ratio as inlet h_ac = HAPropsSI('H', 'T', T_ac, 'P', pin_a, 'W', omega_in) #[J/kg_da] # Dry heat transfer Q_dry = mdot_da * cp_da * (Tin_a - T_ac) # Saturation specific heat at mean water temp (c_s : partial derivative dh_sat/dT @ Tsat_r) c_s = cair_sat(Tin_r) * 1000 #[J/kg-K] # Find new, effective fin efficiency since cs/cp is changed from wetting # Ratio of specific heats [-] DWS.Fins.Air.cs_cp = c_s / cp_da DWS.Fins.WetDry = 'Wet' #Compute the fin efficiency based on the user choice of FinsType if DWS.FinsType == 'WavyLouveredFins': WavyLouveredFins(DWS.Fins) elif DWS.FinsType == 'HerringboneFins': HerringboneFins(DWS.Fins) elif DWS.FinsType == 'PlainFins': PlainFins(DWS.Fins) elif DWS.FinsType == 'MultiLouveredMicroFins': MultiLouveredMicroFins(DWS.Fins) eta_a_wet = DWS.Fins.eta_a_wet UA_o = eta_a_wet * h_a * A_a Ntu_o = eta_a_wet * h_a * A_a / (mdot_da * cp_da) # Wet analysis overall Ntu for two-phase refrigerant # Minimum capacitance rate is by definition on the air side # Ntu_wet is the NTU if the entire two-phase region were to be wetted UA_wet = 1 / (c_s / UA_i + cp_da / UA_o + c_s / UA_w) Ntu_wet = UA_wet / (mdot_da) # Wet effectiveness [-] epsilon_wet = 1 - exp(-(1 - f_dry) * Ntu_wet) # Air saturated at refrigerant saturation temp [J/kg] h_s_s_o = HAPropsSI('H', 'T', Tin_r, 'P', pin_a, 'R', 1.0) #[kJ/kg_da] # Wet heat transfer [W] Q_wet = epsilon_wet * mdot_da * (h_ac - h_s_s_o) # Total heat transfer [W] Q = Q_wet + Q_dry # Air exit enthalpy [J/kg] hout_a = h_ac - Q_wet / mdot_da # Saturated air temp at effective surface temp [J/kg_da] h_s_s_e = h_ac - (h_ac - hout_a) / (1 - exp(-(1 - f_dry) * Ntu_o)) # Effective surface temperature [K] T_s_e = HAPropsSI('T', 'H', h_s_s_e, 'P', pin_a, 'R', 1.0) # Outlet dry-bulb temp [K] Tout_a = T_s_e + (T_ac - T_s_e) * exp(-(1 - f_dry) * Ntu_o) #Sensible heat transfer rate [kW] Q_sensible = mdot_da * cp_da * (Tin_a - Tout_a) #Outlet is saturated vapor Tout_r = DWS.Tdew_r else: #(Single-Phase analysis) #Overall UA UA = 1 / (1 / (UA_i) + 1 / (UA_o) + 1 / (UA_w)) # Min and max capacitance rates [W/K] Cmin = min([cp_r * mdot_r, cp_da * mdot_da]) Cmax = max([cp_r * mdot_r, cp_da * mdot_da]) # Capacitance rate ratio [-] C_star = Cmin / Cmax # Ntu overall [-] Ntu_dry = UA / Cmin if Ntu_dry < 0.0000001: print( "warning: NTU_dry in dry wet segment was negative. forced it to positive value of 0.001!" ) Ntu_dry = 0.0000001 # Counterflow effectiveness [-] #epsilon_dry = ((1 - exp(-Ntu_dry * (1 - C_star))) / # (1 - C_star * exp(-Ntu_dry * (1 - C_star)))) #Crossflow effectiveness (e.g. see Incropera - Fundamentals of Heat and Mass Transfer, 2007, p. 662) if (cp_r * mdot_r) < (cp_da * mdot_da): epsilon_dry = 1 - exp(-C_star**(-1) * (1 - exp(-C_star * (Ntu_dry)))) #Cross flow, single phase, cmax is airside, which is unmixed else: epsilon_dry = (1 / C_star) * (1 - exp(-C_star * (1 - exp(-Ntu_dry)))) #Cross flow, single phase, cmax is refrigerant side, which is mixed # Dry heat transfer [W] Q_dry = epsilon_dry * Cmin * (Tin_a - Tin_r) # Dry-analysis air outlet temp [K] Tout_a_dry = Tin_a - Q_dry / (mdot_da * cp_da) # Dry-analysis outlet temp [K] Tout_r = Tin_r + Q_dry / (mdot_r * cp_r) # Dry-analysis air outlet enthalpy from energy balance [J/kg] hout_a = hin_a - Q_dry / mdot_da # Dry-analysis surface outlet temp [K] (neglect wall thermal conductance) Tout_s = (UA_o * Tout_a_dry + UA_i * Tin_r) / (UA_o + UA_i) # Dry-analysis surface inlet temp [K] (neglect wall thermal conductance) Tin_s = (UA_o * Tin_a + UA_i * Tout_r) / (UA_o + UA_i) # Dry-analysis outlet refrigerant temp [K] Tout_r_dry = Tout_r # Dry fraction [-] f_dry = 1.0 # Air outlet humidity ratio [-] DWS.omega_out = omega_in # If inlet surface temp below dewpoint, whole surface is wetted if Tin_s < Tdp: isFullyWet = True else: isFullyWet = False if Tout_s < Tdp or isFullyWet: # There is some wetting, either the coil is fully wetted or partially wetted # Loop to get the correct c_s # Start with the inlet temp as the outlet temp x1 = Tin_r + 1 #Lowest possible outlet temperature x2 = Tin_a - 1 #Highest possible outlet temperature eps = 1e-8 iter = 1 change = 999 while ((iter <= 3 or change > eps) and iter < 100): if (iter == 1): Tout_r = x1 if (iter > 1): Tout_r = x2 Tout_r_start = Tout_r # Saturated air enthalpy at the inlet water temperature [J/kg] h_s_w_i = HAPropsSI('H', 'T', Tin_r, 'P', pin_a, 'R', 1.0) #[J/kg_da] # Saturation specific heat at mean water temp [J/kg] c_s = cair_sat((Tin_r + Tout_r) / 2.0) * 1000 # Ratio of specific heats [-] DWS.Fins.Air.cs_cp = c_s / cp_da # Find new, effective fin efficiency since cs/cp is changed from wetting # Based on the user choice of FinsType if DWS.FinsType == 'WavyLouveredFins': WavyLouveredFins(DWS.Fins) elif DWS.FinsType == 'HerringboneFins': HerringboneFins(DWS.Fins) elif DWS.FinsType == 'PlainFins': PlainFins(DWS.Fins) elif DWS.FinsType == 'MultiLouveredMicroFins': MultiLouveredMicroFins(DWS.Fins) # Effective humid air mass flow ratio m_star = mdot_da / (mdot_r * (cp_r / c_s)) #compute the new Ntu_owet Ntu_owet = eta_a * h_a * A_a / (mdot_da * cp_da) m_star = min([cp_r * mdot_r / c_s, mdot_da]) / max( [cp_r * mdot_r / c_s, mdot_da]) mdot_min = min([cp_r * mdot_r / c_s, mdot_da]) # Wet-analysis overall Ntu [-] (neglect wall thermal conductance) Ntu_wet = Ntu_o / (1 + m_star * (Ntu_owet / Ntu_i)) if (cp_r * mdot_r > c_s * mdot_da): Ntu_wet = Ntu_o / (1 + m_star * (Ntu_owet / Ntu_i)) else: Ntu_wet = Ntu_i / (1 + m_star * (Ntu_i / Ntu_owet)) # Counterflow effectiveness for wet analysis epsilon_wet = ((1 - exp(-Ntu_wet * (1 - m_star))) / (1 - m_star * exp(-Ntu_wet * (1 - m_star)))) # Wet-analysis heat transfer rate Q_wet = epsilon_wet * mdot_min * (hin_a - h_s_w_i) # Air outlet enthalpy [J/kg_da] hout_a = hin_a - Q_wet / mdot_da # Water outlet temp [K] Tout_r = Tin_r + mdot_da / (mdot_r * cp_r) * (hin_a - hout_a) # Water outlet saturated surface enthalpy [J/kg_da] h_s_w_o = HAPropsSI('H', 'T', Tout_r, 'P', pin_a, 'R', 1.0) #[J/kg_da] #Local UA* and c_s UA_star = 1 / (cp_da / (eta_a * h_a * A_a) + cair_sat( (Tin_a + Tout_r) / 2.0) * 1000 * (1 / (h_r * A_r) + 1 / UA_w)) # Wet-analysis surface temperature [K] Tin_s = Tout_r + UA_star / (h_r * A_r) * (hin_a - h_s_w_o) # Wet-analysis saturation enthalpy [J/kg_da] h_s_s_e = hin_a + (hout_a - hin_a) / (1 - exp(-Ntu_owet)) # Surface effective temperature [K] T_s_e = HAPropsSI('T', 'H', h_s_s_e, 'P', pin_a, 'R', 1.0) # Air outlet temp based on effective temp [K] Tout_a = T_s_e + (Tin_a - T_s_e) * exp(-Ntu_o) #Sensible heat transfer rate [W] Q_sensible = mdot_da * cp_da * (Tin_a - Tout_a) # Error between guess and recalculated value [K] errorToutr = Tout_r - Tout_r_start if (iter > 500): print( "Superheated region wet analysis T_outr convergence failed" ) DWS.Q = Q_dry return if iter == 1: y1 = errorToutr if iter > 1: y2 = errorToutr x3 = x2 - y2 / (y2 - y1) * (x2 - x1) change = abs(y2 / (y2 - y1) * (x2 - x1)) y1 = y2 x1 = x2 x2 = x3 if hasattr(DWS, 'Verbosity') and DWS.Verbosity > 7: print("Fullwet iter %d Toutr %0.5f dT %g" % (iter, Tout_r, errorToutr)) #Update loop counter iter += 1 # Fully wetted outlet temperature [K] Tout_r_wet = Tout_r # Dry fraction f_dry = 0.0 if (Tin_s > Tdp and not isFullyWet): #Partially wet and partially dry with single-phase on refrigerant side """ ----------------------------------------------------------- | * Tout_a <---- * T_a,x <---- * Tin_a | ____________Wet____________| Dry ----------------------------o T_dp ------------------------ | * Tin_r ----> * T_w,x ----> * Tout_r | ----------------------------------------------------------- """ iter = 1 # Now do an iterative solver to find the fraction of the coil that is wetted x1 = 0.0001 x2 = 0.9999 eps = 1e-8 while ((iter <= 3 or error > eps) and iter < 100): if iter == 1: f_dry = x1 if iter > 1: f_dry = x2 K = Ntu_dry * (1.0 - C_star) expk = exp(-K * f_dry) if cp_da * mdot_da < cp_r * mdot_r: Tout_r_guess = (Tdp + C_star * (Tin_a - Tdp) - expk * (1 - K / Ntu_o) * Tin_a) / ( 1 - expk * (1 - K / Ntu_o)) else: Tout_r_guess = (expk * (Tin_a + (C_star - 1) * Tdp) - C_star * (1 + K / Ntu_o) * Tin_a) / ( expk * C_star - C_star * (1 + K / Ntu_o)) # Wet and dry effective effectivenesses epsilon_dry = ((1 - exp(-f_dry * Ntu_dry * (1 - C_star))) / (1 - C_star * exp(-f_dry * Ntu_dry * (1 - C_star)))) epsilon_wet = ((1 - exp(-(1 - f_dry) * Ntu_wet * (1 - m_star))) / (1 - m_star * exp(-(1 - f_dry) * Ntu_wet * (1 - m_star)))) # Temperature of "water" where condensation begins T_w_x = (Tin_r + (mdot_min) / (cp_r * mdot_r) * epsilon_wet * (hin_a - h_s_w_i - epsilon_dry * Cmin / mdot_da * Tin_a)) / (1 - (Cmin * mdot_min) / (cp_r * mdot_r * mdot_da) * epsilon_wet * epsilon_dry) # Temperature of air where condensation begins [K] # Obtained from energy balance on air side T_a_x = Tin_a - epsilon_dry * Cmin * (Tin_a - T_w_x) / ( mdot_da * cp_da) # Enthalpy of air where condensation begins h_a_x = hin_a - cp_da * (Tin_a - T_a_x) # New "water" temperature (stored temporarily to be able to build change Tout_r = (Cmin) / (cp_r * mdot_r) * epsilon_dry * Tin_a + ( 1 - (Cmin) / (cp_r * mdot_r) * epsilon_dry) * T_w_x # Difference between initial guess and outlet error = Tout_r - Tout_r_guess if (iter > 500): print( "Superheated region wet analysis f_dry convergence failed" ) DWS.Q = Q_dry return if iter == 1: y1 = error if iter > 1: y2 = error x3 = x2 - y2 / (y2 - y1) * (x2 - x1) change = abs(y2 / (y2 - y1) * (x2 - x1)) y1 = y2 x1 = x2 x2 = x3 if hasattr(DWS, 'Verbosity') and DWS.Verbosity > 7: print( "Partwet iter %d Toutr_guess %0.5f diff %g f_dry: %g" % (iter, Tout_r_guess, error, f_dry)) #Update loop counter iter += 1 # Wet-analysis saturation enthalpy [J/kg] h_s_s_e = h_a_x + (hout_a - h_a_x) / (1 - exp(-(1 - f_dry) * Ntu_owet)) # Surface effective temperature [K] T_s_e = HAPropsSI('T', 'H', h_s_s_e, 'P', pin_a, 'R', 1.0) # Air outlet temp based on effective surface temp [K] Tout_a = T_s_e + (T_a_x - T_s_e) * exp(-(1 - f_dry) * Ntu_o) # Heat transferred [W] Q = mdot_r * cp_r * (Tout_r - Tin_r) # Dry-analysis air outlet enthalpy from energy balance [J/kg] hout_a = hin_a - Q / mdot_da #Sensible heat transfer rate [kW] Q_sensible = mdot_da * cp_da * (Tin_a - Tout_a) else: Q = Q_wet else: # Coil is fully dry Tout_a = Tout_a_dry Q = Q_dry Q_sensible = Q_dry DWS.f_dry = f_dry DWS.omega_out = HAPropsSI('W', 'T', Tout_a, 'P', 101325, 'H', hout_a) DWS.RHout_a = HAPropsSI('R', 'T', Tout_a, 'P', 101325, 'W', DWS.omega_out) DWS.Tout_a = Tout_a DWS.Q = Q DWS.Q_sensible = Q_sensible DWS.hout_a = hout_a DWS.hin_a = hin_a DWS.Tout_r = Tout_r DWS.Twall_s = Tout_r - Q / UA_i #inner wall temperature for gas cooler model
def OBJECTIVE(x): Tevap = x[0] Tcond = x[1] Tin_CC = x[2] if Cycle.Mode == 'AC': #Condenser heat transfer rate Qcond = epsilon * Cycle.Condenser.Fins.Air.Vdot_ha * rho_air * ( Cycle.Condenser.Fins.Air.Tdb - Tcond) * 1005 #updated #Compressor power pevap = PropsSI('P', 'T', Tevap, 'Q', 1.0, Cycle.Ref) pcond = PropsSI('P', 'T', Tcond, 'Q', 1.0, Cycle.Ref) Cycle.Compressor.pin_r = pevap Cycle.Compressor.pout_r = pcond Cycle.Compressor.Tin_r = Tevap + Cycle.Compressor.DT_sh Cycle.Compressor.Ref = Cycle.Ref Cycle.Compressor.Calculate() W = Cycle.Compressor.W Qcoolingcoil_dry = epsilon * Cycle.CoolingCoil.Fins.Air.Vdot_ha * rho_air * ( Cycle.CoolingCoil.Fins.Air.Tdb - Tin_CC) * 1005 #updated # Air-side heat transfer UA CC = Cycle.CoolingCoil CC.Initialize() UA_a = CC.Fins.h_a * CC.Fins.A_a * CC.Fins.eta_a #Air outlet temp from dry analysis Tout_a = CC.Tin_a - Qcoolingcoil_dry / (CC.Fins.mdot_a * CC.Fins.cp_a) # Refrigerant side UA f, h, Re = Correlations.f_h_1phase_Tube( Cycle.Pump.mdot_g / CC.Ncircuits, CC.ID, Tin_CC, CC.pin_g, CC.Ref_g) UA_r = CC.A_g_wetted * h #Refrigerant outlet temp cp_g = PropsSI('C', 'T', Tin_CC, 'P', Cycle.Pump.pin_g, Cycle.Pump.Ref_g) #*1000 Tout_CC = Tin_CC + Qcoolingcoil_dry / (Cycle.Pump.mdot_g * cp_g) #Get wall temperatures at inlet and outlet from energy balance T_so_a = (UA_a * CC.Tin_a + UA_r * Tout_CC) / (UA_a + UA_r) T_so_b = (UA_a * Tout_a + UA_r * Tin_CC) / (UA_a + UA_r) Tdewpoint = HAPropsSI( 'D', 'T', CC.Fins.Air.Tdb, 'P', 101325, 'R', CC.Fins.Air.RH ) #Updated from HumAir_Single(CC.Fins.Air.Tdb, 101325, 'RH',CC.Fins.Air.RH,'DewPoint') #Now calculate the fully-wet analysis #Evaporator is bounded by saturated air at the refrigerant temperature. h_ai = HAPropsSI( 'H', 'T', CC.Fins.Air.Tdb, 'P', 101325, 'R', CC.Fins.Air.RH ) #Updated from HumAir_Single(CC.Fins.Air.Tdb, 101325, 'RH', CC.Fins.Air.RH,'Enthalpy') h_s_w_o = HAPropsSI( 'H', 'T', Tin_CC, 'P', 101325, 'R', 1.0 ) #Updated from HumAir_Single(Tin_CC, 101325, 'RH', 1.0,'Enthalpy') Qcoolingcoil_wet = epsilon * CC.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) Qcoolingcoil = f_dry * Qcoolingcoil_dry + ( 1 - f_dry) * Qcoolingcoil_wet Tin_IHX = Tin_CC + Qcoolingcoil / (Cycle.Pump.mdot_g * cp_g) QIHX = epsilon * Cycle.Pump.mdot_g * cp_g * (Tin_IHX - Tevap) Qcond_enthalpy = Cycle.Compressor.mdot_r * ( Cycle.Compressor.hout_r - PropsSI('H', 'T', Tcond - Cycle.DT_sc_target, 'P', pcond, Cycle.Ref)) #*1000) resids = [ QIHX + W + Qcond, Qcond + Qcond_enthalpy, Qcoolingcoil - QIHX ] return resids elif Cycle.Mode == 'HP': #Evaporator heat transfer rate Qevap = epsilon * Cycle.Evaporator.Fins.Air.Vdot_ha * rho_air * ( Cycle.Evaporator.Fins.Air.Tdb - Tevap) * 1005 #updated #Compressor power pevap = PropsSI('P', 'T', Tevap, 'Q', 1.0, Cycle.Ref) pcond = PropsSI('P', 'T', Tcond, 'Q', 1.0, Cycle.Ref) 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 will be dry Qcoolingcoil = epsilon * Cycle.CoolingCoil.Fins.Air.Vdot_ha * rho_air * ( Tin_CC - Cycle.CoolingCoil.Fins.Air.Tdb) * 1005 #updated cp_g = PropsSI('C', 'T', Tin_CC, 'P', Cycle.Pump.pin_g, Cycle.Pump.Ref_g) #*1000 Tin_IHX = Tin_CC - Qcoolingcoil / (Cycle.Pump.mdot_g * cp_g) QIHX = epsilon * Cycle.Pump.mdot_g * cp_g * (Tin_IHX - Tcond) QIHX_enthalpy = Cycle.Compressor.mdot_r * ( Cycle.Compressor.hout_r - PropsSI('H', 'T', Tcond - Cycle.DT_sc_target, 'P', pcond, Cycle.Ref)) #*1000) resids = [ QIHX + W + Qevap, QIHX + QIHX_enthalpy, Qcoolingcoil + QIHX ] return resids
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
def TB(self, values): # Set of the temperature value self._temperature = values[0] # Check if the entered wet bulb temperature value is lower than the dry # one if (values[1] > values[0]): raise ValueError("Wet bulb temperature is lower than the dry one!") else: self._wet_bulb_temperature = values[1] # The use of dry and wet bulb temperatures being usually quite slow with # CoolProp, the option fast_computation can be used here when a large # amount of temperature values is involved if not self.fast_computation: # Calculation of the corresponding relative humidity, using the # CoolProp package self._relative_humidity = HAPropsSI('R', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'B', self.wet_bulb_temperature\ +273.15) # Calculation of the corresponding specific humidity value self._specific_humidity = HAPropsSI('W', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'B', self.wet_bulb_temperature\ +273.15) # Dew point temperature self._dew_point_temperature = HAPropsSI('D', 'P', self.pressure*1e5, 'T',\ self.temperature+273.15, 'B',\ self.wet_bulb_temperature\ +273.15)-273.15 # Specific enthalpy, in kJ/kg self._specific_enthalpy = HAPropsSI('H', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'B', self.wet_bulb_temperature\ +273.15)*1e-3 # Specific volume, in m^3/kg self._specific_volume = HAPropsSI('V', 'P', self.pressure*1e5, 'T', self.temperature+273.15, 'B', self.wet_bulb_temperature\ +273.15) else: # When fast computation is called, specific humidity is computed # in a simplified way, according to the ASHRAE method . self._specific_humidity = self._TBtoW(self.temperature,\ self.wet_bulb_temperature) # Partial pressure of water vapour pvap = self.pressure*1e5*self.specific_humidity/\ (self.specific_humidity+ALPHAW) # Equilibrium pressure of water vapour at the dry temperature psatd = self.__equilibrium_vapor_pressure(self.temperature) # Relative humidity self._relative_humidity = pvap / psatd # Dew point temperature, see [1, page 6.10] lnpvap = np.log(pvap * 1e-3) if self.temperature >= 0: self._dew_point_temperature = 6.54+14.526*lnpvap\ +0.7389*pow(lnpvap,2)+0.09486*pow(lnpvap,3)\ +0.4569*pow(pvap*1e-3,0.1984) else: self._dew_point_temperature = 6.09+12.608*lnpvap\ +0.4959*pow(lnpvap,2) # Specific enthalpy, in kJ/kg, see [1, page 6.9] self._specific_enthalpy = (DRY_AIR_CP*self.temperature\ +self.specific_humidity*(WATER_VAPOR_CP*self.temperature\ +WATER_LW))*1e-3 # Specific volume, in m^3/kg, using the ideal gas law self._specific_volume = WATER_VAPOR_R\ *(ALPHAW+self.specific_humidity)*(273.15+self.temperature)\ /((1+self.specific_humidity)*self.pressure*1e5)
def Nat_Conv_PanelExterior(A_cs, P_cs, T_film, T_air, RH, orientation, panel_height, panel_width, wind, h_ext_err, B_err, u_err, p_err, a_err, k_err_ext, n_err): T_air = float(T_air) B = B_err*PropsSI('isobaric_expansion_coefficient','P',101325,'T',T_air,'air')#volumetric thermal expansion coefficient [1/k] u = u_err*HAPropsSI('Visc','P',101325,'T',T_air,'R', RH) #Dynamic viscosity [Pa*s] #u = PropsSI('viscosity','P',101325,'T',T_air,'air') #Dynamic viscosity [Pa*s] p = p_err*PropsSI('DMASS','P',101325,'T',T_air,'air') #density [kg/m^3] v = u/p #kinematic viscosity a = a_err*(((5.68172*(10.0**(-17.0)))* (T_air**4.0))-((1.76304*(10.0**(-13.0)))*(T_air**3.0))+((2.81311*(10.0**(-10.0)))*(T_air**2.0))+((1.03147*(10.0**(-8.0)))*T_air)-(1.47967*(10.0**(-6.0)))) #thermal diffusivity [m2/s] #k = PropsSI('conductivity','P',101325,'T',T_air,'air') #thermal conductivity [W/m k] k = k_err_ext*HAPropsSI('K','P',101325,'T',T_air,'R', RH) #thermal conductivity [W/m/k] g = constants.g if orientation ==0: #for verticle panels L = panel_height #characteristic length Gr_L = (g*B*(abs(T_air - T_film))*(L**3))/(v**2) Pr = v/a Ra_L = Gr_L*Pr n = 1*n_err Re_L = (p*wind*panel_width)/u Nu_L_force=0.664*(Pr**(1/3))*(Re_L**(1/2)) #UWT Nu_L_nat = (0.825+ ((0.387*(Ra_L**(1/6))) / ((1+ ((0.492/Pr)**(9/16)) )**(8/27))))**2 Nu_L=((Nu_L_nat**n)+(Nu_L_force**n))**(1/n) if Nu_L_force != 0 and Nu_L_nat !=0: if 0.99< abs(Nu_L/ Nu_L_force)<1.01: Nu_L = Nu_L_force if 0.99< abs(Nu_L/ Nu_L_nat)<1.01: Nu_L = Nu_L_nat else: #horiztonal panel L = A_cs / P_cs #characteristic length Gr_L = (g*B*(abs(T_air - T_film))*(L**3))/(v**2) Pr = v/a Ra_L = Gr_L*Pr Re_L = 0 n = 1*n_err if T_film<=T_air: #UWT if Ra_L<10**7: Nu_L_nat = 0.54*Ra_L**0.25 else: Nu_L_nat = 0.15*Ra_L**(1/3) else: Nu_L_nat = 0.27*Ra_L**0.25 Re_L = (p*wind*panel_width)/u Nu_L_force=0.664*(Pr**(1/3))*(Re_L**(1/2)) Nu_L=((Nu_L_nat**n)+(Nu_L_force**n))**(1/n) if Nu_L_force != 0 and Nu_L_nat !=0: if 0.99< abs(Nu_L/ Nu_L_force)<1.01: Nu_L = Nu_L_force if 0.99< abs(Nu_L/ Nu_L_nat)<1.01: Nu_L = Nu_L_nat # ============================================================================= # #UHF # if Ra_L>5*10**8: # 0.13*Ra_L**(1/3) # if Ra_L<5*10**8: # 0.16*Ra_L**(1/3) # ============================================================================= h_PanelExterior = (Nu_L*k/L)*h_ext_err Q1_NCEx = h_PanelExterior*A_cs*(T_air - T_film) #Q1_NCEx = total heat transfer (W) Natural Convection Exterior return Q1_NCEx, Ra_L, Pr, h_PanelExterior, Re_L, k
def PropertyLookup( desired, unit_system=None, verbose=False, **kwargs, ): """ Each of the follow properties/parameters is expected to be a quantity with units :param desired: Dependent from two of the following independent properties :param T: dry-bulb Temperature (Default value = None) :param T_wb: wet-bulb Temperature (Default value = None) :param T_dp: dew-point Temperature (Default value = None) :param p: pressure (Default value = None) :param p_w: partial pressure of water vapor (Default value = None) :param w: humidity ratio (Default value = None) :param v: mixture volume per unit dry air (Default value = None) :param v_ha: mixture volume per unit humid air (Default value = None) :param h: mixture enthalpy per unit dry air (Default value = None) :param h_ha: mixture enthalpy per unit humid air (Default value = None) :param s: mixture entropy per unit dry air (Default value = None) :param rel_hum: relative humidity (Default value = None) :param y: water mole fraction (Default value = None) :param unit_system: unit system for return value - one of 'SI_C', 'SI_K', 'English_F', 'English_R' (Default value = ) :param verbose: show debug information (Default value = False) :param **kwargs: """ desired = CP_HA_trans[desired] PropsSI_args = [ desired ] # add the desired parameter as the first argument to pass to CoolProp.PropsSI def process_indep_arg(arg, CPSymb): """ Add a property symbol and its value to the CoolProp.PropSI argument string :param arg: value of independent parameter :param CPSymb: CoolProp symbol :param exponent: exponent used to invert the value (Default value = 1) :param AltSymb: symbol to use for inverted values (Default value = None) """ if arg is not None: # if AltSymb: PropsSI_args.append(AltSymb) # else: PropsSI_args.append( CPSymb) # Add independent parameter symbol to argument list if CP_HA_symb_to_units[CPSymb] is not None: value = float( arg.to(CP_HA_symb_to_units[CPSymb]).magnitude ) # Add independent parameter value to argument list with appropriate magnitude and units stripped elif isinstance(arg, Quantity): value = float(arg.magnitude) else: value = float( arg ) # Add independent paramter value directly to argument list if it has no units that need to be adjusted PropsSI_args.append(value) for k, v in kwargs.items(): if k in CP_HA_trans.keys(): process_indep_arg(v, CP_HA_trans[k]) def humidity_search(PropsSI_args): desired = PropsSI_args[0] for i, v in enumerate(PropsSI_args): if v == 'P': P = PropsSI_args[i + 1] elif v == 'R': R_target = PropsSI_args[i + 1] elif v == 'W': W = PropsSI_args[i + 1] T = 273.15 # starting guess T_guess = T n_steps = 100 search_steps = [5, -5, 1, -1, 0.1, -0.1, 0.01, -0.01] for step in search_steps: cont = True n_step = 0 while cont: if n_step > 0: T_guess += step try: R = HAPropsSI('R', 'T', T_guess, 'W', W, 'P', P) error = abs(R_target - R) if step > 0: T = T_guess if R < R_target: cont = False elif step < 0 and R < R_target: T = T_guess else: cont = False except ValueError: if step < 0: cont = False n_step += 1 if n_step > n_steps: cont = False if desired == 'Tdb': return T else: return HAPropsSI(desired, 'P', P, 'W', W, 'Tdb', T) if verbose: print('Calling: CoolProp.CoolProp.HAPropsSI({})'.format(','.join( [str(i) for i in PropsSI_args]))) print(PropsSI_args) if "R" in PropsSI_args[1:] and "W" in PropsSI_args[1:]: result = humidity_search(PropsSI_args) else: result = HAPropsSI(*PropsSI_args) # Determine the units of the value as returned from CoolProp CP_return_units = CP_HA_symb_to_units[desired] CP_return_type = CP_HA_symb_to_type[desired] # Determine the preferred units for the value if unit_system is None: result_units = preferred_units_from_type(CP_return_type, units.preferred_units) else: result_units = preferred_units_from_type(CP_return_type, unit_system) # Convert the returned value to the preferred units if result_units is not None: result = Quantity(result, CP_return_units).to(result_units) return result