9.0 KiB
Step 10: prepared-analysis-flow-and-full-procedure
읽어야 할 파일
AGENTS.mddocs/ARCHITECTURE.mddocs/ADR.mddocs/nonlinear-static-newton-raphson/requirements.mddocs/nonlinear-static-newton-raphson/formulation.mddocs/nonlinear-static-newton-raphson/numerical-review.mddocs/nonlinear-static-newton-raphson/io.mdinclude/fesa/analysis/analysis.hinclude/fesa/analysis/linear_static_analysis.hsrc/fesa/analysis/linear_static_analysis.cppsrc/fesa/app/fesa_application.cppinclude/fesa/io/hdf5/hdf5_results_writer.hinclude/fesa/results/results_writer.hinclude/fesa/results/nonlinear_results_writer.h- Step 0 files:
include/fesa/app/output_paths.h,src/fesa/app/output_paths.cpp - Step 1 files:
include/fesa/model/domain.h,src/fesa/io/abaqus/domain_mapping_context.cpp - Step 5 files:
include/fesa/analysis/nonlinear_static_control.h - Step 6 files:
include/fesa/solvers/linear/tangent_solver.h - Step 7 files:
include/fesa/analysis/newton_iteration_log.h - Step 8 files:
include/fesa/analysis/nonlinear_analysis_state.h - Step 9 files:
include/fesa/results/nonlinear_results_writer.h,include/fesa/io/hdf5/nonlinear_hdf5_results_writer.h
이전 Step 전제
Steps 0-9 provide path/lease, Domain procedure identity, nonlinear element/control/solver/log/state, and nonlinear HDF5 writer.
소유 파일
- Create:
include/fesa/analysis/prepared_analysis.h - Create:
src/fesa/analysis/prepared_analysis.cpp - Create:
include/fesa/analysis/linear_static_procedure.h - Create:
src/fesa/analysis/linear_static_procedure.cpp - Create:
include/fesa/analysis/nonlinear_static_procedure.h - Create:
src/fesa/analysis/nonlinear_static_procedure.cpp - Modify:
include/fesa/analysis/linear_static_analysis.h - Modify:
src/fesa/analysis/linear_static_analysis.cpp - Modify:
src/fesa/app/fesa_application.cpp - Test:
tests/integration/analysis/linear_static_analysis_test.cpp - Create:
tests/integration/analysis/nonlinear_static_procedure_test.cpp - Test:
tests/integration/app/fesa_application_test.cpp - Modify:
src/fesa/CMakeLists.txt - Modify:
tests/CMakeLists.txt
인터페이스
namespace fesa {
struct PreparedAnalysisInput {
Domain domain;
std::vector<Diagnostic> diagnostics;
};
Result<PreparedAnalysisInput> PrepareAnalysisInput(
const std::filesystem::path& input_path);
struct LinearStaticExecutionResult {
AnalysisState state;
std::vector<Diagnostic> diagnostics;
};
class LinearStaticProcedureExecutor {
public:
LinearStaticProcedureExecutor(const ParallelFor& parallel_for,
LinearSolver& linear_solver);
Result<LinearStaticExecutionResult> Execute(const Domain& domain) const;
private:
const ParallelFor& parallel_for_;
LinearSolver& linear_solver_;
};
struct NonlinearStaticExecutionResult {
NonlinearAnalysisState state;
std::vector<Diagnostic> diagnostics;
};
class NonlinearStaticProcedureExecutor {
public:
NonlinearStaticProcedureExecutor(const ParallelFor& parallel_for,
TangentSolver& tangent_solver);
Result<NonlinearStaticExecutionResult> Execute(
const Domain& domain, NewtonIterationLogWriter& log) const;
private:
const ParallelFor& parallel_for_;
TangentSolver& tangent_solver_;
};
using PreparedAnalysisOutcome =
std::variant<LinearStaticExecutionResult, NonlinearStaticExecutionResult>;
Result<PreparedAnalysisOutcome> ExecutePreparedAnalysis(
const Domain& domain,
LinearStaticProcedureExecutor& linear_executor,
NonlinearStaticProcedureExecutor& nonlinear_executor,
NewtonIterationLogWriter& log);
Status FinalizePreparedAnalysisResult(
const DerivedOutputPaths& paths,
const Domain& domain,
const PreparedAnalysisOutcome& outcome,
const std::vector<Diagnostic>& diagnostics,
ResultsWriter& linear_writer,
NonlinearResultsWriter& nonlinear_writer);
} // namespace fesa
RED
Add tests first.
NSNR-PROC-001: app validates argv, derives paths, acquiresOutputWriteLease, opens log, then parses/maps exactly once.NSNR-PROC-002: parse/map diagnostics are sorted and preserved in prepared input.NSNR-PROC-003: linearNLGEOM=NOrun usesLinearStaticProcedureExecutorand preserves existing numerical/HDF5 meaning except output names and log lifecycle.NSNR-PROC-004: nonlinearNLGEOM=YESrun usesNonlinearStaticProcedureExecutor.NSNR-PROC-005: linear executor receives injectedParallelForand existingLinearSolver; nonlinear executor receives injectedParallelForandTangentSolver.NSNR-PROC-006: app constructs and owns concreteTbbParallelFor,MklPardisoSolver,MklPardisoTangentSolver,Hdf5ResultsWriter, andNonlinearHdf5ResultsWriter.NSNR-PROC-007: procedure computation/recovery returns a validated outcome without opening HDF5.NSNR-PROC-008: app closes log successfully before calling injected linear or nonlinear writer.NSNR-PROC-009: log close failure blocks HDF5 candidate creation.NSNR-PROC-010: nonlinear executor buildsNonlinearStateBaselineInputfrom Domain nodes in stable internal order, preserving each node'sEntityIndexand fullSourceEntityId, then constructs state throughNonlinearAnalysisState::Create(domain, dofs, baseline)before the first increment; the factor-zero baseline is committed state only and is not an accepted frame.NSNR-PROC-011: nonlinear increment loop uses factors from Step 5 and iterations1..100.NSNR-PROC-012: each entered iteration performs fresh tangent factorization and solvesKff * delta = -r_f.NSNR-PROC-013: global external vector/tangent from Step 5 is assembled once and combined with approved signsr = f_int - f_ext,K_T = K_int - K_ext; the fixed-moment tangent is subtracted once and is never duplicated per incident element.NSNR-PROC-014: iteration 100 can accept if gates pass; failure at 100 emitsnonlinear-nonconvergencewith no retry.NSNR-PROC-015: nonfinite data, factorization failure, solve failure, invalid accepted state, and log failure map to approved diagnostics.NSNR-PROC-016: constrained correction is zero and reactions/free residuals come from full residualr = f_int - f_ext.NSNR-PROC-017: failed nonlinear run preserves prior final HDF5 according to output lifecycle.NSNR-PROC-018: deterministic repeat produces same sparse structure, nodal source-identity order, result row order, diagnostics, and log line ordering.
Run:
cmake --build --preset windows-msvc-ninja-debug
ctest --preset windows-msvc-ninja-debug -R "LinearStaticAnalysis|NonlinearStaticProcedure|FesaApplication" --output-on-failure
Expected: new tests fail. Unexpected pass stops.
GREEN
Refactor current parse/map and linear compute/recovery out of LinearStaticAnalysis::Run() into PrepareAnalysisInput and LinearStaticProcedureExecutor. Keep LinearStaticAnalysis as a compatibility wrapper that delegates through the new flow and does not contain nonlinear conditions. Implement NonlinearStaticProcedureExecutor in nonlinear_static_procedure.* using Steps 2-8, constructing state only through NonlinearAnalysisState::Create(...) with one baseline per Domain node in stable internal order, forming r = f_int - f_ext and K_T = K_int - K_ext, preserving EntityIndex plus full SourceEntityId into final writer inputs, and delaying all HDF5 work until FinalizePreparedAnalysisResult. The app owns concrete adapters and passes them through interfaces.
VERIFY
cmake --preset windows-msvc-ninja-debug
cmake --build --preset windows-msvc-ninja-debug
ctest --preset windows-msvc-ninja-debug -R "LinearStaticAnalysis|NonlinearStaticProcedure|FesaApplication" --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 10 status and one-line payload. Executor owns timestamps, commits, retry, and advancement.
금지사항
- Do not parse/map twice. 이유: source identity, diagnostics, and Domain lifetime must be deterministic.
- Do not reconstruct nodal identity from source labels alone. 이유: labels can repeat across instances and HDF5/reference matching requires full
SourceEntityId. - Do not open HDF5 before log close succeeds. 이유: io.md requires log close success before HDF5 candidate open/write/final replace.
- Do not insert nonlinear branches into
LinearStaticAnalysisprivate lifecycle. 이유: new procedure owns its own lifecycle. - Do not replace final HDF5 on failed analysis, log failure, or HDF5 failure. 이유: asymmetric preservation contract requires prior valid final preservation.
- Do not construct MKL/TBB/HDF5 backends inside procedure executors. 이유: dependencies are injected so tests can observe lifecycle and no backend type crosses analysis/core public boundaries.