diff --git a/src/EnergyPlus/ScheduleManager.cc b/src/EnergyPlus/ScheduleManager.cc index 0b71a7a78be..36353173d74 100644 --- a/src/EnergyPlus/ScheduleManager.cc +++ b/src/EnergyPlus/ScheduleManager.cc @@ -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 @@ -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); @@ -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); @@ -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); @@ -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); @@ -4340,7 +4333,7 @@ namespace ScheduleManager { if (MinString == ">") { MinValueOk = (MinValue > Minimum); } else { - MinValueOk = (MinValue >= Minimum); + MinValueOk = (FLT_EPSILON >= Minimum - MinValue); } if (present(Maximum)) { @@ -4348,10 +4341,10 @@ namespace ScheduleManager { if (MaxString() == "<") { MaxValueOk = (MaxValue < Maximum); } else { - MaxValueOk = (MaxValue <= Maximum); + MaxValueOk = (MaxValue - Maximum <= FLT_EPSILON); } } else { - MaxValueOk = (MaxValue <= Maximum); + MaxValueOk = (MaxValue - Maximum <= FLT_EPSILON); } } @@ -4431,7 +4424,7 @@ namespace ScheduleManager { if (MinString == ">") { MinValueOk = (MinValue > Minimum); } else { - MinValueOk = (MinValue >= Minimum); + MinValueOk = (FLT_EPSILON >= Minimum - MinValue); } if (present(Maximum)) { @@ -4439,10 +4432,10 @@ namespace ScheduleManager { if (MaxString() == "<") { MaxValueOk = (MaxValue < Maximum); } else { - MaxValueOk = (MaxValue <= Maximum); + MaxValueOk = (MaxValue - Maximum <= FLT_EPSILON); } } else { - MaxValueOk = (MaxValue <= Maximum); + MaxValueOk = (MaxValue - Maximum <= FLT_EPSILON); } } diff --git a/tst/EnergyPlus/unit/ScheduleManager.unit.cc b/tst/EnergyPlus/unit/ScheduleManager.unit.cc index 5e7a9b6219c..5a3f2264251 100644 --- a/tst/EnergyPlus/unit/ScheduleManager.unit.cc +++ b/tst/EnergyPlus/unit/ScheduleManager.unit.cc @@ -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