Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8623d71
Add failing EMS unit test to demonstrate that variable initialized af…
joseph-robertson Jan 29, 2026
ead50b6
Formatting.
joseph-robertson Jan 29, 2026
65966b8
fix uninitialized var
mitchute Jan 30, 2026
d039752
Add test to show difference between calling ManageEMS individually vs…
joseph-robertson Jan 30, 2026
69e2e71
Add AlwaysFindSeriousError to EMS manager data struct.
joseph-robertson Feb 9, 2026
c1c2bee
Update EvaluateStack to use new AlwaysFindSeriousError.
joseph-robertson Feb 9, 2026
68543c1
Update ManageSimulation to use new AlwaysFindSeriousError around Setu…
joseph-robertson Feb 9, 2026
cf65f57
Clean up new EMS variable unit tests.
joseph-robertson Feb 9, 2026
9f9c099
Check for global variable instead of forcing error find.
joseph-robertson Feb 9, 2026
590e0ad
Check for internal variable as well.
joseph-robertson Feb 10, 2026
836fd7e
Formatting in new unit test.
joseph-robertson Feb 10, 2026
b0bb17c
Temporary debugging changes in some testfiles.
joseph-robertson Feb 10, 2026
bf8e227
Set Type and Error only if serious error found.
joseph-robertson Feb 11, 2026
9817171
Minor calling point changes in a few testfiles.
joseph-robertson Feb 11, 2026
4d1b4aa
Remove extra EMS output from idf test files.
joseph-robertson Feb 12, 2026
0ed3853
Add summary comments to EvaluateExpression around uninitialized error…
joseph-robertson Feb 12, 2026
e63954f
Formatting for new unit test.
joseph-robertson Feb 12, 2026
0388944
Merge branch 'develop' into fix-ems-var-init-after-ref
joseph-robertson Feb 12, 2026
fc9f8d1
Merge branch 'develop' into fix-ems-var-init-after-ref
mitchute Feb 17, 2026
7ab44a1
For RetailPackagedTESCoil.idf, try moving only the Troof block above …
joseph-robertson Feb 18, 2026
00da99c
Revert program changes in RetailPackagedTESCoil.idf; instead just ini…
joseph-robertson Feb 18, 2026
d60fe2c
Elaborate EvaluateExpression explanation; add unrelated closing quota…
joseph-robertson Feb 20, 2026
58cddd5
Revert sample file calling point changes; instead, make offending ope…
joseph-robertson Feb 20, 2026
fa13d1c
Merge branch 'develop' into fix-ems-var-init-after-ref
joseph-robertson Feb 20, 2026
250d892
Merge branch 'develop' into fix-ems-var-init-after-ref
mitchute Feb 23, 2026
e729a79
Merge branch 'fix-ems-var-init-after-ref' of github.com:NatLabRockies…
mitchute Feb 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/EnergyPlus/DataRuntimeLanguage.hh
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,11 @@ namespace DataRuntimeLanguage {
ErlValueType Value; // values taken by Erl variables
bool ReadOnly; // true if Erl variable is read-only
bool SetByExternalInterface; // set to true if value is set by ExternalInterface
bool SetByGlobalVariable;
bool SetByInternalVariable;

// Default Constructor
ErlVariableType() : StackNum(0), ReadOnly(false), SetByExternalInterface(false)
ErlVariableType() : StackNum(0), ReadOnly(false), SetByExternalInterface(false), SetByGlobalVariable(false), SetByInternalVariable(false)
{
}
};
Expand Down
1 change: 1 addition & 0 deletions src/EnergyPlus/EMSManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ namespace EMSManager {
} else {
VariableNum = RuntimeLanguageProcessor::NewEMSVariable(state, cAlphaArgs(1), 0);
state.dataRuntimeLang->EMSInternalVarsUsed(InternVarNum).ErlVariableNum = VariableNum;
state.dataRuntimeLang->ErlVariable(VariableNum).SetByInternalVariable = true;
}

state.dataRuntimeLang->EMSInternalVarsUsed(InternVarNum).UniqueIDName = cAlphaArgs(2);
Expand Down
61 changes: 34 additions & 27 deletions src/EnergyPlus/RuntimeLanguageProcessor.cc

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/EnergyPlus/SimulationManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ namespace SimulationManager {
state.dataGlobal->KickOffSimulation = true;

Weather::ResetEnvironmentCounter(state);

SetupSimulation(state, ErrorsFound);

FaultsManager::CheckAndReadFaults(state);
Expand Down Expand Up @@ -330,6 +331,7 @@ namespace SimulationManager {
ReportNodeConnections(state);
}
SystemReports::CreateEnergyReportStructure(state);

bool anyEMSRan;
// point to finish setup processing EMS, sensor ready now
EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::SetupSimulation, anyEMSRan, ObjexxFCL::Optional_int_const());
Expand Down
37 changes: 37 additions & 0 deletions testfiles/HospitalBaselineReheatReportEMS.idf
Original file line number Diff line number Diff line change
Expand Up @@ -77655,6 +77655,43 @@
Flr_1_Stor_DT2, !- <none>
Flr_1_Waiting_DT2; !- <none>

