UF_resistance_models.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. """
  2. 超滤膜阻力模型模块
  3. ====================
  4. 本模块定义了超滤膜阻力的动态变化模型,包括:
  5. 1. ResistanceIncreaseModel: 过滤阶段膜阻力上升模型
  6. 2. ResistanceDecreaseModel: 反洗阶段膜阻力下降模型
  7. 这些模型用于模拟超滤膜在运行过程中的阻力变化,是强化学习环境的核心组件。
  8. """
  9. import torch
  10. import numpy as np
  11. # ==================== 膜阻力上升模型 ====================
  12. class ResistanceIncreaseModel(torch.nn.Module):
  13. """
  14. 过滤阶段膜阻力上升模型
  15. 功能说明:
  16. - 计算在过滤阶段膜阻力的增长量 ΔR
  17. - 膜阻力上升主要由污染物在膜表面的累积引起
  18. - 阻力增长速率与膜通量(J)和过滤时长(L_s)相关
  19. 模型公式:
  20. ΔR = nuK × J × L_s
  21. 其中:
  22. - nuK: 膜阻力增长系数(反映水质污染特性)
  23. - J: 膜通量 = q_UF / A / 3600 [m/s]
  24. - L_s: 过滤时长 [秒]
  25. """
  26. def __init__(self):
  27. """初始化膜阻力上升模型(无需训练参数)"""
  28. super().__init__()
  29. def forward(self, p, L_s):
  30. """
  31. 前向传播:计算膜阻力上升量
  32. 参数:
  33. p (UFParams): 超滤运行参数对象,包含:
  34. - q_UF: 过滤进水流量 [m³/h]
  35. - nuK: 膜阻力增长系数 [m⁻¹/s]
  36. L_s (float): 过滤时长 [秒]
  37. 返回:
  38. float: 膜阻力上升量 ΔR(已缩放1e10)
  39. 注意:
  40. - 实际膜阻力量级为1e12,为便于数值计算已缩放至1e2量级
  41. - 膜面积 A = 128组 × 40 m²/组 = 5120 m²
  42. """
  43. # 计算膜有效面积(锡山水厂配置:128组膜,每组40m²)
  44. A = 128 * 40.0 # [m²]
  45. # 计算膜通量 J = 流量 / 面积 / 时间单位转换
  46. # q_UF [m³/h] → J [m³/(m²·s)]
  47. J = p.q_UF / A / 3600 # [m/s]
  48. # 膜阻力上升模型(线性模型,已缩放)
  49. # nuK: 阻力增长速率,反映水质污染特性
  50. # J: 膜通量,通量越大污染速率越快
  51. # L_s: 过滤时间,时间越长累积污染越多
  52. dR = p.nuK * J * L_s # [缩放后的阻力单位]
  53. return float(dR)
  54. # ==================== 膜阻力下降模型 ====================
  55. class ResistanceDecreaseModel(torch.nn.Module):
  56. """
  57. 反洗阶段膜阻力下降模型
  58. 功能说明:
  59. - 计算物理反冲洗能够去除的膜阻力量
  60. - 区分可逆污染和不可逆污染
  61. - 反洗时长影响去除效率
  62. 模型原理:
  63. 1. 膜污染分为两类:
  64. - 可逆污染:可通过物理反洗去除(如表面颗粒物)
  65. - 不可逆污染:无法通过物理反洗去除(如孔内吸附污染)
  66. 2. 不可逆污染累积模型:
  67. R_irr = R0 + slope × t^power
  68. 其中 t 为累积运行时间
  69. 3. 反洗效率模型:
  70. time_gain = 1 - exp(-t_bw / τ)
  71. 反洗时间越长,去除效率越高,但存在上限
  72. """
  73. def __init__(self):
  74. """初始化膜阻力下降模型(无需训练参数)"""
  75. super().__init__()
  76. def forward(self, p, R0, R_end, L_h_next_start, t_bw_s):
  77. """
  78. 前向传播:计算物理反洗能够去除的膜阻力
  79. 参数:
  80. p (UFParams): 超滤运行参数对象,包含:
  81. - slope: 不可逆污染增长斜率
  82. - power: 不可逆污染增长幂次
  83. - tau_bw_s: 反洗时长影响的时间尺度
  84. R0 (float): 本超级周期初始膜阻力
  85. R_end (float): 过滤结束时的膜阻力(峰值)
  86. L_h_next_start (float): 下一小周期起始时的累积运行时间 [小时]
  87. t_bw_s (float): 物理反洗时长 [秒]
  88. 返回:
  89. float: 物理反洗实际去除的膜阻力量
  90. 计算步骤:
  91. 1. 基于长期污染模型计算本周期的不可逆污染增量
  92. 2. 计算可逆污染量 = 当前总污染 - 不可逆污染
  93. 3. 应用时间因子(反洗时长的影响)
  94. 4. 返回实际去除的阻力(不超过可逆污染量)
  95. """
  96. # ========== 步骤1:计算不可逆污染累积 ==========
  97. # 使用幂律模型描述长期不可逆污染的累积
  98. # R_irr(t) = R0 + slope × t^power
  99. # 下一小周期开始时的理论膜阻力
  100. delta_R = p.slope * (L_h_next_start ** p.power)
  101. R_next_start = R0 + delta_R
  102. # 这部分污染可以通过物理反洗去除
  103. reversible_R = max(R_end - R_next_start, 0.0)
  104. # ========== 步骤3:计算反洗时间效率因子 ==========
  105. # 使用指数衰减模型:time_gain = 1 - exp(-t_bw / τ)
  106. # τ (tau_bw_s): 时间尺度参数
  107. # - 反洗时间 t_bw = 0 时,time_gain = 0(无去除效果)
  108. # - 反洗时间 t_bw → ∞ 时,time_gain → 1(达到最大效率)
  109. # - 反洗时间 t_bw = τ 时,time_gain ≈ 0.632(去除63.2%)
  110. # τ参考计算: 以60s去除效率高于95%的要求推算得τ取20s
  111. # 该取值下:
  112. # - 反洗时间 t_bw = 40s 时,time_gain ≈ 0.865(去除86.5%)
  113. # - 反洗时间 t_bw = 60s 时,time_gain ≈ 0.950(去除95.0%)
  114. time_gain = 1.0 - np.exp(- (t_bw_s / p.tau_bw_s))
  115. # ========== 步骤4:计算实际去除的膜阻力 ==========
  116. # 实际去除量 = 可逆污染量 × 时间效率因子
  117. dR_bw = reversible_R * time_gain
  118. # 确保去除量不超过可逆污染总量(物理约束)
  119. return float(np.clip(dR_bw, 0.0, reversible_R))
  120. # ===== 主程序 =====
  121. if __name__ == "__main__":
  122. model_fp = ResistanceIncreaseModel()
  123. model_bw = ResistanceDecreaseModel()
  124. torch.save(model_fp.state_dict(), "resistance_model_fp.pth")
  125. torch.save(model_bw.state_dict(), "resistance_model_bw.pth")
  126. print("模型已安全保存为 resistance_model_fp.pth、resistance_model_bw.pth")