Files
FESADev/tests/unit/analysis/thermal_time_grid_test.cpp
T

109 lines
4.4 KiB
C++

#include "fesa/analysis/thermal_time_grid.h"
#include <gtest/gtest.h>
#include <cmath>
#include <limits>
TEST(ThermalTimeGrid, SingleStepUsesPeriodAsActualIncrement) {
const auto grid = fesa::ThermalTimeGrid::Create(2.0, 3.0, 1U);
ASSERT_TRUE(grid.HasValue());
EXPECT_EQ(grid.Value().Count(), 1U);
EXPECT_EQ(grid.Value().Delta(1U), 2.0);
}
TEST(ThermalTimeGrid, PreservesGenuineRemainderOutsideInputCells) {
const auto grid =
fesa::ThermalTimeGrid::Create(std::nextafter(.9, 1.0), .3, 4U);
ASSERT_TRUE(grid.HasValue());
EXPECT_EQ(grid.Value().Count(), 4U);
EXPECT_EQ(grid.Value().Delta(4U), 1.6653345369377348e-16);
}
TEST(ThermalTimeGrid, OriginalSubnormalCellsRespectOpenAndClosedContact) {
const double tiny = std::numeric_limits<double>::denorm_min();
const auto even = fesa::ThermalTimeGrid::Create(20 * tiny, 6 * tiny, 4U);
const auto odd = fesa::ThermalTimeGrid::Create(17 * tiny, 5 * tiny, 4U);
ASSERT_TRUE(even.HasValue());
ASSERT_TRUE(odd.HasValue());
EXPECT_EQ(even.Value().Count(), 3U);
EXPECT_EQ(odd.Value().Count(), 4U);
EXPECT_EQ(odd.Value().Delta(4U), 2 * tiny);
}
TEST(ThermalTimeGrid, DecimalCellsCounterexampleAndScale) {
for (const int exponent : {-1000, 0, 1000}) {
const double period = std::ldexp(.9, exponent);
const double delta = std::ldexp(.3, exponent);
const auto grid = fesa::ThermalTimeGrid::Create(period, delta, 3U);
ASSERT_TRUE(grid.HasValue());
EXPECT_EQ(grid.Value().Count(), 3U);
EXPECT_EQ(grid.Value().Delta(3U), delta);
EXPECT_EQ(grid.Value().Time(3U), period);
}
const auto old_counterexample =
fesa::ThermalTimeGrid::Create(5.351455173733616, .17262758624947144, 31U);
ASSERT_TRUE(old_counterexample.HasValue());
EXPECT_EQ(old_counterexample.Value().Count(), 31U);
EXPECT_EQ(old_counterexample.Value().Delta(31U), .17262758624947144);
EXPECT_FALSE(
fesa::ThermalTimeGrid::Create(5.351455173733616, .17262758624947144, 30U)
.HasValue());
}
TEST(ThermalTimeGrid, BinadeLimitsAndMaximumFinitePreserveOriginalCells) {
const double max = std::numeric_limits<double>::max();
const auto grid = fesa::ThermalTimeGrid::Create(max, max / 3, 3U);
ASSERT_TRUE(grid.HasValue());
EXPECT_EQ(grid.Value().Count(), 3U);
EXPECT_EQ(grid.Value().Delta(3U), max / 3);
const auto upper =
fesa::ThermalTimeGrid::Create(4294967295., 1., 4294967295U);
ASSERT_TRUE(upper.HasValue());
EXPECT_EQ(upper.Value().Count(), 4294967295U);
EXPECT_TRUE(upper.Value().Frame(4294967295U).HasValue());
EXPECT_FALSE(
fesa::ThermalTimeGrid::Create(4294967296., 1., 4294967295U).HasValue());
EXPECT_FALSE(fesa::ThermalTimeGrid::Create(
max, std::numeric_limits<double>::denorm_min(), 4294967295U)
.HasValue());
}
TEST(ThermalTimeGrid, ShortenedIncrementAndCheckedFrames) {
const auto grid = fesa::ThermalTimeGrid::Create(10., 3., 4U);
ASSERT_TRUE(grid.HasValue());
EXPECT_EQ(grid.Value().Count(), 4U);
EXPECT_EQ(grid.Value().Time(0U), 0.);
for (std::uint32_t i = 1; i <= 4; ++i) {
ASSERT_TRUE(grid.Value().Frame(i).HasValue());
EXPECT_EQ(grid.Value().Time(i), i == 4 ? 10. : 3. * i);
EXPECT_EQ(grid.Value().Delta(i), i == 4 ? 1. : 3.);
}
EXPECT_FALSE(grid.Value().Frame(0U).HasValue());
EXPECT_FALSE(grid.Value().Frame(5U).HasValue());
const auto decimals = fesa::ThermalTimeGrid::Create(1., .1);
ASSERT_TRUE(decimals.HasValue());
EXPECT_EQ(decimals.Value().Time(3U), .30000000000000004);
EXPECT_EQ(decimals.Value().Delta(10U), .1);
const double below = std::nextafter(.9, 0.);
const auto close = fesa::ThermalTimeGrid::Create(below, .3, 3U);
const auto short_last =
fesa::ThermalTimeGrid::Create(std::nextafter(below, 0.), .3, 3U);
ASSERT_TRUE(close.HasValue());
ASSERT_TRUE(short_last.HasValue());
EXPECT_EQ(close.Value().Delta(3U), .3);
EXPECT_EQ(short_last.Value().Delta(3U), .2999999999999998);
}
TEST(ThermalTimeGrid, RejectsInvalidControlsBeforeIntegerConversion) {
for (double bad : {0., -1., std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::quiet_NaN()}) {
EXPECT_FALSE(fesa::ThermalTimeGrid::Create(bad, 1.).HasValue());
EXPECT_FALSE(fesa::ThermalTimeGrid::Create(1., bad).HasValue());
}
EXPECT_FALSE(fesa::ThermalTimeGrid::Create(1., 1., 0U).HasValue());
const auto equal = fesa::ThermalTimeGrid::Create(2., 2., 1U);
ASSERT_TRUE(equal.HasValue());
EXPECT_EQ(equal.Value().Delta(1U), 2.);
}