run_this.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import pandas as pd
  2. import numpy as np
  3. import os
  4. from sklearn.linear_model import LinearRegression
  5. # ============================================================
  6. BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
  7. FEATURE_PATH = f"{BASE_DIR}/use_data/test_cycle_sample.csv"
  8. # ============================================================
  9. # viscosity
  10. # ============================================================
  11. def xishan_viscosity(T):
  12. x = (T + 273.15) / 300
  13. factor = 890 / (
  14. 280.68 * x ** -1.9 +
  15. 511.45 * x ** -7.7 +
  16. 61.131 * x ** -19.6 +
  17. 0.45903 * x ** -40
  18. )
  19. return 0.00089 / factor
  20. # ============================================================
  21. # unit mapping
  22. # ============================================================
  23. def get_unit_cols(unit):
  24. return {
  25. "flux": f"{unit}_FluxF",
  26. "dpt1": f"C.M.{unit}_DB@DPT_1",
  27. "dpt2": f"C.M.{unit}_DB@DPT_2"
  28. }
  29. # ============================================================
  30. # resistance
  31. # ============================================================
  32. def compute_resistance(df, unit):
  33. cols = get_unit_cols(unit)
  34. flux = df[cols["flux"]]
  35. dpt1 = df[cols["dpt1"]]
  36. dpt2 = df[cols["dpt2"]]
  37. mu = xishan_viscosity(df["C.M.RO_TT_ZJS@out"])
  38. df["R1"] = dpt1 * 3.6e12 / (mu * flux)
  39. return df
  40. # ============================================================
  41. # V accumulation
  42. # ============================================================
  43. def compute_V(df, unit):
  44. cols = get_unit_cols(unit)
  45. flux = df[cols["flux"]].values
  46. dt = 300
  47. J = flux * (1e-3 / 3600)
  48. V = np.zeros(len(df))
  49. for i in range(1, len(df)):
  50. V[i] = V[i-1] + J[i-1] * dt
  51. df["V"] = V
  52. return df
  53. # ============================================================
  54. # fit model (POWER LAW)
  55. # R = a * V^b
  56. # log R = log a + b log V
  57. # ============================================================
  58. def fit_model(df, R_col):
  59. df = df.dropna(subset=[R_col, "V"])
  60. df = df[(df[R_col] > 0) & (df["V"] > 0)]
  61. if len(df) < 10:
  62. return None
  63. V = df["V"].values
  64. R = df[R_col].values / 1e12
  65. X = np.log(V + 1e-9).reshape(-1, 1)
  66. y = np.log(R + 1e-9)
  67. model = LinearRegression()
  68. model.fit(X, y)
  69. return model
  70. # ============================================================
  71. # solve V limit (analytical)
  72. # ============================================================
  73. def solve_v_limit(model, R_limit):
  74. if model is None:
  75. return None
  76. b = model.coef_[0]
  77. log_a = model.intercept_
  78. target = np.log(R_limit / 1e12)
  79. if abs(b) < 1e-12:
  80. return np.inf
  81. logV = (target - log_a) / b
  82. V_limit = np.exp(logV)
  83. return V_limit
  84. # ============================================================
  85. # main per unit
  86. # ============================================================
  87. def process_unit(unit, df_new, TMP_limit=0.23):
  88. df = df_new.copy()
  89. df = compute_resistance(df, unit)
  90. df = compute_V(df, unit)
  91. # =========================
  92. # 当前状态
  93. # =========================
  94. mu_avg = xishan_viscosity(df["C.M.RO_TT_ZJS@out"]).mean()
  95. cols = get_unit_cols(unit)
  96. flux_avg = df[cols["flux"]].mean()
  97. V_now = df["V"].iloc[-1]
  98. R_now = df["R1"].iloc[-1]
  99. days = max((df["time"].max() - df["time"].min()).total_seconds() / 86400, 1e-6)
  100. V_daily = V_now / days
  101. # =========================
  102. # model
  103. # =========================
  104. model = fit_model(df, "R1")
  105. if model is None:
  106. return None
  107. # =========================
  108. # R limit from TMP
  109. # =========================
  110. R_limit = TMP_limit * 3.6e12 / (mu_avg * flux_avg)
  111. # =========================
  112. # solve
  113. # =========================
  114. V_limit = solve_v_limit(model, R_limit)
  115. remaining_days = (V_limit - V_now) / max(V_daily, 1e-9)
  116. remaining_days = min(remaining_days, 90 - days)
  117. return {
  118. "unit": unit,
  119. "R_now": R_now,
  120. "V_now": V_now,
  121. "R_limit": R_limit,
  122. "V_limit": V_limit,
  123. "remaining_days": remaining_days
  124. }
  125. # ============================================================
  126. # main
  127. # ============================================================
  128. def main(units, TMP_limit=0.23):
  129. df_new = pd.read_csv(FEATURE_PATH)
  130. df_new["time"] = pd.to_datetime(df_new["time"])
  131. results = []
  132. for u in units:
  133. res = process_unit(u, df_new, TMP_limit)
  134. if res is not None:
  135. results.append(res)
  136. return pd.DataFrame(results)
  137. # ============================================================
  138. # run
  139. # ============================================================
  140. if __name__ == "__main__":
  141. units_to_run = ["RO4"]
  142. out = main(units_to_run, TMP_limit=0.20)
  143. print(f"该机组预计下次CIP为:{out['remaining_days'].iloc[0]:.2f} 天后")