Skip to content

Commit 79da40f

Browse files
Merge 7ab44a1 into 9bf4ef9
2 parents 9bf4ef9 + 7ab44a1 commit 79da40f

File tree

8 files changed

+201
-14
lines changed

8 files changed

+201
-14
lines changed

src/EnergyPlus/DataRuntimeLanguage.hh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,11 @@ namespace DataRuntimeLanguage {
394394
ErlValueType Value; // values taken by Erl variables
395395
bool ReadOnly; // true if Erl variable is read-only
396396
bool SetByExternalInterface; // set to true if value is set by ExternalInterface
397+
bool SetByGlobalVariable;
398+
bool SetByInternalVariable;
397399

398400
// Default Constructor
399-
ErlVariableType() : StackNum(0), ReadOnly(false), SetByExternalInterface(false)
401+
ErlVariableType() : StackNum(0), ReadOnly(false), SetByExternalInterface(false), SetByGlobalVariable(false), SetByInternalVariable(false)
400402
{
401403
}
402404
};

src/EnergyPlus/EMSManager.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@ namespace EMSManager {
809809
} else {
810810
VariableNum = RuntimeLanguageProcessor::NewEMSVariable(state, cAlphaArgs(1), 0);
811811
state.dataRuntimeLang->EMSInternalVarsUsed(InternVarNum).ErlVariableNum = VariableNum;
812+
state.dataRuntimeLang->ErlVariable(VariableNum).SetByInternalVariable = true;
812813
}
813814

814815
state.dataRuntimeLang->EMSInternalVarsUsed(InternVarNum).UniqueIDName = cAlphaArgs(2);

src/EnergyPlus/RuntimeLanguageProcessor.cc

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,6 @@ ErlValueType EvaluateStack(EnergyPlusData &state, int const StackNum)
816816
ReturnValue.Number = 0.0;
817817

