coil_steam.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import numpy as np
  2. try:
  3. import pymc as pm
  4. except:
  5. pass
  6. from ._base_components import BaseComponents
  7. class SteamCoilFs(BaseComponents):
  8. def __init__(self, name):
  9. super().__init__(name)
  10. @classmethod
  11. def model(
  12. cls,
  13. TinA,ToutA,FA,
  14. param,
  15. engine
  16. ):
  17. b1 = param['b1']
  18. b2 = param['b2']
  19. b3 = param['b3']
  20. Fs = b1 * (ToutA - TinA) * FA + b2 * TinA + b3
  21. return {'Fs':Fs}
  22. def prior(self):
  23. param = {
  24. 'b1': pm.HalfNormal(f'{self.name}_b1',sigma=10),
  25. 'b2': pm.Normal(f'{self.name}_b2',sigma=10),
  26. 'b3': pm.Normal(f'{self.name}_b3',sigma=10),
  27. }
  28. return param
  29. class SteamCoilFs2(BaseComponents):
  30. def __init__(self, name):
  31. super().__init__(name)
  32. @classmethod
  33. def model(cls,TinA,ToutA,FA,param,engine):
  34. b1 = param['b1']
  35. b2 = param['b2']
  36. FP = np.exp(b1 * (ToutA - TinA)*FA + b2)
  37. FUNC = cls.get_func_by_engine(engine)
  38. WHERE = FUNC['WHERE']
  39. LT = FUNC['LT']
  40. param_change_point = param['change_point']
  41. param_b1 = param['a1']
  42. param_b2 = param['a2']
  43. param_b3 = param['a3']
  44. param_Ps_change_point = param_b1 + param_b2 * param_change_point
  45. Fs = WHERE(
  46. LT(FP,param_Ps_change_point * param_change_point),
  47. get_root(param_b1,param_b2,FP),
  48. get_root(param_b1+(param_b2-param_b3)*param_change_point,param_b3,FP)
  49. )
  50. return {'FP':FP,'Fs':Fs}
  51. def prior(self):
  52. param = {
  53. 'b1' : pm.Normal(f'{self.name}_b1',mu=0.08,sigma=0.1,initval=0.08),
  54. 'b2' : pm.Normal(f'{self.name}_b2',mu=3.65,sigma=0.02,initval=3.65),
  55. 'change_point': pm.Normal(f'{self.name}_change_point',mu=104,sigma=1,initval=104),
  56. 'a1' : pm.Normal(f'{self.name}_a1',mu=17.5,sigma=1,initval=17.5),
  57. 'a2' : pm.Normal(f'{self.name}_a2',mu=0.2,sigma=0.1,initval=0.2),
  58. 'a3' : pm.Normal(f'{self.name}_a3',mu=1.5,sigma=0.1,initval=1.5),
  59. }
  60. return param
  61. class SteamCoil(BaseComponents):
  62. def __init__(self, name):
  63. super().__init__(name)
  64. @classmethod
  65. def model(
  66. cls,
  67. TinA,ToutA,FA,
  68. param,
  69. engine
  70. ):
  71. Q = (ToutA - TinA) * FA * cls.CONSTANT['c_p_air']
  72. return {'Q':Q,'Fs':Q}
  73. def prior(self):
  74. param = {}
  75. return param
  76. def get_root(b0,b1,FP):
  77. return (np.sqrt(b0**2+4*b1*FP)-b0)/(2*b1)
  78. class SteamCoilVal(BaseComponents):
  79. def __init__(self, name,Fs_rated):
  80. super().__init__(name)
  81. self.Fs_rated = Fs_rated
  82. if self.Fs_rated is None:
  83. raise Exception('Fs_rated must be provided')
  84. def model(
  85. self,
  86. TinA,ToutA,FA,
  87. param,
  88. engine
  89. ):
  90. FUNC = self.get_func_by_engine(engine)
  91. EXP = FUNC['EXP']
  92. Val = smooth_exp_transition(
  93. x = (ToutA - TinA) / 100,
  94. s = param['s'] - param['s_offset'] * TinA / 100,
  95. a = param['a'],
  96. b = param['b'],
  97. d = param['d'],
  98. FUNC_where = FUNC['WHERE']
  99. ) * 100
  100. sigma = EXP((ToutA - TinA) / 100 * param['alpha2'] + param['alpha1'])
  101. Fs = self.get_Fs_by_Val_and_Tin(Val,TinA,engine=engine)
  102. return {'Val':Val,'sigma':sigma,'Fs':Fs}
  103. def prior(self):
  104. param = {
  105. 's' : pm.Normal(f'{self.name}_s', mu=0, sigma=10,initval=0),
  106. 'a' : pm.HalfNormal(f'{self.name}_a', sigma=10,initval=1),
  107. 'b' : pm.Normal(f'{self.name}_b', mu=0, sigma=10,initval=0),
  108. 'd' : pm.HalfNormal(f'{self.name}_d', sigma=10,initval=1),
  109. 's_offset': pm.HalfNormal(f'{self.name}_s_offset', sigma=1,initval=0.1),
  110. 'alpha1' : pm.Normal(f'{self.name}_alpha1', mu=0, sigma=10,initval=-5),
  111. 'alpha2' : pm.HalfNormal(f'{self.name}_alpha2', sigma=10,initval=5)
  112. }
  113. return param
  114. def get_Fs_by_Val_and_Tin(self,Val,Tin,engine):
  115. WHERE = self.get_func_by_engine(engine)['WHERE']
  116. def piecewise_function(x, a, b, s, k):
  117. y_max = a * s + b + a / k
  118. y = WHERE(
  119. x < s,
  120. a * x + b,
  121. y_max - (a / k) * np.exp(-k * (x - s))
  122. )
  123. return y
  124. Fs = piecewise_function(
  125. Val / 100,
  126. a = 4.48157826,
  127. b = -0.62511713,
  128. s = 0.47809967 + Tin / 100 * (-0.37605304),
  129. k = 16.03141911 + Tin / 100 * 1.74054886
  130. )
  131. return Fs * self.Fs_rated
  132. def smooth_exp_transition(x, s, a, b, d,FUNC_where):
  133. """
  134. 光滑连接的线性-指数分段函数
  135. 参数:
  136. - x: 输入变量
  137. - s: 分段点
  138. - a: 线性部分斜率
  139. - b: 线性部分截距
  140. - d: 指数增长率
  141. """
  142. # 计算常数项
  143. c = a / (d * np.exp(d * s))
  144. e = a * s + b - a / d
  145. y = FUNC_where(
  146. x <= s,
  147. a * x + b,
  148. c * np.exp(d * x) + e
  149. )
  150. return y