Files
Aislo/resources/tester/test_533_2_stab3d_search.py
T
eomsangdonandClaude Opus 5.5 834a86e76e perf(533-2 2차): E04 탐색 프로세스 병렬 · 솔버 수렴 묶음 빼기 · 창 배열 덜 펴기 — 1 km 띠 287 s → 32 s
- Search: 후보 덩이를 프로세스로 나눠 셈(workers · 0 = 자동 · 격자 5만 칸 이상이면 CPU − 2 · 12 까지) · 낸 차례대로 합침 — 일꾼 수와 무관하게 같은 값
- Search: 지층은 임시 파일로 일꾼에 넘김(spawn 관이면 일꾼이 차례로 떠 12 개 6 s) · 돌려받는 칸은 iy · ix · group(int32)만
- Search: 고친 노드 판정 = 반지름 시작 때 셀 최소(덩이 나눔과 무관) · 1차 SearchParams 칸 · SearchResult 꼴 그대로
- Search: 1단계 거르기 = 활동면 높이를 창 전체가 아니라 걸친 칸에서만 · 큰 창 배열 펴지 않음
- Column: Bishop · Janbu 고정점 — 기둥별 상수 미리 · 수렴한 활동체 기둥은 빼며 셈(값 같음)
- 측정(검증_sub5 57 측점 · 노드 2 m · 구 + 타원체 2): 1차 287 s → 한 프로세스 217 s → 12 프로세스 32.1 s · 셀 9.7만 F 전후 최대 차 6e-15 · 전역 최소 1.099 그대로
- 시험: 일꾼 1 · 2 같은 값

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 21:22:28 +09:00

100 lines
3.4 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.
"""533-2 E04 활동면 탐색 — Scoops3D 검증 표 전역 최소 ±3 %.
Reid 외(2015) Scoops3D 표 6.8 · 6.11(CLARA-W 와 같은 구): H 10 m 제방
- 30° · λ 0.125(γ 19 · φ 20° · c 8.64 kPa) → Bishop 1.32 · 부피 1,124 m³
- Donald & Giam 1a 2:1 · γ 20 · φ 19.6° · c 3 kPa → 1.04
- 표 6.7 원뿔 30° · r_u 0.4 → 1.626
탐색 격자는 시험 시간 때문에 문헌 임계 중심 둘레로 좁힘.
"""
import numpy as np
import pytest
from E04_Stab3D.E04_Stab3D_Engine_Column import Strata
from E04_Stab3D.E04_Stab3D_Engine_Search import SearchParams, search
def _embankment(run, gamma, phi, c, dx=1.0):
x = np.arange(-25, run + 35 + 1e-9, dx)
y = np.arange(-40, 40 + 1e-9, dx)
xx, _ = np.meshgrid(x, y)
z = np.clip(xx / run * 10.0, 0, 10.0)
mat = {"id": "m", "name": "m", "gamma_t": gamma, "gamma_sat": gamma, "c": c, "phi": phi}
return Strata(x, y, z, np.zeros((0,) + z.shape), [mat])
def test_embankment_30deg_global_minimum():
st = _embankment(10 / np.tan(np.radians(30)), 19, 20, 8.64)
p = SearchParams(
box=(-2, 10, -1, 1),
h_min=4,
h_max=24,
spacing=1.0,
coarse=2,
max_depth=20,
v_min=50,
v_max=2e4,
ratios=(1.0,),
)
r = search(st, p)
assert r.best["governing"] == pytest.approx(1.32, rel=0.03)
assert r.best["volume"] == pytest.approx(1124, rel=0.15)
f = r.f_min
assert np.nanmin(f) == pytest.approx(r.best["governing"])
# 셀별 최소 지도: 임계 활동체 안 셀은 전역 최소 · 부피 래스터가 같이 채워짐
assert np.isfinite(r.volume[np.isfinite(f)]).all()
def test_donald_giam_1a():
st = _embankment(20, 20, 19.6, 3.0)
p = SearchParams(
box=(-4, 6, -1, 1),
h_min=16,
h_max=30,
spacing=1.0,
coarse=2,
max_depth=20,
v_min=50,
v_max=3e4,
ratios=(1.0,),
)
assert search(st, p).best["governing"] == pytest.approx(1.04, rel=0.03)
def test_wet_cone_pore_pressure_ratio():
"""Scoops3D 표 6.7 · 원뿔 30° · λ 0.125(γ 20 · φ 30°) · r_u 0.4 → Bishop 1.626(도표 1.644)."""
h = 10.0
r0 = h / np.tan(np.radians(30))
x = np.arange(-r0 - 15, r0 + 15 + 1e-9, 0.5)
xx, yy = np.meshgrid(x, x)
z = np.clip(h - np.hypot(xx, yy) * np.tan(np.radians(30)), 0, h)
c = 0.125 * 20 * h * np.tan(np.radians(30))
mat = {"id": "m", "name": "m", "gamma_t": 20, "gamma_sat": 20, "c": c, "phi": 30}
st = Strata(x, x, z, np.zeros((0,) + z.shape), [mat])
p = SearchParams(
box=(8, r0 + 4, -1, 1),
spacing=1.0,
h_min=1,
h_max=21,
h_step=2,
coarse=4,
max_depth=15,
v_min=20,
v_max=3e4,
ratios=(1.0,),
groundwater={"mode": "ru", "ru": 0.4},
)
assert search(st, p).best["governing"] == pytest.approx(1.626, rel=0.03)
def test_workers_same_result():
"""프로세스 나눔 — 일꾼 수와 무관하게 셀별 최소 F · 전역 최소가 같음."""
st = _embankment(10 / np.tan(np.radians(30)), 19, 20, 8.64)
kw = dict(box=(-2, 10, -4, 4), h_min=4, h_max=20, spacing=2.0, coarse=2, max_depth=16)
kw.update(v_min=50, v_max=2e4, ratios=(1.0, 2.0))
one = search(st, SearchParams(workers=1, **kw))
two = search(st, SearchParams(workers=2, **kw))
np.testing.assert_array_equal(one.f_min, two.f_min)
assert one.best["governing"] == two.best["governing"]
assert one.evaluated == two.evaluated