From 8adf825f22a5eced8f43df3da491a039505128f6 Mon Sep 17 00:00:00 2001 From: Jason Glazer Date: Tue, 5 Sep 2023 09:47:23 -0500 Subject: [PATCH 01/12] Change blank name to severe instead of fatal. --- src/EnergyPlus/OutputReportTabular.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EnergyPlus/OutputReportTabular.cc b/src/EnergyPlus/OutputReportTabular.cc index 0aaadc08999..2481caa04d0 100644 --- a/src/EnergyPlus/OutputReportTabular.cc +++ b/src/EnergyPlus/OutputReportTabular.cc @@ -1501,7 +1501,7 @@ void GetInputOutputTableSummaryReports(EnergyPlusData &state) for (int iReport = 1; iReport <= NumAlphas; ++iReport) { bool nameFound = false; if (AlphArray(iReport).empty()) { - ShowFatalError(state, "Blank report name in Output:Table:SummaryReports"); + ShowSevereError(state, "Blank report name in Output:Table:SummaryReports"); } else if (UtilityRoutines::SameString(AlphArray(iReport), "AnnualBuildingUtilityPerformanceSummary")) { ort->displayTabularBEPS = true; ort->WriteTabularFiles = true; From aceec2b10138fdebd23724703b26df2fa4d8b43f Mon Sep 17 00:00:00 2001 From: Jason Glazer Date: Tue, 5 Sep 2023 11:48:51 -0500 Subject: [PATCH 02/12] Change to Warning for blank in output tabular summary reports --- src/EnergyPlus/OutputReportTabular.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EnergyPlus/OutputReportTabular.cc b/src/EnergyPlus/OutputReportTabular.cc index 2481caa04d0..335c257615c 100644 --- a/src/EnergyPlus/OutputReportTabular.cc +++ b/src/EnergyPlus/OutputReportTabular.cc @@ -1501,7 +1501,7 @@ void GetInputOutputTableSummaryReports(EnergyPlusData &state) for (int iReport = 1; iReport <= NumAlphas; ++iReport) { bool nameFound = false; if (AlphArray(iReport).empty()) { - ShowSevereError(state, "Blank report name in Output:Table:SummaryReports"); + ShowWarningError(state, "Blank report name in Output:Table:SummaryReports"); } else if (UtilityRoutines::SameString(AlphArray(iReport), "AnnualBuildingUtilityPerformanceSummary")) { ort->displayTabularBEPS = true; ort->WriteTabularFiles = true; From 2e389465c06c2581aadfaa6858f8c4116c8da1ac Mon Sep 17 00:00:00 2001 From: Jason Glazer Date: Tue, 5 Sep 2023 13:45:29 -0500 Subject: [PATCH 03/12] For missing columns in annual reports, changed to a warning and don't add to vector --- src/EnergyPlus/OutputReportTabularAnnual.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/OutputReportTabularAnnual.cc b/src/EnergyPlus/OutputReportTabularAnnual.cc index d191cf9b5ac..c63ade3f1c7 100644 --- a/src/EnergyPlus/OutputReportTabularAnnual.cc +++ b/src/EnergyPlus/OutputReportTabularAnnual.cc @@ -130,7 +130,11 @@ void GetInputTabularAnnual(EnergyPlusData &state) for (jAlpha = 4; jAlpha <= numAlphas; jAlpha += 2) { curVarMtr = alphArray(jAlpha); if (curVarMtr.empty()) { - ShowFatalError(state, "Blank report name in Output:Table:Annual"); + ShowWarningError( + state, + format("{}: Blank column specified in '{}', need to provide a variable or meter or EMS variable name ", + currentModuleObject, + alphArray(1))); } if (jAlpha <= numAlphas) { std::string aggregationString = alphArray(jAlpha + 1); @@ -144,7 +148,9 @@ void GetInputTabularAnnual(EnergyPlusData &state) } else { curNumDgts = 2; } - annualTables.back().addFieldSet(curVarMtr, curAgg, curNumDgts); + if (!curVarMtr.empty()) { + annualTables.back().addFieldSet(curVarMtr, curAgg, curNumDgts); + } } annualTables.back().setupGathering(state); } else { From 214379d7234895c0ca51f36b274e8bf695a47e03 Mon Sep 17 00:00:00 2001 From: Jason Glazer Date: Tue, 5 Sep 2023 14:08:35 -0500 Subject: [PATCH 04/12] Change missing column for monthly reports to a warning and make warning more informative. --- src/EnergyPlus/OutputReportTabular.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/EnergyPlus/OutputReportTabular.cc b/src/EnergyPlus/OutputReportTabular.cc index 335c257615c..66a69b1aede 100644 --- a/src/EnergyPlus/OutputReportTabular.cc +++ b/src/EnergyPlus/OutputReportTabular.cc @@ -366,7 +366,10 @@ void GetInputTabularMonthly(EnergyPlusData &state) int const curTable = AddMonthlyReport(state, AlphArray(1), int(NumArray(1))); for (int jField = 2; jField <= NumAlphas; jField += 2) { if (AlphArray(jField).empty()) { - ShowFatalError(state, "Blank report name in Output:Table:Monthly"); + ShowWarningError(state, + format("{}: Blank column specified in '{}', need to provide a variable or meter name ", + CurrentModuleObject, + ort->MonthlyInput(TabNum).name)); } std::string const curAggString = AlphArray(jField + 1); AggType curAggType; // kind of aggregation identified (see AggType parameters) @@ -402,7 +405,9 @@ void GetInputTabularMonthly(EnergyPlusData &state) ShowWarningError(state, format("{}={}, Variable name={}", CurrentModuleObject, ort->MonthlyInput(TabNum).name, AlphArray(jField))); ShowContinueError(state, format("Invalid aggregation type=\"{}\" Defaulting to SumOrAverage.", curAggString)); } - AddMonthlyFieldSetInput(state, curTable, AlphArray(jField), "", curAggType); + if (!AlphArray(jField).empty()) { + AddMonthlyFieldSetInput(state, curTable, AlphArray(jField), "", curAggType); + } } } } From 0407dddb0775fb301fb1f0cceeb689a36c6c326d Mon Sep 17 00:00:00 2001 From: Jason Glazer Date: Tue, 5 Sep 2023 14:11:11 -0500 Subject: [PATCH 05/12] Some reformatting --- src/EnergyPlus/OutputReportTabularAnnual.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/EnergyPlus/OutputReportTabularAnnual.cc b/src/EnergyPlus/OutputReportTabularAnnual.cc index c63ade3f1c7..613974155ce 100644 --- a/src/EnergyPlus/OutputReportTabularAnnual.cc +++ b/src/EnergyPlus/OutputReportTabularAnnual.cc @@ -130,11 +130,10 @@ void GetInputTabularAnnual(EnergyPlusData &state) for (jAlpha = 4; jAlpha <= numAlphas; jAlpha += 2) { curVarMtr = alphArray(jAlpha); if (curVarMtr.empty()) { - ShowWarningError( - state, - format("{}: Blank column specified in '{}', need to provide a variable or meter or EMS variable name ", - currentModuleObject, - alphArray(1))); + ShowWarningError(state, + format("{}: Blank column specified in '{}', need to provide a variable or meter or EMS variable name ", + currentModuleObject, + alphArray(1))); } if (jAlpha <= numAlphas) { std::string aggregationString = alphArray(jAlpha + 1); From c196cce2fb6b0a42b82ad61dee98d787911dd214 Mon Sep 17 00:00:00 2001 From: rraustad Date: Fri, 15 Sep 2023 22:04:12 -0400 Subject: [PATCH 06/12] Move 10135 to new branch --- src/EnergyPlus/ZoneTempPredictorCorrector.cc | 156 ++++++++---------- tst/EnergyPlus/unit/UnitarySystem.unit.cc | 18 +- .../unit/ZoneTempPredictorCorrector.unit.cc | 13 ++ 3 files changed, 91 insertions(+), 96 deletions(-) diff --git a/src/EnergyPlus/ZoneTempPredictorCorrector.cc b/src/EnergyPlus/ZoneTempPredictorCorrector.cc index 30e8d7cce6a..66de3fc4495 100644 --- a/src/EnergyPlus/ZoneTempPredictorCorrector.cc +++ b/src/EnergyPlus/ZoneTempPredictorCorrector.cc @@ -5012,114 +5012,96 @@ void DownInterpolate4HistoryValues(Real64 const OldTimeStep, // The down step ratio, DSRatio = OldTimeStep/ NewTimeStep // is expected to be roughly integer-valued and near 2.0 or 3.0 or 4.0 or more. - // first construct data on timestamps for interpolating with later - Real64 const oldTime0 = 0.0; - Real64 const oldTime1 = oldTime0 - OldTimeStep; - - Real64 const newTime0 = 0.0; - Real64 const newTime1 = newTime0 - NewTimeStep; - Real64 const newTime2 = newTime1 - NewTimeStep; - Real64 const newTime3 = newTime2 - NewTimeStep; - Real64 const newTime4 = newTime3 - NewTimeStep; - + // old math variables + // Real64 const oldTime0 = 0.0; + // Real64 const oldTime1 = oldTime0 - OldTimeStep; + // Real64 const newTime0 = 0.0; + // Real64 const newTime1 = newTime0 - NewTimeStep; + // Real64 const newTime2 = newTime1 - NewTimeStep; + // Real64 const newTime3 = newTime2 - NewTimeStep; + // Real64 const newTime4 = newTime3 - NewTimeStep; + + Real64 constexpr realTWO = 2.0; + Real64 constexpr realTHREE = 3.0; + // first determine the ratio of system time step to zone time step Real64 const DSRatio = OldTimeStep / NewTimeStep; // should pretty much be an integer value 2, 3, 4, etc. newVal0 = oldVal0; - if (std::abs(DSRatio - 2.0) < 0.01) { // DSRatio = 2 + if (std::abs(DSRatio - realTWO) < 0.01) { // DSRatio = 2 + // when DSRatio = 2 the 1st point lies exactly between old points, and 2nd point is old 1st point // first two points lie between oldVal0 and oldVal1 - newVal1 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime1) / (OldTimeStep)); - newVal2 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime2) / (OldTimeStep)); + // old math example + // newVal1 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime1) / (OldTimeStep)); + // newVal2 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime2) / (OldTimeStep)); + newVal1 = (oldVal0 + oldVal1) / realTWO; + newVal2 = oldVal1; + // when DSRatio = 2 the 3rd point lies exactly between old points, and 4th point is old 2nd point // last two points lie between oldVal1 and oldVal2 - newVal3 = oldVal1 + (oldVal2 - oldVal1) * ((oldTime1 - newTime3) / (OldTimeStep)); - newVal4 = oldVal1 + (oldVal2 - oldVal1) * ((oldTime1 - newTime4) / (OldTimeStep)); - } else if (std::abs(DSRatio - 3.0) < 0.01) { // DSRatio = 3 + // newVal3 = oldVal1 + (oldVal2 - oldVal1) * ((oldTime1 - newTime3) / (OldTimeStep)); + // newVal4 = oldVal1 + (oldVal2 - oldVal1) * ((oldTime1 - newTime4) / (OldTimeStep)); + newVal3 = (oldVal1 + oldVal2) / realTWO; + newVal4 = oldVal2; + } else if (std::abs(DSRatio - realTHREE) < 0.01) { // DSRatio = 3 + // when DSRatio = 3 the 1st point lies 1/3 way between old points, and 2nd and 3rd points are 2/3 and 3/3 the way // first three points lie between oldVal0 and oldVal1 - newVal1 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime1) / (OldTimeStep)); - newVal2 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime2) / (OldTimeStep)); - newVal3 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime3) / (OldTimeStep)); - // last point lie between oldVal1 and oldVal2 - newVal4 = oldVal1 + (oldVal2 - oldVal1) * ((oldTime1 - newTime4) / (OldTimeStep)); + // newVal1 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime1) / (OldTimeStep)); + // newVal2 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime2) / (OldTimeStep)); + // newVal3 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime3) / (OldTimeStep)); + Real64 delta10 = (oldVal1 - oldVal0) / realTHREE; + newVal1 = oldVal0 + delta10; + newVal2 = newVal1 + delta10; + newVal3 = oldVal1; + // last point lies 1/3 way between oldVal1 and oldVal2 + // newVal4 = oldVal1 + (oldVal2 - oldVal1) * ((oldTime1 - newTime4) / (OldTimeStep)); + newVal4 = oldVal1 + (oldVal2 - oldVal1) / realTHREE; } else { // DSRatio = 4 or more - // all new points lie between oldVal0 and oldVal1 - newVal1 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime1) / (OldTimeStep)); - newVal2 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime2) / (OldTimeStep)); - newVal3 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime3) / (OldTimeStep)); - newVal4 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime4) / (OldTimeStep)); + // all new points lie between oldVal0 and oldVal1 (if DSRatio = 4, newVal4 = oldVal1) + // newVal1 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime1) / (OldTimeStep)); + // newVal2 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime2) / (OldTimeStep)); + // newVal3 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime3) / (OldTimeStep)); + // newVal4 = oldVal0 + (oldVal1 - oldVal0) * ((oldTime0 - newTime4) / (OldTimeStep)); + Real64 delta10 = (oldVal1 - oldVal0) / DSRatio; + newVal1 = oldVal0 + delta10; + newVal2 = newVal1 + delta10; + newVal3 = newVal2 + delta10; + newVal4 = newVal3 + delta10; } } Real64 DownInterpolate4HistoryValues(Real64 OldTimeStep, Real64 NewTimeStep, std::array const &oldVals, std::array &newVals) { - // first construct data on timestamps for interpolating with later - Real64 const oldTime0 = 0.0; - Real64 const oldTime1 = oldTime0 - OldTimeStep; + Real64 constexpr realTWO = 2.0; + Real64 constexpr realTHREE = 3.0; + // first determine the ratio of system time step to zone time step + Real64 const DSRatio = OldTimeStep / NewTimeStep; // should pretty much be an integer value 2, 3, 4, etc. - Real64 const newTime0 = 0.0; - Real64 const newTime1 = newTime0 - NewTimeStep; - Real64 const newTime2 = newTime1 - NewTimeStep; - Real64 const newTime3 = newTime2 - NewTimeStep; - Real64 const newTime4 = newTime3 - NewTimeStep; + newVals[0] = oldVals[0]; - Real64 const DSRatio = OldTimeStep / NewTimeStep; // should pretty much be an integer value 2, 3, 4, etc. + if (std::abs(DSRatio - realTWO) < 0.01) { // DSRatio = 2 + // first point lies exactly between (oldVals[0] and oldVals[1]) + newVals[1] = (oldVals[0] + oldVals[1]) / realTWO; + // 2nd point is oldVal[1] and last point lies exactly between (oldVals[1] and oldVals[2]) + newVals[2] = oldVals[1]; + newVals[3] = (oldVals[1] + oldVals[2]) / realTWO; - if (std::abs(DSRatio - 2.0) < 0.01) { // DSRatio = 2 - // first two points lie between oldVals[0] and oldVals[1] - Real64 delta10 = oldVals[1] - oldVals[0]; - newVals[0] = oldVals[0] + delta10 * ((oldTime0 - newTime1) / OldTimeStep); - newVals[1] = oldVals[0] + delta10 * ((oldTime0 - newTime2) / OldTimeStep); - // last two points lie between oldVals[1] and oldVals[2] - Real64 delta21 = oldVals[2] - oldVals[1]; - newVals[2] = oldVals[1] + delta21 * ((oldTime1 - newTime3) / OldTimeStep); - newVals[3] = oldVals[1] + delta21 * ((oldTime1 - newTime4) / OldTimeStep); - } else if (std::abs(DSRatio - 3.0) < 0.01) { // DSRatio = 3 - // first three points lie between oldVals[0] and oldVals[1] - Real64 delta10 = oldVals[1] - oldVals[0]; - newVals[0] = oldVals[0] + delta10 * ((oldTime0 - newTime1) / OldTimeStep); - newVals[1] = oldVals[0] + delta10 * ((oldTime0 - newTime2) / OldTimeStep); - newVals[2] = oldVals[0] + delta10 * ((oldTime0 - newTime3) / OldTimeStep); - // last point lie between oldVals[1] and oldVals[2] - Real64 delta21 = (oldVals[2] - oldVals[1]) / OldTimeStep; - newVals[3] = oldVals[1] + delta21 * ((oldTime1 - newTime4) / OldTimeStep); + } else if (std::abs(DSRatio - realTHREE) < 0.01) { // DSRatio = 3 + // first two points lie between (oldVals[0] and oldVals[1]) + Real64 delta10 = (oldVals[1] - oldVals[0]) / realTHREE; + newVals[1] = oldVals[0] + delta10; + newVals[2] = newVals[1] + delta10; + // last point is oldVals[1] + newVals[3] = oldVals[1]; } else { // DSRatio = 4 or more - // all new points lie between oldVals[0] and oldVals[1] - Real64 delta10 = oldVals[1] - oldVals[0]; - newVals[0] = oldVals[0] + delta10 * ((oldTime0 - newTime1) / OldTimeStep); - newVals[1] = oldVals[0] + delta10 * ((oldTime0 - newTime2) / OldTimeStep); - newVals[2] = oldVals[0] + delta10 * ((oldTime0 - newTime3) / OldTimeStep); - newVals[3] = oldVals[0] + delta10 * ((oldTime0 - newTime4) / OldTimeStep); + // all new points lie between (oldVals[0] and oldVals[1]) + Real64 delta10 = (oldVals[1] - oldVals[0]) / DSRatio; + newVals[1] = oldVals[0] + delta10; + newVals[2] = newVals[1] + delta10; + newVals[3] = newVals[2] + delta10; } return oldVals[0]; - - // if (std::abs(DSRatio - 2.0) < 0.01) { // DSRatio = 2 - // // first two points lie between oldVals[0] and oldVals[1] - // Real64 ratio10 = (oldVals[1] - oldVals[0]) / OldTimeStep; - // newVals[0] = oldVals[0] + ratio10 * (oldTime0 - newTime1); - // newVals[1] = oldVals[0] + ratio10 * (oldTime0 - newTime2); - // // last two points lie between oldVals[1] and oldVals[2] - // Real64 ratio21 = (oldVals[2] - oldVals[1]) / OldTimeStep; - // newVals[2] = oldVals[1] + ratio21 * (oldTime1 - newTime3); - // newVals[3] = oldVals[1] + ratio21 * (oldTime1 - newTime4); - // } else if (std::abs(DSRatio - 3.0) < 0.01) { // DSRatio = 3 - // // first three points lie between oldVals[0] and oldVals[1] - // Real64 ratio10 = (oldVals[1] - oldVals[0]) / OldTimeStep; - // newVals[0] = oldVals[0] + ratio10 * (oldTime0 - newTime1); - // newVals[1] = oldVals[0] + ratio10 * (oldTime0 - newTime2); - // newVals[2] = oldVals[0] + ratio10 * (oldTime0 - newTime3); - // // last point lie between oldVals[1] and oldVals[2] - // Real64 ratio21 = (oldVals[2] - oldVals[1]) / OldTimeStep; - // newVals[3] = oldVals[1] + ratio21 * (oldTime1 - newTime4); - - //} else { // DSRatio = 4 or more - // // all new points lie between oldVals[0] and oldVals[1] - // Real64 ratio10 = (oldVals[1] - oldVals[0]) / OldTimeStep; - // newVals[0] = oldVals[0] + ratio10 * (oldTime0 - newTime1); - // newVals[1] = oldVals[0] + ratio10 * (oldTime0 - newTime2); - // newVals[2] = oldVals[0] + ratio10 * (oldTime0 - newTime3); - // newVals[3] = oldVals[0] + ratio10 * (oldTime0 - newTime4); - //} } void InverseModelTemperature(EnergyPlusData &state, int const ZoneNum, // Zone number diff --git a/tst/EnergyPlus/unit/UnitarySystem.unit.cc b/tst/EnergyPlus/unit/UnitarySystem.unit.cc index 7e0bff099b5..cac7f311123 100644 --- a/tst/EnergyPlus/unit/UnitarySystem.unit.cc +++ b/tst/EnergyPlus/unit/UnitarySystem.unit.cc @@ -23690,7 +23690,7 @@ TEST_F(EnergyPlusFixture, UnitarySystemModel_MultiSpeedFanWSHP_Test) latOut); // first speed heating EXPECT_NEAR(thisSys.m_SpeedRatio, 0.0, 0.0001); - EXPECT_NEAR(thisSys.m_CycRatio, 0.81485929, 0.0001); + EXPECT_NEAR(thisSys.m_CycRatio, 0.81485980, 0.0001); EXPECT_EQ(thisSys.m_SpeedNum, 1); EXPECT_NEAR(sensOut, 2000.0, 0.5); @@ -23709,7 +23709,7 @@ TEST_F(EnergyPlusFixture, UnitarySystemModel_MultiSpeedFanWSHP_Test) ZoneEquipment, sensOut, latOut); - EXPECT_NEAR(thisSys.m_SpeedRatio, 0.691837, 0.0001); + EXPECT_NEAR(thisSys.m_SpeedRatio, 0.691942, 0.0001); EXPECT_NEAR(thisSys.m_CycRatio, 1.0, 0.0001); EXPECT_EQ(thisSys.m_SpeedNum, 2); EXPECT_NEAR(sensOut, 3000.0, 2); @@ -23734,7 +23734,7 @@ TEST_F(EnergyPlusFixture, UnitarySystemModel_MultiSpeedFanWSHP_Test) sensOut, latOut); EXPECT_NEAR(thisSys.m_SpeedRatio, 0.0, 0.0001); - EXPECT_NEAR(thisSys.m_CycRatio, 0.801813, 0.0001); + EXPECT_NEAR(thisSys.m_CycRatio, 0.809727, 0.0001); EXPECT_EQ(thisSys.m_SpeedNum, 1); EXPECT_NEAR(sensOut, -800.0, 2); state->dataZoneEnergyDemand->ZoneSysEnergyDemand[0].RemainingOutputRequired = -1500.0; @@ -23753,10 +23753,10 @@ TEST_F(EnergyPlusFixture, UnitarySystemModel_MultiSpeedFanWSHP_Test) ZoneEquipment, sensOut, latOut); - EXPECT_NEAR(thisSys.m_SpeedRatio, 0.27708, 0.0001); + EXPECT_NEAR(thisSys.m_SpeedRatio, 0.27929, 0.0001); EXPECT_NEAR(thisSys.m_CycRatio, 1.0, 0.0001); EXPECT_EQ(thisSys.m_SpeedNum, 2); - EXPECT_NEAR(sensOut, -1500.0, 2); + EXPECT_NEAR(sensOut, -1501.3, 2); // Variable speed water coil state->dataZoneEnergyDemand->ZoneSysEnergyDemand[1].RemainingOutputRequired = -100.0; @@ -23780,7 +23780,7 @@ TEST_F(EnergyPlusFixture, UnitarySystemModel_MultiSpeedFanWSHP_Test) latOut); // first speed cooling EXPECT_NEAR(thisSys1.m_SpeedRatio, 0.0, 0.0001); - EXPECT_NEAR(thisSys1.m_CycRatio, 0.507924, 0.0001); + EXPECT_NEAR(thisSys1.m_CycRatio, 0.510465, 0.0001); EXPECT_EQ(thisSys1.m_SpeedNum, 1); EXPECT_NEAR(sensOut, -100.0, 2); @@ -23800,7 +23800,7 @@ TEST_F(EnergyPlusFixture, UnitarySystemModel_MultiSpeedFanWSHP_Test) sensOut, latOut); // Sixth speed cooling - EXPECT_NEAR(thisSys1.m_SpeedRatio, 0.361666, 0.0001); + EXPECT_NEAR(thisSys1.m_SpeedRatio, 0.392999, 0.0001); EXPECT_NEAR(thisSys1.m_CycRatio, 1.0, 0.0001); EXPECT_EQ(thisSys1.m_SpeedNum, 6); EXPECT_NEAR(sensOut, -500.0, 2); @@ -23826,7 +23826,7 @@ TEST_F(EnergyPlusFixture, UnitarySystemModel_MultiSpeedFanWSHP_Test) latOut); // First speed heating EXPECT_NEAR(thisSys1.m_SpeedRatio, 0.0, 0.0001); - EXPECT_NEAR(thisSys1.m_CycRatio, 0.244636, 0.0001); + EXPECT_NEAR(thisSys1.m_CycRatio, 0.245589, 0.0001); EXPECT_EQ(thisSys1.m_SpeedNum, 1); EXPECT_NEAR(sensOut, 100.0, 2); state->dataZoneEnergyDemand->ZoneSysEnergyDemand[1].RemainingOutputRequired = 500.0; @@ -23845,7 +23845,7 @@ TEST_F(EnergyPlusFixture, UnitarySystemModel_MultiSpeedFanWSHP_Test) sensOut, latOut); // Second speed heating - EXPECT_NEAR(thisSys1.m_SpeedRatio, 0.926240, 0.0001); + EXPECT_NEAR(thisSys1.m_SpeedRatio, 0.945581, 0.0001); EXPECT_NEAR(thisSys1.m_CycRatio, 1.0, 0.0001); EXPECT_EQ(thisSys1.m_SpeedNum, 2); EXPECT_NEAR(sensOut, 500.0, 2); diff --git a/tst/EnergyPlus/unit/ZoneTempPredictorCorrector.unit.cc b/tst/EnergyPlus/unit/ZoneTempPredictorCorrector.unit.cc index 49c2b47d7b1..5b0004d839f 100644 --- a/tst/EnergyPlus/unit/ZoneTempPredictorCorrector.unit.cc +++ b/tst/EnergyPlus/unit/ZoneTempPredictorCorrector.unit.cc @@ -1682,4 +1682,17 @@ TEST_F(EnergyPlusFixture, DownInterpolate4HistoryValues_Test) EXPECT_NEAR(DSHistoryValue2, 2.0, 0.000001); EXPECT_NEAR(DSHistoryValue3, 2.5, 0.000001); EXPECT_NEAR(DSHistoryValue4, 3.0, 0.000001); + + std::array newValue = {0.0, 0.0, 0.0, 0.0}; + std::array oldValue = {DSHistoryValue1, DSHistoryValue2, DSHistoryValue3, DSHistoryValue4}; + Real64 returnValue = DownInterpolate4HistoryValues(PriorTimeStep, state->dataHVACGlobal->TimeStepSys, oldValue, newValue); + EXPECT_NEAR(returnValue, oldValue[0], 0.000001); // setting up history terms for shortened time step simulation + EXPECT_NEAR(newValue[0], 1.5, 0.000001); // values are interpolated to provide history terms at the new time step + EXPECT_NEAR(newValue[1], 1.75, 0.000001); + EXPECT_NEAR(newValue[2], 2.0, 0.000001); + EXPECT_NEAR(newValue[3], 2.25, 0.000001); + EXPECT_NEAR(oldValue[0], DSHistoryValue1, 0.000001); // values are same as before + EXPECT_NEAR(oldValue[1], DSHistoryValue2, 0.000001); + EXPECT_NEAR(oldValue[2], DSHistoryValue3, 0.000001); + EXPECT_NEAR(oldValue[3], DSHistoryValue4, 0.000001); } From b1f2bac86250e0c82caf9f562215ef32ad8569f7 Mon Sep 17 00:00:00 2001 From: Jason Glazer Date: Tue, 12 Dec 2023 15:22:44 -0600 Subject: [PATCH 07/12] Add protection for bin number vector in annual report --- src/EnergyPlus/OutputReportTabularAnnual.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/EnergyPlus/OutputReportTabularAnnual.cc b/src/EnergyPlus/OutputReportTabularAnnual.cc index 613974155ce..26f2a8bd710 100644 --- a/src/EnergyPlus/OutputReportTabularAnnual.cc +++ b/src/EnergyPlus/OutputReportTabularAnnual.cc @@ -1358,7 +1358,9 @@ std::vector AnnualTable::calculateBins(int const numberOfBins, } else { // determine which bin the results are in binNum = int((*valueIt - bottomOfBins) / intervalSize); - returnBins[binNum] += *elapsedTimeIt; + if (binNum < binNum && binNum >= 0) { + returnBins[binNum] += *elapsedTimeIt; + } } ++elapsedTimeIt; } From 64a7e3fbfbf901591dd88109664dc30d900f05b6 Mon Sep 17 00:00:00 2001 From: Jason Glazer Date: Wed, 13 Dec 2023 06:52:07 -0600 Subject: [PATCH 08/12] Add unit test OutputReportTabularMonthly_WarnMonthlyBlankVariable --- .../unit/OutputReportTabular.unit.cc | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc index 02079680f88..1f0d0e29035 100644 --- a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc +++ b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc @@ -12792,6 +12792,68 @@ TEST_F(EnergyPlusFixture, OutputReportTabularMonthly_WarnMonthlyDisplayExtraWarn compare_err_stream(expected_error); } +TEST_F(EnergyPlusFixture, OutputReportTabularMonthly_WarnMonthlyBlankVariable) +{ + // #6919 - Warn instead of fatal on blank monthly table + std::string const idf_objects = delimited_string({ + "Output:Table:Monthly,", + " Space Gains Annual Report, !- Name", + " 2, !- Digits After Decimal", + " , !- Variable or Meter 1 Name", + " SumOrAverage; !- Aggregation Type for Variable or Meter 1", + + "Output:Table:SummaryReports,", + " AllSummaryAndMonthly; !- Report 1 Name", + }); + + ASSERT_TRUE(process_idf(idf_objects)); + + Real64 extLitUse; + + SetupOutputVariable(*state, + "Exterior Lights Electricity Energy", + OutputProcessor::Unit::J, + extLitUse, + OutputProcessor::SOVTimeStepType::Zone, + OutputProcessor::SOVStoreType::Summed, + "Lite1", + {}, + "Electricity", + "Exterior Lights", + "General"); + + SetupOutputVariable(*state, + "Exterior Lights Electricity Energy", + OutputProcessor::Unit::J, + extLitUse, + OutputProcessor::SOVTimeStepType::Zone, + OutputProcessor::SOVStoreType::Summed, + "Lite2", + {}, + "Electricity", + "Exterior Lights", + "General"); + + state->dataGlobal->DoWeathSim = true; + state->dataGlobal->KindOfSim = Constant::KindOfSim::RunPeriodWeather; // Trigger the extra warning + state->dataGlobal->TimeStepZone = 0.25; + state->dataGlobal->TimeStepZoneSec = state->dataGlobal->TimeStepZone * 60.0; + state->dataGlobal->DisplayExtraWarnings = true; + + GetInputTabularMonthly(*state); + EXPECT_EQ(state->dataOutRptTab->MonthlyInputCount, 1); + GetInputOutputTableSummaryReports(*state); + EXPECT_EQ(state->dataOutRptTab->MonthlyInputCount, numNamedMonthly + 1); + + InitializeTabularMonthly(*state); + + std::string const expected_error = delimited_string({ + " ** Warning ** Output:Table:Monthly: Blank column specified in 'SPACE GAINS ANNUAL REPORT', need to provide a variable or meter name " + }); + compare_err_stream(expected_error); +} + + TEST_F(EnergyPlusFixture, OutputReportTabularMonthly_NoWarnMonthlIfNoWeatherFileRun) { // #9621 - Only warn if a bad variable is defined in a Monthly table user requested, not on the AllSummaryAndMonthly ones From 1dc8d9fc280a443f2f07e322036fb1ee03bc3e9a Mon Sep 17 00:00:00 2001 From: Jason Glazer Date: Wed, 13 Dec 2023 08:27:33 -0600 Subject: [PATCH 09/12] Add OutputReportTabularAnnual_WarnBlankVariable unit test --- .../unit/OutputReportTabularAnnual.unit.cc | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tst/EnergyPlus/unit/OutputReportTabularAnnual.unit.cc b/tst/EnergyPlus/unit/OutputReportTabularAnnual.unit.cc index 9b6ac093ff5..223b45448cf 100644 --- a/tst/EnergyPlus/unit/OutputReportTabularAnnual.unit.cc +++ b/tst/EnergyPlus/unit/OutputReportTabularAnnual.unit.cc @@ -555,3 +555,40 @@ TEST_F(SQLiteFixture, OutputReportTabularAnnual_CurlyBraces) EXPECT_TRUE(false) << "Missing braces in monthly table for : " << colHeader; } } + +TEST_F(EnergyPlusFixture, OutputReportTabularAnnual_WarnBlankVariable) +{ + std::string const idf_objects = delimited_string({ + "Output:Table:Annual,", + "Space Gains Annual Report, !- Name", + "Filter1, !- Filter", + "Schedule2, !- Schedule Name", + "Zone People Total Heating Energy, !- Variable or Meter 1 Name", + "SumOrAverage, !- Aggregation Type for Variable or Meter 1", + "4, !- field Digits After Decimal 1", + ", !- Variable or Meter 2 Name", + "hoursNonZero, !- Aggregation Type for Variable or Meter 2", + ", !- field Digits After Decimal 2", + "Zone Electric Equipment Total Heating Energy; !- Variable or Meter 3 Name", + }); + + ASSERT_TRUE(process_idf(idf_objects)); + + state->dataGlobal->DoWeathSim = true; + + EXPECT_FALSE(state->dataOutRptTab->WriteTabularFiles); + GetInputTabularAnnual(*state); + EXPECT_TRUE(state->dataOutRptTab->WriteTabularFiles); + + EXPECT_EQ(state->dataOutputReportTabularAnnual->annualTables.size(), 1u); + + std::vector::iterator firstTable = state->dataOutputReportTabularAnnual->annualTables.begin(); + + std::vector tableParams = firstTable->inspectTable(); + + std::string const expected_error = delimited_string( + {" ** Warning ** Output:Table:Annual: Blank column specified in 'SPACE GAINS ANNUAL REPORT', need to provide a variable or meter or EMS variable name ", + " ** Warning ** Invalid aggregation type=\"\" Defaulting to SumOrAverage."}); + + compare_err_stream(expected_error); +} From 0ef512035a3cf907a206ed3d12af86ceb2c04d93 Mon Sep 17 00:00:00 2001 From: Jason Glazer Date: Wed, 13 Dec 2023 08:59:47 -0600 Subject: [PATCH 10/12] Fix formatting --- tst/EnergyPlus/unit/OutputReportTabular.unit.cc | 6 ++---- tst/EnergyPlus/unit/OutputReportTabularAnnual.unit.cc | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc index 1f0d0e29035..0bda9435cc6 100644 --- a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc +++ b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc @@ -12847,13 +12847,11 @@ TEST_F(EnergyPlusFixture, OutputReportTabularMonthly_WarnMonthlyBlankVariable) InitializeTabularMonthly(*state); - std::string const expected_error = delimited_string({ - " ** Warning ** Output:Table:Monthly: Blank column specified in 'SPACE GAINS ANNUAL REPORT', need to provide a variable or meter name " - }); + std::string const expected_error = delimited_string( + {" ** Warning ** Output:Table:Monthly: Blank column specified in 'SPACE GAINS ANNUAL REPORT', need to provide a variable or meter name "}); compare_err_stream(expected_error); } - TEST_F(EnergyPlusFixture, OutputReportTabularMonthly_NoWarnMonthlIfNoWeatherFileRun) { // #9621 - Only warn if a bad variable is defined in a Monthly table user requested, not on the AllSummaryAndMonthly ones diff --git a/tst/EnergyPlus/unit/OutputReportTabularAnnual.unit.cc b/tst/EnergyPlus/unit/OutputReportTabularAnnual.unit.cc index 223b45448cf..344a6a1bbed 100644 --- a/tst/EnergyPlus/unit/OutputReportTabularAnnual.unit.cc +++ b/tst/EnergyPlus/unit/OutputReportTabularAnnual.unit.cc @@ -586,9 +586,9 @@ TEST_F(EnergyPlusFixture, OutputReportTabularAnnual_WarnBlankVariable) std::vector tableParams = firstTable->inspectTable(); - std::string const expected_error = delimited_string( - {" ** Warning ** Output:Table:Annual: Blank column specified in 'SPACE GAINS ANNUAL REPORT', need to provide a variable or meter or EMS variable name ", - " ** Warning ** Invalid aggregation type=\"\" Defaulting to SumOrAverage."}); + std::string const expected_error = delimited_string({" ** Warning ** Output:Table:Annual: Blank column specified in 'SPACE GAINS ANNUAL " + "REPORT', need to provide a variable or meter or EMS variable name ", + " ** Warning ** Invalid aggregation type=\"\" Defaulting to SumOrAverage."}); compare_err_stream(expected_error); } From e78c6168ec58ed8843c177ce9b517b3edd3f0d55 Mon Sep 17 00:00:00 2001 From: Jason Glazer Date: Fri, 5 Jan 2024 13:50:20 -0600 Subject: [PATCH 11/12] Update unit test to use new SetupOutputVariable form --- tst/EnergyPlus/unit/OutputReportTabular.unit.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc index c92cfa3f3f8..f5f97a46b23 100644 --- a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc +++ b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc @@ -12792,26 +12792,24 @@ TEST_F(EnergyPlusFixture, OutputReportTabularMonthly_WarnMonthlyBlankVariable) SetupOutputVariable(*state, "Exterior Lights Electricity Energy", - OutputProcessor::Unit::J, + Constant::Units::J, extLitUse, OutputProcessor::SOVTimeStepType::Zone, OutputProcessor::SOVStoreType::Summed, "Lite1", - {}, - "Electricity", - "Exterior Lights", + Constant::eResource::Electricity, + OutputProcessor::SOVEndUseCat::ExteriorLights, "General"); SetupOutputVariable(*state, "Exterior Lights Electricity Energy", - OutputProcessor::Unit::J, + Constant::Units::J, extLitUse, OutputProcessor::SOVTimeStepType::Zone, OutputProcessor::SOVStoreType::Summed, "Lite2", - {}, - "Electricity", - "Exterior Lights", + Constant::eResource::Electricity, + OutputProcessor::SOVEndUseCat::ExteriorLights, "General"); state->dataGlobal->DoWeathSim = true; From 504183decfb2a6be3a81a3631924075c74a994df Mon Sep 17 00:00:00 2001 From: Jason Glazer Date: Fri, 5 Jan 2024 14:00:50 -0600 Subject: [PATCH 12/12] Add useful comparison --- src/EnergyPlus/OutputReportTabularAnnual.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EnergyPlus/OutputReportTabularAnnual.cc b/src/EnergyPlus/OutputReportTabularAnnual.cc index 9c9b7c912d3..cda26404566 100644 --- a/src/EnergyPlus/OutputReportTabularAnnual.cc +++ b/src/EnergyPlus/OutputReportTabularAnnual.cc @@ -1358,7 +1358,7 @@ std::vector AnnualTable::calculateBins(int const numberOfBins, } else { // determine which bin the results are in binNum = int((*valueIt - bottomOfBins) / intervalSize); - if (binNum < binNum && binNum >= 0) { + if (binNum < numberOfBins && binNum >= 0) { returnBins[binNum] += *elapsedTimeIt; } }