- 측점 보조 탭 = 저장된 pipe_points 측점만 읽음 · 입력은 이 탭 자기 기본값(B05/B06 · 배수유역 값과 안 이음) - 1-1 합리식(Qd = Q × 할증) · 1-2 Kirpich 도달시간(최소 5분) · 1-3 rt = (R24/24)·(24/T)^0.557 - 2 단면검토 — 관 단면 그림 · 단면적 · 윤변 · 경심 · 경사 · n · Manning 유속 · Q = A·V · OK/NG 점선 상자 · 유출율 - 선택지(할증 2.0/1.5/1.2 · 만관/240°/유효 70 % · 관 종류별 n) · 기본값 한 파일(B08_Quantity_Hydro_Defaults.py) - 계산 = 서버 단독(B08_Quantity_Engine_Hydro · /quantity/hydro · /quantity/hydro/calc · 최신 응답만) · 입력은 캐시만 · 어떤 파일에도 안 씀 - 흰 종이 계산서(입력 빨강 · 계산 파랑 · 주요 입력 노랑) · 쪽 표시 · 시험 test_62_2_b08_hydro_engine.py Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UoSr2sqvYtBf1dtQdus88s
79 lines
3.2 KiB
Python
79 lines
3.2 KiB
Python
"""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,
|
||
}
|