EnergyManagementSystem:GlobalVariable,
A, !- Erl Variable 1 Name
B, !- Erl Variable 2 Name
C, !- Erl Variable 3 Name
D, !- <none>
E, !- <none>
F, !- <none>
G, !- <none>
H, !- <none>
I, !- <none>
J, !- <none>
K, !- <none>
L, !- <none>
M, !- <none>
N, !- <none>
O, !- <none>
P, !- <none>
Q, !- <none>
R, !- <none>
S, !- <none>
T, !- <none>
U, !- <none>
V, !- <none>
W, !- <none>
X, !- <none>
Y, !- <none>
Z, !- <none>
AA, !- <none>
BB, !- <none>
CC, !- <none>
DD, !- <none>
EE, !- <none>
FF, !- <none>
GG, !- <none>
HH, !- <none>
II; !- <none>
Comment on lines +77658 to +77693
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So we can avoid EvaluateExpression errors during setup.


!- =========== ALL OBJECTS IN CLASS: ENERGYMANAGEMENTSYSTEM:OUTPUTVARIABLE ===========

EnergyManagementSystem:OutputVariable,
Expand Down
12 changes: 7 additions & 5 deletions testfiles/RetailPackagedTESCoil.idf
Original file line number Diff line number Diff line change
Expand Up @@ -7949,7 +7949,7 @@
SET SumReliefMCT = SumReliefMCT + (h_Relief_4 * mdotRelief_4 ); !- <none>

EnergyManagementSystem:Program,
IntializeParameters, !- Name
InitializeParameters, !- Name
Set CV_Height = 1.0, !- Program Line 1
Set CV_effWidth = 40.0, !- Program Line 2
Set CV_crossSectArea = CV_Height * CV_effWidth, !- <none>
Expand Down Expand Up @@ -8066,8 +8066,10 @@

EnergyManagementSystem:GlobalVariable,
Troof, !- Erl Variable 1 Name
CV_Height, !- Erl Variable 2 Name
CV_crossSectArea, !- Erl Variable 3 Name
DeltaT, !- Erl Variable 2 Name
ratioT, !- Erl Variable 3 Name
Comment on lines +8069 to +8070
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So we can avoid EvaluateExpression errors during setup.

CV_Height, !- <none>
CV_crossSectArea, !- <none>
C_v, !- <none>
rhoAir, !- <none>
CpAir, !- <none>
Expand Down Expand Up @@ -8101,7 +8103,7 @@
EnergyManagementSystem:ProgramCallingManager,
Model Flat Roof Microclimate, !- Name
BeginTimestepBeforePredictor, !- EnergyPlus Model Calling Point
IntializeParameters, !- Program Name 1
InitializeParameters, !- Program Name 1
ModelFlatRoofMicroClime, !- Program Name 2
ApplyMicroClimeActuators;!- Program Name 3

Expand All @@ -8115,7 +8117,7 @@
Run SumReliefAirMCTterm, !- <none>
Run CalcWindTerms, !- <none>
Run CalcBouyancyTerms, !- <none>
SEt Numerator = WindMCT + NatBouyMCT + SumHATroof + QdotCond + SumReliefMCT, !- <none>
Set Numerator = WindMCT + NatBouyMCT + SumHATroof + QdotCond + SumReliefMCT, !- <none>
Set Denominator = WindMC + NatBouyMC + SumHAroof + SumIntakeMdotCp, !- <none>
Set Troof = Numerator / Denominator, !- <none>
IF Ta < 2.0, !- <none>
Expand Down
5 changes: 5 additions & 0 deletions testfiles/_ResidentialBase.idf
Original file line number Diff line number Diff line change
Expand Up @@ -7785,6 +7785,11 @@
EnergyManagementSystem:GlobalVariable,
natural_vent_program_Qwhf; !- Erl Variable 1 Name

EnergyManagementSystem:GlobalVariable,
Qducts, !- Erl Variable 1 Name
Qsupply, !- Erl Variable 2 Name
Qexhaust; !- Erl Variable 3 Name
Comment on lines +7788 to +7791
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So we can avoid EvaluateExpression errors during setup.


!- =========== ALL OBJECTS IN CLASS: ENERGYMANAGEMENTSYSTEM:OUTPUTVARIABLE ===========

