def Validate(self): """ Check that all required fields are included, and no extra fields not listed here are added This is quite strict, but for the best to avoid typos """ reqFields = [('RH', float, 0, 1), ('Tdb', float, -80 + 273.15, 200 + 273.15), ('FanPower', float, 0, 4000), ('p', float, 0.01, 10000), ('Vdot_ha', float, 0.001, 10)] optFields = ['RHmean', 'Tmean'] d = dict(self.Air.__dict__) #The current values ValidateFields(d, reqFields, optFields) reqFields = [('FPI', float, 0.1, 100), ('Pd', float, 0.000001, 0.1), ('xf', float, 0.000001, 0.1), ('t', float, 0.00001, 0.01), ('k_fin', float, 0.01, 10000)] optFields = None d = dict(self.Fins.__dict__) #The current values ValidateFields(d, reqFields, optFields) reqFields = [('NTubes_per_bank', int, 0.1, 100), ('Ncircuits', int, 1, 50), ('Nbank', float, 1, 50), ('Ltube', float, 0.001, 10), ('ID', float, 0.0001, 1), ('OD', float, 0.0001, 1), ('Pl', float, 0.0001, 1), ('Pt', float, 0.0001, 1)] optFields = None d = dict(self.Tubes.__dict__) #The current values ValidateFields(d, reqFields, optFields)
def Initialize(self): #Input validation the first call of Initialize if False:#not hasattr(self,'IsValidated'): self.Fins.Validate() reqFields=[ ('Ref',str,None,None), ('psat_r',float,0.001,100000000), ('Fins',IsFinsClass,None,None), ('FinsType',str,None,None), ('hin_r',float,-100000,10000000), ('mdot_r',float,0.000001,10), ] optFields=['Verbosity'] d=self.__dict__ #Current fields in model ValidateFields(d,reqFields,optFields) self.IsValidated=True # Retrieve some parameters from nested structures # for code compactness self.ID=self.Fins.Tubes.ID self.OD=self.Fins.Tubes.OD self.Ltube=self.Fins.Tubes.Ltube self.NTubes_per_bank=self.Fins.Tubes.NTubes_per_bank self.Nbank=self.Fins.Tubes.Nbank self.Ncircuits=self.Fins.Tubes.Ncircuits self.Tin_a=self.Fins.Air.Tdb # Calculate an effective length of circuit if circuits are # not all the same length TotalLength=self.Ltube*self.NTubes_per_bank*self.Nbank self.Lcircuit=TotalLength/self.Ncircuits # Wetted area on the refrigerant side self.A_r_wetted=self.Ncircuits*pi*self.ID*self.Lcircuit self.V_r=self.Ncircuits*self.Lcircuit*pi*self.ID**2/4.0 #Average mass flux of refrigerant in circuit self.G_r = self.mdot_r/(self.Ncircuits*pi*self.ID**2/4.0) #[kg/m^2-s] ## Bubble and dew temperatures (same for fluids without glide) self.Tbubble_r=PropsSI('T','P',self.psat_r,'Q',0,self.Ref) self.Tdew_r=PropsSI('T','P',self.psat_r,'Q',1,self.Ref) ## Mean temperature for use in HT relationships self.Tsat_r=(self.Tbubble_r+self.Tdew_r)/2 # Latent heat self.h_fg=(PropsSI('H','T',self.Tdew_r,'Q',1.0,self.Ref)-PropsSI('H','T',self.Tbubble_r,'Q',0.0,self.Ref))*1. #*1000. #[J/kg] self.Fins.Air.RHmean=self.Fins.Air.RH #Update with user FinType if self.FinsType == 'WavyLouveredFins': WavyLouveredFins(self.Fins) elif self.FinsType == 'HerringboneFins': HerringboneFins(self.Fins) elif self.FinsType == 'PlainFins': PlainFins(self.Fins) self.mdot_ha=self.Fins.mdot_ha #[kg_ha/s] self.mdot_da=self.Fins.mdot_da #[kg_da/s]
def Initialize(self): #Input validation the first call of Initialize if False:#not hasattr(self,'IsValidated'): self.Fins.Validate() reqFields=[ ('Ref',str,None,None), ('psat_r',float,1e-6,100000), ('Fins',IsFinsClass,None,None), ('hin_r',float,-100000,10000000), ('mdot_r',float,0.000001,10), ] optFields=['Verbosity'] d=self.__dict__ #Current fields in model ValidateFields(d,reqFields,optFields) self.IsValidated=True # Retrieve some parameters from nested structures # for code compactness self.ID=self.Fins.Tubes.ID self.OD=self.Fins.Tubes.OD self.Ltube=self.Fins.Tubes.Ltube self.NTubes_per_bank=self.Fins.Tubes.NTubes_per_bank self.Nbank=self.Fins.Tubes.Nbank self.Ncircuits=self.Fins.Tubes.Ncircuits self.Tin_a=self.Fins.Air.Tdb # Calculate an effective length of circuit if circuits are # not all the same length TotalLength=self.Ltube*self.NTubes_per_bank*self.Nbank self.Lcircuit=TotalLength/self.Ncircuits # Wetted area on the refrigerant side self.A_r_wetted=self.Ncircuits*pi*self.ID*self.Lcircuit self.V_r=self.Ncircuits*self.Lcircuit*pi*self.ID**2/4.0 #Average mass flux of refrigerant in circuit self.G_r = self.mdot_r/(self.Ncircuits*pi*self.ID**2/4.0) #[kg/m^2-s] """ Tsat() is a relatively slow function since it does a Dekker solve over the full two-phase region. So store the value in order to cut down on computational work. """ ## Bubble and dew temperatures (same for fluids without glide) self.Tbubble_r=Props('T','P',self.psat_r,'Q',0,self.Ref) self.Tdew_r=Props('T','P',self.psat_r,'Q',1,self.Ref) ## Mean temperature for use in HT relationships self.Tsat_r=(self.Tbubble_r+self.Tdew_r)/2 # Latent heat self.h_fg=(Props('H','T',self.Tdew_r,'Q',1.0,self.Ref)-Props('H','T',self.Tbubble_r,'Q',0.0,self.Ref))*1000. #[J/kg] self.Fins.Air.RHmean=self.Fins.Air.RH self.Fins.h_tp_tuning= self.h_tp_tuning #pass tuning factor WavyLouveredFins(self.Fins) self.mdot_ha=self.Fins.mdot_ha #[kg_ha/s] self.mdot_da=self.Fins.mdot_da #[kg_da/s]
def Validate(self): """ Check that all required fields are included, and no extra fields not listed here are added This is quite strict, but for the best to avoid typos """ reqFields = [('RH', float, 0, 1), ('Tdb', float, -80 + 273.15, 200 + 273.15), ('FanPower', float, 0, 4000), ('p', float, 10, 10000000), ('Vdot_ha', float, 0.001, 10)] optFields = ['RHmean', 'Tmean'] d = dict(self.Air.__dict__) #The current values ValidateFields(d, reqFields, optFields) reqFields = [('FPI', float, 0.1, 100), ('Lf', float, 0.0001, 1), ('t', float, 0.00001, 0.01), ('k_fin', float, 0.01, 10000)] optFields = None d = dict(self.Fins.__dict__) #The current values ValidateFields(d, reqFields, optFields) reqFields = [('NTubes', float, 0.1, 100), ('Nbank', float, 1, 50), ('Npass', float, 1, 50), ('Nports', float, 1, 50), ('Ltube', float, 0.001, 10), ('Td', float, 0.0001, 1), ('Ht', float, 0.0001, 1), ('b', float, 0.0001, 1), ('tw', float, 0.00001, 0.01), ('twp', float, 0.00001, 0.01), ('beta', float, 0.00001, 100)] optFields = None d = dict(self.Tubes.__dict__) #The current values ValidateFields(d, reqFields, optFields) reqFields = [ ('Lalpha', float, 1, 89), ('lp', float, 0.0001, 1), ] optFields = ['Llouv'] d = dict(self.Louvers.__dict__) #The current values ValidateFields(d, reqFields, optFields)
def Calculate(self): #Only validate the first time if not hasattr(self, 'IsValidated'): self.Fins.Validate() reqFields = [ ('Ref', str, None, None), ('Fins', IsFinsClass, None, None), ('FinsType', str, None, None), ('mdot_r', float, 0.00001, 20), ('Tin_r', float, 200, 500), ('psat_r', float, 0.01, 20000000 ) #0.00001,20000 changed to 0.01,20000000 ] optFields = ['Verbosity'] ValidateFields(self.__dict__, reqFields, optFields) self.IsValidated = True # Retrieve some parameters from nested structures # for code compactness self.ID = self.Fins.Tubes.ID self.OD = self.Fins.Tubes.OD self.Ltube = self.Fins.Tubes.Ltube self.NTubes_per_bank = self.Fins.Tubes.NTubes_per_bank self.Nbank = self.Fins.Tubes.Nbank self.Ncircuits = self.Fins.Tubes.Ncircuits self.Tin_a = self.Fins.Air.Tdb ## Bubble and dew temperatures (same for fluids without glide) self.Tbubble = PropsSI('T', 'P', self.psat_r, 'Q', 0.0, self.Ref) self.Tdew = PropsSI('T', 'P', self.psat_r, 'Q', 1.0, self.Ref) # 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) #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 self.sin_r = PropsSI('S', 'T', self.Tin_r, 'P', self.psat_r, self.Ref) #*1000 if self.existsSubcooled == True: self.hout_r = PropsSI('H', 'T', self.Tout_r, 'P', self.psat_r, self.Ref) #*1000 self.sout_r = PropsSI('S', 'T', self.Tout_r, 'P', self.psat_r, self.Ref) #*1000 else: self.Tout_r = self.xout_2phase * self.Tdew + ( 1 - self.xout_2phase) * self.Tbubble self.hout_r = PropsSI( 'H', 'T', self.Tout_r, 'Q', 0, self.Ref ) + self.xout_2phase * ( PropsSI('H', 'T', self.Tout_r, 'Q', 1, self.Ref) - PropsSI('H', 'T', self.Tout_r, 'Q', 0, self.Ref) ) #PropsSI('H','T',self.Tout_r,'Q',self.xout_2phase,self.Ref)#*1000 self.sout_r = PropsSI( 'S', 'T', self.Tout_r, 'Q', 0, self.Ref ) + self.xout_2phase * ( PropsSI('S', 'T', self.Tout_r, 'Q', 1, self.Ref) - PropsSI('S', 'T', self.Tout_r, 'Q', 0, self.Ref) ) #PropsSI('S','T',self.Tout_r,'Q',self.xout_2phase,self.Ref)#*1000 #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
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'] ValidateFields(self.__dict__, reqFields, optFields) self.IsValidated = True # 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 """NEW ADDED""" 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) self.Tbubble = PropsSI('T', 'P', self.psat_r, 'Q', 0.0, self.Ref) self.Tdew = PropsSI('T', 'P', self.psat_r, 'Q', 1.0, self.Ref) # 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 """NEW ADDED""" # 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 self.sin_r = PropsSI('S', 'T', self.Tin_r, 'P', self.psat_r, self.Ref) if self.existsSubcooled == True: self.hout_r = PropsSI('H', 'T', self.Tout_r, 'P', self.psat_r, self.Ref) self.sout_r = PropsSI('S', 'T', self.Tout_r, 'P', self.psat_r, self.Ref) else: self.Tout_r = self.xout_2phase * self.Tdew + ( 1 - self.xout_2phase) * self.Tbubble self.hout_r = PropsSI( 'H', 'T', self.Tbubble, 'Q', 0, self.Ref) + self.xout_2phase * ( PropsSI('H', 'T', self.Tdew, 'Q', 1, self.Ref) - PropsSI('H', 'T', self.Tbubble, 'Q', 0, self.Ref)) self.sout_r = PropsSI( 'S', 'T', self.Tbubble, 'Q', 0, self.Ref) + self.xout_2phase * ( PropsSI('S', 'T', self.Tdew, 'Q', 1, self.Ref) - PropsSI('S', 'T', self.Tbubble, 'Q', 0, self.Ref)) #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]