def psy_chart(self, x, θo, φo): """ Plot results on psychrometric chart. Parameters ---------- x : θM, wM, θs, ws, θC, wC, θS, wS, θI, wI, QtCC, QsCC, QlCC, QsHC, QsTZ, QlTZ results of self.solve_lin or self.m_ls θo, φo outdoor point Returns ------- None. """ # Processes on psychrometric chart wo = psy.w(θo, φo) # Points: O, s, S, I θ = np.append(θo, x[0:10:2]) w = np.append(wo, x[1:10:2]) # Points O s S I Elements A = np.array([ [-1, 1, 0, 0, 0, 1], # MX1 [0, -1, 1, 0, 0, 0], # CC [0, 0, -1, 1, -1, 0], # MX2 [0, 0, 0, -1, 1, 0], # HC [0, 0, 0, 0, -1, 1] ]) # TZ psy.chartA(θ, w, A) θ = pd.Series(θ) w = 1000 * pd.Series(w) # kg/kg -> g/kg P = pd.concat([θ, w], axis=1) # points P.columns = ['θ [°C]', 'w [g/kg]'] output = P.to_string(formatters={ 'θ [°C]': '{:,.2f}'.format, 'w [g/kg]': '{:,.2f}'.format }) print() print(output) Q = pd.Series(x[10:], index=['QtCC', 'QsCC', 'QlCC', 'QsHC', 'QsTZ', 'QlTZ']) # Q.columns = ['kW'] pd.options.display.float_format = '{:,.2f}'.format print() print(Q.to_frame().T / 1000, 'kW') return None
def RecAirVAV(alpha=1, beta=0.1, tSsp=30, tIsp=18, phiIsp=0.49, tO=-1, phiO=1, Qsa=0, Qla=0, mi=2.18, UA=935.83): """ Created on Fri Apr 10 13:57:22 2020 Heating & Adiabatic humidification & Re-heating Recirculated air VAV Variable Air Volume: mass flow rate calculated to have const. supply temp. INPUTS: alpha mixing ratio of outdoor air, - beta by-pass factor of the adiabatic humidifier, - tS supply air, °C tIsp indoor air setpoint, °C phiIsp indoor relative humidity set point, - tO outdoor temperature for design, °C phiO outdoor relative humidity for design, - Qsa aux. sensible heat, W Qla aux. latente heat, W mi infiltration massflow rate, kg/s UA global conductivity bldg, W/K System: MX1: Mixing box HC1: Heating Coil AH: Adiabatic Humidifier MX2: Mixing in humidifier model HC2: Reheating coil TZ: Thermal Zone BL: Building Kw: Controller - humidity Kt: Controller - temperature o: outdoor conditions 0..5 unknown points (temperature, humidity ratio) <----|<-------------------------------------------------| | | | |-------| | -o->MX1--0->HC1--1->| MX2--3->HC2--F-----4->TZ--5-| | |->AH-2-| | | | || | | | |-Kt4-| BL | | | | | |<-----Kt----------|<-t5 |<------------------------------Kw----------|<-w5 16 Unknowns 0..5: 2*6 points (temperature, humidity ratio) QsHC1, QsHC2, QsTZ, QlTZ """ from scipy.optimize import least_squares def Saturation(m): """ Used in VAV to find the mass flow which solves tS = tSsp Parameters ---------- m : mass flow rate of dry air Returns ------- tS - tSsp: difference between supply temp. and its set point """ x = ModelRecAir(m, alpha, beta, tSsp, tIsp, phiIsp, tO, phiO, Qsa, Qla, mi, UA) tS = x[8] return (tS - tSsp) plt.close('all') wO = psy.w(tO, phiO) # hum. out # Mass flow rate res = least_squares(Saturation, 5, bounds=(0, 10)) if res.cost < 1e-10: m = float(res.x) else: print('RecAirVAV: No solution for m') print(f'm = {m: 5.3f} kg/s') x = ModelRecAir(m, alpha, beta, tSsp, tIsp, phiIsp, tO, phiO, Qsa, Qla, mi, UA) # DtS, m = 2, 1 # initial temp; diff; flow rate # while DtS > 0.01: # m = m + 0.01 # # Model # x = ModelRecAir(m, tSsp, mi, tO, phiO, alpha, beta) # tS = x[8] # DtS = -(tSsp - tS) t = np.append(tO, x[0:12:2]) w = np.append(wO, x[1:12:2]) # Adjancy matrix # Points o 0 1 2 3 4 5 Elements A = np.array([[-1, 1, 0, 0, 0, 0, -1], # MX1 [0, -1, 1, 0, 0, 0, 0], # HC1 [0, 0, -1, 1, 0, 0, 0], # AH [0, 0, -1, -1, 1, 0, 0], # MX2 [0, 0, 0, 0, -1, 1, 0], # HC2 [0, 0, 0, 0, 0, -1, 1]]) # TZ psy.chartA(t, w, A) t = pd.Series(t) w = 1000*pd.Series(w) P = pd.concat([t, w], axis=1) # points P.columns = ['t [°C]', 'w [g/kg]'] output = P.to_string(formatters={ 't [°C]': '{:,.2f}'.format, 'w [g/kg]': '{:,.2f}'.format }) print() print(output) Q = pd.Series(x[12:], index=['QsHC1', 'QsHC2', 'QsTZ', 'QlTZ']) # Q.columns = ['kW'] pd.options.display.float_format = '{:,.2f}'.format print() print(Q.to_frame().T/1000, 'kW') return None
def RecAirCAV(alpha=1, beta=0.1, tS=30, tIsp=18, phiIsp=0.49, tO=-1, phiO=1, Qsa=0, Qla=0, mi=2.18, UA=935.83): """ Model: Heating and adiabatic humidification Recycled air CAV Constant Air Volume: mass flow rate calculated for design conditions maintained constant in all situations INPUTS: alpha mixing ratio of outdoor air, - beta by-pass factor of the adiabatic humidifier, - tS supply air, °C tIsp indoor air setpoint, °C phiIsp indoor relative humidity set point, - tO outdoor temperature for design, °C phiO outdoor relative humidity for design, - Qsa aux. sensible heat, W Qla aux. latente heat, W mi infiltration massflow rate, kg/s UA global conductivity bldg, W/K System: MX1: Mixing box HC1: Heating Coil AH: Adiabatic Humidifier MX2: Mixing in humidifier model HC2: Reheating coil TZ: Thermal Zone BL: Building Kw: Controller - humidity Kt: Controller - temperature o: outdoor conditions 0..5 6 unknown points (temperature, humidity ratio) <----|<-------------------------------------------| | | | |-------| | -o->MX1--0->HC1--1->| MX2--3->HC2--4->TZ--5-| | | | | || | | |->AH-2-| | BL | | | | | |<-----Kt----|<-t5 |<------------------------------Kw----|<-w5 16 Unknowns 0..5: 2*6 points (temperature, humidity ratio) QsHC1, QsHC2, QsTZ, QlTZ Returns ------- None """ plt.close('all') wO = psy.w(tO, phiO) # hum. out # Mass flow rate for design conditions # Supplay air mass flow rate # QsZ = UA*(tO - tIsp) + mi*c*(tO - tIsp) # m = - QsZ/(c*(tS - tIsp) # where # tO, wO = -1, 3.5e-3 # outdoor # tS = 30 # supply air # mid = 2.18 # infiltration QsZ = UA*(tOd - tIsp) + mid*c*(tOd - tIsp) m = - QsZ/(c*(tS - tIsp)) print(f'm = {m: 5.3f} kg/s constant for design conditions:') print(f' [tSd = {tS: 3.1f} °C, mi = 2.18 kg/S, tO = -1°C, phi0 = 100%]') # Model x = ModelRecAir(m, alpha, beta, tS, tIsp, phiIsp, tO, phiO, Qsa, Qla, mi, UA) t = np.append(tO, x[0:12:2]) w = np.append(wO, x[1:12:2]) # Adjancy matrix # Points o 0 1 2 3 4 5 Elements A = np.array([[-1, 1, 0, 0, 0, 0, -1], # MX1 [0, -1, 1, 0, 0, 0, 0], # HC1 [0, 0, -1, 1, 0, 0, 0], # AH [0, 0, -1, -1, 1, 0, 0], # MX2 [0, 0, 0, 0, -1, 1, 0], # HC2 [0, 0, 0, 0, 0, -1, 1]]) # TZ psy.chartA(t, w, A) t = pd.Series(t) w = 1000*pd.Series(w) P = pd.concat([t, w], axis=1) # points P.columns = ['t [°C]', 'w [g/kg]'] output = P.to_string(formatters={ 't [°C]': '{:,.2f}'.format, 'w [g/kg]': '{:,.2f}'.format }) print() print(output) Q = pd.Series(x[12:], index=['QsHC1', 'QsHC2', 'QsTZ', 'QlTZ']) # Q.columns = ['kW'] pd.options.display.float_format = '{:,.2f}'.format print() print(Q.to_frame().T/1000, 'kW') return None
def RecAirVAV(alpha=0.5, tSsp=30, tIsp=18, phiIsp=0.5, tO=-1, phiO=1, Qsa=0, Qla=0, mi=2.12, UA=935.83): """ CAV Variable Air Volume: mass flow rate calculated s.t. he supply temp. is maintained constant in all situations INPUTS: INPUTS: m mass flow of supply dry air kg/s alpha mixing ratio of outdoor air tS supply air °C tIsp indoor air setpoint °C phiIsp - tO outdoor temperature for design °C phiO outdoor relative humidity for design - Qsa aux. sensible heat W Qla aux. latente heat W mi infiltration massflow rate kg/s UA global conductivity bldg W/K System (CAV & m introduced by the Fan is cotrolled by tS ) HC: Heating Coil VH: Vapor Humidifier TZ: Thermal Zone F: Supply air fan Kw: Controller - humidity Kt: Controller - temperature o: outdoor conditions 12 Unknowns 0, 1, 2, 3 points (temperature, humidity ratio) QsHC, QlVH, QsTZ, QlTZ <----|<--------------------------------| | | -o->MX--0->HC--1->VH--F-----2-->TZ--3--> / / | | || | | | | | BL | | | | | | | | |_Kt2_|_t2 | | | | | |_____Kw_________|_w3 |_____________Kt_________|_t3 Mass-flow rate (VAV) I-controller: start with m = 0 measure the supply temperature while -(tSsp - tS)>0.01, increase m (I-controller) """ plt.close('all') wO = psy.w(tO, phiO) # hum. out # Mass flow rate DtS, m = 2, 0 # initial temp; diff; flow rate while DtS > 0.01: m = m + 0.01 # Model x = ModelRecAir(m, alpha, tSsp, tIsp, phiIsp, tO, phiO, Qsa, Qla, mi, UA) tS = x[4] DtS = -(tSsp - tS) print('Winter Rec_air VAV') print(f'm = {m: 5.3f} kg/s') # Processes on psychrometric chart # Points o 0 1 2 3 Elements A = np.array([ [-1, 1, 0, 0, -1], # MX [0, -1, 1, 0, 0], # HC [0, 0, -1, 1, 0], # VH [0, 0, 0, -1, 1] ]) # TZ t = np.append(tO, x[0:8:2]) print(f'wO = {wO:6.5f}') w = np.append(wO, x[1:8:2]) psy.chartA(t, w, A) t = pd.Series(t) w = 1000 * pd.Series(w) P = pd.concat([t, w], axis=1) # points P.columns = ['t [°C]', 'w [g/kg]'] output = P.to_string(formatters={ 't [°C]': '{:,.2f}'.format, 'w [g/kg]': '{:,.2f}'.format }) print() print(output) Q = pd.Series(x[8:], index=['QsHC', 'QlVH', 'QsTZ', 'QlTZ']) pd.options.display.float_format = '{:,.2f}'.format print() print(Q.to_frame().T / 1000, 'kW') return None
def RecAirCAV(alpha=0.5, tS=30, tIsp=18, phiIsp=0.5, tO=-1, phiO=1, Qsa=0, Qla=0, mi=2.12, UA=935.83): """ CAV Constant Air Volume: mass flow rate calculated for design conditions maintained constant in all situations INPUTS: alpha mixing ratio of outdoor air tS supply air °C tIsp indoor air setpoint °C phiIsp - tO outdoor temperature for design °C phiO outdoor relative humidity for design - Qsa aux. sensible heat W Qla aux. latente heat W mi infiltration massflow rate kg/s UA global conductivity bldg W/K System: HC: Heating Coil VH: Vapor Humidifier TZ: Thermal Zone Kw: Controller - humidity Kt: Controller - temperature o: outdoor conditions 12 Unknowns 0, 1, 2, 3 points (temperature, humidity ratio) QsHC, QlVH, QsTZ, QlTZ <-3--|<-------------------------| | | -o->MX--0->HC--1->VH--2->TZ--3--> / / || | | | BL | | | | | |_____Kw__|_w3 |_____________Kt__|_t3 """ plt.close('all') wO = psy.w(tO, phiO) # hum. out # Mass flow rate for design conditions # Supplay air mass flow rate # QsZ = UA*(tO - tIsp) + mi*c*(tO - tIsp) # m = - QsZ/(c*(tS - tIsp) # where # tOd, wOd = -1, 3.5e-3 # outdoor # tS = 30 # supply air # mid = 2.18 # infiltration QsZ = UA * (tOd - tIsp) + mid * c * (-1 - tIsp) m = -QsZ / (c * (tS - tIsp)) print('Winter Recirculated_air CAV') print(f'm = {m: 5.3f} kg/s constant (from design conditions)') print(f'Design conditions tS = {tS: 3.1f} °C,' f'mi = {mid:3.1f} kg/s, tO = {tOd:3.1f} °C, ' f'tI = {tIsp:3.1f} °C') # Model x = ModelRecAir(m, alpha, tS, tIsp, phiIsp, tO, phiO, Qsa, Qla, mi, UA) # (m, tS, mi, tO, phiO, alpha) # Processes on psychrometric chart # Points o 0 1 2 3 Elements A = np.array([ [-1, 1, 0, 0, -1], # MX [0, -1, 1, 0, 0], # HC [0, 0, -1, 1, 0], # VH [0, 0, 0, -1, 1] ]) # TZ t = np.append(tO, x[0:8:2]) print(f'wO = {wO:6.5f}') w = np.append(wO, x[1:8:2]) psy.chartA(t, w, A) t = pd.Series(t) w = 1000 * pd.Series(w) P = pd.concat([t, w], axis=1) # points P.columns = ['t [°C]', 'w [g/kg]'] output = P.to_string(formatters={ 't [°C]': '{:,.2f}'.format, 'w [g/kg]': '{:,.2f}'.format }) print() print(output) Q = pd.Series(x[8:], index=['QsHC', 'QlVH', 'QsTZ', 'QlTZ']) pd.options.display.float_format = '{:,.2f}'.format print() print(Q.to_frame().T / 1000, 'kW') return None
def AllOutAirVAV(tSsp=30, tIsp=18, phiIsp=0.5, tO=-1, phiO=1, Qsa=0, Qla=0, mi=2.12, UA=935.83): """ All out air Heating & Vapor humidification VAV Variable Air Volume: mass flow rate calculated to have const. supply temp. INPUTS: tS supply air °C tIsp indoor air setpoint °C phiIsp - tO outdoor temperature for design °C phiO outdoor relative humidity for design - Qsa aux. sensible heat W Qla aux. latente heat W mi infiltration massflow rate kg/s UA global conductivity bldg W/K System: HC: Heating Coil VH: Vapor Humidifier TZ: Thermal Zone BL: Building Kw: Controller - humidity Kt: Controller - temperature o: outdoor conditions 10 Unknowns 0, 1, 2 points (temperature, humidity ratio) QsHC, QlVH, QsTZ, QlTZ --o->HC--0->VH--F-----1-->TZ--2--> / / | | || | | | | | BL | | | |_Kt1_| | | | | | |<----Kw---------|-w2 |<------------Kt---------|-t2 Mass-flow rate (VAV) I-controller: start with m = 0 measure the supply temperature while -(tSsp - tS)>0.01, increase m (I-controller) """ plt.close('all') wO = psy.w(tO, phiO) # outdoor mumidity ratio # Mass flow rate DtS, m = 2, 0 # initial temp; diff; flow rate while DtS > 0.01: m = m + 0.01 # mass-flow rate I-controller # Model x = ModelAllOutAir(m, tSsp, tIsp, phiIsp, tO, phiO, Qsa, Qla, mi, UA) tS = x[2] DtS = -(tSsp - tS) print('Winter All_out_air VAV') print(f'm = {m: 5.3f} kg/s') # Processes on psychrometric chart t = np.append(tO, x[0:5:2]) w = np.append(wO, x[1:6:2]) # Points o 0 1 2 Elements A = np.array([ [-1, 1, 0, 0], # HC [0, -1, 1, 0], # VH [0, 0, 1, -1] ]) # TZ psy.chartA(t, w, A) t = pd.Series(t) w = 1000 * pd.Series(w) P = pd.concat([t, w], axis=1) # points P.columns = ['t [°C]', 'w [g/kg]'] output = P.to_string(formatters={ 't [°C]': '{:,.2f}'.format, 'w [g/kg]': '{:,.2f}'.format }) print() print(output) Q = pd.Series(x[6:], index=['QsHC', 'QlVH', 'QsTZ', 'QlTZ']) # Q.columns = ['kW'] pd.options.display.float_format = '{:,.2f}'.format print() print(Q.to_frame().T / 1000, 'kW') return None
def AllOutAirCAV(tS=30, tIsp=18, phiIsp=0.5, tO=-1, phiO=1, Qsa=0, Qla=0, mi=2.12, UA=935.83): """ All out air CAV Constant Air Volume: mass flow rate calculated for design conditions maintained constant in all situations INPUTS: m mass flow of supply dry air kg/s tS supply air °C tIsp indoor air setpoint °C phiIsp - tO outdoor temperature for design °C phiO outdoor relative humidity for design - Qsa aux. sensible heat W Qla aux. latente heat W mi infiltration massflow rate kg/s UA global conductivity bldg W/K System: HC: Heating Coil VH: Vapor Humidifier TZ: Thermal Zone BL: Building Kw: Controller - humidity Kt: Controller - temperature o: outdoor conditions 10 Unknowns 0, 1, 2 points (temperature, humidity ratio) QsHC, QlVH, QsTZ, QlTZ --o->HC--0->VH--1->TZ--2--> / / || | | | BL | | | | | |<----Kw--|-w2 |<------------Kt--|-t2 """ plt.close('all') wO = psy.w(tO, phiO) # hum. out # Mass flow rate for design conditions # tOd = -1 # outdoor design conditions # mid = 2.18 # infiltration design QsZ = UA * (tOd - tIsp) + mid * c * (tOd - tIsp) m = -QsZ / (c * (tS - tIsp)) print('Winter All_out_air CAV') print(f'm = {m: 5.3f} kg/s constant (from design conditions)') print(f'Design conditions tS = {tS: 3.1f} °C,' f'mi = {mid:3.1f} kg/s, tO = {tOd:3.1f} °C, ' f'tI = {tIsp:3.1f} °C') # Model x = ModelAllOutAir(m, tS, tIsp, phiIsp, tO, phiO, Qsa, Qla, mi, UA) # Processes on psychrometric chart t = np.append(tO, x[0:5:2]) w = np.append(wO, x[1:6:2]) # Adjancy matrix: rows=lines; columns=points # Points O 0 1 2 Elements A = np.array([ [-1, 1, 0, 0], # HC [0, -1, 1, 0], # VH [0, 0, 1, -1] ]) # TZ psy.chartA(t, w, A) t = pd.Series(t) w = 1000 * pd.Series(w) P = pd.concat([t, w], axis=1) # points P.columns = ['t [°C]', 'w [g/kg]'] output = P.to_string(formatters={ 't [°C]': '{:,.2f}'.format, 'w [g/kg]': '{:,.2f}'.format }) print() print(output) Q = pd.Series(x[6:], index=['QsHC', 'QlVH', 'QsTZ', 'QlTZ']) # Q.columns = ['kW'] pd.options.display.float_format = '{:,.2f}'.format print() print(Q.to_frame().T / 1000, 'kW') return x