diff --git a/src/core/geometry.ts b/src/core/geometry.ts index cfa905b..6413581 100644 --- a/src/core/geometry.ts +++ b/src/core/geometry.ts @@ -33,6 +33,8 @@ export const DIM = { padThickness: 0.05, padSize: 1.0, blockSize: 1.2, + /** W11 (제안 2026-11-10): 받침블럭 콘크리트(패드 제외) 최소 높이 = 피복 50 + D13 = 63 mm (교대 I01과 같은 기준). */ + blockMinHeight: 0.063, footingL: 10.4, footingW: 8.15, footingH: 2.0, diff --git a/src/core/validate.ts b/src/core/validate.ts index 8026b06..726e822 100644 --- a/src/core/validate.ts +++ b/src/core/validate.ts @@ -85,6 +85,13 @@ export function validatePier(input: PierInput, model: PierModel, issues: Issue[] if (minBlock <= 0) { issues.push({ code: 'W02', level: 'W', pier: input.name, message: '받침블럭 콘크리트 높이가 0 이하입니다. 블럭을 생략합니다.' }); } + // W11 (2026-11-10): every block between 0 and the minimum height, from its own 교좌면 EL and z. + for (const b of model.blocks) { + const h = b.top - b.bottom; + if (h > 0 && h < DIM.blockMinHeight - 1e-9) { + issues.push({ code: 'W11', level: 'W', pier: input.name, message: `${b.row} 받침 ${b.no}번 받침블럭 콘크리트 ${Math.round(h * 1000)} mm가 최소 ${DIM.blockMinHeight * 1000} mm보다 낮습니다. 교좌면 EL과 받침 z를 확인하세요.` }); + } + } // W03: bearing centre closer than half a block width to a step boundary (interior boundaries only). const halfBlock = DIM.blockSize / 2; for (const b of model.bearings) { diff --git a/tests/seat-el.test.ts b/tests/seat-el.test.ts index ffc466c..39709bd 100644 --- a/tests/seat-el.test.ts +++ b/tests/seat-el.test.ts @@ -73,4 +73,19 @@ describe('교좌면 EL 입력 (2026-11-03)', () => { validatePier(input, m, issues); expect(issues.filter((i) => i.code === 'W10').map((i) => i.level)).toEqual(['I']); }); + + it('W11 when a block is thinner than 63 mm (피복 50 + D13), from its own 교좌면 EL; none for P1', () => { + const p1 = withSeat(loadP1(), SEAT); + const ok: Issue[] = []; + validatePier(p1, buildPier(p1, P1CTX), ok); + expect(ok.filter((i) => i.code === 'W11')).toEqual([]); + // Bearing 1: z 43.561 − pad 50 − 50 mm block → 교좌면 43.461. + const thin = withSeat(loadP1(), [43.461, ...SEAT.slice(1)]); + const m = buildPier(thin, P1CTX); + const issues: Issue[] = []; + validatePier(thin, m, issues); + const w = issues.filter((i) => i.code === 'W11'); + expect(w.length).toBe(1); + expect(w[0].message).toContain('받침 1번'); + }); });