feat(nonlinear-static-newton-raphson): step 11 - equilibrium-projection-and-reference-gate

This commit is contained in:
KOKO\Mimi
2026-08-28 09:22:33 +09:00
parent 65b56b1755
commit 6dbf1b2bcf
30 changed files with 13122 additions and 728 deletions
@@ -2,9 +2,9 @@
> For Harness workers: this plan is an approved Stage 6 planning artifact. It authorizes planning files only. It does not authorize `scripts/execute.py`, C++ implementation, build, CTest, reference solver execution, or evidence-document creation.
**Goal:** `nonlinear-static-newton-raphson` 기능을 C++17/MSVC/CMake/CTest TDD 순서로 구현하고, 승인된 nonlinear MITC4 Newton-Raphson 절차, HDF5 schema v1, log lifecycle, shellNL/shell reference comparison을 검증한다.
**Goal:** `nonlinear-static-newton-raphson` 기능을 C++17/MSVC/CMake/CTest TDD 순서로 완결하고, current-position/spatial-moment global equilibrium, accepted free residual, fine-primary/coarse-companion reference gate와 HDF5 schema v1을 검증한다.
**Architecture:** App layer가 argv 검증, lexical output path derivation, move-only `OutputWriteLease`, log open/close와 final HDF5 writer 호출 순서를 소유한다. 입력 parse/map은 정확히 한 번 수행하고, `StepDefinition::ProcedureKind()`로 linear와 nonlinear procedure executor를 분리한다. `LinearStaticAnalysis`의 기존 private lifecycle에는 nonlinear 조건문을 넣지 않고, 기존 linear numerical/HDF5 의미는 repository-wide output name/log lifecycle 변경만 제외하고 보존한다.
**Architecture:** App layer가 argv 검증, lexical output path derivation, move-only `OutputWriteLease`, log open/close와 final HDF5 writer 호출 순서를 소유한다. 입력 parse/map은 정확히 한 번 수행하고, `StepDefinition::ProcedureKind()`로 linear와 nonlinear procedure executor를 분리한다. Nonlinear accepted state는 current arm과 spatial physical moment로 applied-plus-reaction balance error를 만들고 기존 `/global/equilibrium`에 저장하며, comparator는 existing schema-v1 nodal datasets에서 constrained reaction resultant와 accepted free residual을 별도로 재구성한다. `LinearStaticAnalysis`의 기존 private lifecycle에는 nonlinear 조건문을 넣지 않는다.
**Tech Stack:** C++17, MSVC on Windows, CMake, CTest, GoogleTest, Intel oneAPI MKL/TBB, HDF5, Abaqus `.inp` approved subset, Python 3 Harness scripts.
@@ -15,10 +15,10 @@
| key | value |
| --- | --- |
| feature_id | `nonlinear-static-newton-raphson` |
| status | `approved-planning-files-materialized` |
| status | `ready-for-implementation` |
| owner_agent | `implementation-planning-agent` |
| date | `2026-08-24` |
| approval | User approved the final 13-Step draft on `2026-08-24`; Coordinator recorded `DECISION-036`. |
| date | `2026-08-28` |
| approval | User approved the original 13-Step draft on `2026-08-24`, USER-DECISION-003 revision, and delegated the Coordinator-audited REAPPROVAL-012 Stage 6 reapproval/materialization with both normalized factor-one global force and moment balance gates fixed at `<=1e-8` on `2026-08-28`. |
| source_requirement | `docs/nonlinear-static-newton-raphson/requirements.md` |
| source_research | `docs/nonlinear-static-newton-raphson/research.md` |
| source_formulation | `docs/nonlinear-static-newton-raphson/formulation.md` |
@@ -30,21 +30,52 @@
| document | SHA-256 |
| --- | --- |
| `requirements.md` | `910E351F3F90FFA42F07D15206B55E62C05EAE821E250424430148337506EBF2` |
| `research.md` | `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE` |
| `formulation.md` | `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0` |
| `numerical-review.md` | `9517E11804C45A6F3822D18821D52EA493AE20353C8FFAD61E960F4315977D01` |
| `reference-model.md` | `52D10B1D0C0500B295C5E48BCB3618B309D9696371B8070D4E3DCEE8D3D74CD3` |
| `io.md` | `DBB959A68F17D67CA2B42569610B9C1B595A8BFB5502BC194B7E62B656031B28` |
| `requirements.md` | `89C1AB5F1BEDB7C5F6AD0726ED62F0982181EA8746EDE4661183FD3D18A2408E` |
| `research.md` raw | `4F63D23E03D1A68E5F8563B678FDD6F761F9558165778EF0433133EFAD303570` |
| `formulation.md` | `878028F7B8EC1B91DA9BF00AF78825F50EB0B71046E840A0EEA595AFFD5E14B9` |
| `numerical-review.md` | `C00994EF4BB23A237547459E157EE5BDA96B28CAF08F712CD31A8E0ABBF62D2C` |
| `reference-model.md` | `B2E6845AB59A32F78261B7A47506C27F7BF4B61401B34BC5DE3DAD4F03D6ADDA` |
| `io.md` raw | `ED23274F4F15F7D1DFF886FA8158961362C75960990271D24A5FD010A8D51FD9` |
| `io.md` LF-normalized | `53AFBB1DF27FBD9CE6C2E23EE34480882241A859D3FC1993E82DB61ACC6637EB` |
## Readiness Check
- Upstream document status: Stage 1 requirements approved, Stage 2 research passed, Stage 3 formulation ready for numerical review and approved downstream, Stage 4 numerical/reference review passed for I/O definition, Stage 5 I/O definition approved.
- Upstream document status: Stage 1 requirements, Stage 4 numerical/reference review and Stage 5 I/O definition are complete; REAPPROVAL-012 fixes both factor-one normalized global force and moment balance gates at `<=1e-8`. Stage 3 formulation §§11.4/13.4 already supplies the accepted residual/reaction/global-resultant meaning.
- Missing decisions: none.
- Missing required comparison files: none for declared blocking/reference families.
- Missing required comparison files: none. Fine primary, coarse companion and linear-control exact inputs/CSVs are present; stress files are optional inventory only.
- Planning can proceed: yes.
- REWORK-008의 local reaction blocking conflict는 USER-DECISION-004 option 1로 해소되었다. Local nodal RF/RM은 review-only이고 factor-one global force/moment balance와 accepted free residual이 blocking이다. `AUDIT-001` current-arm/spatial-moment implementation seam은 Step 11에서 RED-first로 닫는다.
- Step 11에는 보존해야 할 uncommitted `NSNR-CTRL-018..021`, `NSNR-LOG-012`, `NSNR-PROC-019`,
`NSNR-HDF5-014`, `NSNR-REF-001..023`, residual-selector GREEN과 comparator/CMake 작업이 있다.
새 계획은 이를 reset/replay하지 않는다.
- `implementation-report.md`, `build-test.md`, canonical `reference-comparison.md`는 아직 없고 Step 12가 actual evidence에서만 생성한다.
- `CMakePresets.json` tracks the approved `windows-msvc-ninja-debug` contract. The ignored `.harness/config.json` selects the matching configure/build/test presets and `.harness/build-ninja-msvc-debug` binary directory.
## Implementation Scope
Included behavior:
- Existing schema-v1 `/global/equilibrium [6]`에 global origin `[0,0,0]`, accepted current
position `X+u`, independently spatial-converted applied/reaction moments를 사용하는
applied-plus-reaction balance error를 기록한다.
- Existing schema-v1 nodal datasets와 exact constraint mask에서 accepted free residual,
constrained reaction resultant와 global balance error를 서로 다른 evidence로 재구성한다.
- Fine nonlinear primary, coarse nonlinear companion와 linear control을 exact read-only artifact로
비교한다. U는 blocking, UR은 warning-only, local RF/RM은 review-only, RM3/stress는 excluded다.
- Internal global force/moment는 dimension-separated normalized `1e-8`, accepted free residual은
NSNR-069으로 blocking 검증하고 external families만 `docs/TOLERANCE.md`를 사용한다.
Excluded behavior and non-goals:
- New HDF5 dataset/schema version, public header/API, tolerance, reference artifact 또는 solver scope
추가가 아니다.
- `fesa.env`, runtime configuration, CLI option 또는 product solver acceptance behavior를 추가하지
않는다. `1e-8`은 comparator-owned internal verification gate의 fixed value다.
- Local nodal reaction을 global sum으로 대체하거나 Abaqus S4와 FESA MITC4 내부 정식화
동등성을 주장하지 않는다.
- Steps 0–10 구현/history replay, selector RED 재현, Abaqus/reference solver 실행, Physics/Release
판정은 포함하지 않는다.
## Global Constraints
- Use `RED -> observed failure -> minimal GREEN -> focused VERIFY -> full CTest` in every implementation Step.
@@ -54,8 +85,12 @@
- Do not create `implementation-report.md`, `build-test.md`, or `reference-comparison.md` before Step 12 produces actual command evidence.
- Do not run Harness from this planning approval. `scripts/execute.py` requires a separate explicit request.
- Implementation and Harness execution remain unauthorized by this materialized plan until the user separately requests Executor execution.
- Preserve source label/instance identity, deterministic row order, deterministic diagnostics, finite checks, and docs/TOLERANCE.md exactly.
- Preserve `U1/U2/U3` blocking and `UR1/UR2/UR3` warning-only. For shellNL, preserve constrained `RF1/RF2`, `RF3`, physical spatial `RM1/RM2` blocking, and exclude `RM3` plus stress from numeric comparison.
- Preserve source label/instance identity, deterministic row order, deterministic diagnostics, finite checks, and `docs/TOLERANCE.md` exactly.
- Residual force/moment channel은 finite-first 검사 뒤 matching external scale 자체로 분기한다. Exact zero이면 denominator output exact `0`과 typed absolute `1.0e-3`; nonzero이면 retained `max(internal,external)` denominator와 dimensionless relative `1.0e-2`만 사용한다. Tolerance band, zero clamp, `max(1,...)`, absolute/relative OR는 금지한다.
- Correction gates, four-channel logical AND, Full Newton, fixed load-factor stepping, maximum 100 iterations와 `nsnr-log-v1` 39-field label/order/TAB schema는 변경하지 않는다.
- Preserve `U1/U2/U3` blocking and `UR1/UR2/UR3` warning-only. Fine/coarse constrained `RF1/RF2`, `RF3`, physical spatial `RM1/RM2` remain review-only with complete deterministic precheck/error reporting; exclude `RM3` and stress from numeric comparison.
- Preserve schema version 1 and all existing HDF5 paths/shapes/components. Do not add a summary dataset or public header.
- Keep internal global balance/free-residual gates separate from external `docs/TOLERANCE.md`; do not add a floor, `max(1,S)`, zero clamp, averaging or collapse.
- Launch every Harness process from VsDevCmd with `-arch=x64 -host_arch=x64` and inherit `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR`. The tracked preset selects Ninja and MSVC Debug without hard-coding machine-local dependency paths.
## Repository Seam Map
@@ -68,11 +103,12 @@
| Domain | `StaticStepDefinition` in `include/fesa/model/model_types.h`; `StepDefinition` in `include/fesa/model/domain.h`. | Store procedure identity, `NLGEOM`, raw four `*STATIC` values and provenance. Do not store derived factor sequence or PRESELECT state. |
| Parser mapping | `src/fesa/io/abaqus/domain_mapping_context.cpp`, `step_definition_mapper.cpp`. | Accept nonlinear static subset, warning no-op PRESELECT, reject unsupported procedure fail-closed. |
| MITC4 | `include/fesa/elements/mitc4_shell.h`, `src/fesa/elements/mitc4_shell.cpp` are linear small-rotation. | Add separate nonlinear MITC4 files with `Create(...)` from four nodes, four initial frames, `ShellSection`, and `LinearElasticMaterial`; element kernels compute internal residual/tangent/recovery only. |
| Loads/control | Current loads are assembled for linear static RHS. | Step 5 owns global-once fixed CLOAD external vector `f_ext` and exact external load tangent `K_ext`, including projected moment `J_l`/map-Hessian terms, with no incident-element multiplication. Step 5 also owns exact convergence constants: relative `1.0e-2`, zero-scale `1.0e-3` with channel-specific units. Step 10 forms `r = f_int - f_ext` and `K_T = K_int - K_ext`. |
| Loads/control | Preserved partial Step 11 work already changes residual selection to matching external scale exact-zero/nonzero and adds `NSNR-CTRL-018..021`/`NSNR-LOG-012`. | Preserve without replay/redesign; run focused regression before the new equilibrium/reference gate. |
| Equilibrium projection | `src/fesa/analysis/nonlinear_static_procedure.cpp` currently sums raw full residual with initial Domain coordinates and raw rotational covectors. | Apply the constraint mask before rotational conversion; use accepted `X+u`; convert applied and constrained-reaction rotational covectors independently with `InverseTransposeLeftJacobianSO3(phi)`; store applied-plus-reaction balance only. |
| Source identity | `SourceEntityId { instance_name, source_label, source_label_text }` and `EntityIndex` exist in `include/fesa/core/source_identity.h`; nodes are stored in stable Domain order. | Step 8 baseline uses both `EntityIndex` and full `SourceEntityId`, requires one node baseline per Domain node in stable internal order, rejects label-only or mismatched identities, and preserves identity into HDF5/reference mapping. |
| Solver | `MklPardisoSolver` uses SPD `mtype=2` and upper-triangle copy. | Preserve unchanged; add `TangentSolver` and MKL unsymmetric full CSR `mtype=11`. |
| Results writer | `ResultsWriter` is the backend-neutral linear writer; `Hdf5ResultsWriter` writes schema-v0 single-frame linear output. | Add `NonlinearResultsWriter` backend-neutral boundary and `NonlinearHdf5ResultsWriter` schema-v1 implementation with delayed finalization after log close. |
| Tests | `fesa_unit_tests`, `fesa_integration_tests`, `fesa_reference_tests` use executable-wide labels. | Add focused test sources and use `ctest -R` regex; do not globally relabel existing tests as nonlinear. |
| Results writer | `NonlinearHdf5ResultsWriter` already writes schema-v1 `/global/equilibrium`, but its location attribute is `global-origin`. | Preserve dataset path/shape/components and change exact location identity to `global-balance-error`; no new dataset or public writer boundary. |
| Tests | Existing integration/HDF5 tests and partial nonlinear comparator are registered in existing executables. | Add RED to existing sources; preserve the current CMake registration and use focused `ctest -R` regex without a new target or global relabel. |
## Work Breakdown
@@ -89,7 +125,7 @@
| 8 | `nonlinear-state-commit-rollback` | 3-7 | Factor-zero baseline construction with `EntityIndex` plus `SourceEntityId`, trial/committed nonlinear state, accepted frames, rollback/preservation. |
| 9 | `nonlinear-hdf5-schema-v1-writer` | 8 | Nonlinear HDF5 schema v1 writer using `std::vector<Diagnostic>`. |
| 10 | `prepared-analysis-flow-and-full-procedure` | 0-9 | Single parse/map prepared analysis flow, separate linear/nonlinear executors, delayed writer finalization. |
| 11 | `reference-comparison-gate` | 0-10 | shellNL nonlinear and shell linear real-input reference comparison. |
| 11 | `equilibrium-projection-and-reference-gate` | 0-10 | Preserve partial selector/comparator work; add new current-arm/spatial-moment, HDF5 location, fine/coarse disposition/internal-gate RED tests; make minimal procedure/writer/comparator GREEN; run focused/full verification. |
| 12 | `execution-closure-and-evidence-docs` | 0-11 | Fresh MSVC evidence, deterministic repeat/reference audit, actual-output evidence docs. |
## TDD Test Plan
@@ -101,20 +137,21 @@
| `NSNR-ROT-*` | finite rotation invariants, `J_l`, branch margin, director update. | 2 |
| `NSNR-ELEM-KIN-*` | nonlinear MITC4 creation inputs, TL shell kinematics, fixed-size four-GP recovery rows, degeneracy fail-closed, linear limit. | 3 |
| `NSNR-ELEM-TAN-*` | same-trial internal residual/tangent, directional derivative, objectivity, symmetry only for internal/no-external cases. | 4 |
| `NSNR-CTRL-*` | load factor path, absolute boundary path, global-once fixed loads and load tangent, moment admissibility, typed four convergence gates with `relative`/`zero-scale` branches and non-injectable exact thresholds/units. | 5 |
| `NSNR-CTRL-*` | Existing coverage plus preserved partial `NSNR-CTRL-018..021`: matching-external exact-zero absolute boundaries, retained nonzero relative boundaries, nonfinite-first/no-clamp selection, unchanged correction gates/four-channel AND. Do not replay/fabricate selector RED. | 5,11 |
| `NSNR-SOLVER-*` | nonsymmetric tangent solve, 0x0, nonfinite/failure translation, SPD solver unchanged. | 6 |
| `NSNR-LOG-*` | serializer-owned 39-field UTF-8/LF/TAB Newton log from explicit stage/failure/channel records and fail-closed write/flush/close. | 7 |
| `NSNR-LOG-*` | Existing serializer coverage plus preserved partial `NSNR-LOG-012`: evaluator-produced zero/nonzero-external decisions retain exact denominator, branch, threshold, unit and 39 fields. | 7,11 |
| `NSNR-STATE-*` | factor-zero baseline creation with stable node order and full source identity, trial/committed separation, accepted frame order, full schema-v1 state inventory, finite atomic commit, rollback. | 8 |
| `NSNR-HDF5-*` | `NonlinearResultsWriter` boundary, schema v1 metadata/model/frame datasets, factor-zero metadata, atomic finalization. | 9 |
| `NSNR-PROC-*` | full procedure orchestration, single parse/map, log close before HDF5, deterministic repeat. | 10 |
| `NSNR-REF-*` | original artifact snapshot, temp input copy run, HDF5-to-original-CSV identity mapping, tolerance, classification, report data. | 11 |
| `NSNR-EVID-*` | fresh evidence docs and diff/hash/warning audits from actual command outputs. | 12 |
| `NSNR-HDF5-*` | Existing schema-v1 coverage plus `NSNR-HDF5-014` exact `/global/equilibrium` `location=global-balance-error`; path/shape/components/version unchanged. | 9,11 |
| `NSNR-PROC-*` | Existing procedure coverage plus collision-resolved `NSNR-PROC-019` exact test `NonlinearStaticProcedure.NonzeroPrescribedMotionWritesCurrentArmSpatialAppliedPlusReactionBalance`. Approved draft label `NSNR-PROC-011` is not reused because completed Step 10 already owns it. | 10,11 |
| `NSNR-REF-*` | Preserve `NSNR-REF-001..023`, including the current-case old-gate RED in `022`; add `024` inclusive `1e-8` force/moment boundary plus approved between-threshold regression and `025` exact-zero-scale force/moment regression before changing the comparator gate. | 11 |
| `NSNR-EVID-*` | `001..007` freshness, disposition, fine/internal inventory, AUDIT-001, command/provenance and actual-output report checks. | 12 |
## CMake And CTest Plan
- Add C++ sources to `src/fesa/CMakeLists.txt` under existing `fesa_solver`.
- Add unit tests to `fesa_unit_tests`, integration tests to `fesa_integration_tests`, reference tests to `fesa_reference_tests`.
- Preserve current executable-wide labels. Use focused regex such as `ctest --preset windows-msvc-ninja-debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure`.
- Step 11 adds no target or `add_test`: procedure/HDF5 tests use existing executables and current partial `tests/CMakeLists.txt` comparator registration is preserved without unrelated edits.
- If scoped per-test labels are introduced, the Step that introduces the mechanism must test it and avoid changing labels for unrelated discovered tests.
- Configure/build/test commands:
@@ -125,6 +162,17 @@ ctest --preset windows-msvc-ninja-debug --show-only=json-v1
ctest --preset windows-msvc-ninja-debug --output-on-failure
```
## Candidate Files and Ownership
Candidate paths guide the Implementation Agent and do not finalize a new public API.
| Step | candidate files | responsibility boundary |
| --- | --- | --- |
| 11 RED | `tests/integration/analysis/nonlinear_static_procedure_test.cpp`; `tests/unit/io/hdf5/nonlinear_hdf5_results_writer_test.cpp`; existing partial `tests/reference/nonlinear_static_reference_{comparison.h,comparison.cpp,cases_test.cpp}` | New behavior must fail before production edits; comparator extensions remain test-private. |
| 11 GREEN | `src/fesa/analysis/nonlinear_static_procedure.cpp`; `src/fesa/io/hdf5/nonlinear_hdf5_results_writer.cpp` | Current-arm/spatial-moment balance and exact dataset location only; no public header/state/schema expansion. |
| 11 preserve | `src/fesa/analysis/nonlinear_static_control.cpp`; `tests/unit/analysis/nonlinear_static_control_test.cpp`; `tests/unit/analysis/newton_iteration_log_test.cpp`; `tests/CMakeLists.txt` | Preserve uncommitted selector/tests/registration and verify them; do not reset, recreate or redesign. |
| 12 evidence | `docs/PRD.md`; `docs/ARCHITECTURE.md`; `docs/ADR.md`; feature `implementation-report.md`, `build-test.md`, `reference-comparison.md` | Directly superseded global statements and actual evidence only; no C++/test/CMake ownership. |
## Data Flow Contract
1. CLI receives `fesa.exe <model.inp>`.
@@ -132,40 +180,55 @@ ctest --preset windows-msvc-ninja-debug --output-on-failure
3. App derives `<stem>_results.h5` and `<stem>_log.txt` beside the lexically normalized user-addressed `.inp`.
4. App acquires move-only `OutputWriteLease` and retains it until all log and HDF5 work ends.
5. App opens/truncates the log, then `PrepareAnalysisInput(input_path)` parses/maps once into `Domain`.
6. Procedure executor receives injected `ParallelFor` plus `LinearSolver` or `TangentSolver` and computes a fully validated linear or nonlinear state without opening HDF5. Nonlinear assembly forms `r = f_int - f_ext` and `K_T = K_int - K_ext` from Step 4 internal quantities and Step 5 global-once external quantities. Nonlinear state construction preserves each node's stable `EntityIndex` and full `SourceEntityId`; source label alone is never a row identity.
6. Procedure executor receives injected `ParallelFor` plus `LinearSolver` or `TangentSolver` and computes a fully validated state without opening HDF5. Nonlinear assembly forms `r=f_int-f_ext` and `K_T=K_int-K_ext`, preserves the existing convergence decisions, then computes accepted global balance in stable node order. For each node it sets `x=X+u`, masks constrained residual components before converting reaction rotation, converts applied and reaction rotational covectors independently with `InverseTransposeLeftJacobianSO3(phi)`, and accumulates `applied+reaction` force and `x cross force + spatial moment` about `[0,0,0]`.
7. App closes the log successfully before invoking injected `ResultsWriter` or `NonlinearResultsWriter`.
8. HDF5 is the authoritative solver output. CSV views are comparison/debug artifacts only.
8. HDF5 is authoritative. Existing schema-v1 `/global/equilibrium [6]` stores only the applied-plus-reaction balance error with `location=global-balance-error`; existing nodal datasets/mask reconstruct accepted free residual and constrained reaction resultant without new datasets.
9. Comparator copies exact inputs to unique build-local directories, runs only the copies, and executes `ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT`. CSV views are comparison/debug artifacts only.
## Reference Inventory
| path | role | rows | SHA-256 |
| --- | --- | ---: | --- |
| `reference/shellNL-meshfine/shellNL-meshfine.inp` | primary nonlinear input | input | `40DF1CE77311C8D799564A21A60F3BDEBB8148D52CAE22B7292FDFAD32018220` |
| `reference/shellNL-meshfine/shellNL-meshfine displacements.csv` | required blocking/warning CSV | 729 | `740819FF8AED0E279961581F7CDBFA12784CFBA3A488C35A652E80103F64433F` |
| `reference/shellNL-meshfine/shellNL-meshfine reactions.csv` | required review-only CSV | 729 | `AEB01C98C596792B0E5F2B86A81945CAB0BEB0C6969CFC6738C6F81DF1F94363` |
| `reference/shellNL-meshfine/shellNL-meshfine stresses.csv` | optional inventory artifact | 5,408 | `6D6213AB5DB9D6B1F5FBD641367D08BACC805967B6C5A95BCE0E1A5395377782` |
| `reference/shellNL/shellNL.inp` | nonlinear input | input | `4BF3ECB0F7F1E8462C573E993DBC97AC5D920C91CF6F23AD4C6891D77FFBADA2` |
| `reference/shellNL/shellNL displacements.csv` | required displacement CSV | 49 | `4E0F99CA9372B1ADF7FAF102F43BC0B887DC743FDEDA378E4342D2CF8E0C0786` |
| `reference/shellNL/shellNL reactions.csv` | required reaction CSV | 49 | `001CB1541A9E94424E5E650509D46BC8724970DF4DE47184D9DB09C7938AB069` |
| `reference/shellNL/shellNL stresses.csv` | nonblocking inventory artifact | 288 | `5500E5114B1C44887528E30CEC054A1EB0F68BE3F4B8CE81FA59FC74A881483F` |
| `reference/shellNL/shellNL displacements.csv` | required blocking/warning CSV | 49 | `4E0F99CA9372B1ADF7FAF102F43BC0B887DC743FDEDA378E4342D2CF8E0C0786` |
| `reference/shellNL/shellNL reactions.csv` | required review-only CSV | 49 | `001CB1541A9E94424E5E650509D46BC8724970DF4DE47184D9DB09C7938AB069` |
| `reference/shellNL/shellNL stresses.csv` | optional inventory artifact | 288 | `5500E5114B1C44887528E30CEC054A1EB0F68BE3F4B8CE81FA59FC74A881483F` |
| `reference/shell/shell.inp` | linear input | input | `4005851E1AB22FD3A16AC17A8D5DA3E051233F69F37419079F3553AD134ECFCF` |
| `reference/shell/shell displacements.csv` | required displacement CSV | 49 | `C81D94E0B4A849F87AA0F79C83A79B94D5661AC79E44ED826919AB432C87746B` |
| `reference/shell/shell reactions.csv` | nonblocking inventory artifact | 49 | `0E34EEC27E700C3C0C744C1DAFD8A3B95EFEF34B8616FE96665876586FE82D41` |
| `reference/shell/shell stresses.csv` | nonblocking inventory artifact | 288 | `2B75A5B0DEB045A283C9BB7E9B1153B79F7537FF487214BF4A23316B59B660A7` |
Blocking and warning families:
External comparison families:
| family | components | rows | disposition |
| --- | --- | ---: | --- |
| `linear.translation` | `U1,U2,U3`, nodes `1..49` | 147 | blocking |
| `linear.rotation` | `UR1,UR2,UR3`, nodes `1..49` | 147 | warning-only |
| `nonlinear.translation` | `U1,U2,U3`, nodes `1..49` | 147 | blocking |
| `nonlinear.rotation` | `UR1,UR2,UR3`, nodes `1..49` | 147 | warning-only |
| `nonlinear.reaction_inplane_force` | `RF1,RF2`, constrained nodes | 48 | blocking |
| `nonlinear.reaction_transverse_force` | `RF3`, constrained nodes | 24 | blocking |
| `nonlinear.reaction_physical_moment` | `RM1,RM2`, constrained nodes | 48 | blocking |
| `coarse.translation` | `U1,U2,U3`, nodes `1..49` | 147 | blocking |
| `coarse.rotation` | `UR1,UR2,UR3`, nodes `1..49` | 147 | warning-only |
| `coarse.local_reaction_inplane_force` | `RF1,RF2`, 24 constrained nodes | 48 | review-only |
| `coarse.local_reaction_transverse_force` | `RF3`, 24 constrained nodes | 24 | review-only |
| `coarse.local_reaction_physical_moment` | `RM1,RM2`, 24 constrained nodes | 48 | review-only |
| `fine.translation` | `U1,U2,U3`, nodes `1..729` | 2,187 | blocking |
| `fine.rotation` | `UR1,UR2,UR3`, nodes `1..729` | 2,187 | warning-only |
| `fine.local_reaction_inplane_force` | `RF1,RF2`, 104 constrained nodes | 208 | review-only |
| `fine.local_reaction_transverse_force` | `RF3`, 104 constrained nodes | 104 | review-only |
| `fine.local_reaction_physical_moment` | `RM1,RM2`, 104 constrained nodes | 208 | review-only |
Constrained node labels for shellNL reactions: `1,3,4,5,6,7,8,9,14,15,16,17,22,23,24,25,26,27,28,29,30,31,32,33`.
Internal blocking families for each fine/coarse accepted factor-one state are free force residual,
free moment residual, global force balance and global moment balance. Global force/moment use separate
normalized `<=1e-8` gates; free residual uses NSNR-069. Constrained reaction resultant force `[3]`
and moment `[3]` is a distinct review-only summary.
Exact shellNL `Frame`: `Increment 10: Step Time = 1.000`.
Constrained labels: coarse `1,3..9,14..17,22..33`; fine `1,3..9,34..57,82..153`.
Step 11 must not run original reference input paths directly. It snapshots exact original artifact inventory, copies input bytes unchanged into a unique build-local temp case directory, runs `FesaApplication` on the copied `.inp`, consumes copied-sibling `_results.h5` and `_log.txt`, compares generated HDF5 to original read-only CSVs, and then verifies original reference directory inventory, bytes, timestamps, and hashes are unchanged. HDF5 source path identity matches the copied user-addressed input; source content identity matches the approved input hash.
Exact fine and coarse nonlinear `Frame`: `Increment 10: Step Time = 1.000`.
Step 11 must not run original reference input paths directly. It snapshots each exact original artifact inventory, copies input bytes unchanged into a unique build-local case directory, runs `FesaApplication` on the copy, consumes copied-sibling `_results.h5` and `_log.txt`, compares generated HDF5 to original read-only CSVs, and verifies original inventory, bytes, timestamps and hashes are unchanged. HDF5 path identity matches the copied input and source content identity matches the approved input hash.
## Acceptance Traceability Matrix
@@ -176,10 +239,10 @@ Step 11 must not run original reference input paths directly. It snapshots exact
| `FESA-REQ-NSNR-041` | 1,3,10 | `NSNR-IO-*`, `NSNR-ELEM-KIN-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-074` | 2,8,10 | `NSNR-ROT-*`, `NSNR-STATE-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-006` | 4,6,10 | `NSNR-ELEM-TAN-*`, `NSNR-SOLVER-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-007` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-069` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-070` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-008` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-007` | 5,10,11 | `NSNR-CTRL-021`, `NSNR-PROC-*`, `NSNR-REF-019` |
| `FESA-REQ-NSNR-069` | 5,10,11 | `NSNR-CTRL-018..020`, `NSNR-LOG-012`, `NSNR-REF-019` |
| `FESA-REQ-NSNR-070` | 5,10,11 | `NSNR-CTRL-021`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-008` | 5,10,11 | `NSNR-CTRL-020`, `NSNR-PROC-*`, `NSNR-REF-019` |
| `FESA-REQ-NSNR-014` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-046` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-048` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
@@ -187,14 +250,14 @@ Step 11 must not run original reference input paths directly. It snapshots exact
| `FESA-REQ-NSNR-063` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-016` | 1,5 | `NSNR-IO-*`, `NSNR-CTRL-*` |
| `FESA-REQ-NSNR-011` | 8,9,10 | `NSNR-STATE-*`, `NSNR-HDF5-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-019` | 4,8,10 | `NSNR-ELEM-TAN-*`, `NSNR-STATE-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-019` | 4,8,10,11 | `NSNR-ELEM-TAN-*`, `NSNR-STATE-*`, `NSNR-PROC-019`, `NSNR-HDF5-014`, `NSNR-REF-022`, `NSNR-REF-024..025` |
| `FESA-REQ-NSNR-020` | 1 | `NSNR-IO-*` |
| `FESA-REQ-NSNR-021` | 8,9,10 | `NSNR-STATE-*`, `NSNR-HDF5-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-024` | 7,10 | `NSNR-LOG-*`, `NSNR-PROC-*` |
| `FESA-REQ-NSNR-021` | 8,9,10,11 | `NSNR-STATE-*`, `NSNR-HDF5-*`, `NSNR-PROC-*`, `NSNR-HDF5-014` |
| `FESA-REQ-NSNR-024` | 7,10,11 | `NSNR-LOG-012`, `NSNR-PROC-*`, `NSNR-REF-019` |
| `FESA-REQ-NSNR-083` | 0,10,12 | `NSNR-CLI-*`, `NSNR-PROC-*`, `NSNR-EVID-*` |
| `FESA-REQ-NSNR-026` | 8,10,11,12 | `NSNR-STATE-*`, `NSNR-PROC-*`, `NSNR-REF-*`, `NSNR-EVID-*` |
| `FESA-REQ-NSNR-030` | 2,3,4,5,6,7,8,9,10,11 | `NSNR-ROT-*`, `NSNR-ELEM-*`, `NSNR-CTRL-*`, `NSNR-SOLVER-*`, `NSNR-LOG-*`, `NSNR-STATE-*`, `NSNR-HDF5-*`, `NSNR-PROC-*`, `NSNR-REF-*` |
| `FESA-REQ-NSNR-034` | 11 | `NSNR-REF-*` |
| `FESA-REQ-NSNR-026` | 8,10,11,12 | `NSNR-STATE-*`, `NSNR-PROC-*`, `NSNR-REF-020..023`, `NSNR-EVID-*` |
| `FESA-REQ-NSNR-030` | 2,3,4,5,6,7,8,9,10,11 | `NSNR-ROT-*`, `NSNR-ELEM-*`, `NSNR-CTRL-*`, `NSNR-SOLVER-*`, `NSNR-LOG-*`, `NSNR-STATE-*`, `NSNR-HDF5-014`, `NSNR-PROC-019`, `NSNR-REF-022`, `NSNR-REF-024..025` |
| `FESA-REQ-NSNR-034` | 11,12 | `NSNR-REF-020..023`, `NSNR-EVID-003..007` |
## Numerical Review Coverage
@@ -208,7 +271,9 @@ Step 11 must not run original reference input paths directly. It snapshots exact
| patch/sign recovery | 3,4 |
| load/boundary path and `rho_M` | 5,10 |
| Newton factor/iteration lifecycle | 5,7,10 |
| four convergence gates | 5,7,10 |
| four convergence gates | 5,7,10,11; preserved partial selector/control/log work is regression-verified in Step 11 |
| global balance/current-arm/spatial moment | 11 |
| review-only local reaction and fine/coarse reference | 11,12 |
| commit/rollback/determinism | 8,10,11,12 |
## Validation Commands
@@ -226,21 +291,51 @@ ctest --preset windows-msvc-ninja-debug --show-only=json-v1
ctest --preset windows-msvc-ninja-debug --output-on-failure
```
Focused CTest commands are written explicitly in each `stepN.md`.
Step 11 focused commands additionally include:
```powershell
ctest --preset windows-msvc-ninja-debug -R "^(NonlinearConvergence|NewtonIterationLog)\." --output-on-failure
ctest --preset windows-msvc-ninja-debug -R "^(NonlinearStaticProcedure|NonlinearHdf5ResultsWriter)\." --output-on-failure
ctest --preset windows-msvc-ninja-debug -R "^NonlinearStaticReference\." --output-on-failure
ctest --preset windows-msvc-ninja-debug -R "^(NonlinearStaticReference|ReferenceTolerance|Mitc4Reference)\." --output-on-failure
```
Harness Python validation is not in scope unless a Step changes Harness Python behavior, hook behavior, or agent configuration.
## Risks And Downstream Handoff
- Main implementation risk: current `LinearStaticAnalysis` owns parse/map and HDF5 write internally. Step 10 must refactor through prepared analysis flow so log close precedes HDF5 finalization for both linear and nonlinear runs.
- Main numerical risk: nonlinear MITC4 tangent and finite rotation derivatives must pass internal derivative/objectivity tests before reference comparison can be meaningful.
- Main backend risk: nonlinear tangent can be nonsymmetric. Preserve SPD `MklPardisoSolver` unchanged and add separate `TangentSolver`.
- Handoff to Implementation Agent through Coordinator: execute Steps 0..12 in order, one current Step at a time, with RED observed failure evidence before GREEN implementation, then focused/full CTest. Final reference gate is Step 11; evidence-document closure is Step 12.
- Current numerical risk: nonzero prescribed motion exposes the existing raw-residual/initial-arm
shortcut. The minimal fix must preserve same-state, stable-order and mask-before-spatial-conversion
semantics; passing zero-prescribed shellNL cases alone is insufficient evidence.
- Current reference risk: fine/coarse U and internal balance/free-residual are blocking, but local RF/RM
may still show large review-only errors. Do not convert those findings into omitted rows, relaxed
tolerance or a blocking gate.
- Current worktree risk: Step 11 contains partial selector/comparator/CMake edits. Preserve and continue
those files; do not delete, reset, replay selector RED or replace the comparator design wholesale.
- Handoff to Implementation Agent through Coordinator: after a separate explicit Harness request,
resume only Executor-selected Step 11. Preserve existing `NSNR-PROC-019`, `NSNR-HDF5-014` and
`NSNR-REF-020..023`; first re-observe the current-case old-gate RED, then add `NSNR-REF-024..025`
before changing the comparator-only shared force/moment gate to `1e-8`. Verify preserved
selector/log tests, then run focused/full preset validation.
Step 12 remains actual-evidence closure.
## Harness Step Draft
| Step | name | one-module scope | prerequisites | stop condition |
| ---: | --- | --- | --- | --- |
| 11 | `equilibrium-projection-and-reference-gate` | Nonlinear accepted equilibrium projection, exact HDF5 location and test-private reference gate | Steps 0–10 completed; approved upstream hashes; partial Step 11 work preserved; VsDevCmd/preset dependency environment | Stop on unexpected RED, public API/schema/tolerance/reference change, reference mutation, or any focused/full failure. |
| 12 | `execution-closure-and-evidence-docs` | Fresh evidence reports plus directly superseded PRD/ARCH/ADR statements | Step 11 completed with actual command/reference evidence | Stop if Step 11 is incomplete, evidence is stale/untraceable, a code/test/CMake change is needed, or any final command fails. |
Both Step files contain exact commands, file ownership, RED/GREEN/VERIFY order and prohibitions.
Materialization does not select or execute either Step.
## Open Issues
None.
None blocking planning. Revised upstream contracts and exact required artifacts are complete; actual
RED/GREEN/build/reference outcomes remain Step 11/12 evidence and are not pre-claimed.
## Plan Approval Boundary
The user-approved plan and pending phase files do not authorize Harness execution. `scripts/execute.py nonlinear-static-newton-raphson` requires a separate explicit user request.
The Coordinator-audited REAPPROVAL-012 revision authorizes this planning/phase materialization and
blocked-to-pending recovery. It does not itself execute Harness; Executor invocation remains under
the Coordinator's separately audited execution authority.