Files
Pier_v1/tests/abut-members.test.ts
ypshimandClaude Haiku 5.5 5e64a4f2ed feat(abut): 벽체 높이 H_w = 받침 ① 교좌면 ~ 흉벽 상단 연직 (기본 3326)
- 사용자 도면(2026-11-04): 받침 ① 위치에서 받침 ① 교좌면부터 흉벽 상단까지 연직 거리. 모든 교대 기본값 3326 (QA-4 가정 2500 대체)
- 입력 이름 "벽체 높이 · 받침 ① 기준 연직", ② 정면도에 받침 ① 기준선과 H_w 치수
- ③ 흉벽 철근표 대표 단면 = 받침 ① 위치 (P1–P3는 그 단면에서 정확히 계산)
- 테스트: 흉벽 상단 IP1 48.006 / IP3 47.661 등 + 0.826 반영, 교대흉벽철근.md §11 재현은 2500을 넣어 유지, 3326 기본 확인 (P1 3945)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-11-04 17:20:05 +09:00

60 lines
2.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import * as XLSX from 'xlsx';
import { describe, expect, it } from 'vitest';
import { buildAbut } from '../src/core/abut/geometry';
import { parseAbutments, toAbutInput } from '../src/core/abut/parse';
import { buildMembers } from '../src/core/abut/members';
const RAG = fileURLToPath(new URL('../../../RAG/운곡교P1입력.xlsx', import.meta.url));
// 운곡교 A1, 기준 입력 파일에서 읽음 (spec_abut §10.1).
const input = toAbutInput(parseAbutments(XLSX.read(readFileSync(RAG), { type: 'buffer' })).abutments[0]);
const model = buildAbut(input);
const m = buildMembers(model, { bottomEl: input.foundationBottomEl, pileLengthMm: input.pileLengthMm });
describe('교대 A1 벽체 · 흉벽 · 저판 · 말뚝 (AA3, spec_abut §10.1)', () => {
it('저판 상면 41.995 (기초 하단 40.895 + 두께 1.1)', () => {
expect(m.footingTopEl).toBeCloseTo(41.995, 3);
});
it('wall height ① 구간 2.372 m, five segments with the seat EL of each bearing', () => {
expect(m.wallSegments).toHaveLength(5);
const first = m.wallSegments.find((w) => Math.abs(w.seatEl - 44.367) < 1e-6)!;
expect(first.heightM).toBeCloseTo(2.372, 3);
});
it('wall segments tile the axis from 0 to L with the step boundaries', () => {
const w = m.wallSegments;
expect(w[0].sFrom).toBeCloseTo(0, 9);
expect(w[w.length - 1].sTo).toBeCloseTo(model.length, 9);
expect(w[0].sTo).toBeCloseTo(model.stepBounds[0], 9);
for (let i = 1; i < w.length; i++) expect(w[i].sFrom).toBeCloseTo(w[i - 1].sTo, 9);
});
it('흉벽 상단 EL 48.006 at IP1 end and 47.661 at IP3 end; slope −2.829 %', () => {
expect(m.parapetTopStartEl).toBeCloseTo(48.006, 2);
expect(m.parapetTopEndEl).toBeCloseTo(47.661, 2);
expect(m.parapetSlope * 100).toBeCloseTo(-2.829, 2);
});
it('말뚝 3열 × 6본 = 18, rows at t −1.15 / +0.85 / +2.15, spacing ≈ 2.179 m', () => {
expect(m.piles.map((r) => r.t)).toEqual([-1.15, 0.85, 2.15]);
expect(m.piles.every((r) => r.s.length === 6)).toBe(true);
const gap = m.piles[0].s[1] - m.piles[0].s[0];
expect(gap).toBeCloseTo(2.179, 2);
expect(m.piles[0].s[0]).toBeCloseTo(0.65, 6);
});
it('말뚝 선단 EL 19.295 (40.895 − 21.6 m)', () => {
expect(m.pileBottomEl).toBeCloseTo(19.295, 3);
});
it('without a foundation the footing and piles have no EL (no crash)', () => {
const bare = buildMembers(model);
expect(bare.footingBottomEl).toBeUndefined();
expect(bare.pileBottomEl).toBeUndefined();
expect(bare.piles[0].s).toHaveLength(6);
});
});