Add MITC4 drilling diagnostics output and comparison contract
This commit is contained in:
@@ -19,6 +19,10 @@
|
||||
#include "fesa/model/domain.h"
|
||||
#include "io/hdf5/eigen_hdf5_self_check.h"
|
||||
|
||||
#include "io/hdf5/mitc4_drilling_diagnostics.h"
|
||||
|
||||
#include "mitc4_fault_test_helpers.h"
|
||||
|
||||
namespace {
|
||||
|
||||
fesa::ModelDefinition Definition(const std::filesystem::path& source) {
|
||||
@@ -81,6 +85,10 @@ TEST(EigenHdf5ResultsWriter, WritesModalSchemaAndRejectsTamperedState) {
|
||||
const hid_t file =
|
||||
H5Fopen(path.string().c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
|
||||
ASSERT_GE(file, 0);
|
||||
const auto drilling = fesa::hdf5_internal::ReadDrillingDiagnostics(file);
|
||||
ASSERT_TRUE(drilling);
|
||||
EXPECT_EQ(drilling->formulation, fesa::Mitc4DrillingModeName(*state.drilling_mode));
|
||||
EXPECT_TRUE(drilling->frames.empty());
|
||||
EXPECT_GT(H5Lexists(file, "/steps/Step-1/eigen/modes", H5P_DEFAULT), 0);
|
||||
const hid_t controls =
|
||||
H5Dopen2(file, "/steps/Step-1/eigen/backend/base_fpm", H5P_DEFAULT);
|
||||
@@ -105,7 +113,8 @@ TEST(EigenHdf5ResultsWriter, WritesModalSchemaAndRejectsTamperedState) {
|
||||
[](auto& candidate) { candidate.constraint_mask[0] = 1U; },
|
||||
[](auto& candidate) { candidate.nodal_reduction[0].rcond_inf = 1e-15; },
|
||||
[](auto& candidate) { candidate.backend.base_fpm[5U] = 1; },
|
||||
[](auto& candidate) { candidate.eta_gram = 1e-5; }};
|
||||
[](auto& candidate) { candidate.eta_gram = 1e-5; },
|
||||
[](auto& candidate) { candidate.drilling_mode.reset(); }};
|
||||
for (const auto& mutate : mutations) {
|
||||
auto candidate = state;
|
||||
mutate(candidate);
|
||||
@@ -133,6 +142,27 @@ TEST(EigenHdf5ResultsWriter, WritesModalSchemaAndRejectsTamperedState) {
|
||||
locked_final.close();
|
||||
ASSERT_TRUE(
|
||||
fesa::hdf5_internal::SelfCheckEigenFile(path, domain, state, {}).IsOk());
|
||||
for (const auto mode : {fesa::Mitc4DrillingMode::kDirectSpring,
|
||||
fesa::Mitc4DrillingMode::kLegacyCorotatedTwist}) {
|
||||
state.drilling_mode = mode;
|
||||
ASSERT_TRUE(writer.Write(path, domain, state, {}).IsOk());
|
||||
fesa::hdf5_internal::Hdf5Handle stored_file{
|
||||
H5Fopen(path.string().c_str(), H5F_ACC_RDONLY, H5P_DEFAULT), H5Fclose};
|
||||
const auto stored = fesa::hdf5_internal::ReadDrillingDiagnostics(stored_file.Get());
|
||||
ASSERT_TRUE(stored);
|
||||
EXPECT_EQ(stored->formulation, fesa::Mitc4DrillingModeName(mode));
|
||||
EXPECT_TRUE(stored->frames.empty());
|
||||
}
|
||||
{
|
||||
fesa::hdf5_internal::Hdf5Handle stored_file{
|
||||
H5Fopen(path.string().c_str(), H5F_ACC_RDWR, H5P_DEFAULT), H5Fclose};
|
||||
fesa::hdf5_internal::Hdf5Handle metadata{
|
||||
H5Gopen2(stored_file.Get(), "/metadata", H5P_DEFAULT), H5Gclose};
|
||||
ASSERT_GE(H5Adelete(metadata.Get(), "mitc4_drilling_formulation"), 0);
|
||||
ASSERT_GE(H5Adelete(metadata.Get(), "drilling_diagnostics_version"), 0);
|
||||
}
|
||||
EXPECT_FALSE(fesa::hdf5_internal::SelfCheckEigenFile(path, domain, state, {}).IsOk());
|
||||
ASSERT_TRUE(writer.Write(path, domain, state, {}).IsOk());
|
||||
const hid_t corrupt_file =
|
||||
H5Fopen(path.string().c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
|
||||
ASSERT_GE(corrupt_file, 0);
|
||||
@@ -153,3 +183,22 @@ TEST(EigenHdf5ResultsWriter, WritesModalSchemaAndRejectsTamperedState) {
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
TEST(EigenHdf5ResultsWriter, DrillingLifecycleFaultsPreserveFinalBytes) {
|
||||
const auto path = std::filesystem::temp_directory_path() / "fesa-eigen-drilling-fault.h5";
|
||||
auto domain = fesa::Domain::Create(Definition(path.parent_path() / "shell.inp"));
|
||||
ASSERT_TRUE(domain.HasValue());
|
||||
auto state = fesa::LinearFrequencyProcedureExecutor{}.Execute(domain.Value());
|
||||
ASSERT_TRUE(state.HasValue());
|
||||
for (const std::string fault : {"candidate-close", "reader-close", "markers"}) {
|
||||
SCOPED_TRACE(fault);
|
||||
std::ofstream(path, std::ios::binary | std::ios::trunc) << "prior";
|
||||
EXPECT_FALSE(fesa::hdf5_internal::WriteEigenFile(path, domain.Value(), state.Value(), {},
|
||||
fesa::test::Mitc4LifecycleFault(fault)).IsOk());
|
||||
std::ifstream stream{path, std::ios::binary};
|
||||
EXPECT_EQ((std::string{std::istreambuf_iterator<char>{stream}, {}}), "prior");
|
||||
}
|
||||
std::error_code ignored;
|
||||
std::filesystem::remove(path, ignored);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user