Add MITC4 drilling diagnostics output and comparison contract

This commit is contained in:
KOKO\Mimi
2026-10-20 09:45:58 +09:00
parent 3d5c296651
commit a73d3fc9ca
31 changed files with 1175 additions and 45 deletions
@@ -22,6 +22,10 @@
#include "math/finite_values.h"
#include "results/shell_result_recovery.h"
#include "io/hdf5/mitc4_drilling_diagnostics.h"
#include "io/hdf5/mitc4_file_hooks.h"
namespace fesa {
namespace {
@@ -955,10 +959,10 @@ Status ValidateDiagnostics(const std::vector<Diagnostic>& diagnostics) {
} // namespace
Status NonlinearHdf5ResultsWriter::Write(
Status hdf5_internal::WriteNonlinearFile(
const std::filesystem::path& output_path, const Domain& domain,
const NonlinearAnalysisState& state,
const std::vector<Diagnostic>& diagnostics) {
const std::vector<Diagnostic>& diagnostics, const Mitc4FileHooks& hooks) {
if (output_path.empty() || output_path.filename().empty()) {
return Failure("invalid-output-path", "The HDF5 output path must name a file.");
}
@@ -981,6 +985,11 @@ Status NonlinearHdf5ResultsWriter::Write(
}
try {
for (const auto& frame : state.AcceptedFrames()) {
hdf5_internal::ValidateDrillingEvidence(frame.global_equilibrium, frame.mitc4_drilling);
hdf5_internal::RequireDrilling(frame.mitc4_drilling->mode ==
state.AcceptedFrames().front().mitc4_drilling->mode);
}
hdf5_internal::Hdf5ErrorSilencer silence_backend_errors;
const std::filesystem::path candidate_path =
hdf5_internal::MakeCandidatePath(output_path);
@@ -989,25 +998,29 @@ Status NonlinearHdf5ResultsWriter::Write(
H5Fcreate(candidate_path.string().c_str(), H5F_ACC_EXCL,
H5P_DEFAULT, H5P_DEFAULT),
"Unable to create nonlinear temporary HDF5 file."),
H5Fclose};
hooks.candidate_close};
(void)hdf5_internal::CreateGroup(file.Get(), "/model");
(void)hdf5_internal::CreateGroup(file.Get(), "/model/shell");
(void)hdf5_internal::CreateGroup(file.Get(), "/steps/Step-1");
WriteMetadata(file.Get(), domain);
hdf5_internal::WriteDrillingMetadata(file.Get(), state.AcceptedFrames().front().mitc4_drilling->mode);
WriteNodes(file.Get(), domain);
WriteElements(file.Get(), domain);
WriteModelData(file.Get(), domain, model_data);
WriteAcceptedFrameTable(file.Get(), state.AcceptedFrames());
for (const auto& frame : state.AcceptedFrames()) {
WriteFrame(file.Get(), domain, frame);
hdf5_internal::WriteDrillingFrame(file.Get(),
"/steps/Step-1/frames/" + std::to_string(frame.frame_index), *frame.mitc4_drilling);
}
WriteDiagnostics(file.Get(), diagnostics);
hdf5_internal::RequireHdf5(H5Fflush(file.Get(), H5F_SCOPE_GLOBAL),
"Unable to flush nonlinear temporary HDF5 file.");
hdf5_internal::RequireHdf5(
file.CloseChecked(), "Unable to close nonlinear temporary HDF5 file.");
if (hooks.before_self_check) hooks.before_self_check(candidate_path);
const Status self_check = hdf5_internal::NonlinearSelfCheck(
candidate_path, domain, state, diagnostics.size());
candidate_path, domain, state, diagnostics.size(), hooks.reader_close);
const Status atomic = hdf5_internal::AtomicFinalizeValidatedCandidate(
candidate_path, output_path, self_check);
if (atomic.IsOk()) {
@@ -1021,4 +1034,10 @@ Status NonlinearHdf5ResultsWriter::Write(
}
}
Status NonlinearHdf5ResultsWriter::Write(
const std::filesystem::path& output_path, const Domain& domain,
const NonlinearAnalysisState& state, const std::vector<Diagnostic>& diagnostics) {
return hdf5_internal::WriteNonlinearFile(output_path, domain, state, diagnostics);
}
} // namespace fesa