/** * ③ 철근배근 공통 규칙 (spec §6.2 · plan C1). Lengths in mm, stresses in MPa. * fck and fy are inputs. The defaults below are assumed values and must be shown as such (I02). */ /** Material inputs of ③ 공통 설정 (spec §6.2). fck and fy are inputs; the defaults are assumed values (I02). */ export interface Material { /** 콘크리트 강도 fck (MPa). */ fck: number; /** H = SD400 항복강도 (MPa). */ fyH: number; /** S = SD500 항복강도 (MPa). */ fyS: number; } export const DEFAULT_MATERIAL: Material = { fck: 27, fyH: 400, fyS: 500 }; /** True while the values are the assumed defaults (정보 I02 on the rebar screen). */ export function isAssumedMaterial(m: Material): boolean { return m.fck === DEFAULT_MATERIAL.fck && m.fyH === DEFAULT_MATERIAL.fyH && m.fyS === DEFAULT_MATERIAL.fyS; } export const MATERIAL_DEFAULTS = { fck: 27, /** H = SD400, S = SD500. */ fy: { H: 400, S: 500 } as const, /** 경량 콘크리트 계수 λ (보통 콘크리트 1.0). */ lambda: 1.0, /** Marks that these are assumed values (정보 I02). */ assumed: true, } as const; /** Development length l_d = 0.6·d_b·f_y / (λ·√f_ck) (spec §4 공통 설계 규약, 보정계수 1.0). */ export function developmentLength(db: number, fy: number, fck: number, lambda = MATERIAL_DEFAULTS.lambda): number { if (db <= 0 || fy <= 0 || fck <= 0 || lambda <= 0) throw new Error('정착길이 계산 값은 모두 0보다 커야 합니다.'); return (0.6 * db * fy) / (lambda * Math.sqrt(fck)); } /** Lap splice length l_s = 1.3·l_d (spec §4 공통 설계 규약). */ export function spliceLength(db: number, fy: number, fck: number, lambda = MATERIAL_DEFAULTS.lambda): number { return 1.3 * developmentLength(db, fy, fck, lambda); } /** Nominal diameters d (mm) of the bar sizes used in the documents (코핑철근.md, 기둥철근.md). */ export const NOMINAL_DIAMETER = { D13: 12.7, H16: 15.9, H19: 19.1, D22: 22.2, H25: 25.4, H29: 28.6, S32: 31.8, D35: 34.9, /** SD500 names used by the footing document (same nominal diameters). */ S16: 15.9, S19: 19.1, S25: 25.4, S29: 28.6, } as const; export type BarSize = keyof typeof NOMINAL_DIAMETER; export type HookKind = 'main90' | 'tie90' | 'stirrup135'; /** * Standard hook lengths (KDS 14 20 52, spec §4). Refuses bar sizes outside the table rather than guessing. * - main90: 주철근 90°, D25 이하 15.5 d_b, D29–D35 16.5 d_b * - tie90: 띠철근 90°, D16 이하 8.5 d_b * - stirrup135: 스터럽 135°, 2.5·d_b·(3π/4) + 6·d_b (spec formula, as written) */ export function hookLength(kind: HookKind, db: number): number { if (kind === 'main90') { if (db <= 25) return 15.5 * db; if (db <= 35) return 16.5 * db; throw new Error(`주철근 90° 갈고리 표에 없는 지름입니다 (D${db}).`); } if (kind === 'tie90') { if (db <= 16) return 8.5 * db; throw new Error(`띠철근 90° 갈고리 표에 없는 지름입니다 (D${db}).`); } return 2.5 * db * ((3 * Math.PI) / 4) + 6 * db; } /** * Splice of a long bar into two pieces (추천안 for Q-B6): each piece is half the total plus half the lap, * and the lap is l_s = 1.3·l_d. Used only when the bar is longer than the standard bar length. */ export function splitPieces(total: number, db: number, fy: number, fck: number, standard: number): { pieces: number; pieceLength: number; lap: number } | null { if (total <= standard) return null; const lap = spliceLength(db, fy, fck); return { pieces: 2, pieceLength: total / 2 + lap / 2, lap }; }