Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| # --------------------------- | |
| # Small-Hydro 4-Mode Simulator (Gradio) | |
| # --------------------------- | |
| # ์์ | |
| RHO = 1000.0 # kg/m^3 | |
| G = 9.80665 # m/s^2 | |
| PF_TARGET = 0.98 # ํ์์ฉ | |
| # ํจ์จ ๊ทผ์ฌ (์๋์ ๋ r = Q/Qn) | |
| def efficiency_from_relative_flow(r): | |
| r = max(0.0, min(1.2, float(r))) | |
| curve = [ | |
| (0.00, 0.00), | |
| (0.10, 0.40), | |
| (0.30, 0.60), | |
| (0.50, 0.75), | |
| (0.70, 0.85), | |
| (0.90, 0.90), | |
| (1.00, 0.91), | |
| (1.20, 0.88), | |
| ] | |
| for (x1, y1), (x2, y2) in zip(curve[:-1], curve[1:]): | |
| if x1 <= r <= x2: | |
| t = 0.0 if x2 == x1 else (r - x1) / (x2 - x1) | |
| return y1 + t * (y2 - y1) | |
| return 0.0 | |
| def electrical_power_kw(Q_in, head_m, eta): | |
| try: | |
| Q_in = float(Q_in); head_m = float(head_m); eta = float(eta) | |
| except Exception: | |
| return 0.0 | |
| if Q_in < 0 or head_m < 0: | |
| return 0.0 | |
| return (RHO * G * Q_in * head_m * max(0.0, min(1.0, eta))) / 1000.0 | |
| def decide_mode(Q_in, q_low, q_high, rain_mm, dp_kpa, rain_thr, dp_limit, emergency): | |
| if emergency: | |
| return "Emergency" | |
| if Q_in < q_low: | |
| return "Low-Flow" | |
| if Q_in > q_high or dp_kpa > dp_limit or rain_mm >= rain_thr: | |
| return "Flood" | |
| return "Normal" | |
| def run_sim(Q_in, rain_mm, dp_kpa, emergency, Hn, Qn, rain_thr, dp_limit): | |
| # ์ซ์/๋ถ๋ฆฌ์ธ ํ์ ๋ณด์ | |
| try: | |
| Q_in = float(Q_in) | |
| rain_mm = float(rain_mm) | |
| dp_kpa = float(dp_kpa) | |
| Hn = float(Hn) | |
| Qn = float(Qn) | |
| rain_thr = float(rain_thr) | |
| dp_limit = float(dp_limit) | |
| emergency = bool(emergency) | |
| except Exception: | |
| return "โ ๏ธ ์ ๋ ฅ ์ค๋ฅ: ์ซ์/์ฒดํฌ ๊ฐ์ ํ์ธํ์ธ์." | |
| if Qn <= 0 or Hn <= 0: | |
| return "โ ๏ธ ์ค๊ณ๊ฐ(Hโ, Qโ)์ 0๋ณด๋ค ์ปค์ผ ํฉ๋๋ค." | |
| # ์๊ณ์น | |
| q_low = 0.4 * Qn | |
| q_high = 1.2 * Qn | |
| # ๋ชจ๋ ํ๋จ | |
| mode = decide_mode(Q_in, q_low, q_high, rain_mm, dp_kpa, rain_thr, dp_limit, emergency) | |
| # ์๋์ ๋, ํจ์จ, ๊ธฐ๋ณธ ์ถ๋ ฅ | |
| r = min(Q_in, Qn) / Qn | |
| eta = efficiency_from_relative_flow(r) | |
| p_kw = electrical_power_kw(min(Q_in, Qn), Hn, eta) | |
| # ์ธ๋ถ ์ค์ ๊ฐ(ํฐ๋ฏธ๋ ๋ฒ์ ๊ณผ ๋์ผ ๋ ธ์ถ) | |
| guide_vane_pct = round(min(100.0, max(10.0, r * 100.0)), 1) | |
| gate_open_pct = guide_vane_pct | |
| curtail = False | |
| bypass = False | |
| dump = False | |
| soc_map = { | |
| "Normal": (55, 70), | |
| "Low-Flow": (45, 65), | |
| "Flood": (35, 45), | |
| "Emergency": (30, 50), | |
| } | |
| # ๋ชจ๋๋ณ ์กฐ์ | |
| if mode == "Flood": | |
| curtail = True | |
| bypass = True | |
| dump = True | |
| guide_vane_pct = max(20.0, guide_vane_pct - 20.0) | |
| gate_open_pct = guide_vane_pct | |
| p_kw *= 0.6 # ๋ณด์์น | |
| elif mode == "Low-Flow": | |
| guide_vane_pct = max(15.0, min(55.0, guide_vane_pct)) | |
| gate_open_pct = guide_vane_pct | |
| p_kw *= 0.85 | |
| elif mode == "Emergency": | |
| curtail = True | |
| bypass = True | |
| dump = False | |
| guide_vane_pct = 0.0 | |
| gate_open_pct = 0.0 | |
| p_kw = 0.0 | |
| soc_lo, soc_hi = soc_map.get(mode, (55, 70)) | |
| # ์ถ๋ ฅ Markdown | |
| lines = [] | |
| lines.append(f"## ์ด์ ๋ชจ๋: **{mode}**") | |
| lines.append("") | |
| lines.append("### ์ ๋ ฅ ์์ฝ") | |
| lines.append(f"- ์ ๋ Q: **{Q_in:.2f} mยณ/s**") | |
| lines.append(f"- ๊ฐ์ฐ ์๋ณด: **{rain_mm:.1f} mm/24h**") | |
| lines.append(f"- ํธ๋์๋ ฮP: **{dp_kpa:.1f} kPa**") | |
| lines.append(f"- ์ค๊ณ ๋์ฐจ Hโ: **{Hn:.2f} m**, ์ค๊ณ ์ ๋ Qโ: **{Qn:.2f} mยณ/s**") | |
| lines.append(f" (์ ์ ๋ ์๊ณ **{q_low:.2f}**, ๊ณ ์ ๋ ์๊ณ **{q_high:.2f}**)") | |
| lines.append("") | |
| lines.append("### ์ถ์ /์ค์ ๊ฐ") | |
| lines.append(f"- ์ถ์ ํจ์จ(eta): {eta:.3f}") | |
| lines.append(f"- ์ถ์ ์ถ๋ ฅ(kW): {p_kw:.1f}") | |
| lines.append(f"- ์ค์ _๊ฐ์ด๋๋ฒ ์ธ(%): {guide_vane_pct:.1f}") | |
| lines.append(f"- ์ค์ _์ทจ์๋ฌธ๊ฐ๋(%): {gate_open_pct:.1f}") | |
| lines.append(f"- ์ปคํ ์ผ: {curtail}") | |
| lines.append(f"- ๋ฐ์ดํจ์ค๊ฐ๋ฐฉ: {bypass}") | |
| lines.append(f"- ๋คํ๋ก๋๊ฐ๋: {dump}") | |
| lines.append(f"- ESS_SoC_๋ชฉํ(%): {soc_lo}โ{soc_hi}") | |
| lines.append(f"- ์ญ๋ฅ ๋ชฉํ: {PF_TARGET}") | |
| lines.append("") | |
| lines.append("> ์ฐธ๊ณ : ์ถ๋ ฅ์ ๊ฐ์ด ํจ์จ๊ณก์ /์ปคํ ์ผ ๋ฐ์ ๋ณด์์น์ ๋๋ค.") | |
| return "\n".join(lines) | |
| # --------------------------- | |
| # Gradio UI | |
| # --------------------------- | |
| with gr.Blocks(theme=gr.themes.Soft(), title="Small-Hydro 4-Mode Simulator") as demo: | |
| gr.Markdown("## ๐ ์์๋ ฅ 4-๋ชจ๋ ์๋ฎฌ๋ ์ดํฐ (Hugging Face Spaces)") | |
| with gr.Row(): | |
| Q_in = gr.Number(label="ํ์ฌ ์ ๋ Q (mยณ/s)", value=3.0) | |
| rain = gr.Number(label="๊ฐ์ฐ ์๋ณด (mm/24h)", value=0) | |
| dp = gr.Number(label="ํธ๋์๋ ฮP (kPa)", value=0) | |
| emer = gr.Checkbox(label="๋น์ ์๋ (Emergency)", value=False) | |
| with gr.Accordion("๊ณ ๊ธ ์ค์ (์ค๊ณ/์๊ณ๊ฐ)", open=False): | |
| with gr.Row(): | |
| Hn = gr.Number(label="์ค๊ณ ๋์ฐจ Hโ (m)", value=8.0) | |
| Qn = gr.Number(label="์ค๊ณ ์ ๋ Qโ (mยณ/s)", value=3.5) | |
| with gr.Row(): | |
| rain_thr = gr.Number(label="ํ์ ํ๋จ ๊ฐ์ฐ ์๊ณ (mm/24h)", value=40.0) | |
| dp_limit = gr.Number(label="ํธ๋์๋ ฮP ์๊ณ (kPa)", value=3.0) | |
| btn = gr.Button("์๋ฎฌ๋ ์ด์ ์คํ", variant="primary") | |
| out = gr.Markdown() | |
| btn.click( | |
| fn=run_sim, | |
| inputs=[Q_in, rain, dp, emer, Hn, Qn, rain_thr, dp_limit], | |
| outputs=out | |
| ) | |
| # Hugging Face/๋ก์ปฌ ๋ชจ๋์์ ์์ ํ๊ฒ ์คํ | |
| if __name__ == "__main__": | |
| demo.launch() | |