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
@@ -37,6 +37,8 @@
#error FESA_TEST_BINARY_DIR must identify the CMake binary root.
#endif
#include "mitc4_drilling_reader.h"
namespace fesa::test {
namespace {
@@ -896,6 +898,8 @@ std::vector<std::uint8_t> ReadConstraintMask(const hid_t file,
}
struct Hdf5Projection {
std::uint64_t selected_frame_index;
std::optional<Mitc4DrillingDiagnosticsReport> drilling_diagnostics;
std::filesystem::path copied_input_path;
std::vector<Hdf5Node> nodes;
std::vector<double> displacement;
@@ -972,7 +976,7 @@ Hdf5Projection ReadNonlinearHdf5(
const std::uint64_t frame_index = ReadFactorOneFrame(file.Get());
const std::string root = "/steps/Step-1/frames/" +
std::to_string(frame_index) + "/nodal/";
return {copied_input,
return {frame_index, ReadMitc4DrillingReport(file.Get()), copied_input,
nodes,
ReadNodalDataset(file.Get(), root + "displacement",
"UX,UY,UZ,URX,URY,URZ", contract.node_count),
@@ -1320,6 +1324,16 @@ void AppendInternalEquilibrium(NonlinearReferenceComparisonReport* report,
applied_moment_scale += applied_resultant.Norm();
reaction_moment_scale += constrained_resultant.Norm();
}
const std::array<double, 6>* moment_balance = &projection.global_equilibrium;
if (projection.drilling_diagnostics &&
projection.drilling_diagnostics->formulation == "direct-initial-director-spring") {
const auto& frames = projection.drilling_diagnostics->frames;
const auto selected = std::find_if(frames.begin(), frames.end(), [&](const auto& frame) {
return frame.frame_index == projection.selected_frame_index;
});
if (selected == frames.end()) Fail("schema-mismatch", "Missing factor-one drilling diagnostics.");
moment_balance = &selected->equilibrium_with_drilling;
}
report->constrained_reaction_resultant = {
reaction_force.Components(), reaction_moment.Components()};
const std::string prefix = ContractFor(reference_case).family_prefix;
@@ -1329,9 +1343,9 @@ void AppendInternalEquilibrium(NonlinearReferenceComparisonReport* report,
projection.global_equilibrium[2U]},
applied_force_scale, reaction_force_scale);
AppendGlobalBalance(report, prefix + "global_moment_balance",
{projection.global_equilibrium[3U],
projection.global_equilibrium[4U],
projection.global_equilibrium[5U]},
{(*moment_balance)[3U],
(*moment_balance)[4U],
(*moment_balance)[5U]},
applied_moment_scale, reaction_moment_scale);
AppendFreeResidual(report, prefix + "accepted_free_force_residual",
projection, false);
@@ -1385,6 +1399,7 @@ void CompareLinearCase(NonlinearReferenceComparisonReport& report,
: diagnostics.front().message;
Fail("schema-mismatch", message);
}
report.drilling_diagnostics = legacy.Value().drilling_diagnostics;
for (const auto& metric : legacy.Value().metrics) {
ReferenceToleranceFamilyDecision tolerance{};
tolerance.identity = metric.blocking ? "linear.translation" : "linear.rotation";
@@ -1418,6 +1433,7 @@ void CompareNonlinearCase(NonlinearReferenceComparisonReport& report,
report.generated_results_hdf5);
report.copied_input_path = hdf5.copied_input_path;
report.generated_log_path = DerivedLogPath(hdf5.copied_input_path);
report.drilling_diagnostics = hdf5.drilling_diagnostics;
RequireExactNodeLabels(hdf5.nodes, contract.node_count);
const auto displacement_rows = ReadCsvWideRows(
reference_case.displacement_csv_path, true, kDisplacementComponents,
@@ -1475,6 +1491,7 @@ void ComparePressureCase(NonlinearReferenceComparisonReport& report,
ReadNonlinearHdf5(reference_case, report.generated_results_hdf5);
report.copied_input_path = hdf5.copied_input_path;
report.generated_log_path = DerivedLogPath(hdf5.copied_input_path);
report.drilling_diagnostics = hdf5.drilling_diagnostics;
RequireExactNodeLabels(hdf5.nodes, contract.node_count);
RequirePressureInstance(hdf5.nodes);
const auto displacement_rows =