feat(shell-surface-pressure-load): step 6 - compare-pressure-reference
This commit is contained in:
@@ -62,6 +62,7 @@ struct CaseContract {
|
||||
const CaseContract& ContractFor(const NonlinearReferenceCase& reference_case) {
|
||||
static const CaseContract kCoarse{49U, true, "coarse."};
|
||||
static const CaseContract kFine{729U, true, "fine."};
|
||||
static const CaseContract kPressure{729U, true, "pressure."};
|
||||
static const CaseContract kLinear{49U, false, "linear."};
|
||||
if (reference_case.case_id == "shellnl-s4-final") {
|
||||
return kCoarse;
|
||||
@@ -69,6 +70,9 @@ const CaseContract& ContractFor(const NonlinearReferenceCase& reference_case) {
|
||||
if (reference_case.case_id == "shellnl-meshfine-s4-final") {
|
||||
return kFine;
|
||||
}
|
||||
if (reference_case.case_id == "shellnl-meshfine-pressure-s4-follower") {
|
||||
return kPressure;
|
||||
}
|
||||
if (reference_case.case_id == "shell-s4-linear-limit") {
|
||||
return kLinear;
|
||||
}
|
||||
@@ -276,11 +280,49 @@ std::string Fnv1a64(const std::string& input) {
|
||||
struct DeclaredArtifact {
|
||||
std::filesystem::path path;
|
||||
const char* sha256;
|
||||
std::uintmax_t expected_byte_size{0U};
|
||||
NonlinearReferenceArtifactDisposition disposition{
|
||||
NonlinearReferenceArtifactDisposition::kRequired};
|
||||
};
|
||||
|
||||
std::vector<DeclaredArtifact> DeclaredArtifacts(
|
||||
const NonlinearReferenceCase& reference_case) {
|
||||
const std::filesystem::path root{FESA_TEST_SOURCE_DIR};
|
||||
if (reference_case.case_id == "shellnl-meshfine-pressure-s4-follower") {
|
||||
const auto directory = root / "reference" / "shellNL-meshfine-pressure";
|
||||
const std::vector<DeclaredArtifact> artifacts{
|
||||
{directory / "shellNL-meshfine-pressure.inp",
|
||||
"53718CCC9B41C23FCC1B509A51D66F1347E87ACA43A74F1D6CEC4D2085F4B90E",
|
||||
56665U, reference_case.input_artifact_disposition},
|
||||
{directory / "shellNL-meshfine-pressure displacements.csv",
|
||||
"2FE53F98EAC9F04779100721C3EDF8049EB1DBFE733EBCBD819AEEED03B81198",
|
||||
111182U, reference_case.displacement_artifact_disposition},
|
||||
{directory / "shellNL-meshfine-pressure reactions.csv", nullptr, 0U,
|
||||
reference_case.reaction_artifact_disposition},
|
||||
{directory / "shellNL-meshfine-pressure stresses.csv", nullptr, 0U,
|
||||
reference_case.stress_artifact_disposition}};
|
||||
if (Normalized(reference_case.original_input_path) !=
|
||||
Normalized(artifacts[0U].path) ||
|
||||
Normalized(reference_case.displacement_csv_path) !=
|
||||
Normalized(artifacts[1U].path) ||
|
||||
Normalized(reference_case.reaction_csv_path) !=
|
||||
Normalized(artifacts[2U].path) ||
|
||||
Normalized(reference_case.stress_inventory_path) !=
|
||||
Normalized(artifacts[3U].path) ||
|
||||
reference_case.input_artifact_disposition !=
|
||||
NonlinearReferenceArtifactDisposition::kRequired ||
|
||||
reference_case.displacement_artifact_disposition !=
|
||||
NonlinearReferenceArtifactDisposition::kRequired ||
|
||||
reference_case.reaction_artifact_disposition !=
|
||||
NonlinearReferenceArtifactDisposition::kReviewOnly ||
|
||||
reference_case.stress_artifact_disposition !=
|
||||
NonlinearReferenceArtifactDisposition::kExcluded) {
|
||||
Fail("needs-reference-artifacts",
|
||||
"The pressure reference case does not use its declared artifact "
|
||||
"dispositions.");
|
||||
}
|
||||
return artifacts;
|
||||
}
|
||||
if (reference_case.case_id == "shellnl-meshfine-s4-final") {
|
||||
const auto directory = root / "reference" / "shellNL-meshfine";
|
||||
const std::vector<DeclaredArtifact> artifacts{
|
||||
@@ -364,7 +406,7 @@ ArtifactSnapshot Snapshot(const DeclaredArtifact& artifact) {
|
||||
}
|
||||
const std::string bytes = ReadBytes(artifact.path);
|
||||
const std::string hash = Sha256(bytes);
|
||||
if (hash != artifact.sha256) {
|
||||
if (artifact.sha256 == nullptr || hash != artifact.sha256) {
|
||||
Fail("reference-artifact-hash-mismatch",
|
||||
"A declared reference artifact does not match its approved hash.");
|
||||
}
|
||||
@@ -373,6 +415,11 @@ ArtifactSnapshot Snapshot(const DeclaredArtifact& artifact) {
|
||||
Fail("needs-reference-artifacts",
|
||||
"A declared reference artifact size cannot be read.");
|
||||
}
|
||||
if (artifact.expected_byte_size != 0U &&
|
||||
size != artifact.expected_byte_size) {
|
||||
Fail("reference-artifact-size-mismatch",
|
||||
"A declared reference artifact does not match its approved size.");
|
||||
}
|
||||
const auto write_time = std::filesystem::last_write_time(artifact.path, error);
|
||||
if (error) {
|
||||
Fail("needs-reference-artifacts",
|
||||
@@ -983,6 +1030,17 @@ void RequireExactNodeLabels(const std::vector<Hdf5Node>& nodes,
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Row>
|
||||
void RequirePressureInstance(const std::vector<Row>& rows) {
|
||||
const std::string expected = "PART-1-1";
|
||||
if (!std::all_of(rows.begin(), rows.end(), [&expected](const Row& row) {
|
||||
return UppercaseAscii(row.instance_name) == expected;
|
||||
})) {
|
||||
Fail("schema-mismatch",
|
||||
"The pressure reference instance identity is out of contract.");
|
||||
}
|
||||
}
|
||||
|
||||
std::string Key(const std::string& instance_name,
|
||||
const std::int64_t source_node_label,
|
||||
const std::string& component) {
|
||||
@@ -1411,6 +1469,38 @@ void CompareNonlinearCase(NonlinearReferenceComparisonReport& report,
|
||||
AppendInternalEquilibrium(&report, reference_case, hdf5);
|
||||
}
|
||||
|
||||
void ComparePressureCase(NonlinearReferenceComparisonReport& report,
|
||||
const NonlinearReferenceCase& reference_case) {
|
||||
const CaseContract& contract = ContractFor(reference_case);
|
||||
const auto hdf5 =
|
||||
ReadNonlinearHdf5(reference_case, report.generated_results_hdf5);
|
||||
report.copied_input_path = hdf5.copied_input_path;
|
||||
report.generated_log_path = DerivedLogPath(hdf5.copied_input_path);
|
||||
RequireExactNodeLabels(hdf5.nodes, contract.node_count);
|
||||
RequirePressureInstance(hdf5.nodes);
|
||||
const auto displacement_rows =
|
||||
ReadCsvWideRows(reference_case.displacement_csv_path, true,
|
||||
kDisplacementComponents, contract.node_count);
|
||||
RequireExactNodeLabels(displacement_rows, contract.node_count);
|
||||
RequirePressureInstance(displacement_rows);
|
||||
|
||||
const std::vector<std::size_t> translations{0U, 1U, 2U};
|
||||
const std::vector<std::size_t> rotations{3U, 4U, 5U};
|
||||
const std::vector<std::int64_t> all_nodes;
|
||||
AppendFamily(report, "pressure_nodal_translation_blocking",
|
||||
{"U1", "U2", "U3"}, NonlinearReferenceDisposition::kBlocking,
|
||||
ProjectHdf5(hdf5, hdf5.displacement, kDisplacementComponents,
|
||||
translations, all_nodes),
|
||||
ProjectCsv(displacement_rows, kDisplacementComponents,
|
||||
translations, all_nodes));
|
||||
AppendFamily(report, "pressure_nodal_rotation_warning", {"UR1", "UR2", "UR3"},
|
||||
NonlinearReferenceDisposition::kWarningOnly,
|
||||
ProjectHdf5(hdf5, hdf5.displacement, kDisplacementComponents,
|
||||
rotations, all_nodes),
|
||||
ProjectCsv(displacement_rows, kDisplacementComponents, rotations,
|
||||
all_nodes));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NonlinearInternalEquilibriumReport EvaluateGlobalBalance(
|
||||
@@ -1434,7 +1524,10 @@ Result<std::vector<ArtifactSnapshot>> ArtifactCheck(
|
||||
std::vector<ArtifactSnapshot> snapshots;
|
||||
snapshots.reserve(artifacts.size());
|
||||
for (const auto& artifact : artifacts) {
|
||||
snapshots.push_back(Snapshot(artifact));
|
||||
if (artifact.disposition ==
|
||||
NonlinearReferenceArtifactDisposition::kRequired) {
|
||||
snapshots.push_back(Snapshot(artifact));
|
||||
}
|
||||
}
|
||||
return Result<std::vector<ArtifactSnapshot>>::Success(std::move(snapshots));
|
||||
} catch (const ComparisonFailure& exception) {
|
||||
@@ -1542,8 +1635,11 @@ Result<NonlinearReferenceComparisonReport> CompareHdf5ToReferenceCsv(
|
||||
if (!std::filesystem::is_regular_file(hdf5_results_path)) {
|
||||
Fail("schema-mismatch", "The generated HDF5 result is missing.");
|
||||
}
|
||||
auto report = MakeReport(reference_case, hdf5_results_path, before.Value(), {});
|
||||
if (ContractFor(reference_case).nonlinear) {
|
||||
auto report =
|
||||
MakeReport(reference_case, hdf5_results_path, before.Value(), {});
|
||||
if (reference_case.case_id == "shellnl-meshfine-pressure-s4-follower") {
|
||||
ComparePressureCase(report, reference_case);
|
||||
} else if (ContractFor(reference_case).nonlinear) {
|
||||
CompareNonlinearCase(report, reference_case);
|
||||
} else if (reference_case.case_id == "shell-s4-linear-limit") {
|
||||
CompareLinearCase(report, reference_case);
|
||||
@@ -1552,12 +1648,14 @@ Result<NonlinearReferenceComparisonReport> CompareHdf5ToReferenceCsv(
|
||||
}
|
||||
const auto after = ArtifactCheck(reference_case);
|
||||
if (!after.HasValue()) {
|
||||
return Result<NonlinearReferenceComparisonReport>::Failure(after.GetStatus());
|
||||
return Result<NonlinearReferenceComparisonReport>::Failure(
|
||||
after.GetStatus());
|
||||
}
|
||||
report.post_run_artifacts = after.Value();
|
||||
report.blocking_passed = report.external_blocking_passed &&
|
||||
report.internal_blocking_passed;
|
||||
return Result<NonlinearReferenceComparisonReport>::Success(std::move(report));
|
||||
report.blocking_passed =
|
||||
report.external_blocking_passed && report.internal_blocking_passed;
|
||||
return Result<NonlinearReferenceComparisonReport>::Success(
|
||||
std::move(report));
|
||||
} catch (const ComparisonFailure& exception) {
|
||||
return Result<NonlinearReferenceComparisonReport>::Failure(
|
||||
FailureStatus(reference_case, exception.Code(), exception.what()));
|
||||
|
||||
Reference in New Issue
Block a user