Add MITC4 drilling diagnostics output and comparison contract
This commit is contained in:
@@ -23,6 +23,10 @@
|
||||
#include "fesa/fem/dof_manager.h"
|
||||
#include "io/hdf5/hdf5_raii.h"
|
||||
|
||||
#include "io/hdf5/mitc4_drilling_diagnostics.h"
|
||||
|
||||
#include "mitc4_fault_test_helpers.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using fesa::hdf5_internal::Hdf5Handle;
|
||||
@@ -145,6 +149,8 @@ fesa::DynamicAcceptedFrameState MakeFrame(const fesa::Domain& domain,
|
||||
{fesa::ShellSectionPosition::kMiddle, 0.0, {}},
|
||||
{fesa::ShellSectionPosition::kTop, 1.0, {}}}}});
|
||||
}
|
||||
frame.mitc4_drilling = fesa::Mitc4DrillingEvidence{
|
||||
fesa::Mitc4DrillingMode::kDirectSpring, {}, frame.global_equilibrium};
|
||||
return frame;
|
||||
}
|
||||
|
||||
@@ -670,3 +676,58 @@ TEST(DynamicHdf5ResultsWriter, FailedAtomicReplacementPreservesPreviousBytes) {
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
TEST(DynamicHdf5ResultsWriter, DrillingModesIncludeInitialAndEveryAcceptedFrame) {
|
||||
for (const auto mode : {fesa::Mitc4DrillingMode::kDirectSpring,
|
||||
fesa::Mitc4DrillingMode::kLegacyCorotatedTwist}) {
|
||||
auto fixture = MakeFixture();
|
||||
for (std::uint32_t i = 0; i < 3U; ++i) {
|
||||
auto frame = MakeFrame(*fixture.domain, i);
|
||||
frame.mitc4_drilling->mode = mode;
|
||||
ASSERT_TRUE(fixture.state.CommitAcceptedFrame(frame).IsOk());
|
||||
}
|
||||
TempFile path{"drilling-roundtrip"};
|
||||
ASSERT_TRUE(fesa::DynamicHdf5ResultsWriter{}.Write(path.Path(), *fixture.domain, fixture.state, {}).IsOk());
|
||||
Hdf5Handle file{H5Fopen(path.Path().string().c_str(), H5F_ACC_RDONLY, H5P_DEFAULT), H5Fclose};
|
||||
const auto stored = fesa::hdf5_internal::ReadDrillingDiagnostics(file.Get());
|
||||
ASSERT_TRUE(stored);
|
||||
EXPECT_EQ(stored->formulation, fesa::Mitc4DrillingModeName(mode));
|
||||
ASSERT_EQ(stored->frames.size(), 3U);
|
||||
for (std::size_t i = 0; i < 3U; ++i) {
|
||||
EXPECT_EQ(stored->frames[i].frame_index, i);
|
||||
EXPECT_EQ(stored->frames[i].raw_equilibrium, fixture.state.AcceptedFrames()[i].global_equilibrium);
|
||||
EXPECT_EQ(stored->frames[i].equilibrium_with_drilling,
|
||||
fixture.state.AcceptedFrames()[i].mitc4_drilling->equilibrium_with_drilling);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DynamicHdf5ResultsWriter, DrillingMissingActualStatePreservesPriorFinal) {
|
||||
auto fixture = MakeFixture();
|
||||
for (std::uint32_t i = 0; i < 3U; ++i) {
|
||||
auto frame = MakeFrame(*fixture.domain, i);
|
||||
frame.mitc4_drilling.reset();
|
||||
ASSERT_TRUE(fixture.state.CommitAcceptedFrame(frame).IsOk());
|
||||
}
|
||||
TempFile path{"drilling-missing"};
|
||||
std::ofstream(path.Path(), std::ios::binary) << "prior";
|
||||
EXPECT_FALSE(fesa::DynamicHdf5ResultsWriter{}.Write(path.Path(), *fixture.domain, fixture.state, {}).IsOk());
|
||||
std::ifstream stream{path.Path(), std::ios::binary};
|
||||
EXPECT_EQ((std::string{std::istreambuf_iterator<char>{stream}, {}}), "prior");
|
||||
}
|
||||
|
||||
|
||||
TEST(DynamicHdf5ResultsWriter, DrillingLifecycleFaultsPreserveFinalBytes) {
|
||||
auto fixture = MakeFixture();
|
||||
CommitHistory(fixture);
|
||||
TempFile path{"drilling-faults"};
|
||||
for (const std::string fault : {"candidate-close", "reader-close", "markers", "datasets"}) {
|
||||
SCOPED_TRACE(fault);
|
||||
std::ofstream(path.Path(), std::ios::binary | std::ios::trunc) << "prior";
|
||||
EXPECT_FALSE(fesa::hdf5_internal::WriteDynamicFile(path.Path(), *fixture.domain, fixture.state, {},
|
||||
fesa::test::Mitc4LifecycleFault(fault)).IsOk());
|
||||
std::ifstream stream{path.Path(), std::ios::binary};
|
||||
EXPECT_EQ((std::string{std::istreambuf_iterator<char>{stream}, {}}), "prior");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user