818818
auto const &thisErlStack = state.dataRuntimeLang->ErlStack(StackNum);
819-
820819
InstructionNum = 1;
821820
while (InstructionNum <= thisErlStack.NumInstructions) {
822821

@@ -1799,9 +1798,14 @@ ErlValueType EvaluateExpression(EnergyPlusData &state, int const ExpressionNum,
17991798
if (thisErlVar.Value.initialized) { // check that value has been initialized
18001799
thisOperand = thisErlVar.Value;
18011800
} else { // value has never been set
1802-
ReturnValue.Type = Value::Error;
1803-
ReturnValue.Error = "EvaluateExpression: Variable = '" + thisErlVar.Name + "' used in expression has not been initialized!";
1804-
if (!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation && !state.dataEMSMgr->FinishProcessingUserInput) {
1801+
// during setup (before simulation), we want to avoid initializing variables to zero without throwing an error
1802+
// throw the error, and write it to edd file, if variable is uninitialized and is *not* a global or internal variable
1803+
// assumption is that if we made it here for a global variable, it is initialized in another program
1804+
if ((!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation && !state.dataEMSMgr->FinishProcessingUserInput) ||
1805+
(!(thisErlVar.SetByGlobalVariable || thisErlVar.SetByInternalVariable))) {
1806+
1807+
ReturnValue.Type = Value::Error;
1808+
ReturnValue.Error = "EvaluateExpression: Variable = '" + thisErlVar.Name + "' used in expression has not been initialized!";
18051809

18061810
// check if this is an arg in CurveValue,
18071811
if (thisErlExpression.Operator !=
@@ -2972,6 +2976,8 @@ void GetRuntimeLanguageUserInput(EnergyPlusData &state)
29722976
// Initialize variables for the ExternalInterface variables.
29732977
// This object requires an initial value.
29742978
ExternalInterfaceInitializeErlVariable(state, VariableNum, SetErlValueNumber(rNumericArgs(1)), false);
2979+
} else {
2980+
state.dataRuntimeLang->ErlVariable(VariableNum).SetByGlobalVariable = true;
29752981
}
29762982
}
29772983
}

src/EnergyPlus/SimulationManager.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ namespace SimulationManager {
268268
state.dataGlobal->KickOffSimulation = true;
269269

270270
Weather::ResetEnvironmentCounter(state);
271+
271272
SetupSimulation(state, ErrorsFound);
272273

273274
FaultsManager::CheckAndReadFaults(state);
@@ -330,6 +331,7 @@ namespace SimulationManager {
330331
ReportNodeConnections(state);
331332
}
332333
SystemReports::CreateEnergyReportStructure(state);
334+
333335
bool anyEMSRan;
334336
// point to finish setup processing EMS, sensor ready now
335337
EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::SetupSimulation, anyEMSRan, ObjexxFCL::Optional_int_const());

testfiles/HospitalBaselineReheatReportEMS.idf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74050,17 +74050,17 @@
7405074050

7405174051
EnergyManagementSystem:ProgramCallingManager,
7405274052
Reheat_Sum_Call, !- Name
74053-
EndofZoneTimestepAfterZoneReporting, !- EnergyPlus Model Calling Point
74053+
BeginNewEnvironment, !- EnergyPlus Model Calling Point
7405474054
Reheat_Sum_Program; !- Program Name 1
7405574055

7405674056
EnergyManagementSystem:ProgramCallingManager,
7405774057
Heat_Sum_Call, !- Name
74058-
EndofZoneTimestepAfterZoneReporting, !- EnergyPlus Model Calling Point
74058+
BeginNewEnvironment, !- EnergyPlus Model Calling Point
7405974059
Heat_Sum_Program; !- Program Name 1
7406074060

7406174061
EnergyManagementSystem:ProgramCallingManager,
7406274062
AHU_Heat_Sum_Call, !- Name
74063-
EndofZoneTimestepAfterZoneReporting, !- EnergyPlus Model Calling Point
74063+
BeginNewEnvironment, !- EnergyPlus Model Calling Point
7406474064
AHU_Heat_Energy_Program; !- Program Name 1
7406574065

7406674066
!- =========== ALL OBJECTS IN CLASS: ENERGYMANAGEMENTSYSTEM:PROGRAM ===========

testfiles/RetailPackagedTESCoil.idf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8114,13 +8114,13 @@
81148114
Run SumIntakeMassFlowHeatCap, !- <none>
81158115
Run SumReliefAirMCTterm, !- <none>
81168116
Run CalcWindTerms, !- <none>
8117-
Run CalcBouyancyTerms, !- <none>
8118-
SEt Numerator = WindMCT + NatBouyMCT + SumHATroof + QdotCond + SumReliefMCT, !- <none>
8119-
Set Denominator = WindMC + NatBouyMC + SumHAroof + SumIntakeMdotCp, !- <none>
8120-
Set Troof = Numerator / Denominator, !- <none>
81218117
IF Ta < 2.0, !- <none>
81228118
Set Troof = Ta, !- <none>
81238119
ENDIF, !- <none>
8120+
Run CalcBouyancyTerms, !- <none>
8121+
Set Numerator = WindMCT + NatBouyMCT + SumHATroof + QdotCond + SumReliefMCT, !- <none>
8122+
Set Denominator = WindMC + NatBouyMC + SumHAroof + SumIntakeMdotCp, !- <none>
8123+
Set Troof = Numerator / Denominator, !- <none>
81248124
IF Troof < Twb, !- <none>
81258125
Set Twb = Troof - 0.2, !- <none>
81268126
ENDIF; !- <none>

testfiles/_ResidentialBase.idf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7296,7 +7296,7 @@
72967296

72977297
EnergyManagementSystem:ProgramCallingManager,
72987298
central_ac_and_furnace_airloop_0_duct_program calling manager, !- Name
7299-
EndOfSystemTimestepAfterHVACReporting, !- EnergyPlus Model Calling Point
7299+
BeginZoneTimestepBeforeInitHeatBalance, !- EnergyPlus Model Calling Point
73007300
central_ac_and_furnace_airloop_0_duct_program; !- Program Name 1
73017301

73027302
EnergyManagementSystem:ProgramCallingManager,

tst/EnergyPlus/unit/EMSManager.unit.cc

Lines changed: 177 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252

5353
// EnergyPlus Headers
5454
#include "Fixtures/EnergyPlusFixture.hh"
55+
#include <EnergyPlus/ConfiguredFunctions.hh>
5556
#include <EnergyPlus/Construction.hh>
5657
#include <EnergyPlus/CurveManager.hh>
5758
#include <EnergyPlus/Data/EnergyPlusData.hh>
@@ -936,7 +937,7 @@ TEST_F(EnergyPlusFixture, TestUnInitializedEMSVariable2)
936937
state->dataEMSMgr->FinishProcessingUserInput = true;
937938
bool anyRan;
938939
EMSManager::ManageEMS(*state, EMSManager::EMSCallFrom::SetupSimulation, anyRan, ObjexxFCL::Optional_int_const());
939-
// Expect the variable to not yet be initialized, call EvaluateExpresssion and check argument
940+
// Expect the variable to not yet be initialized, call EvaluateExpression and check argument
940941

941942
ErlValueType ReturnValue;
942943
bool seriousErrorFound = false;
@@ -958,6 +959,181 @@ TEST_F(EnergyPlusFixture, TestUnInitializedEMSVariable2)
958959
EXPECT_FALSE(seriousErrorFound);
959960
}
960961

962+
TEST_F(EnergyPlusFixture, TestEMSVariableInitAfterRef1)
963+
{
964+
// test for #11360 - EMS variable initialized after reference, outside of ManageSimulation
965+
std::string const idf_objects = delimited_string({
966+
967+
"EnergyManagementSystem:Program,",
968+
" ev_discharge_program, !- Name",
969+
" Set power_mult = site_temp_adj, !- Program Line 1",
970+
" Set site_temp_adj = 0.1; !- Program Line 2",
971+
972+
"EnergyManagementSystem:ProgramCallingManager,",
973+
" ev_discharge_pcm, !- Name",
974+
" BeginTimestepBeforePredictor, !- EnergyPlus Model Calling Point",
975+
" ev_discharge_program; !- Program Name 1",
976+
});
977+
978+
ASSERT_TRUE(process_idf(idf_objects));
979+
state->init_state(*state);
980+
981+
int internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
982+
EXPECT_EQ(internalVarNum, 0);
983+
984+
bool anyRan;
985+
EXPECT_TRUE(state->dataEMSMgr->GetEMSUserInput);
986+
EMSManager::ManageEMS(*state, EMSManager::EMSCallFrom::SetupSimulation, anyRan, ObjexxFCL::Optional_int_const());
987+
988+
internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
989+
ASSERT_GT(internalVarNum, 0);
990+
EXPECT_FALSE(state->dataRuntimeLang->ErlVariable(internalVarNum).Value.initialized);
991+
992+
EXPECT_FALSE(state->dataEMSMgr->GetEMSUserInput);
993+
EMSManager::ManageEMS(*state, EMSManager::EMSCallFrom::BeginNewEnvironment, anyRan, ObjexxFCL::Optional_int_const());
994+
995+
internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
996+
ASSERT_GT(internalVarNum, 0);
997+
EXPECT_FALSE(state->dataRuntimeLang->ErlVariable(internalVarNum).Value.initialized);
998+
999+
EXPECT_FALSE(state->dataEMSMgr->GetEMSUserInput);
1000+
ASSERT_THROW(EMSManager::ManageEMS(*state, EMSManager::EMSCallFrom::BeginTimestepBeforePredictor, anyRan, ObjexxFCL::Optional_int_const()),
1001+
EnergyPlus::FatalError);
1002+
1003+
internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
1004+
ASSERT_GT(internalVarNum, 0);
1005+
EXPECT_FALSE(state->dataRuntimeLang->ErlVariable(internalVarNum).Value.initialized);
1006+
1007+
// Expect the variable to not yet be initialized, call EvaluateExpression and check argument
1008+
bool seriousErrorFound = false;
1009+
ErlValueType ReturnValue = RuntimeLanguageProcessor::EvaluateExpression(
1010+
*state,
1011+
state->dataRuntimeLang->ErlStack(Util::FindItemInList("EV_DISCHARGE_PROGRAM", state->dataRuntimeLang->ErlStack)).Instruction(1).Argument2,
1012+
seriousErrorFound);
1013+
EXPECT_TRUE(seriousErrorFound);
1014+
1015+
const std::string expected_error = delimited_string({
1016+
" ** Severe ** Problem found in EMS EnergyPlus Runtime Language.",
1017+
" ** ~~~ ** Erl program name: EV_DISCHARGE_PROGRAM",
1018+
" ** ~~~ ** Erl program line number: 1",
1019+
" ** ~~~ ** Erl program line text: SET POWER_MULT = SITE_TEMP_ADJ",
1020+
" ** ~~~ ** Error message: *** Error: EvaluateExpression: Variable = 'SITE_TEMP_ADJ' used in expression has not been initialized! "
1021+
"*** ",
1022+
" ** ~~~ ** Environment=, at Simulation time= 00:-15 - 00:00",
1023+
" ** Fatal ** Previous EMS error caused program termination.",
1024+
" ...Summary of Errors that led to program termination:",
1025+
" ..... Reference severe error count=1",
1026+
" ..... Last severe error=Problem found in EMS EnergyPlus Runtime Language.",
1027+
});
1028+
1029+
compare_err_stream(expected_error);
1030+
}
1031+
1032+
TEST_F(EnergyPlusFixture, TestEMSVariableInitAfterRef2)
1033+
{
1034+
// test for #11360 - EMS variable initialized after reference, within ManageSimulation
1035+
std::string const idf_objects = delimited_string({
1036+
"Version," + DataStringGlobals::MatchVersion + ";",
1037+
1038+
"RunPeriod,",
1039+
" Run Period 1, !- Name",
1040+
" 1, !- Begin Month",
1041+
" 1, !- Begin Day of Month",
1042+
" 2007, !- Begin Year",
1043+
" 1, !- End Month",
1044+
" 1, !- End Day of Month",
1045+
" 2007, !- End Year",
1046+
" Monday, !- Day of Week for Start Day",
1047+
" No, !- Use Weather File Holidays and Special Days",
1048+
" No, !- Use Weather File Daylight Saving Period",
1049+
" No, !- Apply Weekend Holiday Rule",
1050+
" Yes, !- Use Weather File Rain Indicators",
1051+
" Yes; !- Use Weather File Snow Indicators",
1052+
1053+
"SimulationControl,",
1054+
" No, !- Do Zone Sizing Calculation",
1055+
" No, !- Do System Sizing Calculation",
1056+
" No, !- Do Plant Sizing Calculation",
1057+
" No, !- Run Simulation for Sizing Periods",
1058+
" Yes, !- Run Simulation for Weather File Run Periods",
1059+
" , !- Do HVAC Sizing Simulation for Sizing Periods",
1060+
" ; !- Maximum Number of HVAC Sizing Simulation Passes",
1061+
1062+
"Site:Location,",
1063+
" Denver Stapleton Intl Arpt CO USA WMO=724690, !- Name",
1064+
" 39.77, !- Latitude {deg}",
1065+
" -104.87, !- Longitude {deg}",
1066+
" -7.00, !- Time Zone {hr}",
1067+
" 1611.00; !- Elevation {m}",
1068+
1069+
"Material,",
1070+
" Concrete Block, !- Name",
1071+
" MediumRough, !- Roughness",
1072+
" 0.1014984, !- Thickness {m}",
1073+
" 0.3805070, !- Conductivity {W/m-K}",
1074+
" 608.7016, !- Density {kg/m3}",
1075+
" 836.8000; !- Specific Heat {J/kg-K}",
1076+
1077+
"Construction,",
1078+
" ConcConstruction, !- Name",
1079+
" Concrete Block; !- Outside Layer",
1080+
1081+
"BuildingSurface:Detailed,"
1082+
" Wall, !- Name",
1083+
" Wall, !- Surface Type",
1084+
" ConcConstruction, !- Construction Name",
1085+
" Zone, !- Zone Name",
1086+
" , !- Space Name",
1087+
" Outdoors, !- Outside Boundary Condition",
1088+
" , !- Outside Boundary Condition Object",
1089+
" SunExposed, !- Sun Exposure",
1090+
" WindExposed, !- Wind Exposure",
1091+
" 0.5000000, !- View Factor to Ground",
1092+
" 4, !- Number of Vertices",
1093+
" 0.000000,0.000000,10.00000, !- X,Y,Z ==> Vertex 1 {m}",
1094+
" 0.000000,0.000000,0, !- X,Y,Z ==> Vertex 2 {m}",
1095+
" 10.00000,0.000000,0, !- X,Y,Z ==> Vertex 3 {m}",
1096+
" 10.00000,0.000000,10.00000; !- X,Y,Z ==> Vertex 4 {m}",
1097+
1098+
"Zone,"
1099+
" Zone, !- Name",
1100+
" 0, !- Direction of Relative North {deg}",
1101+
" 6.000000, !- X Origin {m}",
1102+
" 6.000000, !- Y Origin {m}",
1103+
" 0, !- Z Origin {m}",
1104+
" 1, !- Type",
1105+
" 1, !- Multiplier",
1106+
" autocalculate, !- Ceiling Height {m}",
1107+
" autocalculate; !- Volume {m3}",
1108+
1109+
"EnergyManagementSystem:Program,",
1110+
" ev_discharge_program, !- Name",
1111+
" Set power_mult = site_temp_adj, !- Program Line 1",
1112+
" Set site_temp_adj = 0.1; !- Program Line 2",
1113+
1114+
"EnergyManagementSystem:ProgramCallingManager,",
1115+
" ev_discharge_pcm, !- Name",
1116+
" BeginTimestepBeforePredictor, !- EnergyPlus Model Calling Point",
1117+
" ev_discharge_program; !- Program Name 1",
1118+
});
1119+
1120+
ASSERT_TRUE(process_idf(idf_objects));
1121+
state->init_state(*state);
1122+
1123+
state->dataWeather->WeatherFileExists = true;
1124+
state->files.inputWeatherFilePath.filePath = configured_source_directory() / "weather/USA_CO_Golden-NREL.724666_TMY3.epw";
1125+
1126+
int internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
1127+
EXPECT_EQ(internalVarNum, 0);
1128+
1129+
EXPECT_TRUE(state->dataEMSMgr->GetEMSUserInput);
1130+
ASSERT_THROW(SimulationManager::ManageSimulation(*state), EnergyPlus::FatalError);
1131+
1132+
internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
1133+
ASSERT_GT(internalVarNum, 0);
1134+
EXPECT_FALSE(state->dataRuntimeLang->ErlVariable(internalVarNum).Value.initialized);
1135+
}
1136+
9611137
TEST_F(EnergyPlusFixture, EMSManager_CheckIfAnyEMS_OutEMS)
9621138
{
9631139
std::string const idf_objects = delimited_string({

0 commit comments

Comments
 (0)