diff --git a/E03_StabSection/E03_StabSection_Router_WhatIf.py b/E03_StabSection/E03_StabSection_Router_WhatIf.py index 2893b383c..6eb721d60 100644 --- a/E03_StabSection/E03_StabSection_Router_WhatIf.py +++ b/E03_StabSection/E03_StabSection_Router_WhatIf.py @@ -25,7 +25,7 @@ from functools import lru_cache, partial from uuid import UUID from fastapi import APIRouter, HTTPException -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, model_validator from shapely.geometry import Point, Polygon from common_util.common_util_derived_store import ( @@ -79,6 +79,12 @@ class SupportIn(BaseModel): hole_dia_mm: float = Field(gt=0.0, le=500.0) prestress_kN: float = Field(0.0, ge=0.0) + @model_validator(mode="after") + def _anchor_bond(self) -> "SupportIn": + if self.type == "anchor" and not 0 < self.bond_length_m < self.length_m: + raise ValueError("앵커 정착장은 0 초과 · 길이 미만") + return self + class WhatIfRequest(BaseModel): side: Literal["left", "right"] diff --git a/E03_StabSection/E03_StabSection_UI_Support.css b/E03_StabSection/E03_StabSection_UI_Support.css index 6f6829aa8..c2d8207ed 100644 --- a/E03_StabSection/E03_StabSection_UI_Support.css +++ b/E03_StabSection/E03_StabSection_UI_Support.css @@ -17,6 +17,10 @@ --e03-support: #6250d6; } +.e03-support--prestress { + --e03-support: #1c74d9; +} + .e03-support--not_crossing { --e03-support: #9a9a9a; } diff --git a/E03_StabSection/E03_StabSection_UI_Support.ts b/E03_StabSection/E03_StabSection_UI_Support.ts index 528a7a397..7d87b6cfa 100644 --- a/E03_StabSection/E03_StabSection_UI_Support.ts +++ b/E03_StabSection/E03_StabSection_UI_Support.ts @@ -79,7 +79,7 @@ const FIELDS: NumKey[] = [ "prestress_kN", ]; const ANCHOR_ONLY: NumKey[] = ["bond_length_m", "prestress_kN"]; -const MODES = ["tensile", "pullout", "stripping", "not_crossing"] as const; +const MODES = ["tensile", "pullout", "stripping", "prestress", "not_crossing"] as const; const fmt = (v: number | null | undefined, d = 2): string => v === null || v === undefined || !Number.isFinite(v) ? "-" : v.toFixed(d); diff --git a/E03_StabSection/logic/E03_StabSection_Support.ts b/E03_StabSection/logic/E03_StabSection_Support.ts index 36a6582ff..fb26edeca 100644 --- a/E03_StabSection/logic/E03_StabSection_Support.ts +++ b/E03_StabSection/logic/E03_StabSection_Support.ts @@ -10,7 +10,7 @@ import type { Point } from "./E03_StabSection_Logic"; export type SupportType = "nail" | "anchor"; -export type SupportMode = "tensile" | "pullout" | "stripping" | "not_crossing"; +export type SupportMode = "tensile" | "pullout" | "stripping" | "not_crossing" | "prestress"; /** 서버 · 엔진 입력 꼴(브레인 정함 · sub4 엔진 같은 이름) */ export interface SupportIn { @@ -24,7 +24,7 @@ export interface SupportIn { /** 종방향 간격 — 단위 폭 힘 = 힘 / 간격 */ spacing_m: number; tensile_kN: number; - /** 그라우트 · 지반 부착 — 네일 = 전 길이 · 앵커 = 정착장만 */ + /** 그라우트 · 지반 부착(인발 안전율 넣은 값 · 엔진이 안 나눔) — 네일 = 전 길이 · 앵커 = 정착장만 */ bond_kPa: number; /** 앵커 정착장 · 네일은 무시 */ bond_length_m: number; @@ -56,7 +56,8 @@ export interface SupportLayout { } /** 기본값 후보(사용자 확정 전) — 지식DB 안정성평가 02 §4(천공 φ100 · 풍화토 주면마찰 50~100 kPa · - * SD400 D25 허용 0.6 fy·As = 121.6 kN) · 앵커 = 강연선 φ12.7 × 4 허용 0.6 fpu = 441 kN 흔한 값 */ + * SD400 D25 허용 0.6 fy·As = 121.6 kN · 부착 = 극한 주면마찰 ÷ 인발 안전율 2.0) · + * 앵커 = 강연선 φ12.7 × 4 허용 0.6 fpu = 441 kN · 풍화암 주면마찰 150 kPa ÷ 2.0 흔한 값 */ export const SUPPORT_DEFAULTS: Record = { nail: { type: "nail", @@ -67,7 +68,7 @@ export const SUPPORT_DEFAULTS: Record = { length_m: 6.0, angle_deg: 15, tensile_kN: 121.6, - bond_kPa: 80, + bond_kPa: 40, bond_length_m: 0, hole_dia_mm: 100, prestress_kN: 0, @@ -81,7 +82,7 @@ export const SUPPORT_DEFAULTS: Record = { length_m: 12.0, angle_deg: 30, tensile_kN: 441, - bond_kPa: 150, + bond_kPa: 75, bond_length_m: 6.0, hole_dia_mm: 115, prestress_kN: 200, diff --git a/E05_StabReport/E05_StabReport_Reinforce.py b/E05_StabReport/E05_StabReport_Reinforce.py index cda63ae27..fa8b9865a 100644 --- a/E05_StabReport/E05_StabReport_Reinforce.py +++ b/E05_StabReport/E05_StabReport_Reinforce.py @@ -26,6 +26,7 @@ MODE_NAMES = { "pullout": "인발", "stripping": "머리 쪽 빠짐", "not_crossing": "활동면 안 만남", + "prestress": "선인장(능동)", } SUPPORT_HEAD = ("측점", "비탈 · 조건", "번호 · 종류", "머리 x / z", "길이 m", "각도 °", "간격 m") ST_NG, ST_OK = 10, 11 diff --git a/ui_template/ui_template_locale_e03.ts b/ui_template/ui_template_locale_e03.ts index d4191171f..2b8b49dd7 100644 --- a/ui_template/ui_template_locale_e03.ts +++ b/ui_template/ui_template_locale_e03.ts @@ -175,8 +175,8 @@ export const ui_locales_e03 = { "Heads are placed on the slope face from the toe at first-row height and vertical spacing, driven into the slope (assumption only · original results unchanged).", ], E03_Sp_Source: [ - "기본값 후보(사용자 확정 전) — 지식DB 안정성평가 02 §4: 천공 φ100 mm · 풍화토 주면마찰 50~100 kPa · SD400 D25 허용 121.6 kN · 앵커 = 강연선 φ12.7 × 4 허용 441 kN · 정착장 6 m", - "Default candidates (not yet confirmed) — KB stability 02 §4: hole φ100 mm · weathered soil bond 50–100 kPa · SD400 D25 allowable 121.6 kN · anchor = 4 × φ12.7 strand allowable 441 kN · bond length 6 m", + "기본값 후보(사용자 확정 전) — 지식DB 안정성평가 02 §4: 천공 φ100 mm · 풍화토 극한 주면마찰 50~100 kPa · SD400 D25 허용 121.6 kN · 앵커 = 강연선 φ12.7 × 4 허용 441 kN · 정착장 6 m · 부착 = 극한 ÷ 인발 안전율 2.0 을 넣은 값(엔진이 다시 나누지 않음 · Slide2 와 같음)", + "Default candidates (not yet confirmed) — KB stability 02 §4: hole φ100 mm · weathered soil ultimate bond 50–100 kPa · SD400 D25 allowable 121.6 kN · anchor = 4 × φ12.7 strand allowable 441 kN · bond length 6 m · bond = ultimate ÷ pullout FS 2.0 (engine does not divide again · same as Slide2)", ], E03_Sp_Type: ["종류", "Type"], E03_Sp_nail: ["네일", "Nail"], @@ -188,7 +188,7 @@ export const ui_locales_e03 = { E03_Sp_F_length_m: ["길이 m", "Length m"], E03_Sp_F_angle_deg: ["각도 °(수평 아래)", "Angle ° (below horizontal)"], E03_Sp_F_tensile_kN: ["인장 한도 kN", "Tensile limit kN"], - E03_Sp_F_bond_kPa: ["부착 kPa", "Bond kPa"], + E03_Sp_F_bond_kPa: ["부착 kPa(÷ 안전율)", "Bond kPa (÷ FS)"], E03_Sp_F_bond_length_m: ["정착장 m", "Bond length m"], E03_Sp_F_hole_dia_mm: ["천공 지름 mm", "Hole dia. mm"], E03_Sp_F_prestress_kN: ["선인장 kN", "Prestress kN"], @@ -209,6 +209,7 @@ export const ui_locales_e03 = { E03_Sp_Mode_tensile: ["인장", "Tensile"], E03_Sp_Mode_pullout: ["인발", "Pullout"], E03_Sp_Mode_stripping: ["머리 쪽 빠짐", "Stripping"], + E03_Sp_Mode_prestress: ["선인장(능동)", "Prestress (active)"], E03_Sp_Mode_not_crossing: ["활동면 안 만남", "Not crossing"], E03_Sp_Mode_pending: ["결과 없음", "No result"], } as const satisfies Record;