EnergyManagementSystem:OutputVariable,
Expand Down
178 changes: 177 additions & 1 deletion tst/EnergyPlus/unit/EMSManager.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

// EnergyPlus Headers
#include "Fixtures/EnergyPlusFixture.hh"
#include <EnergyPlus/ConfiguredFunctions.hh>
#include <EnergyPlus/Construction.hh>
#include <EnergyPlus/CurveManager.hh>
#include <EnergyPlus/Data/EnergyPlusData.hh>
Expand Down Expand Up @@ -936,7 +937,7 @@ TEST_F(EnergyPlusFixture, TestUnInitializedEMSVariable2)
state->dataEMSMgr->FinishProcessingUserInput = true;
bool anyRan;
EMSManager::ManageEMS(*state, EMSManager::EMSCallFrom::SetupSimulation, anyRan, ObjexxFCL::Optional_int_const());
// Expect the variable to not yet be initialized, call EvaluateExpresssion and check argument
// Expect the variable to not yet be initialized, call EvaluateExpression and check argument

ErlValueType ReturnValue;
bool seriousErrorFound = false;
Expand All @@ -958,6 +959,181 @@ TEST_F(EnergyPlusFixture, TestUnInitializedEMSVariable2)
EXPECT_FALSE(seriousErrorFound);
}

TEST_F(EnergyPlusFixture, TestEMSVariableInitAfterRef1)
{
// test for #11360 - EMS variable initialized after reference, outside of ManageSimulation
std::string const idf_objects = delimited_string({

"EnergyManagementSystem:Program,",
" ev_discharge_program, !- Name",
" Set power_mult = site_temp_adj, !- Program Line 1",
" Set site_temp_adj = 0.1; !- Program Line 2",

"EnergyManagementSystem:ProgramCallingManager,",
" ev_discharge_pcm, !- Name",
" BeginTimestepBeforePredictor, !- EnergyPlus Model Calling Point",
" ev_discharge_program; !- Program Name 1",
});

ASSERT_TRUE(process_idf(idf_objects));
state->init_state(*state);

int internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
EXPECT_EQ(internalVarNum, 0);

bool anyRan;
EXPECT_TRUE(state->dataEMSMgr->GetEMSUserInput);
EMSManager::ManageEMS(*state, EMSManager::EMSCallFrom::SetupSimulation, anyRan, ObjexxFCL::Optional_int_const());

internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
ASSERT_GT(internalVarNum, 0);
EXPECT_FALSE(state->dataRuntimeLang->ErlVariable(internalVarNum).Value.initialized);

EXPECT_FALSE(state->dataEMSMgr->GetEMSUserInput);
EMSManager::ManageEMS(*state, EMSManager::EMSCallFrom::BeginNewEnvironment, anyRan, ObjexxFCL::Optional_int_const());

internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
ASSERT_GT(internalVarNum, 0);
EXPECT_FALSE(state->dataRuntimeLang->ErlVariable(internalVarNum).Value.initialized);

EXPECT_FALSE(state->dataEMSMgr->GetEMSUserInput);
ASSERT_THROW(EMSManager::ManageEMS(*state, EMSManager::EMSCallFrom::BeginTimestepBeforePredictor, anyRan, ObjexxFCL::Optional_int_const()),
EnergyPlus::FatalError);

internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
ASSERT_GT(internalVarNum, 0);
EXPECT_FALSE(state->dataRuntimeLang->ErlVariable(internalVarNum).Value.initialized);

// Expect the variable to not yet be initialized, call EvaluateExpression and check argument
bool seriousErrorFound = false;
ErlValueType ReturnValue = RuntimeLanguageProcessor::EvaluateExpression(
*state,
state->dataRuntimeLang->ErlStack(Util::FindItemInList("EV_DISCHARGE_PROGRAM", state->dataRuntimeLang->ErlStack)).Instruction(1).Argument2,
seriousErrorFound);
EXPECT_TRUE(seriousErrorFound);

const std::string expected_error = delimited_string({
" ** Severe ** Problem found in EMS EnergyPlus Runtime Language.",
" ** ~~~ ** Erl program name: EV_DISCHARGE_PROGRAM",
" ** ~~~ ** Erl program line number: 1",
" ** ~~~ ** Erl program line text: SET POWER_MULT = SITE_TEMP_ADJ",
" ** ~~~ ** Error message: *** Error: EvaluateExpression: Variable = 'SITE_TEMP_ADJ' used in expression has not been initialized! "
"*** ",
" ** ~~~ ** Environment=, at Simulation time= 00:-15 - 00:00",
" ** Fatal ** Previous EMS error caused program termination.",
" ...Summary of Errors that led to program termination:",
" ..... Reference severe error count=1",
" ..... Last severe error=Problem found in EMS EnergyPlus Runtime Language.",
});

compare_err_stream(expected_error);
}

