diff --git a/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md b/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md index 79636fe..8996c3b 100644 --- a/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md +++ b/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md @@ -7,7 +7,9 @@ - status: `approved` - approved_by: user - approved_on: `2026-08-08` +- amended_on: `2026-08-09` - source_formulation: `docs/formulations/3d-isoparametric-euler-beam-formulation.md` +- reference_baseline: `reference/cantilever beam/` from source commit `2b34d0b` - implementation_environment: C++17, MSVC, CMake, CTest, GoogleTest, Intel oneMKL, Intel oneTBB, HDF5 ## 1. 목적 @@ -50,7 +52,7 @@ authoritative HDF5 파일 `results.h5`에 기록하는 FESA V0 파이프라인 - MKL PARDISO factorization과 substitution의 분리 - oneTBB 기반 element-local 계산 - 변위, 반력, equilibrium end action, section resultant, axial `S11` 출력 -- Abaqus B33 변위·반력·section resultant reference comparison +- 승인된 `reference/cantilever beam/` B33 bundle의 변위·반력·section resultant comparison ### 2.2 제외 범위 @@ -285,8 +287,10 @@ node label 또는 node set이며 assembly-level set의 `INSTANCE` parameter를 Abaqus B31은 transverse shear deformation을 포함하는 Timoshenko beam이고 B33은 2절점 cubic Euler–Bernoulli beam이다. FESA V0는 `TYPE=B33`만 Euler 요소로 매핑한다. -`TYPE=B31`은 `unsupported-element-formulation` 오류로 거부한다. 기존 B31 reference -결과를 tolerance 확대로 Euler reference인 것처럼 사용하지 않는다. +`TYPE=B31`은 `unsupported-element-formulation` 오류로 거부한다. +`reference/cantilever beam/cantilever beam.inp`는 source commit `2b34d0b`에서 +`TYPE=B33`으로 생성된 승인 reference input이다. Reference artifact check는 비교 전에 +이 element type을 다시 확인하며 B31로 되돌아간 입력이나 결과를 허용하지 않는다. 이 결정은 [[Abaqus Structural Element Families]], [[Beam and Frame Finite Elements]], [[Abaqus-Analysis-User-s-Guide-Volume-IV|Abaqus Analysis User's Guide Volume IV]]의 @@ -355,7 +359,7 @@ beam-family 구분을 따른다. - generalized strain/resultant: 두 Gauss point의 formulation 값 Abaqus internal-force CSV는 equilibrium end action이 아니라 section resultant와 -비교한다. component mapping은 다음과 같다. +비교한다. 일반 component mapping은 다음과 같다. | Abaqus | FESA local component | | --- | --- | @@ -366,6 +370,24 @@ Abaqus internal-force CSV는 equilibrium end action이 아니라 section resulta | `SM1` | `MY` | | `SM2` | `MZ` | +승인된 B33 reference의 `cantilever beam elemental forces.csv`는 element label 없이 +`Frame`, `Part Instance Name`, `Node Label`, `SF1`, `SM1`, `SM2`, `SM3`을 기록한다. +따라서 이 파일의 comparison은 다음 규칙을 사용한다. + +- Reference row key는 `(Step-1, frame 0, instance name, source node label, component)`다. + 단일 step invariant에 따라 CSV의 `Increment 1: Step Time = 1.000`을 + `(Step-1, frame 0)`으로 정규화한다. +- FESA endpoint section resultant를 동일한 section-cut 부호로 변환한 뒤 source node + station으로 정규화한다. Interior node의 두 인접 element endpoint 값은 먼저 승인된 + tolerance 안에서 서로 일치해야 한다. 불일치는 평균으로 숨기지 않고 + `tolerance-failure`로 보고한다. +- Interior endpoint가 일치하면 stable internal element ID가 작은 endpoint를 대표 row로 + 선택한다. Boundary node는 하나의 endpoint를 사용한다. +- 이 bundle에서 비교하는 mapping은 `SF1 -> N`, `SM1 -> My`, `SM2 -> Mz`, + `SM3 -> T`다. CSV에 없는 `SF2`와 `SF3`는 reference comparison 대상이 아니며, + FESA equilibrium end action의 transverse force는 unit/analytical test와 physics sanity로 + 검증한다. + ### 8.3 Axial stress General beam section은 section point에서 axial stress만 복구한다. @@ -405,9 +427,11 @@ coordinate convention, element formulation을 기록한다. Node/element group ID와 instance/source label mapping을 함께 저장한다. Abaqus `.inp` 자체에는 단위 선언이 없으므로 일반 solver run의 unit-system label은 -`user-consistent-unspecified`로 기록한다. Reference comparison에서는 별도 -`metadata.json`이 선언한 단위계를 authoritative unit label로 사용하며, solver가 입력 -파일만 보고 SI를 추론하지 않는다. +`user-consistent-unspecified`로 기록하고 solver가 입력 파일만 보고 SI를 추론하지 +않는다. 승인된 cantilever B33 reference에 한해서는 이 설계와 후속 Reference Model +Contract가 입력 수치의 단위계를 SI로 선언하고, reference verification이 동일한 입력으로 +생성된 FESA 결과에 그 외부 단위 계약을 적용한다. 새 reference model은 별도 +`metadata.json`에 단위계를 선언해야 한다. - displacement: `[node_count, 6]` - reaction: `[node_count, 6]` @@ -471,6 +495,8 @@ GoogleTest target에는 FESA warning policy를 강제하지 않는다. - axial, torsion, y/z bending cantilever analytical cases - HDF5 schema, identity, component, metadata, atomic finalization - CLI `.inp -> results.h5` integration +- 승인된 B33 CSV header/Frame 정규화, node-station matching, interior endpoint 일치 검사 +- zero 및 near-zero reference row를 포함한 component-scale 혼합 허용오차 검사 ### 11.3 수치 tolerance @@ -479,13 +505,37 @@ GoogleTest target에는 FESA warning policy를 강제하지 않는다. | matrix symmetry and Gauss/closed-form comparison | normalized `1e-12` | | rigid-mode and linear-system residual | normalized `1e-10` | | analytical solution tests | relative `1e-9` | -| Abaqus B33 reference comparison | relative `1e-6` | +| Abaqus B33 reference comparison | component-scale relative `1e-6` | | SI displacement and rotation absolute floor | `1e-9` | | SI force and moment absolute floor | `1e-3` | -Reference row 판정은 `abs_error <= abs_tol OR rel_error <= rel_tol`을 사용한다. -Reference metadata가 SI가 아니면 quantity별 absolute tolerance를 동일 차원으로 변환해야 -하며 변환 근거를 verification report에 기록한다. +Reference row 판정은 zero-reference에서도 의미가 있도록 component-scale 혼합 +허용오차를 사용한다. 같은 model, step/frame, quantity, component의 Abaqus reference +rows에 대해 다음 값을 계산한다. + +```text +reference_scale = max(abs(reference_value_i)) +row_tolerance = absolute_floor + 1e-6 * reference_scale +row_pass = abs(fesa_value_i - reference_value_i) <= row_tolerance +``` + +- Scale은 displacement, rotation, force, moment 및 각 component를 섞지 않는다. +- Scale은 read-only Abaqus reference 값만 사용하며 FESA 결과로 조정하지 않는다. +- Scale이 0이면 absolute floor만 적용한다. +- 모든 row를 개별 판정하며 reference 값을 zero-clamp하거나 row를 제거하지 않는다. +- Missing/extra row, nonfinite value, schema 또는 identity mismatch는 tolerance 계산 전에 + 실패한다. +- Report는 max absolute error, component-scale normalized error, RMS error, norm error, + worst row/component를 기록한다. + +현재 B33 `SM1`의 reference scale은 `1.0e7`이고 moment row tolerance는 +`1.0e-3 + 1.0e-6 * 1.0e7 = 10.001`이다. 자유단 reference residue `-1.56e-2`와 +FESA의 이론적 zero 사이 오차 `1.56e-2`는 이 기준을 통과하지만, 예를 들어 `100`의 +자유단 moment 오차는 실패한다. + +승인된 cantilever bundle은 SI absolute floor를 사용한다. 이후 SI가 아닌 reference를 +추가하면 quantity별 absolute floor를 해당 단위로 변환하고 변환 근거를 metadata와 +verification report에 기록해야 한다. ### 11.4 공통 build/test command @@ -509,21 +559,43 @@ CTest discovery 결과는 한 개 이상의 test를 포함해야 한다. ## 12. Reference 및 release gate -기존 `reference/cantilever beam/` bundle은 Abaqus B31 결과이므로 수정하지 않고 V0 -Euler verification에 사용하지 않는다. Reference Model Contract는 사람이 Abaqus에서 -생성할 B33 bundle의 다음 artifact를 요구한다. +`reference/cantilever beam/`을 V0의 승인된 Abaqus B33 reference baseline으로 사용한다. +논리 model ID는 `cantilever-beam-b33`, reference schema ID는 +`abaqus-cae-report-csv-v0`이며 source baseline은 commit `2b34d0b`이다. Input header가 +기록한 generator는 `Abaqus/CAE Learning Edition 2024`다. 모델은 SI 단위계, global +Cartesian nodal output, beam local section-force output, `Step-1`, increment 1, +step time 1.0 계약으로 해석한다. -- `model.inp` using `TYPE=B33` -- `metadata.json` with Abaqus version, units, coordinate system, provenance, tolerances -- `_displacements.csv` -- `_reactions.csv` -- `_internalforces.csv` -- `README.md` -- stress CSV: explicitly `not-applicable` for this feature +| Purpose | Approved artifact | +| --- | --- | +| analysis input | `reference/cantilever beam/cantilever beam.inp` | +| displacement | `reference/cantilever beam/cantilever beam displacements.csv` | +| reaction | `reference/cantilever beam/cantilever beam reactions.csv` | +| section resultant | `reference/cantilever beam/cantilever beam elemental forces.csv` | +| stress | N/A: beam stress reference comparison은 승인 범위에서 제외 | + +이 기존 bundle의 space-containing filename과 CAE report header는 승인된 legacy alias로 +그대로 지원하며 reference artifact를 rename하거나 rewrite하지 않는다. `metadata.json`과 +`README.md`는 이 baseline에 한해서 N/A다. 이 설계와 Step 5의 Reference Model Contract가 +대신 model ID, provenance, units, coordinate system, schema, file inventory, tolerance와 +stress N/A 사유를 기록한다. 이후 추가하는 reference model에는 canonical artifact 이름, +`metadata.json`, `README.md`를 요구한다. + +Reference verification은 build/test gate 통과 후 승인 input으로 FESA `results.h5`를 +생성하고 다음을 직접 비교한다. + +- nodal displacement: CSV `U1/U2/U3/UR1/UR2/UR3`과 HDF5 displacement +- nodal reaction: CSV `RF1/RF2/RF3/RM1/RM2/RM3`과 HDF5 reaction +- section resultant: CSV `SF1/SM1/SM2/SM3`과 node station으로 정규화한 HDF5 + section resultant +- stress: 명시적 N/A + +Artifact check는 네 파일의 존재, B33 element type, expected header, 유일한 row key, +finite value를 확인한다. 하나라도 충족하지 않으면 `needs-reference-artifacts` 또는 +`schema-mismatch`로 분류하고 comparison을 시작하지 않는다. 현재 baseline은 +`metadata.json` 또는 `README.md` 부재만으로 차단하지 않는다. Agent와 Harness는 Abaqus를 실행하거나 reference artifact를 생성·수정하지 않는다. -B33 artifact가 없으면 reference-verification step은 `blocked`로 끝나며 사용자가 bundle을 -준비한 후 해당 step을 `pending`으로 되돌려 재개한다. Reference comparison이 pass한 뒤에만 physics sanity를 수행한다. Physics sanity는 global force/moment equilibrium, reaction sign, displacement direction, symmetry, element @@ -539,7 +611,8 @@ gate evidence와 known limitations를 확인한다. 2. 모든 production C++ 변경에 대응 테스트와 RED/GREEN/VERIFY evidence가 있다. 3. MSVC x64 Debug configure, build, CTest discovery, 전체 CTest가 성공한다. 4. `fesa.exe`가 승인된 B33 single-step input에서 `results.h5`를 생성한다. -5. HDF5 변위·반력·내력 rows가 Abaqus B33 reference CSV와 tolerance 안에서 일치한다. +5. HDF5 변위·반력·내력 rows가 승인된 cantilever B33 reference CSV와 component-scale + 혼합 tolerance 안에서 일치한다. 6. Beam stress reference comparison은 명시적 N/A이고 stress output schema/test는 통과한다. 7. Physics sanity가 pass한다.