feat(E03): analyze_station 에 groundwater_for(condition, model) 인자 — 조건마다 모형 지하수 갈아 끼움 · None 이면 그대로 (532-2 2차 ⑥)

- 시험: 건기 그대로 · 우기 r_u 0.3 이 지표 포화보다 안전율 높음

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 03:23:00 +09:00
co-authored by Claude Opus 5.5
parent 6c486da9dc
commit f243524436
2 changed files with 29 additions and 0 deletions
@@ -8,6 +8,7 @@ import time
from E03_StabSection.E03_StabSection_Engine_Model import section_model_from_b06
from E03_StabSection.E03_StabSection_Engine_Search import METHODS, analyze
from E03_StabSection.E03_StabSection_Types import groundwater as norm_groundwater
#: 활동면 최소 깊이(m) — 지표를 얇게 긁는 면(표토 박리)은 사면 붕괴로 보지 않음.
MIN_DEPTH_M = 0.3
@@ -26,10 +27,14 @@ def analyze_station(
noncircular: bool = True,
min_depth: float = MIN_DEPTH_M,
case_workers: int = 1,
groundwater_for=None,
**model_kw,
) -> dict:
"""측점 하나 — case_workers > 1 이면 비탈 × 조건 경우를 프로세스로 나눠 돎(측점 하나만 다시 셀 때).
groundwater_for(condition, model) → 엔진 지하수 꼴 — 주면 조건마다 모형 지하수를 갈아 끼움
(E02 `station_groundwater` 꼴) · None 이면 모형 기본(우기 = 지표 수위).
서버 프로세스 안에서는 1(차례로) 그대로 둠 — 자식이 main.py 를 다시 읽음(`Worker` 머리글).
"""
t0 = time.perf_counter()
@@ -46,6 +51,8 @@ def analyze_station(
seismic_kh=seismic_kh if cond == "seismic" else 0.0,
**model_kw,
)
if groundwater_for is not None:
model["groundwater"] = norm_groundwater(groundwater_for(cond, model))
out.setdefault("areas", model["areas"])
jobs += [(cond, model, side) for side in model["sides"]]
kw = {"methods": methods, "noncircular": noncircular, "min_depth": min_depth}
@@ -238,6 +238,28 @@ def test_지하수_측점_모형에_끼움():
assert res["methods"]["bishop"]["min"]["F"] > 0 # 끼운 모형이 엔진에서 돎
def test_측점_해석_groundwater_for_인자():
ground = ground_model.build_initial(ground_model.load_defaults(), [])
ground["groundwater"].update(wet_mode="ru", ru=0.3)
seen = []
def gw_for(cond, model):
seen.append(cond)
return ground_model.station_groundwater(ground, cond, model)
kw = {"conditions": ("dry", "wet"), "methods": ("bishop",), "noncircular": False}
base = analyze_station(CROSS, DESIGN, **kw)
out = analyze_station(CROSS, DESIGN, groundwater_for=gw_for, **kw)
assert seen == ["dry", "wet"]
F = {(c["condition"], c["side"]): c["min_F"]["bishop"] for c in out["cases"]}
F0 = {(c["condition"], c["side"]): c["min_F"]["bishop"] for c in base["cases"]}
for (cond, side), f in F.items():
if cond == "dry":
assert f == pytest.approx(F0[cond, side]) # 건기 = 수위 없음 그대로
else:
assert f > F0[cond, side] # r_u 0.3 < 지표 포화
@pytest.fixture
def project(tmp_path, monkeypatch):
async def fake_project(_project_id):