109 lines
4.4 KiB
C++
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.);
|
|
}
|