DHU_AB.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. from typing import Union
  2. import numpy as np
  3. import pandas as pd
  4. import pymc as pm
  5. import pytensor.tensor as pt
  6. from .._base._base_device import BaseDevice
  7. from ...components import (
  8. coil_water,coil_steam,wheel2,wheel3,mixed
  9. )
  10. from ..utils.fit_utils import (
  11. observe,reorder_posterior
  12. )
  13. from ...tools.optimizer import optimizer
  14. from ...tools.data_cleaner import DataCleaner
  15. class DHU_AB(BaseDevice):
  16. val_rw_adj_target = ('coil_2_DoutA','coil_3_DoutA')
  17. def __init__(
  18. self,
  19. DHU_type = 'A',
  20. exist_Fa_H = True,
  21. exist_Fa_B = True,
  22. wheel_1 = None,
  23. wheel_2 = None,
  24. coolingcoil_2 = 'CoolingCoil2',
  25. coolingcoil_3 = 'CoolingCoil2',
  26. heatingcoil_1 = 'SteamCoil',
  27. heatingcoil_2 = 'SteamCoil',
  28. mixed_1 = 'Mixed',
  29. mixed_2 = 'Mixed',
  30. ) -> None:
  31. super().__init__()
  32. self.DHU_type = DHU_type.replace('DHU_','')
  33. if self.DHU_type == 'A':
  34. wheel_1 = wheel_1 if wheel_1 is not None else 'WheelS3'
  35. wheel_2 = wheel_2 if wheel_2 is not None else 'WheelS3'
  36. elif self.DHU_type == 'B':
  37. wheel_1 = wheel_1 if wheel_1 is not None else 'WheelS2V2'
  38. wheel_2 = wheel_2 if wheel_2 is not None else 'WheelS3V3'
  39. else:
  40. raise Exception('DHU_type must be A or B')
  41. self.components_str = {
  42. 'wheel_1' : wheel_1,
  43. 'wheel_2' : wheel_2,
  44. 'coil_2' : coolingcoil_2,
  45. 'coil_3' : coolingcoil_3,
  46. 'heatingcoil_1': heatingcoil_1,
  47. 'heatingcoil_2': heatingcoil_2,
  48. 'mixed_1' : mixed_1,
  49. 'mixed_2' : mixed_2
  50. }
  51. self.exist_Fa_H = exist_Fa_H
  52. self.exist_Fa_B = exist_Fa_B
  53. self.record_load_info(
  54. components_str = self.components_str,
  55. DHU_type = self.DHU_type,
  56. exist_Fa_H = self.exist_Fa_H,
  57. exist_Fa_B = self.exist_Fa_B
  58. )
  59. @property
  60. def components(self):
  61. comp_map = {
  62. 'WheelS2':wheel2,'WheelS3':wheel3,'CoolingCoil':coil_water,
  63. 'SteamCoil':coil_steam,'Mixed':mixed
  64. }
  65. output ={}
  66. for comp_name,comp_model in self.components_str.items():
  67. for comp_map_k,comp_map_v in comp_map.items():
  68. if comp_model.startswith(comp_map_k):
  69. output[comp_name] = getattr(comp_map_v,comp_model)(comp_name)
  70. return output
  71. @property
  72. def model_input_data_columns(self):
  73. columns = {
  74. 'Tin_F' : 'coil_1_ToutA',
  75. 'Hin_F' : 'coil_1_HoutA',
  76. 'fan_1_Hz' : 'fan_1_Hz',
  77. 'fan_2_Hz' : 'fan_2_Hz',
  78. 'coil_1_TinW' : 'coil_1_TinW',
  79. 'coil_2_TinW' : 'coil_2_TinW',
  80. 'coil_3_TinW' : 'coil_3_TinW',
  81. 'coil_1_Val' : 'coil_1_Val',
  82. 'coil_2_Val' : 'coil_2_Val',
  83. 'coil_3_Val' : 'coil_3_Val',
  84. 'wheel_1_TinR': 'wheel_1_TinR',
  85. 'wheel_2_TinR': 'wheel_2_TinR',
  86. }
  87. if self.exist_Fa_H:
  88. columns['mixed_1_TinM'] = 'mixed_1_TinM'
  89. columns['mixed_1_HinM'] = 'mixed_1_HinM'
  90. if self.exist_Fa_B:
  91. columns['mixed_2_TinM'] = 'mixed_2_TinM'
  92. columns['mixed_2_HinM'] = 'mixed_2_HinM'
  93. return columns
  94. @property
  95. def model_observe_data_columns(self):
  96. columns = {
  97. 'mixed_1_ToutA' : 'mixed_1_ToutA',
  98. 'mixed_1_DoutA' : 'mixed_1_DoutA',
  99. 'coil_2_ToutA' : 'coil_2_ToutA',
  100. 'coil_2_DoutA' : 'coil_2_DoutA',
  101. 'wheel_2_ToutP' : 'wheel_2_ToutP',
  102. 'wheel_2_DoutP' : 'wheel_2_DoutP',
  103. 'wheel_2_ToutR' : 'wheel_2_ToutR',
  104. }
  105. if self.DHU_type == 'A':
  106. columns['wheel_1_ToutC'] = 'wheel_1_ToutC'
  107. for idx in [1,2]:
  108. heatingcoil_idx = f'heatingcoil_{idx}'
  109. if isinstance(self.components[heatingcoil_idx],coil_steam.SteamCoilFs2):
  110. columns[f'{heatingcoil_idx}_FP'] = f'{heatingcoil_idx}_FP'
  111. columns[f'{heatingcoil_idx}_Fs'] = f'{heatingcoil_idx}_Fs'
  112. elif isinstance(self.components[heatingcoil_idx],coil_steam.SteamCoilFs):
  113. columns[f'{heatingcoil_idx}_Fs'] = f'{heatingcoil_idx}_Fs'
  114. elif isinstance(self.components[heatingcoil_idx],coil_steam.SteamCoil):
  115. columns['wheel_2_ToutC'] = 'wheel_2_ToutC'
  116. else:
  117. raise Exception('WRONG')
  118. return columns
  119. def fit(
  120. self,
  121. input_data : pd.DataFrame,
  122. observed_data: pd.DataFrame,
  123. rw_FA_val : bool = False,
  124. plot_TVP : bool = True,
  125. ):
  126. if len(input_data) < 30:
  127. raise Exception('数据量过少')
  128. with pm.Model() as self.MODEL_PYMC:
  129. param_prior = {name:comp.prior() for name,comp in self.components.items()}
  130. param_prior['F_air'] = AirFlow_DHU_AB.prior(
  131. rw_FA_val = rw_FA_val,
  132. N = len(input_data),
  133. exist_Fa_H = self.exist_Fa_H,
  134. exist_Fa_B = self.exist_Fa_B
  135. )
  136. res = self.model(
  137. **{k:input_data.loc[:,v].values for k,v in self.model_input_data_columns.items()},
  138. engine = 'pymc',
  139. components = self.components,
  140. param = param_prior
  141. )
  142. for std_name,name in self.model_observe_data_columns.items():
  143. if name not in observed_data.columns:
  144. continue
  145. observed_data = observed_data.rename(columns={name:std_name})
  146. std_name_equp,std_name_point = std_name.rsplit('_',1)
  147. sigma = {
  148. 'wheel_2_DoutP' : 0.3,
  149. 'heatingcoil_1_Fs': 20,
  150. 'heatingcoil_2_Fs': 20,
  151. 'heatingcoil_1_FP': 10000,
  152. 'heatingcoil_2_FP': 10000,
  153. }
  154. observe(
  155. name = std_name,
  156. var = res[std_name_equp][std_name_point],
  157. observed = observed_data,
  158. sigma = sigma.get(std_name,1)
  159. )
  160. self.param_posterior = pm.find_MAP(maxeval=50000,include_transformed=False)
  161. self.record_load_info(
  162. param_posterior = self.param_posterior
  163. )
  164. self.record_model(
  165. model_name = 'ATD',
  166. model = reorder_posterior(param_prior,self.param_posterior),
  167. train_data = {'x':np.array([1])},
  168. train_metric = {'R2':1,'MAE':1,'MAPE':1}
  169. )
  170. self.TVP_data = self.get_TVP(self.param_posterior,observed_data)
  171. self.TVP_metric = self.get_metric(self.TVP_data)
  172. if plot_TVP:
  173. self.plot_TVP(self.TVP_data).show()
  174. return self
  175. @property
  176. def F_air_val_rw(self):
  177. return self.model_info['model_ATD']['F_air']['val_rw']
  178. def set_F_air_val_rw(self,value:float):
  179. self.model_info['model_ATD']['F_air']['val_rw'] = value
  180. return self
  181. def clean_data(
  182. self,
  183. data : pd.DataFrame,
  184. data_type : list=['input','observed'],
  185. print_process: bool = True,
  186. fill_zero : bool = False,
  187. save_log : Union[str,None] = None
  188. ) -> pd.DataFrame:
  189. data = data.replace(-9999,np.nan)
  190. clean_data = DataCleaner(data,print_process=print_process)
  191. if 'input' in data_type:
  192. clean_data = (
  193. clean_data
  194. .rm_rolling_fluct(window=60,fun='ptp',thre=0.1,include_cols=['State'])
  195. .rm_rule('State != 1')
  196. .rm_outrange(method='raw',upper=140,lower=20,include_cols=['wheel_1_TinR','wheel_2_TinR'])
  197. )
  198. if self.DHU_type == 'A':
  199. clean_data = (
  200. clean_data
  201. .rm_rule('wheel_1_ToutC<=coil_1_ToutA')
  202. )
  203. if 'observed' in data_type:
  204. pass
  205. clean_data = clean_data.get_data(
  206. fill = 0 if fill_zero else None,
  207. save_log = save_log
  208. )
  209. return clean_data
  210. def optimize(
  211. self,
  212. cur_input_data : pd.DataFrame,
  213. wheel_1_TinR_ub: float = 120,
  214. wheel_1_TinR_lb: float = 70,
  215. wheel_2_TinR_ub: float = 120,
  216. wheel_2_TinR_lb: float = 70,
  217. constrains : list = None,
  218. logging : bool = True
  219. ) -> list:
  220. constrains = [] if constrains is None else constrains
  221. cur_input_data = cur_input_data.iloc[[0],:]
  222. opt_var_boundary = {
  223. 'wheel_1_TinR':{'lb':wheel_1_TinR_lb,'ub':wheel_1_TinR_ub},
  224. 'wheel_2_TinR':{'lb':wheel_2_TinR_lb,'ub':wheel_2_TinR_ub},
  225. }
  226. opt_var_value = cur_input_data.loc[:,list(opt_var_boundary.keys())]
  227. oth_var_value = (
  228. cur_input_data
  229. .loc[:,list(self.model_input_data_columns.values())]
  230. .drop(opt_var_value.columns,axis=1)
  231. )
  232. opt_res = optimizer(
  233. model = self,
  234. opt_var_boundary = opt_var_boundary,
  235. opt_var_value = opt_var_value,
  236. oth_var_value = oth_var_value,
  237. target = 'summary_Fs',
  238. target_min = True,
  239. constrains = constrains,
  240. logging = logging,
  241. other_kwargs = {'NIND':2000,'MAXGEN':50}
  242. )
  243. return opt_res
  244. def model(self,*args,**kwargs):
  245. if self.DHU_type == 'A':
  246. return model_A(*args,**kwargs)
  247. elif self.DHU_type == 'B':
  248. return model_B(*args,**kwargs)
  249. else:
  250. raise ValueError('DHU_type must be A or B')
  251. def model_A(
  252. Tin_F, # 前表冷后温度
  253. Hin_F, # 前表冷后湿度
  254. fan_1_Hz, # 处理侧风机频率
  255. fan_2_Hz, # 再生侧风机频率
  256. coil_1_TinW, # 前表冷进水温度
  257. coil_2_TinW, # 中表冷进水温度
  258. coil_3_TinW, # 后表冷进水温度
  259. coil_1_Val, # 前表冷阀门开度
  260. coil_2_Val, # 中表冷阀门开度
  261. coil_3_Val, # 后表冷阀门开度
  262. wheel_1_TinR, # 前转轮再生侧温度
  263. wheel_2_TinR, # 后转轮再生侧温度
  264. engine : str,
  265. components: dict,
  266. param : dict,
  267. mixed_1_TinM = 0, # 回风温度(处理侧)
  268. mixed_1_HinM = 0, # 回风湿度(处理侧)
  269. mixed_2_TinM = 0, # 补风温度(再生侧)
  270. mixed_2_HinM = 0, # 补风湿度(再生侧)
  271. ) -> dict:
  272. # 水的质量流量
  273. coil_2_FW = coil_2_Val / 100
  274. coil_3_FW = coil_3_Val / 100
  275. # 空气的质量流量
  276. air_flow = AirFlow_DHU_AB.model(fan_1_Hz=fan_1_Hz,fan_2_Hz=fan_2_Hz,param=param,type='DHU_A')
  277. # 前转轮
  278. wheel_1_res = components['wheel_1'].model(
  279. TinP = Tin_F,
  280. HinP = Hin_F,
  281. FP = air_flow['wheel_1_FaP'],
  282. TinR = wheel_1_TinR,
  283. HinR = 0,
  284. FR = air_flow['wheel_1_FaR'],
  285. TinC = Tin_F,
  286. HinC = Hin_F,
  287. FC = air_flow['wheel_1_FaC'],
  288. engine = engine,
  289. param = param['wheel_1']
  290. )
  291. # 处理侧混风(回风)
  292. mixed_1_res = components['mixed_1'].model(
  293. TinA = wheel_1_res['ToutP'],
  294. HinA = wheel_1_res['HoutP'],
  295. FA = air_flow['mixed_1_FaA'],
  296. TinM = mixed_1_TinM,
  297. HinM = mixed_1_HinM,
  298. FM = air_flow['mixed_1_FaM'],
  299. engine = engine
  300. )
  301. # 中表冷
  302. coil_2_res = components['coil_2'].model(
  303. TinA = mixed_1_res['ToutA'],
  304. HinA = mixed_1_res['HoutA'],
  305. FA = air_flow['coil_2_FaA'],
  306. TinW = coil_2_TinW,
  307. FW = coil_2_FW,
  308. engine = engine,
  309. param = param['coil_2']
  310. )
  311. # 后转轮
  312. wheel_2_res = components['wheel_2'].model(
  313. TinP = coil_2_res['ToutA'],
  314. HinP = coil_2_res['HoutA'],
  315. FP = air_flow['wheel_2_FaP'],
  316. TinC = wheel_1_res['ToutC'],
  317. HinC = wheel_1_res['HoutC'],
  318. FC = air_flow['wheel_2_FaC'],
  319. TinR = wheel_2_TinR,
  320. HinR = 0,
  321. FR = air_flow['wheel_2_FaR'],
  322. engine = engine,
  323. param = param['wheel_2'],
  324. )
  325. # 后表冷
  326. coil_3_res = components['coil_3'].model(
  327. TinA = wheel_2_res['ToutP'],
  328. HinA = wheel_2_res['HoutP'],
  329. FA = air_flow['coil_3_FaA'],
  330. TinW = coil_3_TinW,
  331. FW = coil_3_FW,
  332. engine = engine,
  333. param = param['coil_3']
  334. )
  335. # 后转轮湿度修正
  336. wheel_2_res_adj = components['wheel_2'].model(
  337. TinP = coil_2_res['ToutA'],
  338. HinP = coil_2_res['HoutA'],
  339. FP = air_flow['wheel_2_FaP'],
  340. TinC = wheel_1_res['ToutC'],
  341. HinC = wheel_1_res['HoutC'],
  342. FC = air_flow['wheel_2_FaC'],
  343. TinR = wheel_2_TinR,
  344. HinR = wheel_2_res['HoutC'],
  345. FR = air_flow['wheel_2_FaR'],
  346. engine = engine,
  347. param = param['wheel_2'],
  348. )
  349. # 再生侧混风(排风)
  350. mixed_2_res = components['mixed_2'].model(
  351. TinA = wheel_2_res_adj['ToutR'],
  352. HinA = wheel_2_res_adj['HoutR'],
  353. FA = air_flow['mixed_2_FaA'],
  354. TinM = mixed_2_TinM,
  355. HinM = mixed_2_HinM,
  356. FM = air_flow['mixed_2_FaM'],
  357. engine = engine
  358. )
  359. # 前转轮湿度修正
  360. wheel_1_res_adj = components['wheel_1'].model(
  361. TinP = Tin_F,
  362. HinP = Hin_F,
  363. FP = air_flow['wheel_1_FaP'],
  364. TinR = wheel_1_TinR,
  365. HinR = mixed_2_res['HoutA'],
  366. FR = air_flow['wheel_1_FaR'],
  367. TinC = Tin_F,
  368. HinC = Hin_F,
  369. FC = air_flow['wheel_1_FaC'],
  370. engine = engine,
  371. param = param['wheel_1']
  372. )
  373. # 前再生加热盘管
  374. heatingcoil_1_res = components['heatingcoil_1'].model(
  375. TinA = mixed_2_res['ToutA'],
  376. ToutA = wheel_1_TinR,
  377. FA = air_flow['heatingcoil_1_Fa'],
  378. param = param['heatingcoil_1'],
  379. engine = engine
  380. )
  381. # 后再生加热盘管
  382. heatingcoil_2_res = components['heatingcoil_2'].model(
  383. TinA = wheel_2_res_adj['ToutC'],
  384. ToutA = wheel_2_TinR,
  385. FA = air_flow['heatingcoil_2_Fa'],
  386. param = param['heatingcoil_2'],
  387. engine = engine
  388. )
  389. return {
  390. 'coil_2' : coil_2_res,
  391. 'coil_3' : coil_3_res,
  392. 'wheel_1' : wheel_1_res_adj,
  393. 'wheel_2' : wheel_2_res_adj,
  394. 'mixed_1' : mixed_1_res,
  395. 'mixed_2' : mixed_2_res,
  396. 'heatingcoil_1': heatingcoil_1_res,
  397. 'heatingcoil_2': heatingcoil_2_res,
  398. 'Fa' : air_flow,
  399. 'summary' : {
  400. 'Fs':heatingcoil_1_res['Fs'] + heatingcoil_2_res['Fs'],
  401. }
  402. }
  403. def model_B(
  404. Tin_F, # 前表冷后温度
  405. Hin_F, # 前表冷后湿度
  406. fan_1_Hz, # 处理侧风机频率
  407. fan_2_Hz, # 再生侧风机频率
  408. coil_1_TinW, # 前表冷进水温度
  409. coil_2_TinW, # 中表冷进水温度
  410. coil_3_TinW, # 后表冷进水温度
  411. coil_1_Val, # 前表冷阀门开度
  412. coil_2_Val, # 中表冷阀门开度
  413. coil_3_Val, # 后表冷阀门开度
  414. wheel_1_TinR, # 前转轮再生侧温度
  415. wheel_2_TinR, # 后转轮再生侧温度
  416. engine : str,
  417. components: dict,
  418. param : dict,
  419. mixed_1_TinM = 0, # 回风温度(处理侧)
  420. mixed_1_HinM = 0, # 回风湿度(处理侧)
  421. mixed_2_TinM = 0, # 补风温度(再生侧)
  422. mixed_2_HinM = 0, # 补风湿度(再生侧)
  423. ) -> dict:
  424. # 水的质量流量
  425. coil_2_FW = coil_2_Val / 100
  426. coil_3_FW = coil_3_Val / 100
  427. # 空气的质量流量
  428. air_flow = AirFlow_DHU_AB.model(fan_1_Hz=fan_1_Hz,fan_2_Hz=fan_2_Hz,param=param,type='DHU_B')
  429. # 前转轮
  430. wheel_1_res = components['wheel_1'].model(
  431. TinP = Tin_F,
  432. HinP = Hin_F,
  433. FP = air_flow['wheel_1_FaP'],
  434. TinR = wheel_1_TinR,
  435. HinR = 0,
  436. FR = air_flow['wheel_1_FaR'],
  437. engine = engine,
  438. param = param['wheel_1'],
  439. )
  440. # 处理侧混风(回风)
  441. mixed_1_res = components['mixed_1'].model(
  442. TinA = wheel_1_res['ToutP'],
  443. HinA = wheel_1_res['HoutP'],
  444. FA = air_flow['mixed_1_FaA'],
  445. TinM = mixed_1_TinM,
  446. HinM = mixed_1_HinM,
  447. FM = air_flow['mixed_1_FaM'],
  448. engine = engine
  449. )
  450. # 中表冷
  451. coil_2_res = components['coil_2'].model(
  452. TinA = mixed_1_res['ToutA'],
  453. HinA = mixed_1_res['HoutA'],
  454. FA = air_flow['coil_2_FaA'],
  455. TinW = coil_2_TinW,
  456. FW = coil_2_FW,
  457. engine = engine,
  458. param = param['coil_2']
  459. )
  460. # 后转轮
  461. wheel_2_res = components['wheel_2'].model(
  462. TinP = coil_2_res['ToutA'],
  463. HinP = coil_2_res['HoutA'],
  464. FP = air_flow['wheel_2_FaP'],
  465. TinC = mixed_1_res['ToutA'],
  466. HinC = mixed_1_res['HoutA'],
  467. FC = air_flow['wheel_2_FaC'],
  468. TinR = wheel_2_TinR,
  469. HinR = 0,
  470. FR = air_flow['wheel_2_FaR'],
  471. engine = engine,
  472. param = param['wheel_2'],
  473. )
  474. # 后表冷
  475. coil_3_res = components['coil_3'].model(
  476. TinA = wheel_2_res['ToutP'],
  477. HinA = wheel_2_res['HoutP'],
  478. FA = air_flow['coil_3_FaA'],
  479. TinW = coil_3_TinW,
  480. FW = coil_3_FW,
  481. engine = engine,
  482. param = param['coil_3']
  483. )
  484. # 后转轮湿度修正
  485. wheel_2_res_adj = components['wheel_2'].model(
  486. TinP = coil_2_res['ToutA'],
  487. HinP = coil_2_res['HoutA'],
  488. FP = air_flow['wheel_2_FaP'],
  489. TinC = mixed_1_res['ToutA'],
  490. HinC = mixed_1_res['HoutA'],
  491. FC = air_flow['wheel_2_FaC'],
  492. TinR = wheel_2_TinR,
  493. HinR = wheel_2_res['HoutC'],
  494. FR = air_flow['wheel_2_FaR'],
  495. engine = engine,
  496. param = param['wheel_2'],
  497. )
  498. # 再生侧混风(排风)
  499. mixed_2_res = components['mixed_2'].model(
  500. TinA = wheel_2_res_adj['ToutR'],
  501. HinA = wheel_2_res_adj['HoutR'],
  502. FA = air_flow['mixed_2_FaA'],
  503. TinM = mixed_2_TinM,
  504. HinM = mixed_2_HinM,
  505. FM = air_flow['mixed_2_FaM'],
  506. engine = engine
  507. )
  508. # 前转轮湿度修正
  509. wheel_1_res_adj = components['wheel_1'].model(
  510. TinP = Tin_F,
  511. HinP = Hin_F,
  512. FP = air_flow['wheel_1_FaP'],
  513. TinR = wheel_1_TinR,
  514. HinR = mixed_2_res['HoutA'],
  515. FR = air_flow['wheel_1_FaR'],
  516. engine = engine,
  517. param = param['wheel_1'],
  518. )
  519. # 前蒸气盘管
  520. heatingcoil_1_res = components['heatingcoil_1'].model(
  521. TinA = mixed_2_res['ToutA'],
  522. ToutA = wheel_1_TinR,
  523. FA = air_flow['heatingcoil_1_Fa'],
  524. param = param['heatingcoil_1'],
  525. engine = engine
  526. )
  527. # 后蒸气盘管
  528. heatingcoil_2_res = components['heatingcoil_2'].model(
  529. TinA = wheel_2_res_adj['ToutC'],
  530. ToutA = wheel_2_TinR,
  531. FA = air_flow['heatingcoil_2_Fa'],
  532. param = param['heatingcoil_2'],
  533. engine = engine
  534. )
  535. return {
  536. 'coil_2' : coil_2_res,
  537. 'coil_3' : coil_3_res,
  538. 'wheel_1' : wheel_1_res_adj,
  539. 'wheel_2' : wheel_2_res_adj,
  540. 'mixed_1' : mixed_1_res,
  541. 'mixed_2' : mixed_2_res,
  542. 'heatingcoil_1': heatingcoil_1_res,
  543. 'heatingcoil_2': heatingcoil_2_res,
  544. 'Fa' : air_flow,
  545. 'summary' : {
  546. 'Fs':heatingcoil_1_res['Fs'] + heatingcoil_2_res['Fs'],
  547. }
  548. }
  549. class AirFlow_DHU_AB:
  550. @classmethod
  551. def model(cls,fan_1_Hz,fan_2_Hz,param,type):
  552. # 当定频风机固定的时候,各出入口处的基准的风量
  553. F_air_S_base = 1
  554. F_air_X_base = param['F_air']['X_base']
  555. F_air_H_base = param['F_air'].get('H_base',0)
  556. F_air_B_base = param['F_air'].get('B_base',0)
  557. F_air_val_rw = param['F_air'].get('val_rw',0)
  558. F_air_val_pct = param['F_air'].get('val_pct',0)
  559. # 新风阀的变化造成的基准风量变化
  560. F_air_S_base_adj = F_air_S_base
  561. F_air_X_base_adj = F_air_X_base + F_air_val_rw
  562. F_air_H_base_adj = F_air_H_base - F_air_val_rw * F_air_val_pct if 'H_base' in param['F_air'] else 0
  563. F_air_B_base_adj = F_air_B_base - F_air_val_rw * (1 - F_air_val_pct) if 'B_base' in param['F_air'] else 0
  564. # 考虑风机频率变化对风量的影响,得到最终风量
  565. F_air_HzP_X = param['F_air']['HzP_X']
  566. F_air_HzP_H = param['F_air'].get('HzP_H',0)
  567. F_air_HzP_S = F_air_HzP_X + F_air_HzP_H
  568. F_air_HzR_B = param['F_air'].get('HzR_B',0)
  569. Fa_S = F_air_S_base_adj + F_air_HzP_S * (fan_1_Hz / 50)
  570. Fa_H = F_air_H_base_adj + F_air_HzP_H * (fan_1_Hz / 50)
  571. Fa_X = F_air_X_base_adj + F_air_HzP_X * (fan_1_Hz / 50)
  572. Fa_B = F_air_B_base_adj + F_air_HzR_B * (fan_2_Hz / 50)
  573. Fa_P = Fa_B + Fa_X + Fa_H - Fa_S
  574. if type == 'DHU_A':
  575. wheel_1_FaP = Fa_S - Fa_H
  576. wheel_1_FaC = Fa_X - wheel_1_FaP
  577. wheel_1_FaR = Fa_P
  578. wheel_2_FaP = Fa_S
  579. wheel_2_FaC = wheel_1_FaC
  580. wheel_2_FaR = wheel_1_FaC
  581. mixed_1_FaM = Fa_H
  582. mixed_1_FaA = wheel_1_FaP
  583. mixed_2_FaM = Fa_B
  584. mixed_2_FaA = wheel_1_FaC
  585. coil_2_FaA = Fa_S
  586. coil_3_FaA = Fa_S
  587. heatingcoil_1_Fa = Fa_P
  588. heatingcoil_2_Fa = wheel_1_FaC
  589. elif type == 'DHU_B':
  590. wheel_1_FaP = Fa_X
  591. wheel_1_FaC = None
  592. wheel_1_FaR = Fa_P
  593. wheel_2_FaP = Fa_S
  594. wheel_2_FaC = Fa_X + Fa_H - Fa_S
  595. wheel_2_FaR = wheel_2_FaC
  596. mixed_1_FaM = Fa_H
  597. mixed_1_FaA = Fa_X
  598. mixed_2_FaM = Fa_B
  599. mixed_2_FaA = wheel_2_FaC
  600. coil_2_FaA = Fa_S
  601. coil_3_FaA = Fa_S
  602. heatingcoil_1_Fa = Fa_P
  603. heatingcoil_2_Fa = wheel_2_FaC
  604. else:
  605. raise Exception('type error')
  606. return {
  607. 'Fa_S':Fa_S,'Fa_H':Fa_H,'Fa_X':Fa_X,'Fa_B':Fa_B,'Fa_P':Fa_P,
  608. 'wheel_1_FaP':wheel_1_FaP,'wheel_1_FaC':wheel_1_FaC,'wheel_1_FaR':wheel_1_FaR,
  609. 'wheel_2_FaP':wheel_2_FaP,'wheel_2_FaC':wheel_2_FaC,'wheel_2_FaR':wheel_2_FaR,
  610. 'mixed_1_FaM':mixed_1_FaM,'mixed_1_FaA':mixed_1_FaA,
  611. 'mixed_2_FaM':mixed_2_FaM,'mixed_2_FaA':mixed_2_FaA,
  612. 'coil_2_FaA':coil_2_FaA,'coil_3_FaA':coil_3_FaA,
  613. 'heatingcoil_1_Fa':heatingcoil_1_Fa,'heatingcoil_2_Fa':heatingcoil_2_Fa
  614. }
  615. @classmethod
  616. def prior(
  617. cls,
  618. rw_FA_val : bool,
  619. N : int,
  620. exist_Fa_H: bool,
  621. exist_Fa_B: bool
  622. ) -> dict:
  623. param = {}
  624. # 新风参数
  625. param['HzP_X'] = pm.HalfNormal('F_air_HzP_X',sigma=1,initval=1)
  626. param['X_base'] = pm.TruncatedNormal('F_air_X_base',mu=0.5,sigma=0.2,lower=0,initval=0.5)
  627. if exist_Fa_H:
  628. param['HzP_H'] = pm.HalfNormal('F_air_HzP_H',sigma=1,initval=0.1)
  629. param['H_base'] = pm.TruncatedNormal('F_air_H_base',mu=0.6,sigma=0.2,lower=0,upper=0.999,initval=0.6)
  630. if exist_Fa_B:
  631. param['HzR_B'] = pm.HalfNormal('F_air_HzR_B',sigma=1,initval=0.5)
  632. param['B_base'] = pm.TruncatedNormal('F_air_B_base',mu=0.2,sigma=0.1,lower=0,initval=0.1)
  633. if rw_FA_val:
  634. period = 48
  635. n_segments = int(np.ceil(N/period))
  636. remainder = N % period
  637. repeat = [period] * (n_segments - 1) + ([remainder] if remainder != 0 else [])
  638. rw = pm.GaussianRandomWalk(
  639. 'rw',sigma=0.1,init_dist=pm.Normal.dist(mu=0,sigma=0.3),shape=n_segments)
  640. param['val_rw'] = pm.Deterministic('F_air_val_rw',pt.repeat(rw,repeat))
  641. param['val_pct'] = pm.Beta('F_air_val_pct',alpha=8,beta=1,initval=0.9)
  642. # param['val_pct'] = pm.Dirichlet('F_air_val_pct',np.array([0.1,0.1,0.8]),initval=np.array([0.1,0.1,0.8]))
  643. else:
  644. param['val_rw'] = 0
  645. param['val_pct'] = 0
  646. return param