# Step 6: backend-neutral-tangent-solver ## 읽어야 할 파일 - `AGENTS.md` - `docs/ARCHITECTURE.md` - `docs/ADR.md` - `docs/nonlinear-static-newton-raphson/formulation.md` - `docs/nonlinear-static-newton-raphson/numerical-review.md` - `include/fesa/solvers/linear/linear_solver.h` - `include/fesa/solvers/linear/mkl_pardiso_solver.h` - `src/fesa/solvers/linear/mkl_pardiso_solver.cpp` - `tests/unit/solvers/linear/linear_solver_test.cpp` - `tests/unit/solvers/linear/mkl_pardiso_solver_test.cpp` - Step 4 files: `include/fesa/elements/nonlinear_mitc4_shell.h` ## 이전 Step 전제 Step 4 defines generally nonsymmetric nonlinear tangent matrices. Current SPD `MklPardisoSolver` must remain unchanged. ## 소유 파일 - Create: `include/fesa/solvers/linear/tangent_solver.h` - Create: `include/fesa/solvers/linear/mkl_pardiso_tangent_solver.h` - Create: `src/fesa/solvers/linear/mkl_pardiso_tangent_solver.cpp` - Create: `tests/unit/solvers/linear/tangent_solver_test.cpp` - Test: `tests/unit/solvers/linear/mkl_pardiso_solver_test.cpp` - Modify: `src/fesa/CMakeLists.txt` - Modify: `tests/CMakeLists.txt` ## 인터페이스 ```cpp namespace fesa { class TangentSolver { public: virtual ~TangentSolver() = default; virtual Status FactorizeFresh(const SparseMatrix& matrix) = 0; virtual Status SolveCorrection(const Vector& rhs, Vector& correction) const = 0; }; class MklPardisoTangentSolver final : public TangentSolver { public: MklPardisoTangentSolver(); ~MklPardisoTangentSolver() override; Status FactorizeFresh(const SparseMatrix& matrix) override; Status SolveCorrection(const Vector& rhs, Vector& correction) const override; }; } // namespace fesa ``` The MKL tangent adapter uses unsymmetric PARDISO full CSR with `mtype=11`. Existing `MklPardisoSolver` keeps `mtype=2`, SPD symmetry validation, and upper-triangle copy unchanged. ## RED Add tests first. - `NSNR-SOLVER-001`: nonsymmetric 2x2 matrix factorizes and solves a known correction. - `NSNR-SOLVER-002`: `0x0` matrix factorize/solve succeeds with zero-size vectors. - `NSNR-SOLVER-003`: nonfinite matrix or RHS values fail without modifying output correction. - `NSNR-SOLVER-004`: singular/factorization failure maps to deterministic solver diagnostic. - `NSNR-SOLVER-005`: solve before successful factorization fails with solver diagnostic. - `NSNR-SOLVER-006`: existing SPD `MklPardisoSolver` still rejects nonsymmetric public CSR and passes prior tests. Run: ```powershell cmake --build .harness/build --config Debug ctest --test-dir .harness/build -C Debug -R "TangentSolver|MklPardiso" --output-on-failure ``` Expected: new tests fail. Unexpected pass stops. ## GREEN Implement backend-neutral tangent solver boundary and MKL full-CSR adapter. Factorization is fresh per call, releases previous backend state, validates dimensions and finite values, and translates PARDISO errors to FESA `Status`. ## VERIFY ```powershell cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` "-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` "-DMKL_DIR=$mklDir" ` "-DTBB_DIR=$tbbDir" ` "-DHDF5_DIR=$hdf5Dir" cmake --build .harness/build --config Debug ctest --test-dir .harness/build -C Debug -R "TangentSolver|MklPardiso" --output-on-failure ctest --test-dir .harness/build -C Debug --show-only=json-v1 ctest --test-dir .harness/build -C Debug --output-on-failure ``` Recheck `.harness/config.json` before default commands. ## 상태 기록 Update only Step 6 status and one-line payload. Executor owns timestamps, commits, retry, and advancement. ## 금지사항 - Do not modify SPD `MklPardisoSolver` behavior except tests proving it is unchanged. 이유: existing linear solver contract must remain stable. - Do not symmetrize or regularize tangent matrices. 이유: approved tangent may be nonsymmetric and failures must surface. - Do not expose MKL types in public headers. 이유: backend types remain behind solver boundaries.