Files
FESADev/tests/reference/reference_tolerance_policy_test.cpp
T
2026-08-18 02:29:26 +09:00

119 lines
4.5 KiB
C++

#include "reference_tolerance_policy.h"
#include <gtest/gtest.h>
#include <algorithm>
#include <cmath>
#include <limits>
#include <string>
#include <utility>
#include <vector>
namespace {
using fesa::test::ReferenceToleranceBranch;
using fesa::test::ReferenceToleranceFamily;
using fesa::test::ReferenceTolerancePolicy;
using fesa::test::ReferenceToleranceRow;
ReferenceToleranceFamily MakeFamily(std::string identity,
std::vector<std::string> components,
bool blocking,
std::vector<ReferenceToleranceRow> rows) {
return {std::move(identity), std::move(components), blocking,
std::move(rows)};
}
TEST(ReferenceTolerancePolicy,
AppliesRelativeAndNearZeroThresholdsAtTheirInclusiveBoundaries) {
const auto evaluation = ReferenceTolerancePolicy::Evaluate({MakeFamily(
"displacement-translation", {"UX", "UY", "UZ"}, true,
{{105.0, 100.0}, {105.001, 100.0}, {2.0, 1.0}, {2.001, 1.0}})});
ASSERT_TRUE(evaluation.valid);
ASSERT_EQ(evaluation.families.size(), 1U);
const auto& family = evaluation.families.front();
EXPECT_EQ(family.row_count, 4U);
EXPECT_DOUBLE_EQ(family.reference_scale, 100.0);
EXPECT_DOUBLE_EQ(family.near_zero_band, 1.0);
EXPECT_EQ(family.near_zero_count, 2U);
EXPECT_FALSE(family.passed);
ASSERT_EQ(family.rows.size(), 4U);
EXPECT_EQ(family.rows[0U].branch, ReferenceToleranceBranch::kRelative);
EXPECT_TRUE(family.rows[0U].relative_error_applicable);
EXPECT_DOUBLE_EQ(family.rows[0U].relative_error, 0.05);
EXPECT_DOUBLE_EQ(family.rows[0U].threshold, 5.0);
EXPECT_TRUE(family.rows[0U].passed);
EXPECT_FALSE(family.rows[1U].passed);
EXPECT_EQ(family.rows[2U].branch, ReferenceToleranceBranch::kNearZero);
EXPECT_FALSE(family.rows[2U].relative_error_applicable);
EXPECT_DOUBLE_EQ(family.rows[2U].threshold, 1.0);
EXPECT_TRUE(family.rows[2U].passed);
EXPECT_FALSE(family.rows[3U].passed);
}
TEST(ReferenceTolerancePolicy,
RejectsFamiliesWhoseScaleRelativeRmsExceedsOnePercent) {
const auto evaluation = ReferenceTolerancePolicy::Evaluate({MakeFamily(
"reaction-force", {"RF1", "RF2", "RF3"}, true,
{{101.1, 100.0}, {101.1, 100.0}, {101.1, 100.0}, {101.1, 100.0}})});
ASSERT_TRUE(evaluation.valid);
const auto& family = evaluation.families.front();
EXPECT_EQ(family.row_count, 4U);
EXPECT_TRUE(std::all_of(family.rows.begin(), family.rows.end(),
[](const auto& row) { return row.passed; }));
EXPECT_NEAR(family.relative_rms, 0.011, 1.0e-15);
EXPECT_FALSE(family.rms_passed);
EXPECT_FALSE(family.passed);
EXPECT_FALSE(evaluation.passed);
}
TEST(ReferenceTolerancePolicy,
FailsClosedForZeroScaleNonzeroErrorWithoutNonfiniteMetrics) {
const auto evaluation = ReferenceTolerancePolicy::Evaluate(
{MakeFamily("section-force", {"N"}, true, {{0.0, 0.0}, {1.0, 0.0}})});
ASSERT_TRUE(evaluation.valid);
const auto& family = evaluation.families.front();
EXPECT_EQ(family.row_count, 2U);
EXPECT_DOUBLE_EQ(family.reference_scale, 0.0);
EXPECT_DOUBLE_EQ(family.near_zero_band, 0.0);
EXPECT_EQ(family.near_zero_count, 2U);
EXPECT_EQ(family.diagnostic_code, "zero-reference-scale-nonzero-error");
EXPECT_EQ(family.rows[0U].branch, ReferenceToleranceBranch::kZeroScaleExact);
EXPECT_TRUE(family.rows[0U].passed);
EXPECT_FALSE(family.rows[1U].passed);
EXPECT_FALSE(family.rows[1U].relative_error_applicable);
EXPECT_TRUE(std::isfinite(family.relative_rms));
EXPECT_DOUBLE_EQ(family.relative_rms, 0.0);
EXPECT_FALSE(family.rms_passed);
EXPECT_FALSE(family.passed);
}
TEST(ReferenceTolerancePolicy,
KeepsWarningOnlyFamilyExceedanceOutOfBlockingVerdict) {
const auto evaluation = ReferenceTolerancePolicy::Evaluate(
{MakeFamily("translation", {"U1", "U2", "U3"}, true, {{0.0, 0.0}}),
MakeFamily("rotation", {"UR1", "UR2", "UR3"}, false, {{1.0, 0.0}})});
ASSERT_TRUE(evaluation.valid);
ASSERT_EQ(evaluation.families.size(), 2U);
EXPECT_TRUE(evaluation.families[0U].passed);
EXPECT_FALSE(evaluation.families[1U].passed);
EXPECT_TRUE(evaluation.passed);
}
TEST(ReferenceTolerancePolicy,
RejectsNonfiniteInputsBeforeToleranceEvaluation) {
const auto evaluation = ReferenceTolerancePolicy::Evaluate(
{MakeFamily("displacement-translation", {"UX", "UY", "UZ"}, true,
{{std::numeric_limits<double>::quiet_NaN(), 0.0}})});
EXPECT_FALSE(evaluation.valid);
EXPECT_EQ(evaluation.diagnostic_code, "nonfinite-comparison-value");
EXPECT_TRUE(evaluation.families.empty());
}
}