119 lines
4.5 KiB
C++
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());
|
|
}
|
|
|
|
}
|