fix(E03): 보강 있어도 탐색 한계 그대로 — 진입 넓힘 걷음(긴 네일이 Fs 를 낮춘 흠 · 536-3 · 요구 351)
- 원인: 보강 때 진입 한계를 보강재 끝 뒤까지 넓혀 보강 없는 해석이 안 본 위쪽 자연 비탈 면이 들어옴 (사본 E 0+720 우 깎기 우기 L 25 m — 그 면 보강 없음 0.722 · 보강 0.845 → 보강 없음 임계 1.027 보다 낮아 보임) - 같은 면에서는 보강이 늘 F 를 올림(힘 방향 · 부호 · 능동/수동 · 교점은 흠 없음) - 고침: 넓힘 · _exit_lo 걷음(보강 없는 해석과 같은 면 무리) · 0+720 L 3/6/9/12/25 = 1.049/1.148/1.289/1.421/1.487 - 시험: 같은 면 보강 F ≥ 보강 없음(네일 · 앵커 · 길이 셋 · 다섯 방법 · 면 9) · 측점 꼴 길이 늘려도 안 낮아짐 · 탐색 한계 그대로(옛 넓힘 시험 갈음) · Slide2 #47 · #85 · #86 그대로 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,6 @@ import time
|
||||
import numpy as np
|
||||
|
||||
from E03_StabSection import E03_StabSection_Engine_LEM as lem
|
||||
from E03_StabSection import E03_StabSection_Engine_Support as support
|
||||
from E03_StabSection.E03_StabSection_Engine_Describe import describe, safety_map
|
||||
from E03_StabSection.E03_StabSection_Engine_Surface import ( # noqa: F401 — 밖에서 Search 로 부르던 이름
|
||||
METHODS,
|
||||
@@ -46,11 +45,6 @@ FAR_TOL = 0.02
|
||||
|
||||
|
||||
# ---- 원호 ---------------------------------------------------------------------
|
||||
def _exit_lo(limits) -> float:
|
||||
"""진출 아래 한계 — limits 셋째 칸(보강으로 진입만 넓힌 때 원래 한계) · 없으면 limits[0]."""
|
||||
return limits[2] if len(limits) > 2 else limits[0]
|
||||
|
||||
|
||||
def entry_exit_circles(prep, limits, n_points=25, thetas_deg=(10, 20, 35, 50, 65, 80, 100, 120)):
|
||||
xl, xr = limits[:2]
|
||||
pts = np.linspace(xl, xr, n_points)
|
||||
@@ -60,7 +54,6 @@ def entry_exit_circles(prep, limits, n_points=25, thetas_deg=(10, 20, 35, 50, 65
|
||||
xX = np.repeat(xX, len(thetas_deg))
|
||||
th = np.tile(np.radians(thetas_deg), len(i))
|
||||
xc, zc, R, ok = circle_from_chord(prep, xE, xX, th)
|
||||
ok &= xX >= _exit_lo(limits) - 1e-6
|
||||
return xc[ok], zc[ok], R[ok], xE[ok], xX[ok]
|
||||
|
||||
|
||||
@@ -87,7 +80,7 @@ def grid_radius_circles(prep, limits, gx, gz, n_radii=10):
|
||||
owner = np.repeat(np.arange(len(cx)), n_radii)
|
||||
xc, zc = cx[owner], cz[owner]
|
||||
xE, xX, ok = circle_cross_surface(prep, xc, zc, R)
|
||||
ok &= (xE >= limits[0] - 1e-6) & (xX <= limits[1] + 1e-6) & (xX >= _exit_lo(limits) - 1e-6)
|
||||
ok &= (xE >= limits[0] - 1e-6) & (xX <= limits[1] + 1e-6)
|
||||
return xc[ok], zc[ok], R[ok], xE[ok], xX[ok], owner[ok]
|
||||
|
||||
|
||||
@@ -106,7 +99,7 @@ def _circle_eval(prep, xc, zc, R, xE, xX, n, min_depth, methods, chunk=4000):
|
||||
def refine_circle(prep, limits, method, seeds, n, min_depth, seed=0, maxiter=None):
|
||||
"""원호 다듬기 — (진입 x, 진출 x, 중심각) 차분진화 · 첫 무리 = 거친 탐색의 좋은 면."""
|
||||
fun = objective(method)
|
||||
lo = np.array([limits[0], _exit_lo(limits), np.radians(3)])
|
||||
lo = np.array([limits[0], limits[0], np.radians(3)])
|
||||
hi = np.array([limits[1], limits[1], np.radians(170)])
|
||||
|
||||
def obj(p):
|
||||
@@ -136,7 +129,7 @@ def _cloud(prep, limits, method, p0, n, min_depth, seed, k=CLOUD_SIZE, keep=10):
|
||||
"""원 (진입 x, 진출 x, 중심각) 둘레 구름 k 개를 method 로 한 번에 셈 → 풀리는 좋은 것 keep 개."""
|
||||
rng = np.random.default_rng(seed)
|
||||
span = limits[1] - limits[0]
|
||||
lo = np.array([limits[0], _exit_lo(limits), np.radians(3)])
|
||||
lo = np.array([limits[0], limits[0], np.radians(3)])
|
||||
hi = np.array([limits[1], limits[1], np.radians(170)])
|
||||
p = np.clip(p0 + rng.normal(size=(k, 3)) * [0.03 * span, 0.03 * span, np.radians(4)], lo, hi)
|
||||
xc, zc, R, ok = circle_from_chord(prep, p[:, 0], p[:, 1], p[:, 2])
|
||||
@@ -310,7 +303,7 @@ def optimize_polyline(
|
||||
fun = objective(method)
|
||||
xl, xr = limits[:2]
|
||||
depth_max = max(prep.surface(np.linspace(xl, xr, 50)).max() - prep.bottom_z, 1.0)
|
||||
lo = np.array([xl, _exit_lo(limits)] + [0.02] * m + [0.0] * m)
|
||||
lo = np.array([xl, xl] + [0.02] * m + [0.0] * m)
|
||||
hi = np.array([xr, xr] + [0.98] * m + [depth_max] * m)
|
||||
|
||||
def obj(p):
|
||||
@@ -393,7 +386,6 @@ def block_seeds(prep, limits, m, n_points=12, angles=((55, 35), (65, 25))):
|
||||
xE = _ray_to_surface(prep, a, za, act, -1.0)
|
||||
xX = _ray_to_surface(prep, b, zb, pas, 1.0)
|
||||
good = np.isfinite(xE) & np.isfinite(xX) & (xE >= xl) & (xX <= xr)
|
||||
good &= xX >= _exit_lo(limits)
|
||||
for e, x0, x1, xx in zip(xE[good], a[good], b[good], xX[good]):
|
||||
ix = np.linspace(x0, x1, m)
|
||||
d = layer_bottom_depth(prep, ix, mat)
|
||||
@@ -429,13 +421,8 @@ def analyze(
|
||||
lim = (float(prep.surface_x[0]), float(prep.surface_x[-1]))
|
||||
else:
|
||||
lim = tuple(sorted((s * float(limits[0]), s * float(limits[1]))))
|
||||
if prep.supports is not None:
|
||||
# 보강 — 임계면이 보강재 끝 뒤(더 깊이 · 더 멀리)로 옮겨 가는 것도 찾게 진입 한계만 끝 뒤까지 넓힘
|
||||
# (진출 = 원래 한계 셋째 칸 — 설계 비탈 밖 자연 비탈만 무너지는 면은 보강 전처럼 안 봄)
|
||||
reach = float(np.min(support.tips(prep.supports))) - max(
|
||||
2.0, 0.25 * prep.supports["L"].max()
|
||||
)
|
||||
lim = (max(min(lim[0], reach), float(prep.surface_x[0])), lim[1], lim[0])
|
||||
# 보강이 있어도 탐색 한계 그대로 — 보강 없는 해석과 같은 면 무리에서 찾아야 보강 전후가 맞섬
|
||||
# (한계를 넓히면 보강 없이 안 본 자연 비탈 면이 들어와 보강 뒤 F 가 오히려 낮아 보임)
|
||||
results: dict = {m: {} for m in methods}
|
||||
counts = {}
|
||||
contour = smap = None
|
||||
|
||||
Reference in New Issue
Block a user