현장타설말뚝철근.md §5–§6 (사용자 결정 2026-11-06: 11-06 겹침 결정이 11-05 커플러 회신을 대체). - 희생강관 기본 적용, 상단 지반고 + 2500 (그림 값, Q-PL4 가정). 암반 근입부 지름 입력 추가(기본 D − 150, 강관 없으면 D) - 말뚝 철근망 반지름을 근입부 기준으로 (D 3000: r 1300 / 1268.2) - 두 철근 원이 다르면 자동 겹침이음: 기둥 주철근이 지반고 아래 l_s(1.3 l_d, S32 2387)까지 내려감, 지반고 커플러 없음. 원이 같으면(근입부 없음) 지반고 커플러. 저장된 방식은 그대로 둠 - 겹침 구간의 말뚝 띠철근은 바깥 기둥 주철근을 감싸는 반지름 - 겹침 모드에서도 주기 커플러(기둥 지반고 + @3000, 말뚝 지반고 − @3000, 내측 + 150) - RB-PL07: 두 원 간격 > min(l_s/5, 150)이면 경고 - 이전 '겹침부 미계산' 표시 제거. 기존 커플러 테스트는 희생강관 미적용 입력으로 유지 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
63 lines
3.1 KiB
TypeScript
63 lines
3.1 KiB
TypeScript
import type { PierInput } from './types';
|
||
|
||
/** EL in metres, lengths in mm. User image and clarifications 2026-11-05; casing default and rock socket per 현장타설말뚝철근.md (2026-11-06). */
|
||
export interface CastInPlaceShapeSettings {
|
||
betaLengthMm?: number;
|
||
weatheredRockEl?: number;
|
||
bedrockEl?: number;
|
||
casingOn?: boolean;
|
||
casingTopEl?: number;
|
||
casingBottomEl?: number;
|
||
clayBottomEl?: number;
|
||
/** 암반 근입부 지름 (mm, 희생강관 아래). Absent = D − 150 with a casing, D without (현장타설말뚝철근.md §1.1, Q-PL3). */
|
||
socketDiameterMm?: number;
|
||
}
|
||
|
||
/** Rock-socket diameter (mm): the input, else D − 150 when the casing is on (default on, spec §3 2026-11-06), else D. */
|
||
export function castSocketDiameterMm(input: Pick<PierInput, 'castInPlaceShape' | 'columnDiameterMm'>): number {
|
||
const s = input.castInPlaceShape ?? {};
|
||
const d = input.columnDiameterMm ?? 2000;
|
||
return s.socketDiameterMm ?? ((s.casingOn ?? true) ? d - 150 : d);
|
||
}
|
||
|
||
export function castShape(input: Pick<PierInput, 'groundEl' | 'pileLengthMm' | 'castInPlaceShape' | 'columnDiameterMm'>) {
|
||
const s = input.castInPlaceShape ?? {};
|
||
const pileBottomEl = input.groundEl - input.pileLengthMm / 1000;
|
||
const bedrockEl = s.bedrockEl ?? pileBottomEl + 1;
|
||
const betaLengthMm = s.betaLengthMm ?? 9000;
|
||
return {
|
||
pileTopEl: input.groundEl, pileBottomEl,
|
||
betaLengthMm, betaEl: input.groundEl - betaLengthMm / 1000,
|
||
weatheredRockEl: s.weatheredRockEl ?? pileBottomEl + 5,
|
||
bedrockEl,
|
||
// 희생강관: 적용, 상단 지반고 + 2500 (그림 값, 엑셀 문구 + 3000 — Q-PL4 가정), 하단 = 기반암 EL.
|
||
casingOn: s.casingOn ?? true,
|
||
casingTopEl: s.casingTopEl ?? input.groundEl + 2.5,
|
||
casingBottomEl: s.casingBottomEl ?? bedrockEl,
|
||
clayBottomEl: s.clayBottomEl,
|
||
socketDiameterMm: castSocketDiameterMm(input),
|
||
};
|
||
}
|
||
|
||
export function castShapeIssues(value: unknown): string[] {
|
||
if (value === undefined) return [];
|
||
if (!value || typeof value !== 'object' || Array.isArray(value)) return ['현장타설 형상 입력 형식이 맞지 않습니다.'];
|
||
const out: string[] = [];
|
||
for (const [key, v] of Object.entries(value)) {
|
||
if (v === undefined) continue;
|
||
if (key === 'casingOn') { if (typeof v !== 'boolean') out.push('희생강관 적용 여부가 맞지 않습니다.'); }
|
||
else if (!['betaLengthMm', 'weatheredRockEl', 'bedrockEl', 'casingTopEl', 'casingBottomEl', 'clayBottomEl', 'socketDiameterMm'].includes(key) || typeof v !== 'number' || !Number.isFinite(v) || (key === 'betaLengthMm' || key === 'socketDiameterMm') && v <= 0) out.push(`현장타설 형상 ${key} 값이 맞지 않습니다.`);
|
||
}
|
||
return out;
|
||
}
|
||
|
||
/** DXF note 4. Do not substitute weathered-rock EL for the independent clay-layer EL. */
|
||
export function castLowerZone(input: Pick<PierInput, 'groundEl' | 'pileLengthMm' | 'castInPlaceShape' | 'columnDiameterMm'>) {
|
||
const s = castShape(input);
|
||
if (s.clayBottomEl === undefined) return null;
|
||
const d = (input.columnDiameterMm ?? 2000) / 1000;
|
||
const a = s.betaEl - 3 * d;
|
||
const b = s.clayBottomEl + d;
|
||
return { bottomEl: a, topEl: b, valid: a < b };
|
||
}
|