#include "fesa/analysis/prepared_analysis.h" #include #include "fesa/analysis/hht_dynamic_procedure.h" #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" #include "fesa/app/output_paths.h" #include "fesa/io/abaqus/domain_mapper.h" #include "fesa/io/abaqus/input_reader.h" #include "fesa/results/dynamic_results_writer.h" #include "fesa/results/eigen_results_writer.h" #include "fesa/results/nonlinear_results_writer.h" #include "fesa/results/results_writer.h" #include "fesa/results/thermal_results_writer.h" namespace fesa { Result PrepareAnalysisInput( const std::filesystem::path& input_path) { const Result syntax = AbaqusInputReader{}.Read(input_path); if (!syntax.HasValue()) { return Result::Failure(syntax.GetStatus()); } Result mapped = AbaqusDomainMapper{}.Map(syntax.Value()); if (!mapped.HasValue()) { return Result::Failure(mapped.GetStatus()); } PreparedAnalysisInput prepared{std::move(mapped.Value()), {}}; prepared.diagnostics = prepared.domain.Warnings(); SortDiagnostics(prepared.diagnostics); return Result::Success(std::move(prepared)); } Result ExecutePreparedAnalysis( const Domain& domain, LinearStaticProcedureExecutor& linear_executor, NonlinearStaticProcedureExecutor& nonlinear_executor, const LinearFrequencyProcedureExecutor& frequency_executor, NewtonIterationLogWriter& log, const HhtDynamicProcedureExecutor* dynamic_executor, const TransientHeatProcedureExecutor* thermal_executor) { if (domain.ThermalStep() != nullptr) { if (thermal_executor == nullptr) { return Result::Failure( Status::Failure(FailureCategory::kSolver, {{Severity::kError, "missing-thermal-executor", {}, "HEAT TRANSFER", {}, "Thermal execution adapter is required."}})); } auto thermal = thermal_executor->Execute(domain); if (!thermal.HasValue()) { return Result::Failure(thermal.GetStatus()); } return Result::Success( PreparedAnalysisOutcome{std::move(thermal.Value())}); } if (domain.Steps().Size() != 1U) { return Result::Failure(Status::Failure( FailureCategory::kInput, {{Severity::kError, "invalid-analysis-step-count", {}, "*STEP", {}, "Prepared analysis requires exactly one analysis step."}})); } if (domain.Dynamic() != nullptr) { if (dynamic_executor == nullptr) return Result::Failure( Status::Failure(FailureCategory::kSolver, {{Severity::kError, "missing-dynamic-executor", {}, "DYNAMIC", {}, "Dynamic execution adapter is required."}})); auto dynamic = dynamic_executor->Execute(domain, log); if (!dynamic.HasValue()) return Result::Failure(dynamic.GetStatus()); return Result::Success( PreparedAnalysisOutcome{std::move(dynamic.Value())}); } if (domain.Steps()[0U].IsFrequency()) { auto eigen = frequency_executor.Execute(domain); if (!eigen.HasValue()) { return Result::Failure(eigen.GetStatus()); } return Result::Success( PreparedAnalysisOutcome{std::move(eigen.Value())}); } if (domain.Steps()[0U].IsNonlinearStatic()) { Result nonlinear = nonlinear_executor.Execute(domain, log); if (!nonlinear.HasValue()) { return Result::Failure(nonlinear.GetStatus()); } return Result::Success( PreparedAnalysisOutcome{std::move(nonlinear.Value())}); } Result linear = linear_executor.Execute(domain); if (!linear.HasValue()) { return Result::Failure(linear.GetStatus()); } return Result::Success( PreparedAnalysisOutcome{std::move(linear.Value())}); } Status FinalizePreparedAnalysisResult( const DerivedOutputPaths& paths, const Domain& domain, const PreparedAnalysisOutcome& outcome, const std::vector& diagnostics, ResultsWriter& linear_writer, NonlinearResultsWriter& nonlinear_writer, EigenResultsWriter& eigen_writer, DynamicResultsWriter* dynamic_writer, ThermalResultsWriter* thermal_writer) { if (std::holds_alternative(outcome)) { if (thermal_writer == nullptr) { return Status::Failure(FailureCategory::kOutput, {{Severity::kError, "missing-thermal-writer", {}, "HEAT TRANSFER", {}, "Thermal result writer is required."}}); } return thermal_writer->Write( paths.results_path, domain, std::get(outcome).state, diagnostics); } if (std::holds_alternative(outcome)) { if (dynamic_writer == nullptr) return Status::Failure(FailureCategory::kOutput, {{Severity::kError, "missing-dynamic-writer", {}, "DYNAMIC", {}, "Dynamic result writer is required."}}); return dynamic_writer->Write( paths.results_path, domain, std::get(outcome).state, diagnostics); } if (std::holds_alternative(outcome)) { return eigen_writer.Write(paths.results_path, domain, std::get(outcome), diagnostics); } if (std::holds_alternative(outcome)) { return linear_writer.Write( paths.results_path, domain, std::get(outcome).state, diagnostics); } return nonlinear_writer.Write( paths.results_path, domain, std::get(outcome).state, diagnostics); } } // namespace fesa