"""B08 4탭 홍수량 계산서 엔진 — 순수 식 (PLAN 62-2 · 계산 자리 ③ 서버 단독). 배수유역 계산 코드(`common_util_drainage_detail` 등)를 부르지 않음 — 화면 입력만으로 계산. 1-1 합리식 Q = (1/3.6)·f·rt·A[㎢] · Qd = Q × 할증 1-2 도달시간 Kirpich T = 0.0663·L[㎞]^0.77·s^-0.385 [hr] · s = H/L · 최소 도달시간 적용 1-3 강우강도 rt = (R24/24)·(24/T)^0.557 (Mononobe형) 2 단면검토 V = (1/n)·R^(2/3)·S^(1/2) · Q = A·V · 판정 Q ≥ Qd · 유출율 = Q/Qd """ from __future__ import annotations import math from typing import Any from B08_Quantity.B08_Quantity_Hydro_Defaults import PIPE_KINDS MONONOBE_EXPONENT = 0.557 EFFECTIVE_RATIO = 0.7 def section_props(section: str, diameter_m: float) -> dict[str, float]: """단면 가정별 단면적 A · 윤변 P · 경심 R.""" d = diameter_m full_area = math.pi * d * d / 4.0 if section == "arc240": # 240° 부채꼴 + 현 아래 삼각형(반지름 둘 · 끼인각 120°) — 수심 0.75D area = full_area * 240.0 / 360.0 + (d / 2.0) ** 2 * math.sin(math.radians(60)) * math.cos( math.radians(60) ) perimeter = math.pi * d * 240.0 / 360.0 return {"area": area, "perimeter": perimeter, "radius": area / perimeter} if section == "eff70": # 배관 제안 방식 — 유속은 만관 경심(D/4) · 통수단면은 70 % return {"area": EFFECTIVE_RATIO * full_area, "perimeter": math.pi * d, "radius": d / 4.0} return {"area": full_area, "perimeter": math.pi * d, "radius": d / 4.0} def compute(inputs: dict[str, Any]) -> dict[str, Any]: """입력 → 계산서 값 전부(반올림 없음 · 화면이 자릿수를 정함).""" length_m = float(inputs["length_m"]) height_m = float(inputs["height_m"]) slope_ground = height_m / length_m tc_raw_hr = 0.0663 * (length_m / 1000.0) ** 0.77 * slope_ground**-0.385 tc_hr = max(tc_raw_hr, float(inputs["tc_min_minutes"]) / 60.0) r24 = float(inputs["r24_mm"]) intensity = (r24 / 24.0) * (24.0 / tc_hr) ** MONONOBE_EXPONENT runoff = float(inputs["runoff"]) area_km2 = float(inputs["area_km2"]) flow = runoff * intensity * area_km2 / 3.6 design_flow = flow * float(inputs["factor"]) n = inputs.get("n") n = float(n) if n else PIPE_KINDS[inputs["pipe_kind"]] diameter_m = float(inputs["diameter_mm"]) / 1000.0 props = section_props(inputs["section"], diameter_m) slope_bed = 1.0 / float(inputs["slope_denominator"]) velocity = (1.0 / n) * props["radius"] ** (2.0 / 3.0) * math.sqrt(slope_bed) capacity = props["area"] * velocity return { "area_ha": area_km2 * 100.0, "slope_ground": slope_ground, "tc_raw_hr": tc_raw_hr, "tc_hr": tc_hr, "tc_floored": tc_hr > tc_raw_hr, "intensity": intensity, "flow": flow, "design_flow": design_flow, "n": n, "section_area": props["area"], "perimeter": props["perimeter"], "radius": props["radius"], "slope_bed": slope_bed, "velocity": velocity, "capacity": capacity, "ok": capacity >= design_flow, "ratio_pct": capacity / design_flow * 100.0 if design_flow > 0 else None, }