Skip to content

Commit

Permalink
Merge pull request #8390 from NREL/outside-range-warning-and-error-wh…
Browse files Browse the repository at this point in the history
…en-using-linear-interpolation

Outside range warning and error when using linear interpolation with Schedule:Day:Interval
  • Loading branch information
Myoldmopar committed Feb 12, 2021
2 parents 0c192f2 + e73d541 commit 1065335
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 23 deletions.
39 changes: 16 additions & 23 deletions src/EnergyPlus/ScheduleManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -930,13 +930,6 @@ namespace ScheduleManager {
}

SchedTypePtr = DaySchedule(Count).ScheduleTypePtr;
if (ScheduleType(SchedTypePtr).Limited) {
if (any_lt(DaySchedule(Count).TSValue, ScheduleType(SchedTypePtr).Minimum) ||
any_gt(DaySchedule(Count).TSValue, ScheduleType(SchedTypePtr).Maximum)) {
ShowWarningError(state, RoutineName + CurrentModuleObject + "=\"" + Alphas(1) + "\", Values are outside of range for " +
cAlphaFields(2) + '=' + Alphas(2));
}
}
if (!ScheduleType(SchedTypePtr).IsReal) {
// Make sure each is integer
NumErrorFlag = false; // only show error message once
Expand Down Expand Up @@ -3795,11 +3788,11 @@ namespace ScheduleManager {
}

// Min/max for schedule has been set. Test.
MinValueOk = (Schedule(ScheduleIndex).MinValue >= Minimum);
MinValueOk = (FLT_EPSILON >= Minimum - Schedule(ScheduleIndex).MinValue);
if (MinString == ">") {
MinValueOk = (Schedule(ScheduleIndex).MinValue > Minimum);
} else {
MinValueOk = (Schedule(ScheduleIndex).MinValue >= Minimum);
MinValueOk = (FLT_EPSILON >= Minimum - Schedule(ScheduleIndex).MinValue);
}

CheckScheduleValueMinMax = (MinValueOk && MaxValueOk);
Expand Down Expand Up @@ -3907,14 +3900,14 @@ namespace ScheduleManager {
if (MinString == ">") {
MinValueOk = (Schedule(ScheduleIndex).MinValue > Minimum);
} else {
MinValueOk = (Schedule(ScheduleIndex).MinValue >= Minimum);
MinValueOk = (FLT_EPSILON >= Minimum - Schedule(ScheduleIndex).MinValue);
}

MaxValueOk = (Schedule(ScheduleIndex).MaxValue <= Maximum);
MaxValueOk = (Schedule(ScheduleIndex).MaxValue - Maximum <= FLT_EPSILON);
if (MaxString == "<") {
MaxValueOk = (Schedule(ScheduleIndex).MaxValue < Maximum);
} else {
MaxValueOk = (Schedule(ScheduleIndex).MaxValue <= Maximum);
MaxValueOk = (Schedule(ScheduleIndex).MaxValue - Maximum <= FLT_EPSILON);
}

CheckScheduleValueMinMax = (MinValueOk && MaxValueOk);
Expand Down Expand Up @@ -4006,11 +3999,11 @@ namespace ScheduleManager {
}

// Min/max for schedule has been set. Test.
MinValueOk = (Schedule(ScheduleIndex).MinValue >= Minimum);
MinValueOk = (FLT_EPSILON >= Minimum - Schedule(ScheduleIndex).MinValue);
if (MinString == ">") {
MinValueOk = (Schedule(ScheduleIndex).MinValue > Minimum);
} else {
MinValueOk = (Schedule(ScheduleIndex).MinValue >= Minimum);
MinValueOk = (FLT_EPSILON >= Minimum - Schedule(ScheduleIndex).MinValue);
}

CheckScheduleValueMinMax = (MinValueOk && MaxValueOk);
Expand Down Expand Up @@ -4109,14 +4102,14 @@ namespace ScheduleManager {
if (MinString == ">") {
MinValueOk = (Schedule(ScheduleIndex).MinValue > Minimum);
} else {
MinValueOk = (Schedule(ScheduleIndex).MinValue >= Minimum);
MinValueOk = (FLT_EPSILON >= Minimum - Schedule(ScheduleIndex).MinValue);
}

MaxValueOk = (Schedule(ScheduleIndex).MaxValue <= Maximum);
MaxValueOk = (Schedule(ScheduleIndex).MaxValue - Maximum <= FLT_EPSILON);
if (MaxString == "<") {
MaxValueOk = (Schedule(ScheduleIndex).MaxValue < Maximum);
} else {
MaxValueOk = (Schedule(ScheduleIndex).MaxValue <= Maximum);
MaxValueOk = (Schedule(ScheduleIndex).MaxValue - Maximum <= FLT_EPSILON);
}

CheckScheduleValueMinMax = (MinValueOk && MaxValueOk);
Expand Down Expand Up @@ -4340,18 +4333,18 @@ namespace ScheduleManager {
if (MinString == ">") {
MinValueOk = (MinValue > Minimum);
} else {
MinValueOk = (MinValue >= Minimum);
MinValueOk = (FLT_EPSILON >= Minimum - MinValue);
}

if (present(Maximum)) {
if (present(MaxString)) {
if (MaxString() == "<") {
MaxValueOk = (MaxValue < Maximum);
} else {
MaxValueOk = (MaxValue <= Maximum);
MaxValueOk = (MaxValue - Maximum <= FLT_EPSILON);
}
} else {
MaxValueOk = (MaxValue <= Maximum);
MaxValueOk = (MaxValue - Maximum <= FLT_EPSILON);
}
}

Expand Down Expand Up @@ -4431,18 +4424,18 @@ namespace ScheduleManager {
if (MinString == ">") {
MinValueOk = (MinValue > Minimum);
} else {
MinValueOk = (MinValue >= Minimum);
MinValueOk = (FLT_EPSILON >= Minimum - MinValue);
}

if (present(Maximum)) {
if (present(MaxString)) {
if (MaxString() == "<") {
MaxValueOk = (MaxValue < Maximum);
} else {
MaxValueOk = (MaxValue <= Maximum);
MaxValueOk = (MaxValue - Maximum <= FLT_EPSILON);
}
} else {
MaxValueOk = (MaxValue <= Maximum);
MaxValueOk = (MaxValue - Maximum <= FLT_EPSILON);
}
}

Expand Down
82 changes: 82 additions & 0 deletions tst/EnergyPlus/unit/ScheduleManager.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,88 @@ TEST_F(EnergyPlusFixture, ScheduleDayInterval_PartialHourLinearInterp)
EXPECT_NEAR(100.001, LookUpScheduleValue(*state, ASchedIndex, 8, 4), 0.000001);
}

TEST_F(EnergyPlusFixture, ScheduleDayInterval_LinearInterpIntervalHittingIntervals)
{
// J.Thomas - Feb 2021

std::string const idf_objects = delimited_string({
// This schedule should cause issues if interpolation issue is not fixed. Got the initial schedule from the unmethours issue.
"ScheduleTypeLimits, ",
" Fractional, !-Name ",
" 0.1, !-Lower Limit Value",
" 0.9, !-Upper Limit Value",
" Continuous; !-Numeric Type",

"Schedule:Day:Interval,",
" 2LLO Weekday, !- Name",
" Fractional, !- Schedule Type Limits Name",
" Linear, !- Interpolate to Timestep",
" 06:00, !- Time 1 {hh:mm}",
" 0.1, !- Value Until Time 1",
" 07:15, !- Time 2 {hh:mm}",
" 0.9, !- Value Until Time 2",
" 16:15, !- Time 3 {hh:mm}",
" 0.1, !- Value Until Time 3",
" 18:15, !- Time 4 {hh:mm}",
" 0.1, !- Value Until Time 4",
" 24:00, !- Time 5 {hh:mm}",
" 0.9; !-Value Until Time 5 ",

"Schedule:Week:Daily,",
" Week Rule - Jan1-Dec31, !- Name",
" 2LLO Weekday, !- Sunday Schedule:Day Name",
" 2LLO Weekday, !- Monday Schedule:Day Name",
" 2LLO Weekday, !- Tuesday Schedule:Day Name",
" 2LLO Weekday, !- Wednesday Schedule:Day Name",
" 2LLO Weekday, !- Thursday Schedule:Day Name",
" 2LLO Weekday, !- Friday Schedule:Day Name",
" 2LLO Weekday, !- Saturday Schedule:Day Name",
" 2LLO Weekday, !- Holiday Schedule:Day Name",
" 2LLO Weekday, !- SummerDesignDay Schedule:Day Name",
" 2LLO Weekday, !- WinterDesignDay Schedule:Day Name",
" 2LLO Weekday, !- CustomDay1 Schedule:Day Name",
" 2LLO Weekday; !- CustomDay2 Schedule:Day Name",

"Schedule:Year,",
" 2LLOYEAR, !- Name ",
" Fractional, !-Schedule Type Limits Name",
" Week Rule - Jan1-Dec31, !- Schedule:Week Name 1",
" 1, !- Start Month 1 ",
" 1, !- Start Day 1",
" 12, !- End Month 1",
" 31; !- End Day 1",
// End of problem schedule
});

ASSERT_TRUE(process_idf(idf_objects));

state->dataGlobal->NumOfTimeStepInHour = 4;
state->dataGlobal->MinutesPerTimeStep = 15;
state->dataGlobal->TimeStepZone = 0.25;

state->dataEnvrn->Month = 1;
state->dataEnvrn->DayOfMonth = 1;
state->dataGlobal->HourOfDay = 1;
state->dataGlobal->TimeStep = 1;
state->dataEnvrn->DSTIndicator = 0;
state->dataEnvrn->DayOfWeek = 2;
state->dataEnvrn->HolidayIndex = 0;
state->dataEnvrn->DayOfYear_Schedule = General::OrdinalDay(state->dataEnvrn->Month, state->dataEnvrn->DayOfMonth, 1);

int ASchedIndex = GetScheduleIndex(*state, "2LLOYEAR"); // interpolate Linear
// Timesteps will go 1,2,3,4; Not 0,1,2,3, Hours to go as (actual hour+1) therefore 7:15 is 8,1
// Check for values specified in schedule (Lower and upper limits)
EXPECT_NEAR(0.1, LookUpScheduleValue(*state, ASchedIndex, 6, 4), 0.000001); // at 6:00
EXPECT_NEAR(0.1, LookUpScheduleValue(*state, ASchedIndex, 17, 1), 0.000001); // at 16:15
EXPECT_NEAR(0.1, LookUpScheduleValue(*state, ASchedIndex, 19, 1), 0.000001); // at 18:15
EXPECT_NEAR(0.9, LookUpScheduleValue(*state, ASchedIndex, 24, 4), 0.000001); // at 24:00

// Interpolation check
EXPECT_NEAR(0.4199999, LookUpScheduleValue(*state, ASchedIndex, 7, 2), 0.000001); // Value at 06:30
EXPECT_NEAR(0.1000000, LookUpScheduleValue(*state, ASchedIndex, 18, 3), 0.000001); // Value at 06:30
EXPECT_NEAR(0.8304347, LookUpScheduleValue(*state, ASchedIndex, 24, 2), 0.000001); // Value at 06:30
}

TEST_F(EnergyPlusFixture, ScheduleDayInterval_LinearInterpIntervalNotTimestep)
{
// J.Glazer - September 2017
Expand Down

4 comments on commit 1065335

@nrel-bot-3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

develop (Myoldmopar) - x86_64-MacOS-10.15-clang-11.0.0: OK (2295 of 2295 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

develop (Myoldmopar) - x86_64-Linux-Ubuntu-18.04-gcc-7.5: OK (2315 of 2315 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

develop (Myoldmopar) - x86_64-Linux-Ubuntu-18.04-gcc-7.5-UnitTestsCoverage-Debug: OK (1576 of 1576 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

develop (Myoldmopar) - x86_64-Linux-Ubuntu-18.04-gcc-7.5-IntegrationCoverage-Debug: OK (722 of 722 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

Please sign in to comment.