diff --git a/docs/VALIDATION.md b/docs/VALIDATION.md new file mode 100644 index 0000000..14c17e5 --- /dev/null +++ b/docs/VALIDATION.md @@ -0,0 +1,132 @@ +# FESA Phase 1 검증 보고서 + +## 1. 검증 기준과 실행 증거 + +이 보고서는 2026-08-03에 `feat-beam-reference-qualification`에서 새 Debug 빌드와 +테스트를 실행해 수집한 결과다. FESA Beam 검증은 다음 두 gate를 독립적으로 +운영한다. + +- Gate A — FESA 정식화 적합성: FESA가 채택한 선택적 감차적분 Timoshenko + 정식화를 해석해, 에너지, 강체 mode와 평형으로 검증한다. +- Gate B — Abaqus 결과 상관성: Abaqus B31과 FESA의 정식화 차이를 인정하고 + 요청된 결과의 component별 RMSE와 Relative L2를 보고한다. + +실행 결과는 다음과 같다. + +| 명령 | 결과 | +|------|------| +| `cmake --build --preset windows-debug` | MSVC v145 Debug x64 빌드 성공, 새 경고 없음 | +| `ctest --preset windows-debug --output-on-failure` | 68/68 통과 | +| `uv run --with pytest python -m pytest -v -rs` | 20/20 통과 | +| `fesa solve` 후 `fesa-reference-compare` | 42개 요청 위치와 18개 component metric 생성, exit code 0 | + +Harness child의 관리형 WindowsApps PowerShell은 `CreateProcessAsUserW` 오류로 명령을 +시작하지 못했다. 위 명령은 동일 저장소와 preset에서 현재 세션이 직접 실행했으며, +executor 환경 문제를 테스트 성공으로 간주하지 않았다. + +## 2. Gate A — FESA 정식화 적합성 + +### 2.1 요소 정식화와 회복 + +`tests/unit/elements/beam3d2_test.cpp`의 다음 검증이 모두 통과했다. + +| 검증 | 증거 | 판정 기준 | +|------|------|-----------| +| 행렬 유한성·대칭성 | `Beam3D2.ProducesFiniteSymmetricLocalAndGlobalStiffness` | local/global 12×12 전 항 유한, 대칭 항 bitwise equality | +| 강체 mode | `RigidBody.SixIndependentModesHaveZeroStrainEnergy` | 3개 병진과 3개 회전 mode의 energy가 roundoff bound 이내 | +| 축·비틀림 | `Timoshenko.ReproducesAnalyticalAxialSubmatrix`, `ReproducesAnalyticalTorsionalSubmatrix` | 해석 stiffness 대비 `512*epsilon` 상대 규모 | +| 굽힘 y/z | `Timoshenko.ReproducesConstantCurvatureEnergyAboutLocalY/LocalZ` | 해석 strain energy 대비 `512*epsilon` 상대 규모 | +| 전단 y/z | `Timoshenko.ReproducesConstantShearEnergyInLocalY/LocalZ` | 해석 strain energy 대비 `512*epsilon` 상대 규모 | +| 세장비 | `Timoshenko.AvoidsShearLockingAcrossSlendernessSweep` | `L/h={2,10,100,1000}`, `4096*epsilon*(L/h)^2` 상대 규모 | +| 회전 불변성 | `Beam3D2.PreservesGlobalEnergyUnderRigidCoordinateRotation` | 회전 전후 global energy가 `4096*epsilon` 상대 규모 이내 | +| 단면력 회복 | `BeamRecovery.*`, `SectionForce.*` | 축력, 비틀림, 전단, My, Mz와 biaxial 부호를 양 끝에서 검증 | + +### 2.2 Physics sanity와 결정성 + +| 검증 | 증거 | 결과 | +|------|------|------| +| full-system 평형 | `StaticEquilibrium.ReturnedFieldsSatisfyOriginalFullEquation` | `Ku-f-r` 각 DOF가 `1e-12` 이내 | +| 비영 지정 DOF | `ConstraintElimination.ShiftsNonzeroPrescribedValueAndPreservesOriginalSystem` 및 `LinearStaticAnalysis.SolvesAllConstrainedSystemWithoutPardiso` | reduced RHS 이동, full displacement와 reaction 검증 | +| 반력 | `Reaction.UsesOriginalFullEquilibriumEquation` | 원래 full equation에서 회복 | +| production pipeline | `MinimalCantileverPipeline.WritesReadableFiniteEquilibratedResults` | parser→solver→HDF5 결과 유한, 전역 반력 평형 `1e-12` 이내 | +| reference 평형 | `CantileverReference.CorrelatesAllAvailableAbaqusResults` | 절대 `1e-12`와 적용 하중 대비 상대 `2e-13` 중 큰 허용치 이내 | +| 병렬 결정성 | `ThreadCountDeterminism.AssemblyAndLinearStateAreBitwiseStable` | thread `{1,2,16}`에서 10회 반복, matrix/displacement/reaction bitwise 동일 | + +Gate A disposition은 **PASS**다. + +## 3. Gate B — Abaqus 2024 결과 상관성 + +### 3.1 모델과 비교 계약 + +- Abaqus provenance: `reference/cantilever beam/cantilever beam.inp`와 변위, 반력, + 요소 단면력 CSV. 원본 모델의 `SCF=0.25`는 유지한다. +- FESA projection: `reference/cantilever beam/cantilever beam fesa.inp`. 기하, 재료, + 단면, 명시적 전단강성, 경계조건과 하중은 같고 `SCF=0`만 적용한다. +- entity join: nodal 결과 11개씩은 `(Instance, Node Label)`, 요소 단면력 20개는 + `(Instance, Element Label, End Node Label)`로 매칭한다. +- absolute scale: displacement `1e-10`, reaction `1e-8`, internal force `1e-8`. +- 서로 단위가 다른 component는 하나의 norm으로 합치지 않는다. + +요소력 축 순서는 다음과 같다. + +| FESA | Abaqus CSV | +|------|------------| +| `N` | `SF1` | +| `Vy` | `SF3` | +| `Vz` | `SF2` | +| `T` | `SM3` | +| `My` | `SM1` | +| `Mz` | `SM2` | + +component \(c\)의 표본 수를 \(n\), 오차를 \(e_i=a_i-r_i\), absolute scale을 +\(s_i\)라 하면 다음을 사용한다. + +\[ +\operatorname{RMSE}_c=\sqrt{\frac{1}{n}\sum_i e_i^2} +\] + +\[ +\operatorname{RelativeL2}_c= +\frac{\sqrt{\sum_i e_i^2}} +{\max\left(\sqrt{\sum_i r_i^2},\sqrt{\sum_i s_i^2}\right)} +\] + +### 3.2 수집된 correlation metric + +| 물리량 | component | count | RMSE | Relative L2 | +|--------|-----------|------:|-----:|------------:| +| displacement | Ux | 11 | 0 | 0 | +| displacement | Uy | 11 | 0 | 0 | +| displacement | Uz | 11 | 2.1970445023044601e-05 | 2.2349969291714038e-03 | +| displacement | Rx | 11 | 0 | 0 | +| displacement | Ry | 11 | 2.1672945177750166e-09 | 1.0416581667076092e-06 | +| displacement | Rz | 11 | 0 | 0 | +| reaction | RFx | 11 | 0 | 0 | +| reaction | RFy | 11 | 0 | 0 | +| reaction | RFz | 11 | 1.3385150002853335e-07 | 4.4393520322089023e-13 | +| reaction | RMx | 11 | 0 | 0 | +| reaction | RMy | 11 | 7.8149308366928907e-07 | 2.591919334788851e-13 | +| reaction | RMz | 11 | 0 | 0 | +| internal force | N | 20 | 0 | 0 | +| internal force | Vy | 20 | 0 | 0 | +| internal force | Vz | 20 | 2.7107472798172421e-07 | 2.7107472798172426e-13 | +| internal force | T | 20 | 0 | 0 | +| internal force | My | 20 | 474341.64902538335 | 0.082541022764834646 | +| internal force | Mz | 20 | 0 | 0 | + +모든 요청 entity/component가 유일하게 매칭됐고 metric이 유한하므로 Gate B +disposition은 **EVALUABLE**이다. 이는 Abaqus B31과 FESA의 정식화가 동일하거나 +임의 정확도 threshold를 통과했다는 뜻이 아니다. 현재 가장 큰 Relative L2는 +`My=0.082541022764834646`, 다음은 `Uz=0.0022349969291714038`이다. pass/fail +envelope는 mesh 또는 해석적 연구 근거 없이 이 관측값에 맞춰 설정하지 않는다. + +## 4. 검증 범위와 제한 + +- Abaqus 단면 도심 응력 CSV는 제공되지 않았다. `StressCsv`는 synthetic CSV schema와 + `(Instance, Element, End Node)` 매핑만 검증하며, 응력은 **not yet + Abaqus-qualified**다. +- Gate B는 solver 간 correlation이며 Gate A의 해석적 정확도 검증을 대체하지 않는다. +- Abaqus golden 갱신에는 Abaqus 2024 환경과 수동 provenance 검토가 필요하다. +- FESA는 단위 변환을 수행하지 않으므로 입력과 CSV가 일관 단위계를 사용해야 한다. + +현재 이중 gate 결론은 **Gate A PASS / Gate B EVALUABLE**이다.