feat: add eigen2 frequency pipeline and fail-closed validation

Implement MITC4 mass, constrained whitening, MKL FEAST, modal HDF5, and deterministic Value comparison. MSVC Debug builds; 394 of 395 tests pass. Original-model all-c residual and the documented S3 static contract conflict remain unresolved; this is an implementation checkpoint, not feature acceptance.
This commit is contained in:
KOKO\Mimi
2026-09-09 03:14:30 +09:00
parent e74ac247db
commit 22c9d4435c
39 changed files with 7240 additions and 541 deletions
+12 -6
View File
@@ -5,6 +5,7 @@
#include <string>
#include <vector>
#include "fesa/analysis/linear_frequency_procedure.h"
#include "fesa/analysis/linear_static_procedure.h"
#include "fesa/analysis/newton_iteration_log.h"
#include "fesa/analysis/nonlinear_static_procedure.h"
@@ -12,6 +13,7 @@
#include "fesa/app/output_paths.h"
#include "fesa/assembly/parallel_for.h"
#include "fesa/core/diagnostic.h"
#include "fesa/io/hdf5/eigen_hdf5_results_writer.h"
#include "fesa/io/hdf5/hdf5_results_writer.h"
#include "fesa/io/hdf5/nonlinear_hdf5_results_writer.h"
#include "fesa/solvers/linear/mkl_pardiso_solver.h"
@@ -63,8 +65,8 @@ int ExitCodeFor(const Status& status) {
} // namespace
int FesaApplication::Run(const std::vector<std::string>& arguments) {
const auto paths = DeriveSingleInputOutputPaths(
arguments, std::filesystem::current_path());
const auto paths =
DeriveSingleInputOutputPaths(arguments, std::filesystem::current_path());
if (!paths.HasValue()) {
WriteDiagnostics(paths.GetStatus().Diagnostics());
return kUsageExitCode;
@@ -81,6 +83,7 @@ int FesaApplication::Run(const std::vector<std::string>& arguments) {
MklPardisoTangentSolver tangent_solver;
Hdf5ResultsWriter linear_writer;
NonlinearHdf5ResultsWriter nonlinear_writer;
EigenHdf5ResultsWriter eigen_writer;
NewtonIterationLogWriter log;
Status status = log.Open(paths.Value().log_path);
@@ -96,9 +99,11 @@ int FesaApplication::Run(const std::vector<std::string>& arguments) {
} else {
LinearStaticProcedureExecutor linear_executor(parallel_for, linear_solver);
NonlinearStaticProcedureExecutor nonlinear_executor(parallel_for,
tangent_solver);
Result<PreparedAnalysisOutcome> outcome = ExecutePreparedAnalysis(
prepared.Value().domain, linear_executor, nonlinear_executor, log);
tangent_solver);
const LinearFrequencyProcedureExecutor frequency_executor;
Result<PreparedAnalysisOutcome> outcome =
ExecutePreparedAnalysis(prepared.Value().domain, linear_executor,
nonlinear_executor, frequency_executor, log);
if (!outcome.HasValue()) {
status = outcome.GetStatus();
} else {
@@ -109,7 +114,8 @@ int FesaApplication::Run(const std::vector<std::string>& arguments) {
}
status = FinalizePreparedAnalysisResult(
paths.Value(), prepared.Value().domain, outcome.Value(),
prepared.Value().diagnostics, linear_writer, nonlinear_writer);
prepared.Value().diagnostics, linear_writer, nonlinear_writer,
eigen_writer);
if (status.IsOk()) {
return kSuccessExitCode;
}