TEST_F(EnergyPlusFixture, TestEMSVariableInitAfterRef2)
{
// test for #11360 - EMS variable initialized after reference, within ManageSimulation
std::string const idf_objects = delimited_string({
"Version," + DataStringGlobals::MatchVersion + ";",

"RunPeriod,",
" Run Period 1, !- Name",
" 1, !- Begin Month",
" 1, !- Begin Day of Month",
" 2007, !- Begin Year",
" 1, !- End Month",
" 1, !- End Day of Month",
" 2007, !- End Year",
" Monday, !- Day of Week for Start Day",
" No, !- Use Weather File Holidays and Special Days",
" No, !- Use Weather File Daylight Saving Period",
" No, !- Apply Weekend Holiday Rule",
" Yes, !- Use Weather File Rain Indicators",
" Yes; !- Use Weather File Snow Indicators",

"SimulationControl,",
" No, !- Do Zone Sizing Calculation",
" No, !- Do System Sizing Calculation",
" No, !- Do Plant Sizing Calculation",
" No, !- Run Simulation for Sizing Periods",
" Yes, !- Run Simulation for Weather File Run Periods",
" , !- Do HVAC Sizing Simulation for Sizing Periods",
" ; !- Maximum Number of HVAC Sizing Simulation Passes",

"Site:Location,",
" Denver Stapleton Intl Arpt CO USA WMO=724690, !- Name",
" 39.77, !- Latitude {deg}",
" -104.87, !- Longitude {deg}",
" -7.00, !- Time Zone {hr}",
" 1611.00; !- Elevation {m}",

"Material,",
" Concrete Block, !- Name",
" MediumRough, !- Roughness",
" 0.1014984, !- Thickness {m}",
" 0.3805070, !- Conductivity {W/m-K}",
" 608.7016, !- Density {kg/m3}",
" 836.8000; !- Specific Heat {J/kg-K}",

"Construction,",
" ConcConstruction, !- Name",
" Concrete Block; !- Outside Layer",

"BuildingSurface:Detailed,"
" Wall, !- Name",
" Wall, !- Surface Type",
" ConcConstruction, !- Construction Name",
" Zone, !- Zone Name",
" , !- Space Name",
" Outdoors, !- Outside Boundary Condition",
" , !- Outside Boundary Condition Object",
" SunExposed, !- Sun Exposure",
" WindExposed, !- Wind Exposure",
" 0.5000000, !- View Factor to Ground",
" 4, !- Number of Vertices",
" 0.000000,0.000000,10.00000, !- X,Y,Z ==> Vertex 1 {m}",
" 0.000000,0.000000,0, !- X,Y,Z ==> Vertex 2 {m}",
" 10.00000,0.000000,0, !- X,Y,Z ==> Vertex 3 {m}",
" 10.00000,0.000000,10.00000; !- X,Y,Z ==> Vertex 4 {m}",

"Zone,"
" Zone, !- Name",
" 0, !- Direction of Relative North {deg}",
" 6.000000, !- X Origin {m}",
" 6.000000, !- Y Origin {m}",
" 0, !- Z Origin {m}",
" 1, !- Type",
" 1, !- Multiplier",
" autocalculate, !- Ceiling Height {m}",
" autocalculate; !- Volume {m3}",

"EnergyManagementSystem:Program,",
" ev_discharge_program, !- Name",
" Set power_mult = site_temp_adj, !- Program Line 1",
" Set site_temp_adj = 0.1; !- Program Line 2",

"EnergyManagementSystem:ProgramCallingManager,",
" ev_discharge_pcm, !- Name",
" BeginTimestepBeforePredictor, !- EnergyPlus Model Calling Point",
" ev_discharge_program; !- Program Name 1",
});

ASSERT_TRUE(process_idf(idf_objects));
state->init_state(*state);

state->dataWeather->WeatherFileExists = true;
state->files.inputWeatherFilePath.filePath = configured_source_directory() / "weather/USA_CO_Golden-NREL.724666_TMY3.epw";

int internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
EXPECT_EQ(internalVarNum, 0);

EXPECT_TRUE(state->dataEMSMgr->GetEMSUserInput);
ASSERT_THROW(SimulationManager::ManageSimulation(*state), EnergyPlus::FatalError);

internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1);
ASSERT_GT(internalVarNum, 0);
EXPECT_FALSE(state->dataRuntimeLang->ErlVariable(internalVarNum).Value.initialized);
}

TEST_F(EnergyPlusFixture, EMSManager_CheckIfAnyEMS_OutEMS)
{
std::string const idf_objects = delimited_string({
Expand Down
Loading