# Step 9: nonlinear-hdf5-schema-v1-writer ## 읽어야 할 파일 - `AGENTS.md` - `docs/ARCHITECTURE.md` - `docs/ADR.md` - `docs/nonlinear-static-newton-raphson/io.md` - `docs/nonlinear-static-newton-raphson/reference-model.md` - `include/fesa/io/hdf5/hdf5_results_writer.h` - `include/fesa/results/results_writer.h` - `src/fesa/io/hdf5/hdf5_results_writer.cpp` - `src/fesa/io/hdf5/hdf5_primitives.h` - `src/fesa/io/hdf5/hdf5_primitives.cpp` - `src/fesa/io/hdf5/hdf5_self_check.h` - `src/fesa/io/hdf5/hdf5_self_check.cpp` - `tests/unit/io/hdf5/hdf5_results_writer_test.cpp` - Step 8 files: `include/fesa/analysis/nonlinear_analysis_state.h` ## 이전 Step 전제 Step 8 provides committed nonlinear accepted-frame state. Step 0 and Step 10 own the rule that log close succeeds before this writer is invoked. ## 소유 파일 - Create: `include/fesa/io/hdf5/nonlinear_hdf5_results_writer.h` - Create: `src/fesa/io/hdf5/nonlinear_hdf5_results_writer.cpp` - Create: `include/fesa/results/nonlinear_results_writer.h` - Create: `tests/unit/io/hdf5/nonlinear_hdf5_results_writer_test.cpp` - Modify: `src/fesa/io/hdf5/hdf5_primitives.h` - Modify: `src/fesa/io/hdf5/hdf5_primitives.cpp` - Modify: `src/fesa/io/hdf5/hdf5_self_check.h` - Modify: `src/fesa/io/hdf5/hdf5_self_check.cpp` - Modify: `src/fesa/CMakeLists.txt` - Modify: `tests/CMakeLists.txt` ## 인터페이스 ```cpp namespace fesa { class NonlinearResultsWriter { public: virtual ~NonlinearResultsWriter() = default; virtual Status Write(const std::filesystem::path& output_path, const Domain& domain, const NonlinearAnalysisState& state, const std::vector& diagnostics) = 0; }; class NonlinearHdf5ResultsWriter final : public NonlinearResultsWriter { public: Status Write(const std::filesystem::path& output_path, const Domain& domain, const NonlinearAnalysisState& state, const std::vector& diagnostics) override; }; } // namespace fesa ``` ## RED Add tests first. - `NSNR-HDF5-001`: `/metadata` has `schema_version=1`, `feature_id=nonlinear-static-newton-raphson`, and approved procedure/formulation/integration attributes. - `NSNR-HDF5-002`: `/model/nodes`, `/model/elements`, shell section/material/frame/director/constraint datasets match I/O schema. - `NSNR-HDF5-003`: `/steps/Step-1/accepted_frames` has one row per committed increment. - `NSNR-HDF5-004`: final row has load factor `1.0` and `is_factor_one=1`. - `NSNR-HDF5-005`: factor zero metadata exists and factor zero is not a frame. - `NSNR-HDF5-006`: per-frame nodal displacement, triad, director, internal, external, residual, reaction datasets have approved shapes and column ordering. - `NSNR-HDF5-007`: reaction rotational columns store `J_l(phi)^(-T)` spatial physical moment. - `NSNR-HDF5-008`: element shell local frame, generalized strain, section resultant, stress datasets exist with approved shape and identity. - `NSNR-HDF5-009`: `/global/energy` and `/global/equilibrium` exist for each accepted frame. - `NSNR-HDF5-010`: no trial history dataset is written. - `NSNR-HDF5-011`: HDF5 candidate failure preserves prior final file. - `NSNR-HDF5-012`: writer consumes `std::vector` and writes deterministic diagnostics. - `NSNR-HDF5-013`: `NonlinearHdf5ResultsWriter` implements backend-neutral `NonlinearResultsWriter`, and no HDF5 handle/type appears in analysis/core public headers. Run: ```powershell cmake --build --preset windows-msvc-ninja-debug ctest --preset windows-msvc-ninja-debug -R "NonlinearHdf5|Hdf5ResultsWriter" --output-on-failure ``` Expected: new tests fail. Unexpected pass stops. ## GREEN Implement `include/fesa/results/nonlinear_results_writer.h` as the backend-neutral boundary and implement schema-v1 nonlinear HDF5 writer using existing HDF5 RAII/primitives/self-check style. Keep HDF5 and platform types private to `src/fesa/io/hdf5`. ## VERIFY ```powershell cmake --preset windows-msvc-ninja-debug cmake --build --preset windows-msvc-ninja-debug ctest --preset windows-msvc-ninja-debug -R "NonlinearHdf5|Hdf5ResultsWriter" --output-on-failure ctest --preset windows-msvc-ninja-debug --show-only=json-v1 ctest --preset windows-msvc-ninja-debug --output-on-failure ``` Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment. ## 상태 기록 Update only Step 9 status and one-line payload. Executor owns timestamps, commits, retry, and advancement. ## 금지사항 - Do not open, write, or replace HDF5 before log close succeeds. 이유: Step 10 app lifecycle enforces log-before-HDF5 finalization. - Do not write compression, chunking, or trial history. 이유: io.md requires contiguous accepted-state storage. - Do not make CSV an authoritative output. 이유: official solver output is HDF5. - Do not include HDF5 headers from analysis/core public headers. 이유: output backend types stay behind writer interfaces.