169 lines
6.7 KiB
C++
169 lines
6.7 KiB
C++
#include "fesa/analysis/prepared_analysis.h"
|
|
|
|
#include <utility>
|
|
|
|
#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<PreparedAnalysisInput> PrepareAnalysisInput(
|
|
const std::filesystem::path& input_path) {
|
|
const Result<ParsedInput> syntax = AbaqusInputReader{}.Read(input_path);
|
|
if (!syntax.HasValue()) {
|
|
return Result<PreparedAnalysisInput>::Failure(syntax.GetStatus());
|
|
}
|
|
|
|
Result<Domain> mapped = AbaqusDomainMapper{}.Map(syntax.Value());
|
|
if (!mapped.HasValue()) {
|
|
return Result<PreparedAnalysisInput>::Failure(mapped.GetStatus());
|
|
}
|
|
|
|
PreparedAnalysisInput prepared{std::move(mapped.Value()), {}};
|
|
prepared.diagnostics = prepared.domain.Warnings();
|
|
SortDiagnostics(prepared.diagnostics);
|
|
return Result<PreparedAnalysisInput>::Success(std::move(prepared));
|
|
}
|
|
|
|
Result<PreparedAnalysisOutcome> 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<PreparedAnalysisOutcome>::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<PreparedAnalysisOutcome>::Failure(thermal.GetStatus());
|
|
}
|
|
return Result<PreparedAnalysisOutcome>::Success(
|
|
PreparedAnalysisOutcome{std::move(thermal.Value())});
|
|
}
|
|
if (domain.Steps().Size() != 1U) {
|
|
return Result<PreparedAnalysisOutcome>::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<PreparedAnalysisOutcome>::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<PreparedAnalysisOutcome>::Failure(dynamic.GetStatus());
|
|
return Result<PreparedAnalysisOutcome>::Success(
|
|
PreparedAnalysisOutcome{std::move(dynamic.Value())});
|
|
}
|
|
if (domain.Steps()[0U].IsFrequency()) {
|
|
auto eigen = frequency_executor.Execute(domain);
|
|
if (!eigen.HasValue()) {
|
|
return Result<PreparedAnalysisOutcome>::Failure(eigen.GetStatus());
|
|
}
|
|
return Result<PreparedAnalysisOutcome>::Success(
|
|
PreparedAnalysisOutcome{std::move(eigen.Value())});
|
|
}
|
|
|
|
if (domain.Steps()[0U].IsNonlinearStatic()) {
|
|
Result<NonlinearStaticExecutionResult> nonlinear =
|
|
nonlinear_executor.Execute(domain, log);
|
|
if (!nonlinear.HasValue()) {
|
|
return Result<PreparedAnalysisOutcome>::Failure(nonlinear.GetStatus());
|
|
}
|
|
return Result<PreparedAnalysisOutcome>::Success(
|
|
PreparedAnalysisOutcome{std::move(nonlinear.Value())});
|
|
}
|
|
|
|
Result<LinearStaticExecutionResult> linear = linear_executor.Execute(domain);
|
|
if (!linear.HasValue()) {
|
|
return Result<PreparedAnalysisOutcome>::Failure(linear.GetStatus());
|
|
}
|
|
return Result<PreparedAnalysisOutcome>::Success(
|
|
PreparedAnalysisOutcome{std::move(linear.Value())});
|
|
}
|
|
|
|
Status FinalizePreparedAnalysisResult(
|
|
const DerivedOutputPaths& paths, const Domain& domain,
|
|
const PreparedAnalysisOutcome& outcome,
|
|
const std::vector<Diagnostic>& diagnostics, ResultsWriter& linear_writer,
|
|
NonlinearResultsWriter& nonlinear_writer, EigenResultsWriter& eigen_writer,
|
|
DynamicResultsWriter* dynamic_writer,
|
|
ThermalResultsWriter* thermal_writer) {
|
|
if (std::holds_alternative<ThermalExecutionResult>(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<ThermalExecutionResult>(outcome).state, diagnostics);
|
|
}
|
|
if (std::holds_alternative<DynamicExecutionResult>(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<DynamicExecutionResult>(outcome).state, diagnostics);
|
|
}
|
|
if (std::holds_alternative<EigenAnalysisState>(outcome)) {
|
|
return eigen_writer.Write(paths.results_path, domain,
|
|
std::get<EigenAnalysisState>(outcome),
|
|
diagnostics);
|
|
}
|
|
if (std::holds_alternative<LinearStaticExecutionResult>(outcome)) {
|
|
return linear_writer.Write(
|
|
paths.results_path, domain,
|
|
std::get<LinearStaticExecutionResult>(outcome).state, diagnostics);
|
|
}
|
|
|
|
return nonlinear_writer.Write(
|
|
paths.results_path, domain,
|
|
std::get<NonlinearStaticExecutionResult>(outcome).state, diagnostics);
|
|
}
|
|
|
|
} // namespace fesa
|