Files
Aislo/B08_Quantity/B08_Quantity_Engine_Hydro.py
T
eomsangdonandClaude Opus 5.5 5f056ec661 feat(b08): 4탭 홍수량 계산서 — 배수지점 측점 보조 탭 · 견본 모양 한 장 · 서버 계산(PLAN 62-2 · 62-3)
- 측점 보조 탭 = 저장된 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
2026-10-06 18:15:29 +09:00

79 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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,
}