Source code for component.solar.parabolic_trough_collector
# -*- coding: utf-8 -*-"""Created on Tue Jul 30 14:32:39 2024@author: Basilesource : Semi-empirical correlation to model heat losses along solar parabolic trough collectors Rémi Dickes, Vincent Lemort and Sylvain Quoilin https://hdl.handle.net/2268/182680"""import__init__#import component.solar.parabolictroughcollector as parabolictroughcollectorimportCoolProp.CoolPropasCPimportnumpyasnpfromcomponent.base_componentimportBaseComponentfromconnector.mass_connectorimportMassConnectorfromconnector.heat_connectorimportHeatConnector
[docs]classPTCollector(BaseComponent):""" **Component**: Parabolic Trough Collector **Model**: Semi empirical **Description** This model determines the thermal power absorbed by a parabolic trough collector and its heat transfer fluid exhaust specific enthalpy . **Assumptions**: - Heat losses to the ambiant are considered. **Connectors**: su (MassConnector): Mass connector for the suction side. ex (MassConnector): Mass connector for the exhaust side. Q_amb (HeatConnector): Heat connector to the ambiant. **Parameters**: coll_eff: Collector efficieny [-] a [1..9]: semi empirical parameters n_disc: number of discretisations in the lenght of the heat collection element. [-] envel_tau: transmittance of the heat collection element envelop. [-] alpha_r: Receiver absorptivity. [-] refl_m: Mirror reflectivity. [-] epsilon_r: Receiver emittance @ 400°C. [-] eta_other: Other efficiency to be accounted for in the calculation of the overall optical efficiency, different than the transmittance and absorbtivity of the receiver and the mirror reflectivity. [-] V_w_max_tr: maximum wind speed (stowed). [m/s] V_w_max_st: minimum wind speed (stowed). [m/s] Vdot_min: minimum recommended flowrate. [m^3/s] Vdot_max: maximum recommended flowrate. [m^3/s] T_f_min: Minimum operating fluid temperature. [K] T_f_max: Maximum operating fluid temperature. [K] Geometrical parameters: L: length of the parabolic trough collector. [m] W: Width of the parabolic trough collector. [m] A: Area of the parabolic trough collector. [m^2] A_r: Reflective area. [m^2] m: Collector weight. [kg] L_f: Focal Length. [m] Tube_OD: Tube external diameter. [m] Tube_V: Tube volume. [m^3] **Inputs**: fluid: Fluid at the suction of the PT collector. [-] m_dot: Mass flow rate in the PT collector (at suction). [kg/s] T_su: Temperature at the suction. [K] P_su: Pressure at the suction. [Pa] v_wind: Wind speed on the PT collector's heat collection element. [m/s] T_amb: Ambiant temperature. [K] Theta: Incidence angle. [rad] DNI: Direct Normal Irradiance. [W/m^2] **Ouputs**: h_ex: Exhaust side specific enthalpy. [J/kg] Q_dot: Thermal Power absorbed by the PT collector. [W] """def__init__(self):super().__init__()self.su=MassConnector()self.ex=MassConnector()self.Q_amb=HeatConnector()self.v_wind=Noneself.Theta=Noneself.DNI=Nonedefget_required_inputs(self):self.sync_inputs()# Return a list of required inputs# DNI : Direct Natural Irradiation# Incidence anglereturn['P_su','m_dot','T_su','T_amb','DNI','Theta','v_wind','fluid']defget_required_parameters(self):return['coll_eff','L','W','A','A_r','m','L_f','Tube_OD','Tube_V','alpha_r','refl_m','epsilon_r','envel_tau','eta_other','V_w_max_tr','V_w_max_st','Vdot_min','Vdot_max','T_f_min','T_f_max','a','n_disc']defheat_losses(self,k):"Calibrated for soponova_microcsp collector"T_amb=self.Q_amb.T_cold-273.15# °CT_htf=self.T[k]-273.15# °CTerms=[]Terms.append(self.params['a'][0])Terms.append(self.params['a'][1]*(T_htf-T_amb))Terms.append(self.params['a'][2]*(T_htf-T_amb)**2)Terms.append(self.DNI*np.cos(self.Theta)*(self.params['a'][3]*T_htf**2))Terms.append(self.DNI*np.cos(self.Theta)*(self.params['a'][4]*np.sqrt(self.v_wind)))Terms.append(self.params['a'][5]*T_htf**3)Terms.append(self.v_wind*self.params['a'][6])Terms.append(self.v_wind*self.params['a'][7]*(T_htf-T_amb))Terms.append(np.sqrt(self.v_wind)*self.params['a'][8])Terms.append(np.sqrt(self.v_wind)*self.params['a'][9]*(T_htf-T_amb))Terms_np=np.array(Terms)# W/m (of line collector)returnsum(Terms_np)defQ_dot_abs(self,k):# Sun absorbed powereta_opt=self.params['eta_other']*self.params['alpha_r']*self.params['refl_m']*self.params['envel_tau']Q_dot_sun_raw=self.DNI*np.cos(self.Theta)*self.params['W']# *eta_opt # self.L_discQ_dot_sun=Q_dot_sun_raw*eta_optOpt_losses=Q_dot_sun_raw*(1-eta_opt)# Heat loss powerHL=self.heat_losses(k)Q_dot_loss=HL#*self.L_discQ_dot_abs=Q_dot_sun-Q_dot_lossreturnQ_dot_absdefsolve(self):self.check_calculable()self.check_parametrized()self.AS=CP.AbstractState('HEOS',self.su.fluid)ifself.calculableandself.parametrized:self.v_wind=self.inputs['v_wind']self.Theta=self.inputs['Theta']self.DNI=self.inputs['DNI']self.T=np.zeros(self.params['n_disc']+1)self.p=np.zeros(self.params['n_disc']+1)self.h=np.zeros(self.params['n_disc']+1)self.Q_dot_disc=np.zeros(self.params['n_disc'])self.Q_dot_abs_disc=np.zeros(self.params['n_disc'])self.eta_coll=np.zeros(self.params['n_disc'])self.T[0]=self.su.Tself.p[0]=self.su.pself.h[0]=self.su.hself.L_disc=self.params['L']/self.params['n_disc']foriinrange(len(self.Q_dot_disc)):self.Q_dot_disc[i]=self.DNI*np.cos(self.Theta)*self.L_disc*self.params['W']self.Q_dot_abs_disc[i]=self.Q_dot_disc[i]*self.params['coll_eff'](self.DNI,(self.T[i]-self.Q_amb.T_cold))self.eta_coll[i]=self.params['coll_eff'](self.DNI,(self.T[i]-self.Q_amb.T_cold))self.h[i+1]=self.h[i]+self.Q_dot_abs_disc[i]/self.su.m_dotself.p[i+1]=self.p[i]self.AS.update(CP.HmassP_INPUTS,self.h[i+1],self.p[i+1])self.T[i+1]=self.AS.T()self.Q_dot=sum(self.Q_dot_abs_disc)self.ex.set_fluid(self.su.fluid)self.ex.set_m_dot(self.su.m_dot)self.ex.set_h(self.h[-1])self.ex.set_p(self.p[-1])self.solved=Truereturnelse:ifnotself.calculable:print("Input of the component not completely known. Required inputs:")forinputinself.get_required_inputs():ifinputnotinself.inputs:print(f" - {input}")ifnotself.parametrized:print("Parameters of the component not completely known. Required parameters:")forparaminself.get_required_parameters():ifparamnotinself.params:print(f" - {param}")defprint_results(self):ifself.defined:print("=== Heat Exchanger Results ===")print(f" - H_ex: fluid={self.ex['H'].fluid}, T={self.ex['H'].T}, p={self.ex['H'].p}, m_dot={self.ex['H'].m_dot}")print(f" - C_ex: fluid={self.ex['C'].fluid}, T={self.ex['C'].T}, p={self.ex['C'].p}, m_dot={self.ex['C'].m_dot}")print(f" - Q_dot: temperature_in={self.Q_dot}")else:print("Heat Exchanger component is not defined. Ensure it is solved first.")