Merge remote-tracking branch 'origin/sub_laptop_4' into sub_laptop_3

This commit is contained in:
2026-10-25 19:39:01 +09:00
+124
View File
@@ -0,0 +1,124 @@
"""E 안정성평가 공용 꼴 — 2D(E03) · 3D(E04) 해석이 같은 입력 꼴을 씀.
단위: 단위중량 kN/m³ · 점착력 · 하중 kPa · 내부마찰각 ° · 좌표 m.
E04 가 이 파일을 그대로 import — 이름 · 열쇠를 바꾸지 않음.
"""
from typing import Literal, TypedDict
GAMMA_W = 9.81 # 물 단위중량 kN/m³
class Material(TypedDict):
id: str
name: str
gamma_t: float # 습윤 단위중량 (지하수위 위)
gamma_sat: float # 포화 단위중량 (지하수위 아래)
c: float # 유효 점착력
phi: float # 유효 내부마찰각
class Groundwater(TypedDict, total=False):
mode: Literal["none", "ru", "line"]
ru: float # mode="ru" — 간극수압비 u = ru · γ·h
line: list[list[float]] # mode="line" — 지하수위선 [[x, z], …] (2D) · x 오름차순
class Surcharge(TypedDict):
x0: float
x1: float
q: float # 연직 등분포 kPa
# 요구서 345 6장 기본값(사용자가 E02 에서 바꿈) — 사전조사 후보의 보수 쪽.
DEFAULT_MATERIALS: list[Material] = [
{
"id": "weathered_soil",
"name": "풍화토",
"gamma_t": 18.0,
"gamma_sat": 19.0,
"c": 15.0,
"phi": 30.0,
},
{
"id": "weathered_rock",
"name": "풍화암",
"gamma_t": 20.0,
"gamma_sat": 21.0,
"c": 30.0,
"phi": 33.0,
},
{
"id": "soft_rock",
"name": "연암",
"gamma_t": 24.0,
"gamma_sat": 24.5,
"c": 150.0,
"phi": 35.0,
},
{
"id": "hard_rock",
"name": "경암",
"gamma_t": 26.0,
"gamma_sat": 26.0,
"c": 300.0,
"phi": 40.0,
},
{"id": "fill", "name": "성토", "gamma_t": 18.0, "gamma_sat": 19.0, "c": 10.0, "phi": 25.0},
{
"id": "colluvium",
"name": "붕적토",
"gamma_t": 17.5,
"gamma_sat": 18.5,
"c": 5.0,
"phi": 27.0,
},
]
DEFAULT_ROAD_SURCHARGE_KPA = 10.0 # 노면 하중 기본
def material(raw: dict) -> Material:
"""밖에서 온 물성 한 줄을 꼴에 맞춤 — 빠진 γsat 는 γt · 음수 · 범위 밖은 오류."""
gamma_t = float(raw["gamma_t"])
gamma_sat = float(raw.get("gamma_sat", gamma_t))
c = float(raw["c"])
phi = float(raw["phi"])
if gamma_t <= 0 or gamma_sat <= 0 or c < 0 or not 0 <= phi < 90:
raise ValueError(f"물성 범위 밖: {raw}")
return {
"id": str(raw["id"]),
"name": str(raw.get("name", raw["id"])),
"gamma_t": gamma_t,
"gamma_sat": gamma_sat,
"c": c,
"phi": phi,
}
def groundwater(raw: dict | None) -> Groundwater:
"""지하수 꼴 맞춤 — 없으면 none · line 은 x 오름차순으로 정렬."""
if not raw or raw.get("mode", "none") == "none":
return {"mode": "none"}
mode = raw["mode"]
if mode == "ru":
ru = float(raw.get("ru", 0.0))
if not 0 <= ru < 1:
raise ValueError(f"r_u 범위 밖: {ru}")
return {"mode": "ru", "ru": ru}
if mode == "line":
line = sorted([float(x), float(z)] for x, z in raw["line"])
if len(line) < 2:
raise ValueError("지하수위선 점이 둘 미만")
return {"mode": "line", "line": line}
raise ValueError(f"지하수 mode 모름: {mode}")
def surcharges(raw: list[dict] | None) -> list[Surcharge]:
"""상재하중 꼴 맞춤 — x0 < x1 로 정렬 · 길이 0 은 버림."""
out: list[Surcharge] = []
for item in raw or []:
x0, x1 = sorted((float(item["x0"]), float(item["x1"])))
if x1 > x0:
out.append({"x0": x0, "x1": x1, "q": float(item["q"])})
return out