Files
FESADev/src/fesa/io/hdf5/hdf5_results_writer.cpp
T

75 lines
3.0 KiB
C++

#include "fesa/io/hdf5/hdf5_results_writer.h"
#include <exception>
#include <filesystem>
#include <utility>
#include <vector>
#include "io/hdf5/hdf5_atomic_file.h"
#include "io/hdf5/hdf5_model_writer.h"
#include "io/hdf5/hdf5_primitives.h"
#include "io/hdf5/hdf5_raii.h"
#include "io/hdf5/hdf5_result_writer.h"
#include "io/hdf5/hdf5_self_check.h"
namespace fesa {
Status Hdf5ResultsWriter::Write(const std::filesystem::path& output_path,
const Domain& domain,
const AnalysisState& state,
const std::vector<Diagnostic>& diagnostics) {
auto plan_result =
hdf5_internal::BuildWriterPlan(output_path, domain, state, diagnostics);
if (!plan_result.HasValue()) {
return plan_result.GetStatus();
}
hdf5_internal::WriterPlan plan = std::move(plan_result.Value());
try {
hdf5_internal::Hdf5ErrorSilencer silence_backend_errors;
const std::filesystem::path candidate_path =
hdf5_internal::MakeCandidatePath(output_path);
hdf5_internal::CandidateFileGuard cleanup{candidate_path};
hdf5_internal::Hdf5Handle file{
hdf5_internal::RequireHdf5Id(
H5Fcreate(candidate_path.string().c_str(), H5F_ACC_EXCL,
H5P_DEFAULT, H5P_DEFAULT),
"Unable to create the temporary HDF5 file."),
H5Fclose};
(void)hdf5_internal::CreateGroup(file.Get(), "/model");
(void)hdf5_internal::CreateGroup(file.Get(),
"/steps/Step-1/frames/0/nodal");
(void)hdf5_internal::CreateGroup(file.Get(),
"/steps/Step-1/frames/0/element");
if (hdf5_internal::IsShellDomain(domain)) {
(void)hdf5_internal::CreateGroup(file.Get(), "/model/shell");
(void)hdf5_internal::CreateGroup(file.Get(),
"/steps/Step-1/frames/0/element/shell");
(void)hdf5_internal::CreateGroup(file.Get(),
"/steps/Step-1/frames/0/global");
}
hdf5_internal::WriteModel(file.Get(), domain, plan.model_data);
hdf5_internal::WriteResults(file.Get(), domain, state, diagnostics, plan);
hdf5_internal::RequireHdf5(H5Fflush(file.Get(), H5F_SCOPE_GLOBAL),
"Unable to flush the temporary HDF5 file.");
hdf5_internal::RequireHdf5(
file.CloseChecked(),
"Unable to close the temporary HDF5 file after writing.");
const Status self_check = hdf5_internal::SelfCheck(
candidate_path, domain, state, diagnostics.size(), plan.model_data);
const Status atomic = hdf5_internal::AtomicFinalizeValidatedCandidate(
candidate_path, output_path, self_check);
if (atomic.IsOk()) {
cleanup.Release();
}
return atomic;
} catch (const hdf5_internal::Hdf5Failure& failure) {
return hdf5_internal::OutputFailure("hdf5-write-failure", failure.what());
} catch (const std::exception& failure) {
return hdf5_internal::OutputFailure("hdf5-write-failure", failure.what());
}
}
} // namespace fesa