Files
FESADev/src/fesa/app/fesa_application.cpp
T

96 lines
2.9 KiB
C++

#include "fesa/app/fesa_application.h"
#include <filesystem>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include "fesa/analysis/analysis.h"
#include "fesa/analysis/linear_static_analysis.h"
#include "fesa/app/output_paths.h"
#include "fesa/assembly/parallel_for.h"
#include "fesa/core/diagnostic.h"
#include "fesa/io/hdf5/hdf5_results_writer.h"
#include "fesa/solvers/linear/mkl_pardiso_solver.h"
namespace fesa {
namespace {
constexpr int kSuccessExitCode = 0;
constexpr int kUsageExitCode = 2;
constexpr int kInputExitCode = 3;
constexpr int kModelExitCode = 4;
constexpr int kSolverExitCode = 5;
constexpr int kOutputExitCode = 6;
const char* SeverityName(const Severity severity) {
return severity == Severity::kWarning ? "warning" : "error";
}
void WriteDiagnostics(std::vector<Diagnostic> diagnostics) {
SortDiagnostics(diagnostics);
for (const auto& diagnostic : diagnostics) {
// Stable field labels and tab separators keep empty source fields
// explicit without depending on locale-specific formatting.
std::cerr << "severity=" << SeverityName(diagnostic.severity) << '\t'
<< "code=" << diagnostic.code << '\t'
<< "file=" << diagnostic.location.file.generic_u8string() << '\t'
<< "line=" << diagnostic.location.line << '\t'
<< "keyword=" << diagnostic.keyword << '\t'
<< "entity_identity=" << diagnostic.entity_identity << '\t'
<< "message=" << diagnostic.message << '\n';
}
}
int ExitCodeFor(const Status& status) {
switch (status.Category().value_or(FailureCategory::kInput)) {
case FailureCategory::kInput:
return kInputExitCode;
case FailureCategory::kModel:
return kModelExitCode;
case FailureCategory::kSolver:
return kSolverExitCode;
case FailureCategory::kOutput:
return kOutputExitCode;
}
return kInputExitCode;
}
} // namespace
int FesaApplication::Run(const std::vector<std::string>& arguments) {
const auto paths = DeriveSingleInputOutputPaths(
arguments, std::filesystem::current_path());
if (!paths.HasValue()) {
WriteDiagnostics(paths.GetStatus().Diagnostics());
return kUsageExitCode;
}
auto lease = AcquireOutputWriteLease(paths.Value());
if (!lease.HasValue()) {
WriteDiagnostics(lease.GetStatus().Diagnostics());
return kOutputExitCode;
}
AnalysisRequest request;
request.input_path = paths.Value().input_path;
request.output_path = paths.Value().results_path;
request.log_path = paths.Value().log_path;
TbbParallelFor parallel_for;
MklPardisoSolver linear_solver;
Hdf5ResultsWriter results_writer;
std::unique_ptr<Analysis> analysis = std::make_unique<LinearStaticAnalysis>(
parallel_for, linear_solver, results_writer);
const Status status = analysis->Run(request);
if (status.IsOk()) {
return kSuccessExitCode;
}
WriteDiagnostics(status.Diagnostics());
return ExitCodeFor(status);
}
} // namespace fesa