feat(nonlinear-static-newton-raphson): step 12 - execution-closure-and-evidence-docs

This commit is contained in:
KOKO\Mimi
2026-08-28 21:08:58 +09:00
parent d275e844f2
commit bf9487efc2
6 changed files with 317 additions and 11 deletions
+27
View File
@@ -346,3 +346,30 @@ gate와 family RMS gate를 모두 유지해야 한다. Reference family 전체
MITC4 verification report 및 comparator schema는 새 정책에 맞춰 다시 생성해야 하지만 MITC4 verification report 및 comparator schema는 새 정책에 맞춰 다시 생성해야 하지만
reference artifact, HDF5 schema, element formulation과 blocking/warning 분류는 변경하지 reference artifact, HDF5 schema, element formulation과 blocking/warning 분류는 변경하지
않는다. 않는다.
### ADR-023: Nonlinear Static은 prepared dispatch와 accepted-frame evidence로 분리한다
**결정**: CLI는 하나의 `.inp` operand만 받고 input lexical sibling
`<stem>_results.h5`와 `<stem>_log.txt`를 유도한다. `--output`은 지원하지 않는다.
`PrepareAnalysisInput()`이 syntax/semantic map을 한 번만 수행하고, prepared Domain의
procedure identity가 linear static 또는 separate nonlinear full-Newton procedure를 선택한다.
Nonlinear procedure는 trial/committed state, unsymmetric tangent solver와 iteration log를
독립적으로 소유하며 log close 뒤에만 schema-v1 HDF5 writer가 accepted frames를 atomic publish한다.
schema-v1 `/global/equilibrium`의 six values는 global origin `[0,0,0]`에서 current `X+u`
force arm과 spatial physical nodal moments를 쓴 applied-plus-constrained-reaction balance
error다. Accepted free generalized residual과 constrained-reaction resultant는 distinct
projections이며 result dataset을 서로 대체하지 않는다. Nonlinear reference portfolio는 fine
primary `shellNL-meshfine`, coarse companion `shellNL`, linear control `shell`을 분리한다.
External U is blocking, UR is warning-only, local RF/RM is review-only, and RM3/stress is excluded;
the factor-one internal global force/moment balance and accepted free residual remain blocking.
**이유**: Input parse, linear lifecycle, nonlinear trial state와 writer finalization을 한
procedure에 섞으면 output lifetime과 failure atomicity를 검증할 수 없다. Applied-plus-reaction
balance, constrained reaction과 free residual을 구분하면 nonzero prescribed translation/rotation
case에서도 force arm, mask와 rotation-coordinate conversion의 의미가 보존된다.
**트레이드오프**: Nonlinear path는 linear procedure보다 state/backend/writer 수가 늘고 fine
reference run 시간이 길다. 대신 HDF5 authoritative output, immutable CSV artifact와 external
solver internal-algorithm non-equivalence 원칙을 유지하며 local support-force distribution을
blocking tolerance로 위장하지 않는다.
+30 -5
View File
@@ -317,9 +317,25 @@ Abaqus input file
-> LinearSolver::solve(rhs, df) substitution -> LinearSolver::solve(rhs, df) substitution
-> full displacement 복구 -> full displacement 복구
-> full residual/reaction = K*d - F 및 ElementResultBundle 복구 -> full residual/reaction = K*d - F 및 ElementResultBundle 복구
-> ResultsWriter로 results.h5 atomic finalization -> ResultsWriter로 derived `<stem>_results.h5` atomic finalization
``` ```
### 승인된 Nonlinear Static 경로
`PrepareAnalysisInput()`은 input syntax와 semantic Domain을 정확히 한 번 만든다.
`ExecutePreparedAnalysis()`는 sole static step의 procedure identity로 linear static 또는
nonlinear static executor를 선택하며 두 procedure의 mutable state를 공유하지 않는다.
Nonlinear executor는 committed/trial `NonlinearAnalysisState`, full unsymmetric CSR tangent
solver와 closed-before-finalization Newton iteration log를 소유한다. Completion 뒤
`FinalizePreparedAnalysisResult()`가 selected backend-neutral writer로 only accepted frames를
atomic finalization한다.
Nonlinear schema v1의 factor-one `/global/equilibrium`은 raw full-residual sum이 아니라
global origin `[0,0,0]`에서 current `X+u` force arm과 independently spatialized applied and
masked constrained-reaction moments를 합한 applied-plus-reaction balance error다. Accepted
free residual은 generalized residual의 free mask projection이고 constrained-reaction resultant는
별도 review summary다. 어느 quantity도 다른 quantity의 substitute가 아니다.
강성행렬 factorization은 하중벡터 조립보다 먼저 수행한다. 반력은 element end action의 강성행렬 factorization은 하중벡터 조립보다 먼저 수행한다. 반력은 element end action의
별도 합이 아니라 조립된 전체 residual에서 구한다. Constrained component는 physical 별도 합이 아니라 조립된 전체 residual에서 구한다. Constrained component는 physical
reaction이고 free component는 equilibrium residual evidence로 full-index vector에 남긴다. reaction이고 free component는 equilibrium residual evidence로 full-index vector에 남긴다.
@@ -400,7 +416,8 @@ Schema requirements:
- schema version, units, coordinate system, solver version, source input identity를 metadata에 기록한다. - schema version, units, coordinate system, solver version, source input identity를 metadata에 기록한다.
- field output과 history output을 구분한다. - field output과 history output을 구분한다.
- reference comparison을 위한 row identity는 node id, element id, integration point id, step/frame id를 포함한다. - reference comparison을 위한 row identity는 node id, element id, integration point id, step/frame id를 포함한다.
- FESA solver는 `results.h5`를 authoritative output으로 쓴다. - FESA solver는 input lexical sibling `<stem>_results.h5`를 authoritative output으로 쓰며,
같은 directory의 `<stem>_log.txt`는 procedure log다.
- Abaqus reference results는 기능 문서가 선언한 기존 CSV 파일이다. Directory/file - Abaqus reference results는 기능 문서가 선언한 기존 CSV 파일이다. Directory/file
naming, README, metadata 또는 provenance는 architecture readiness 조건이 아니다. naming, README, metadata 또는 provenance는 architecture readiness 조건이 아니다.
- Verification은 기능이 요구하는 source identity와 component를 결정적으로 대응시키고 - Verification은 기능이 요구하는 source identity와 component를 결정적으로 대응시키고
@@ -410,7 +427,7 @@ Schema requirements:
- Writer는 final과 같은 directory의 임시 HDF5에 전체 schema를 쓴 뒤 flush, checked close, - Writer는 final과 같은 directory의 임시 HDF5에 전체 schema를 쓴 뒤 flush, checked close,
read-only reopen/self-check를 수행한다. Existing final은 `ReplaceFileW`, 새 final은 read-only reopen/self-check를 수행한다. Existing final은 `ReplaceFileW`, 새 final은
`MoveFileExW(..., MOVEFILE_WRITE_THROUGH)`로 완료하며 실패 시 temporary artifact를 `MoveFileExW(..., MOVEFILE_WRITE_THROUGH)`로 완료하며 실패 시 temporary artifact를
정리하고 불완전한 파일을 정상 `results.h5`로 노출하지 않는다. 정리하고 불완전한 파일을 정상 `<stem>_results.h5`로 노출하지 않는다.
## V0 결과 복구와 reference normalization ## V0 결과 복구와 reference normalization
@@ -438,10 +455,11 @@ Schema requirements:
## CLI와 diagnostics ## CLI와 diagnostics
```powershell ```powershell
fesa.exe <model.inp> --output <results.h5> fesa.exe <model.inp>
``` ```
`--output`을 생략하면 현재 작업 디렉터리의 `results.h5`를 사용한다. Exit code는 CLI는 input과 같은 lexical sibling directory에 `<stem>_results.h5`와
`<stem>_log.txt`를 유도하고 `--output`을 거부한다. Exit code는
`0=success`, `2=usage`, `3=input syntax/semantic mapping`, `4=model validation`, `0=success`, `2=usage`, `3=input syntax/semantic mapping`, `4=model validation`,
`5=factorization/substitution`, `6=HDF5 output`으로 고정한다. Diagnostic은 `severity`, `5=factorization/substitution`, `6=HDF5 output`으로 고정한다. Diagnostic은 `severity`,
`code`, `file`, `line`, `keyword`, `entity_identity`, `message`를 가지며 stderr에 `code`, `file`, `line`, `keyword`, `entity_identity`, `message`를 가지며 stderr에
@@ -479,3 +497,10 @@ displacement CSV만 사용한다. Global `U1/U2/U3` translation family만 blocki
family-scale row/RMS 정책을 사용한다. S4R은 family-scale row/RMS 정책을 사용한다. S4R은
같은 kernel을 선택하는 source mapping과 metadata를 unit/integration tests로 검증하며 같은 kernel을 선택하는 source mapping과 metadata를 unit/integration tests로 검증하며
`reference/shellR/` artifact는 acceptance comparison에 포함하지 않는다. `reference/shellR/` artifact는 acceptance comparison에 포함하지 않는다.
Approved nonlinear MITC4 verification은 `reference/shellNL-meshfine/` fine primary,
`reference/shellNL/` coarse companion과 `reference/shell/` linear control을 각각 독립
copied-input directory에서 실행한다. Factor-one global force/moment balance와 accepted free
residual은 blocking internal evidence다. External `U1/U2/U3`는 blocking, `UR1/UR2/UR3`는
warning-only이며 local nodal `RF1/RF2/RF3/RM1/RM2`는 deterministic review-only evidence다;
`RM3`와 stress는 nonlinear numerical comparison에서 제외한다.
+24 -6
View File
@@ -2,7 +2,7 @@
## 목표 ## 목표
FESA는 Abaqus `.inp` keyword subset을 입력으로 받아 자체 유한요소 정식화로 구조해석을 FESA는 Abaqus `.inp` keyword subset을 입력으로 받아 자체 유한요소 정식화로 구조해석을
수행하고, step/frame 단위 결과를 `results.h5` HDF5로 저장하며, 기능이 지정한 Abaqus 수행하고, step/frame 단위 결과를 input lexical sibling `<stem>_results.h5` HDF5로 저장하며, 기능이 지정한 Abaqus
reference CSV 수치와 비교 가능한 C++17/MSVC 솔버를 제공한다. Abaqus의 요소 알고리즘, reference CSV 수치와 비교 가능한 C++17/MSVC 솔버를 제공한다. Abaqus의 요소 알고리즘,
적분법, stabilization 또는 내부 결과 생성 절차를 재현하는 것은 목표가 아니다. 적분법, stabilization 또는 내부 결과 생성 절차를 재현하는 것은 목표가 아니다.
@@ -36,7 +36,7 @@ Element/material 계층의 일반적인 runtime polymorphism, iterative solver,
2. FESA는 syntax를 읽은 뒤 semantic mapping과 model validation을 수행한다. 지원하지 않는 모델 의미는 구조화된 diagnostic과 안정된 exit code로 거부한다. 2. FESA는 syntax를 읽은 뒤 semantic mapping과 model validation을 수행한다. 지원하지 않는 모델 의미는 구조화된 diagnostic과 안정된 exit code로 거부한다.
3. 해석 procedure는 active model view, DOF/equation map과 sparse system을 만들고, essential constraint elimination을 적용해 선형계를 factorize하고 substitution한다. 3. 해석 procedure는 active model view, DOF/equation map과 sparse system을 만들고, essential constraint elimination을 적용해 선형계를 factorize하고 substitution한다.
4. FESA는 full displacement를 복구하고 equilibrium residual/reaction과 element 결과를 계산한다. 4. FESA는 full displacement를 복구하고 equilibrium residual/reaction과 element 결과를 계산한다.
5. 성공 시 output request와 무관한 mandatory 결과, metadata와 diagnostic을 versioned `results.h5`에 기록한다. 실패 시 불완전한 최종 결과 파일을 정상 결과처럼 남기지 않는다. 5. 성공 시 output request와 무관한 mandatory 결과, metadata와 diagnostic을 versioned lexical sibling `<stem>_results.h5`에 기록한다. 실패 시 불완전한 최종 결과 파일을 정상 결과처럼 남기지 않는다.
6. 검증 workflow는 기능이 지정한 HDF5 quantity를 기존 Abaqus CSV의 source identity와 6. 검증 workflow는 기능이 지정한 HDF5 quantity를 기존 Abaqus CSV의 source identity와
component에 대응시켜 tolerance를 판정하고, 별도로 equilibrium과 물리적 타당성을 component에 대응시켜 tolerance를 판정하고, 별도로 equilibrium과 물리적 타당성을
검토한다. Reference bundle naming이나 provenance는 수치 비교 gate가 아니다. 검토한다. Reference bundle naming이나 provenance는 수치 비교 gate가 아니다.
@@ -76,10 +76,27 @@ Parser keyword, element kernel, solver backend 또는 output dataset 중 하나
- displacements, reactions, equilibrium end actions, section resultants, generalized results, - displacements, reactions, equilibrium end actions, section resultants, generalized results,
axial `S11` output axial `S11` output
- HDF5 result schema v0 - HDF5 result schema v0
- `fesa.exe <model.inp> --output <results.h5>` CLI - `fesa.exe <model.inp>` CLI with lexical sibling result/log names
- 승인된 `reference/cantilever beam/` B33 결과와 displacement, reaction, section resultant - 승인된 `reference/cantilever beam/` B33 결과와 displacement, reaction, section resultant
comparison; beam stress reference comparison은 N/A comparison; beam stress reference comparison은 N/A
## 승인된 Nonlinear Static 확장
- `*STATIC, NLGEOM=YES` 단일 step은 parse/map을 정확히 한 번 수행한 뒤 linear static과
분리된 full-Newton procedure로 dispatch한다. Nonlinear path는 별도 mutable state,
unsymmetric tangent solver, iteration log writer와 schema-v1 HDF5 writer를 사용한다.
- CLI는 정확히 하나의 `<model.inp>`만 받고 `<stem>_results.h5`와 `<stem>_log.txt`를 같은
lexical sibling directory에 유도한다. `--output`은 지원하지 않는다.
- Nonlinear HDF5 schema v1은 committed accepted frame만 기록한다. factor-zero는 metadata
baseline이며 accepted frame이 아니고, successful factor-one row는 unique
`load_factor=1.0` accepted frame이다.
- Factor-one `/global/equilibrium`은 global origin에서 current `X+u` arm과 spatial physical
moment를 사용한 applied-plus-constrained-reaction balance error다. Accepted free residual과
constrained-reaction resultant는 그 dataset의 대체 quantity가 아니다.
- `shellNL-meshfine`는 primary nonlinear case, `shellNL`은 companion, `shell`은 linear
regression control이다. `U1/U2/U3`는 blocking, `UR1/UR2/UR3`는 warning-only이며 local
`RF/RM`은 review-only (`RM3` 및 stress 제외)로 비교한다.
## 신규 기능의 제품 완료 정의 ## 신규 기능의 제품 완료 정의
새로운 element, load, constraint, material, analysis procedure 또는 output quantity는 다음 조건을 모두 만족할 때 FESA 제품 기능으로 취급한다. 새로운 element, load, constraint, material, analysis procedure 또는 output quantity는 다음 조건을 모두 만족할 때 FESA 제품 기능으로 취급한다.
@@ -102,7 +119,7 @@ Parser keyword, element kernel, solver backend 또는 output dataset 중 하나
| FESA-PRD-003 | FESA는 현재 step의 실행 view를 `AnalysisModel`로 구성해야 한다. | active elements, loads, boundary conditions, properties/materials가 Domain 복사 없이 참조 또는 id view로 연결된다. | analysis model unit test | | FESA-PRD-003 | FESA는 현재 step의 실행 view를 `AnalysisModel`로 구성해야 한다. | active elements, loads, boundary conditions, properties/materials가 Domain 복사 없이 참조 또는 id view로 연결된다. | analysis model unit test |
| FESA-PRD-004 | FESA는 equation numbering과 constraint/free mapping을 `DofManager`에 집중해야 한다. | Node/Element 내부에 equation id를 분산 저장하지 않는다. | code review, DofManager unit test | | FESA-PRD-004 | FESA는 equation numbering과 constraint/free mapping을 `DofManager`에 집중해야 한다. | Node/Element 내부에 equation id를 분산 저장하지 않는다. | code review, DofManager unit test |
| FESA-PRD-005 | FESA는 해석 중 변하는 물리량을 `AnalysisState`에 저장해야 한다. | V0 displacement, external/internal force, residual, constrained reaction, step/frame identity와 element recovery rows가 출력에 연결되고 velocity, acceleration, temperature, iteration history는 할당하지 않는다. | state unit test, integration test | | FESA-PRD-005 | FESA는 해석 중 변하는 물리량을 `AnalysisState`에 저장해야 한다. | V0 displacement, external/internal force, residual, constrained reaction, step/frame identity와 element recovery rows가 출력에 연결되고 velocity, acceleration, temperature, iteration history는 할당하지 않는다. | state unit test, integration test |
| FESA-PRD-006 | FESA는 solver 결과를 HDF5 authoritative output `results.h5`로 저장해야 한다. | V0 step/frame field results, metadata, diagnostics가 schema version과 함께 저장된다. | HDF5 schema test | | FESA-PRD-006 | FESA는 solver 결과를 derived HDF5 authoritative output `<stem>_results.h5`로 저장해야 한다. | V0 step/frame field results, metadata, diagnostics가 schema version과 함께 저장된다. | HDF5 schema test |
| FESA-PRD-007 | FESA는 기능이 지정한 Abaqus reference CSV quantity와 비교 가능한 deterministic source-row/component mapping을 제공해야 한다. | Required source IDs/components는 일대일 대응되고 missing/extra/duplicate/nonfinite row는 tolerance 전에 실패한다. Canonical naming, README, metadata, provenance 또는 CSV schema version은 요구하지 않는다. | reference comparison report | | FESA-PRD-007 | FESA는 기능이 지정한 Abaqus reference CSV quantity와 비교 가능한 deterministic source-row/component mapping을 제공해야 한다. | Required source IDs/components는 일대일 대응되고 missing/extra/duplicate/nonfinite row는 tolerance 전에 실패한다. Canonical naming, README, metadata, provenance 또는 CSV schema version은 요구하지 않는다. | reference comparison report |
| FESA-PRD-008 | FESA의 production C++ 변경은 테스트를 먼저 작성하고 실패를 확인한 뒤 구현해야 한다. | 관련 C++ test file, RED 실패와 후속 GREEN 성공 증거가 있고 Stop의 전체 MSVC build/test가 통과한다. | implementation report, Hook guardrail, CTest | | FESA-PRD-008 | FESA의 production C++ 변경은 테스트를 먼저 작성하고 실패를 확인한 뒤 구현해야 한다. | 관련 C++ test file, RED 실패와 후속 GREEN 성공 증거가 있고 Stop의 전체 MSVC build/test가 통과한다. | implementation report, Hook guardrail, CTest |
| FESA-PRD-009 | FESA는 외부 라이브러리 API를 solver core에 직접 노출하지 않아야 한다. | MKL, TBB, HDF5 의존은 adapter module에 제한된다. | architecture review, dependency review | | FESA-PRD-009 | FESA는 외부 라이브러리 API를 solver core에 직접 노출하지 않아야 한다. | MKL, TBB, HDF5 의존은 adapter module에 제한된다. | architecture review, dependency review |
@@ -139,7 +156,7 @@ Parser keyword, element kernel, solver backend 또는 output dataset 중 하나
required reference quantity의 최소 source-ID/component matching이 승인되어 있다. required reference quantity의 최소 source-ID/component matching이 승인되어 있다.
5. Tests fail before implementation: C++/integration/reference test를 제품 코드보다 먼저 작성하고 같은 Step 안에서 RED 실패와 후속 GREEN 성공을 확인한다. 5. Tests fail before implementation: C++/integration/reference test를 제품 코드보다 먼저 작성하고 같은 Step 안에서 RED 실패와 후속 GREEN 성공을 확인한다.
6. CMake/CTest pass: MSVC/x64/Debug 기준 configure, build, test가 통과한다. 6. CMake/CTest pass: MSVC/x64/Debug 기준 configure, build, test가 통과한다.
7. Reference comparison pass: 기능이 blocking으로 선언한 FESA `results.h5` quantity가 7. Reference comparison pass: 기능이 blocking으로 선언한 FESA `<stem>_results.h5` quantity가
선언된 Abaqus CSV와 source identity/component별로 대응되고 승인된 tolerance 안에 있다. 선언된 Abaqus CSV와 source identity/component별로 대응되고 승인된 tolerance 안에 있다.
8. Physics sanity pass: equilibrium, reaction consistency, displacement direction, symmetry, section-force consistency와 normalized residual이 검토되어 있다. 8. Physics sanity pass: equilibrium, reaction consistency, displacement direction, symmetry, section-force consistency와 normalized residual이 검토되어 있다.
9. Release readiness pass: acceptance traceability, known limitations, release notes draft가 준비되어 있다. 9. Release readiness pass: acceptance traceability, known limitations, release notes draft가 준비되어 있다.
@@ -151,7 +168,8 @@ Parser keyword, element kernel, solver backend 또는 output dataset 중 하나
- instance translation/rotation, nested assembly 및 dependent/independent mesh semantics - instance translation/rotation, nested assembly 및 dependent/independent mesh semantics
- `I12 != 0`, taper, offset, release, curved beam, warping - `I12 != 0`, taper, offset, release, curved beam, warping
- Abaqus `*DLOAD` 입력과 Domain distributed-load object - Abaqus `*DLOAD` 입력과 Domain distributed-load object
- 기하·재료비선형, dynamics, contact, thermal effects - 승인된 fixed-load-factor nonlinear-static 범위를 벗어난 기하·재료비선형, dynamics,
contact, thermal effects
- transverse shear stress와 torsional shear stress recovery - transverse shear stress와 torsional shear stress recovery
- beam stress에 대한 Abaqus reference comparison - beam stress에 대한 Abaqus reference comparison
- Abaqus, Nastran 또는 reference solver 직접 실행 자동화 - Abaqus, Nastran 또는 reference solver 직접 실행 자동화
@@ -0,0 +1,44 @@
# Nonlinear Static Newton-Raphson Build and Test Report
## Metadata
| key | value |
| --- | --- |
| feature_id | `nonlinear-static-newton-raphson` |
| owner_agent | `implementation-agent` |
| working directory | `C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson` |
| configuration | `windows-msvc-ninja-debug`, x64 Debug |
| compiler | MSVC `cl.exe` from VS 18, toolset `14.51.36231` |
| generator | Ninja |
| dependency configuration | `FESA_GTEST_SOURCE_DIR=C:/git/googletest`; MKL `2026.1`; TBB `2023.1`; HDF5 `2.1.1` |
| final classification | none; all commands passed |
## Fresh command log
| stage | command | exit | duration | output tail |
| --- | --- | ---: | ---: | --- |
| configure | `cmake --preset windows-msvc-ninja-debug` | 0 | 1.066 s | `Configuring done`; `Generating done`; build files written to `.harness/build-ninja-msvc-debug` |
| build | `cmake --build --preset windows-msvc-ninja-debug` | 0 | 0.113 s | `ninja: no work to do.` |
| discovery | `ctest --preset windows-msvc-ninja-debug --show-only=json-v1` | 0 | 0.219 s | 302 tests discovered |
| focused control/log | `ctest --preset windows-msvc-ninja-debug -R "^(NonlinearConvergence|NewtonIterationLog)\." --output-on-failure` | 0 | 0.471 s | 14/14 passed |
| focused procedure/writer | `ctest --preset windows-msvc-ninja-debug -R "^(NonlinearStaticProcedure|NonlinearHdf5ResultsWriter)\." --output-on-failure` | 0 | 2.524 s | 7/7 passed |
| nonlinear reference | `ctest --preset windows-msvc-ninja-debug -R "^NonlinearStaticReference\." --output-on-failure` | 0 | 905.404 s | 9/9 passed |
| extended reference | `ctest --preset windows-msvc-ninja-debug -R "^(NonlinearStaticReference|ReferenceTolerance|Mitc4Reference)\." --output-on-failure` | 0 | 930.617 s | 9/9 matched tests passed |
| full CTest | `ctest --preset windows-msvc-ninja-debug --output-on-failure` | 0 | 956.498 s | 302/302 passed; integration 16, unit 256, reference 30 |
The full CTest output reported no failed-test inventory. The build emitted no compiler/linker
output beyond `ninja: no work to do.`; the build tree audit found no new `warning C####` or
`: warning:` record. The only diagnostic setup issue was that standalone HDF5 inspection tools
need Intel `libmmd.dll` on `PATH`; this did not affect the staged test executables, CMake build, or
CTest and is not a product failure.
## Results and handoff
The selected `.harness/config.json` preset was used throughout. All commands were run from the
repository root in an x64 VsDevCmd environment. The final status is
`pass-for-physics-evaluation`; no Harness Python command was required because this Step did not
change Python, hooks, or agent configuration.
This Step changed documentation and its own phase status only. It did not modify C++ production,
tests, CMake, Harness configuration, tolerance, reference artifacts, or output data. The immutable
reference artifact audit before and after comparison was identical; see `reference-comparison.md`.
@@ -0,0 +1,84 @@
# Nonlinear Static Newton-Raphson Implementation Report
## Metadata
| key | value |
| --- | --- |
| feature_id | `nonlinear-static-newton-raphson` |
| phase step | `12: execution-closure-and-evidence-docs` |
| owner_agent | `implementation-agent` |
| evidence date | `2026-08-28` |
| repository HEAD before this Step's documentation edits | `d275e844f27107cfab52309025e259f2156345d2` |
| classification | `pass-for-physics-evaluation` |
## Freshness audit (RED)
Before any build or reference command, `NSNR-EVID-001..007` failed as expected.
`implementation-report.md`, `build-test.md`, and `reference-comparison.md` were absent. The
global documents still advertised `--output`, only the prior linear output path, and did not state
the approved nonlinear current-arm/reaction and fine/coarse reference dispositions. This was an
evidence freshness failure, not a solver failure. No report was created until the fresh commands
below completed.
## Approved inputs and preserved Step history
The consumed upstream document SHA-256 values were: requirements
`89C1AB5F1BEDB7C5F6AD0726ED62F0982181EA8746EDE4661183FD3D18A2408E`, research
`4F63D23E03D1A68E5F8563B678FDD6F761F9558165778EF0433133EFAD303570`, formulation
`878028F7B8EC1B91DA9BF00AF78825F50EB0B71046E840A0EEA595AFFD5E14B9`, numerical review
`C00994EF4BB23A237547459E157EE5BDA96B28CAF08F712CD31A8E0ABBF62D2C`, reference model
`B2E6845AB59A32F78261B7A47506C27F7BF4B61401B34BC5DE3DAD4F03D6ADDA`, I/O
`ED23274F4F15F7D1DFF886FA8158961362C75960990271D24A5FD010A8D51FD9`, implementation plan
`CA3EF7D2E95AA1F15757CD138CEF67E06E51195F59FB8DBE676E5772CC1D6C2C`, and corrections
`4DC996E3D4CA2D515D19E5D244C3A112AF0C9429335698E03089B77B5E79346A`.
Steps 0--10 remain unchanged: derived output/log lease; NLGEOM Domain controls; finite rotations;
nonlinear MITC4 kinematics/recovery; residual/tangent; load/BC/convergence gates; tangent solver;
iteration log; transactional state; nonlinear HDF5 v1; and prepared parse-once dispatch/finalization.
## Step 11 RED to GREEN evidence
The preserved Step 11 transcript SHA-256 is
`292FE06B7F97B1CBE267A36D875342B300E82486B76BDCBCD31EE2192A87ACE3`.
Its RED evidence covered: initial-arm/raw rotation balance (`NSNR-PROC-019`), obsolete
`location=global-origin` (`NSNR-HDF5-014`), missing fine inventory (`NSNR-REF-020`), blocking
local RF/RM (`NSNR-REF-021`), obsolete `1e-10` balance rejection (`NSNR-REF-022`), pre-tolerance
row rejection (`NSNR-REF-023`), inclusive `1e-8` boundary (`NSNR-REF-024`), and exact-zero scale
(`NSNR-REF-025`).
The minimal GREEN slice was limited to the nonlinear procedure current-arm/spatial balance
projection, HDF5 location metadata/self-check, and test-private reference comparator/case
inventory. The relevant production files were `nonlinear_static_procedure.cpp`,
`nonlinear_hdf5_results_writer.cpp`, and `hdf5_self_check.cpp`; test changes remained in the
procedure, writer, convergence/log, and reference-comparator tests. This Step made no C++, test,
CMake, Harness, tolerance, or reference-artifact change.
Fresh VERIFY reran the preserved controls. The focused `NonlinearStaticProcedure` and
`NonlinearHdf5ResultsWriter` command passed 7/7, including
`NonzeroPrescribedMotionWritesCurrentArmSpatialAppliedPlusReactionBalance` and
`WritesSchemaV1GlobalBalanceErrorLocation`. The reference command passed the inclusive and
exact-zero global gate tests. This closes `AUDIT-001`: the tests exercise nonzero prescribed
translation and rotation, `x=X+u`, component-mask-before-conversion, independently converted
applied and constrained rotation covectors, and `location=global-balance-error`.
## Requirement and test traceability
| evidence | fresh result |
| --- | --- |
| `NSNR-CTRL-018..021` convergence controls | 6/6 `NonlinearConvergence.*` passed |
| `NSNR-LOG-012` iteration-log contract | 8/8 `NewtonIterationLog.*` passed |
| `NSNR-PROC-019` current-arm balance | passed in focused 7-test procedure/writer run |
| `NSNR-HDF5-014` v1 equilibrium location | passed in focused 7-test procedure/writer run |
| `NSNR-REF-020..025` portfolio, dispositions, prechecks, 1e-8 and zero-scale | 9/9 `NonlinearStaticReference.*` passed twice and in full CTest |
| blocking external/internal final gate | all 302 CTest tests passed; detailed metrics are in `reference-comparison.md` |
## Handoff and open issues
Implementation-owned classification is `pass-for-physics-evaluation`. The only numerical
differences retained are six deterministic local RF/RM review-only findings; they do not alter
the blocking verdict. No warning-only UR family failed. This report does not claim physics or
release readiness, and numerical agreement does not assert Abaqus S4 internal formulation
equivalence.
No Step 12 production behavior changed. Reference inputs and CSV files were read-only and their
pre/post inventory, byte sizes, timestamps, and SHA-256 values were identical.
@@ -0,0 +1,108 @@
# Nonlinear Static Newton-Raphson Reference Comparison
## Verdict
`blocking-pass-with-review-only-findings`. FESA HDF5 is the authoritative solver output. The
Abaqus CSV files are read-only external comparison evidence; the observed agreement does not imply
Abaqus S4 internal formulation, integration, stabilization, or recovery equivalence.
The literal execution order was `ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT`.
The `COMPARE` commands were
`ctest --preset windows-msvc-ninja-debug -R "^NonlinearStaticReference\." --output-on-failure`
(exit 0, 905.404 s, 9/9 passed), followed by
`ctest --preset windows-msvc-ninja-debug -R "^(NonlinearStaticReference|ReferenceTolerance|Mitc4Reference)\." --output-on-failure`
(exit 0, 930.617 s, 9/9 matched tests passed). The fresh full CTest run then passed 302/302;
its command and output tail are recorded in `build-test.md`.
## Artifact check
Every input, displacement CSV, reaction CSV, and stress-inventory CSV was readable, finite where
required, unique by declared source key, and identical before and after all copied-input executions.
| case / role | exact path | bytes | pre/post UTC mtime | SHA-256 |
| --- | --- | ---: | --- | --- |
| fine primary input | `reference/shellNL-meshfine/shellNL-meshfine.inp` | 56,516 | `2026-08-25T13:53:49.1919675Z` | `40DF1CE77311C8D799564A21A60F3BDEBB8148D52CAE22B7292FDFAD32018220` |
| fine U | `reference/shellNL-meshfine/shellNL-meshfine displacements.csv` | 111,184 | `2026-08-25T14:06:00.1262830Z` | `740819FF8AED0E279961581F7CDBFA12784CFBA3A488C35A652E80103F64433F` |
| fine local reaction | `reference/shellNL-meshfine/shellNL-meshfine reactions.csv` | 108,951 | `2026-08-25T14:05:06.2950127Z` | `AEB01C98C596792B0E5F2B86A81945CAB0BEB0C6969CFC6738C6F81DF1F94363` |
| fine stress inventory | `reference/shellNL-meshfine/shellNL-meshfine stresses.csv` | 1,036,869 | `2026-08-25T14:04:24.2027682Z` | `6D6213AB5DB9D6B1F5FBD641367D08BACC805967B6C5A95BCE0E1A5395377782` |
| coarse companion input | `reference/shellNL/shellNL.inp` | 4,778 | `2026-08-23T16:36:23.9302881Z` | `4BF3ECB0F7F1E8462C573E993DBC97AC5D920C91CF6F23AD4C6891D77FFBADA2` |
| coarse U | `reference/shellNL/shellNL displacements.csv` | 7,542 | `2026-08-23T16:36:23.9282815Z` | `4E0F99CA9372B1ADF7FAF102F43BC0B887DC743FDEDA378E4342D2CF8E0C0786` |
| coarse local reaction | `reference/shellNL/shellNL reactions.csv` | 7,443 | `2026-08-23T16:36:23.9292877Z` | `001CB1541A9E94424E5E650509D46BC8724970DF4DE47184D9DB09C7938AB069` |
| coarse stress inventory | `reference/shellNL/shellNL stresses.csv` | 54,720 | `2026-08-23T16:36:23.9302881Z` | `5500E5114B1C44887528E30CEC054A1EB0F68BE3F4B8CE81FA59FC74A881483F` |
| linear control input | `reference/shell/shell.inp` | 4,770 | `2026-08-23T16:36:23.9272805Z` | `4005851E1AB22FD3A16AC17A8D5DA3E051233F69F37419079F3553AD134ECFCF` |
| linear U | `reference/shell/shell displacements.csv` | 5,592 | `2026-08-23T16:36:23.9262810Z` | `C81D94E0B4A849F87AA0F79C83A79B94D5661AC79E44ED826919AB432C87746B` |
| linear reaction inventory | `reference/shell/shell reactions.csv` | 5,524 | `2026-08-23T16:36:23.9262810Z` | `0E34EEC27E700C3C0C744C1DAFD8A3B95EFEF34B8616FE96665876586FE82D41` |
| linear stress inventory | `reference/shell/shell stresses.csv` | 43,502 | `2026-08-23T16:36:23.9272805Z` | `2B75A5B0DEB045A283C9BB7E9B1153B79F7537FF487214BF4A23316B59B660A7` |
Fine and coarse required nonlinear CSV rows had exact `Frame=Increment 10: Step Time = 1.000`.
The HDF5 `/steps/Step-1/accepted_frames` table had exactly one factor-one row: frame 9, increment
10, load factor 1.0, two Newton iterations. Reference copies and generated artifacts were confined
to these build-local directories:
| case | copied input | generated results / log |
| --- | --- | --- |
| fine | `.harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shellNL-meshfine/shellnl-meshfine-s4-final-72767400538200-0/shellNL-meshfine.inp` | `.harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shellNL-meshfine/shellnl-meshfine-s4-final-72767400538200-0/shellNL-meshfine_results.h5`, SHA-256 `2E9817E173D73FD91C2D34864B69A1EC37483CB25951FB7CCE85895A6C87D2C6`; `.harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shellNL-meshfine/shellnl-meshfine-s4-final-72767400538200-0/shellNL-meshfine_log.txt`, SHA-256 `1DB6FE4AAA2F1443ACC7F9B3F919CC8DD873C90392121DAB6509F1693435DA27` |
| coarse | `.harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shellNL/shellnl-s4-final-73175241456500-1/shellNL.inp` | `.harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shellNL/shellnl-s4-final-73175241456500-1/shellNL_results.h5`, SHA-256 `130E2E7B73B022F216A7A34C88D58114A62595ADD556A0D202B8A7FAC7391F39`; `.harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shellNL/shellnl-s4-final-73175241456500-1/shellNL_log.txt`, SHA-256 `3D5C4F1B20384655F9012ADE842B99E3B06B3799FC9AB16DD6FD141E18B77906` |
| linear | `.harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shell/shell-s4-linear-limit-72742739390700-2/shell.inp` | `.harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shell/shell-s4-linear-limit-72742739390700-2/shell_results.h5`, SHA-256 `8AEE34D5BC80382D7E6DE85C51F0F8BCBF451CD5F5C7B8DDA6C585EB22B31763`; `.harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shell/shell-s4-linear-limit-72742739390700-2/shell_log.txt`, zero bytes, SHA-256 `E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855` |
## Compare and classify
Rows were matched by `(case_id, accepted_state, canonical_instance_name, source_node_label,
component)`, never CSV order. Required HDF5 projections were factor-one
`/steps/Step-1/frames/9/nodal/displacement`, `generalized_internal_force`,
`generalized_external_force`, `generalized_residual`, `reaction`, `/model/nodal_constraint_mask`,
and `/global/equilibrium`; the linear control uses `/steps/Step-1/frames/0/nodal/displacement`.
All required source keys, components, uniqueness and finite checks passed before tolerance.
External families use `docs/TOLERANCE.md`: reference-only scale, near-zero band `0.01*S`, row
relative limit `0.05`, and family RMS limit `0.01`. `rows passed` is the deterministic per-row
decision count; U is blocking and UR is warning-only.
| family | disposition | rows passed | scale | max abs | max relative | relative RMS | result |
| --- | --- | ---: | ---: | ---: | ---: | ---: | --- |
| fine.translation | blocking | 2187/2187 | 2.57957054e-05 | 1.6193812501e-07 | 6.27771648e-03 | 2.27230258e-04 | pass |
| fine.rotation | warning-only | 2187/2187 | 6.58704994e-06 | 3.0109969916e-08 | 3.54510604e-02 | 4.68253850e-04 | pass |
| coarse.translation | blocking | 147/147 | 2.37408203e-05 | 1.9037855439e-07 | 8.57111694e-03 | 1.03327572e-03 | pass |
| coarse.rotation | warning-only | 147/147 | 7.60725743e-06 | 6.8828551252e-08 | 4.69071871e-02 | 2.97713732e-03 | pass |
| linear.translation | blocking | 147/147 | 2.37408203e-05 | 1.9037853492e-07 | 8.57111604e-03 | 1.03327567e-03 | pass |
| linear.rotation | warning-only | 147/147 | 7.60725743e-06 | 6.8828549627e-08 | 4.69071860e-02 | 2.97713730e-03 | pass |
Worst absolute rows were fine U `PART-1-1/node 2/U3`, fine UR
`PART-1-1/node 442/UR1`, coarse U `PART-1-1/node 2/U3`, coarse UR
`PART-1-1/node 37/UR1`, linear U `PART-1-1/node 2/U3`, and linear UR
`PART-1-1/node 44/UR1`. No warning-only family failed.
The eight blocking internal families are independent of Abaqus CSV tolerance.
| family | rows | numerator | scale | metric | gate | result |
| --- | ---: | ---: | ---: | ---: | --- | --- |
| fine.global_force_balance | 3 | 2.6775524023e-07 | 1.2773012379e+05 | 2.09625758e-12 | `<=1e-8` | pass |
| fine.global_moment_balance | 3 | 1.3258637157e-04 | 4.8292847478e+05 | 2.74546602e-10 | `<=1e-8` | pass |
| fine.accepted_free_force_residual | 1875 | 3.8659904671e-03 | 1.0000000000e+05 | 3.86599047e-08 | `<=1e-2` | pass |
| fine.accepted_free_moment_residual | 1875 | 1.3760745787e-06 | 0 | exact-zero typed `<=1e-3` | exact-zero branch | pass |
| coarse.global_force_balance | 3 | 8.2512269735e-07 | 1.0000000439e+05 | 8.25122661e-12 | `<=1e-8` | pass |
| coarse.global_moment_balance | 3 | 4.1788609354e-05 | 2.9558678960e+05 | 1.41375091e-10 | `<=1e-8` | pass |
| coarse.accepted_free_force_residual | 75 | 3.1462885132e-02 | 1.0000000000e+05 | 3.14628851e-07 | `<=1e-2` | pass |
| coarse.accepted_free_moment_residual | 75 | 3.3292052422e-06 | 0 | exact-zero typed `<=1e-3` | exact-zero branch | pass |
The constrained-reaction resultant remains a distinct review summary: fine force
`[1.2306822228e-12, -3.5943123478e-12, 1.0000000000e+05]`, moment
`[2.7057467378e-11, -5.6934368331e-10, -1.3258637157e-04]`; coarse force
`[7.9591888635e-12, 7.2906680693e-12, 1.0000000000e+05]`, moment
`[-1.7826096155e-10, -2.5829649530e-10, -4.1788609352e-05]`.
Local reaction RF/RM source-key/inventory/finite prechecks passed, but the following direct
row/RMS findings remain review-only and therefore do not change the blocking classification.
| review family | rows passed | relative RMS | worst absolute row | finding |
| --- | ---: | ---: | --- | --- |
| coarse in-plane RF | 4/48 | 1.1437709953e-01 | node 3/RF1, 5.3914239451e-01 | review-only failure |
| coarse RF3 | 4/24 | 4.8448360241e-02 | node 31/RF3, 7.1995422354e+02 | review-only failure |
| coarse physical RM1/RM2 | 32/48 | 2.7464126167e-02 | node 22/RM1, 1.0484921048e+03 | review-only failure |
| fine in-plane RF | 12/208 | 1.1971372918e-01 | node 1/RF2, 1.5298653299e-01 | review-only failure |
| fine RF3 | 92/104 | 5.3476362434e-03 | node 9/RF3, 4.6176964624e+01 | review-only row failure |
| fine physical RM1/RM2 | 112/208 | 3.3719303859e-03 | node 52/RM2, 3.1549617088e+01 | review-only row failure |
`RM3` and stress were not numerically compared. Artifact inventory, byte size, timestamp, and
SHA-256 equality before/after all runs prove that no reference artifact changed.