Files
Pier_v1/tests/bearing-height.test.ts
T
ypshimandClaude Haiku 5.5 d7a61df7a9 feat(bearing): 받침별 받침높이로 h3를 정한다 (교각·교대, AP07 폐지)
받침 시트의 받침높이_mm(9열)를 받침마다 읽어 h3 = H − T_ref로 쓴다. 거더 하면 = z + H가 받침마다 지켜진다.
솔플레이트 입력에 h3를 적으면 그 값이 모든 받침에 우선한다. 받침높이가 없으면 기존 기본값(교각 181, 교대 교대 값 − T_ref).
교대는 받침마다 달라도 받침별 값을 쓰므로 AP07(첫 값 사용) 경고를 없앤다.
교각 받침높이가 T_ref 이하이면 S01(E). 입력 양식 받침 표에 받침높이_mm 열을 추가한다.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-11-10 15:11:25 +09:00

84 lines
3.9 KiB
TypeScript
Raw 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 { describe, expect, it } from 'vitest';
import { buildPier } from '../src/core/geometry';
import { validateInput } from '../src/core/validate';
import { parseAbutments, toAbutInput } from '../src/core/abut/parse';
import { buildAbut } from '../src/core/abut/geometry';
import { abutSoles, resolveBearingRule } from '../src/core/abut/bearing-table';
import type { Issue, PierInput } from '../src/core/types';
import { loadInputWorkbook, loadP1, p1Pairs } from './helpers';
// 받침별 받침높이 (2026-11-10): h3 = 그 받침의 받침높이 H − T_ref, 거더 하면 = z + H.
const CTX = { pairs: p1Pairs() };
const withHeights = (input: PierInput, h: Record<number, number | undefined>): PierInput => ({
...input,
bearings: input.bearings.map((b) => ({ ...b, heightMm: b.no in h ? h[b.no] : b.heightMm })),
});
describe('교각 받침별 받침높이', () => {
it('reads 받침높이 from the bearing sheet (P1: 211 for every bearing, so h3 stays 181)', () => {
const p1 = loadP1();
expect(p1.bearings.map((b) => b.heightMm)).toEqual(Array(10).fill(211));
expect(buildPier(p1, CTX).blocks.every((b) => b.plan.h3 === 181)).toBe(true);
});
it('each bearing gets h3 = its H − T_ref; the block (z − pad − drop) does not move', () => {
const base = buildPier(loadP1(), CTX);
const m = buildPier(withHeights(loadP1(), { 3: 174, 8: 188 }), CTX);
const h3 = (no: number) => m.blocks.find((b) => b.no === no)!.plan.h3;
expect(h3(3)).toBe(144);
expect(h3(8)).toBe(158);
expect(h3(1)).toBe(181);
for (const b of m.blocks) {
const o = base.blocks.find((x) => x.no === b.no)!;
expect(b.top).toBeCloseTo(o.top, 9);
expect(b.bottom).toBeCloseTo(o.bottom, 9);
}
});
it('girder underside = z + H: pad top + h3 + T − (T − T_ref) − … equals z + H for every bearing', () => {
const input = withHeights(loadP1(), { 2: 176, 7: 183 });
const m = buildPier(input, CTX);
for (const b of m.blocks) {
const H = input.bearings.find((x) => x.no === b.no)!.heightMm!;
const z = input.bearings.find((x) => x.no === b.no)!.z;
expect(b.padTop + (b.plan.h3 + b.plan.T) / 1000).toBeCloseTo(z + H / 1000, 9);
}
});
it('a typed h3 (솔플레이트 입력) wins over the bearing heights', () => {
const input = { ...withHeights(loadP1(), { 3: 174 }), sole: { h3Mm: 200 } };
expect(buildPier(input, CTX).blocks.every((b) => b.plan.h3 === 200)).toBe(true);
});
it('without 받침높이 the default h3 181 is used', () => {
const input = { ...loadP1(), bearings: loadP1().bearings.map(({ heightMm: _h, ...b }) => b) };
expect(buildPier(input, CTX).blocks.every((b) => b.plan.h3 === 181)).toBe(true);
});
it('S01 (E) when a 받침높이 is not above T_ref, so no body could be built', () => {
const issues: Issue[] = [];
expect(validateInput(withHeights(loadP1(), { 4: 30 }), issues)).toBe(false);
expect(issues.filter((i) => i.code === 'S01').map((i) => i.message)).toEqual([expect.stringContaining('받침 4번')]);
});
});
describe('교대 받침별 받침높이', () => {
const a1 = () => parseAbutments(loadInputWorkbook()).abutments.find((a) => a.name === 'A1')!;
it('different heights per bearing give different h3 and no AP07 warning', () => {
const wb = loadInputWorkbook();
wb.Sheets['받침']['I16'] = { t: 'n', v: 260 };
const { abutments, issues } = parseAbutments(wb);
expect(issues.some((i) => i.code === 'AP07')).toBe(false);
const rec = abutments.find((a) => a.name === 'A1')!;
const soles = abutSoles(buildAbut(toAbutInput(rec)), resolveBearingRule(), rec.bearingHeightMm);
expect(soles.map((s) => s.h3)).toEqual([245, 245, 230, 245, 245]);
});
it('a typed h3 wins for every bearing', () => {
const rec = a1();
const soles = abutSoles(buildAbut(toAbutInput(rec)), resolveBearingRule({ h3Mm: 200 }), rec.bearingHeightMm);
expect(soles.every((s) => s.h3 === 200)).toBe(true);
});
});