diff --git a/src/EnergyPlus/DataGlobals.hh b/src/EnergyPlus/DataGlobals.hh index c8a3e8c1646..89a723fe611 100644 --- a/src/EnergyPlus/DataGlobals.hh +++ b/src/EnergyPlus/DataGlobals.hh @@ -111,6 +111,7 @@ struct DataGlobal : BaseGlobalStruct int numSpaceTypes = 0; // Number of unique space types int TimeStep = 0; // Counter for time steps (fractional hours) Real64 TimeStepZone = 0.0; // Zone time step in fractional hours + bool SetupFlag = false; // True during setup portion of a simulation bool WarmupFlag = false; // True during the warmup portion of a simulation Int64 StdOutputRecordCount = 0; // Count of Standard output records Int64 StdMeterRecordCount = 0; // Count of Meter output records diff --git a/src/EnergyPlus/DataRuntimeLanguage.hh b/src/EnergyPlus/DataRuntimeLanguage.hh index 906fa15b1e8..978370c963a 100644 --- a/src/EnergyPlus/DataRuntimeLanguage.hh +++ b/src/EnergyPlus/DataRuntimeLanguage.hh @@ -364,9 +364,12 @@ namespace DataRuntimeLanguage { int TrendVarPointer; // index to match in TrendVariable structure std::string Error; // holds error message string for reporting bool initialized; // true if number value has been SET (ie. has been on LHS in SET expression) + bool SetupInit; // false when marked by an uninitialized-variable evaluation error so it can be treated as uninitialized later // Default Constructor - ErlValueType() : Type(Value::Null), Number(0.0), Variable(0), Expression(0), TrendVariable(false), TrendVarPointer(0), initialized(false) + ErlValueType() + : Type(Value::Null), Number(0.0), Variable(0), Expression(0), TrendVariable(false), TrendVarPointer(0), initialized(false), + SetupInit(true) { } @@ -379,9 +382,10 @@ namespace DataRuntimeLanguage { bool const TrendVariable, // true if Erl variable is really a trend variable int const TrendVarPointer, // index to match in TrendVariable structure std::string const &Error, // holds error message string for reporting - bool const initialized) + bool const initialized, + bool const SetupInit) : Type(Type), Number(Number), String(String), Variable(Variable), Expression(Expression), TrendVariable(TrendVariable), - TrendVarPointer(TrendVarPointer), Error(Error), initialized(initialized) + TrendVarPointer(TrendVarPointer), Error(Error), initialized(initialized), SetupInit(SetupInit) { } }; @@ -803,11 +807,11 @@ struct RuntimeLanguageData : BaseGlobalStruct Array1D EMSInternalVarsUsed; // internal data that are used Array1D EMSProgramCallManager; // program calling managers DataRuntimeLanguage::ErlValueType Null = DataRuntimeLanguage::ErlValueType( - DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true); // special "null" Erl variable value instance + DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true, true); // special "null" Erl variable value instance DataRuntimeLanguage::ErlValueType False = DataRuntimeLanguage::ErlValueType( - DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true); // special "false" Erl variable value instance + DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true, true); // special "false" Erl variable value instance DataRuntimeLanguage::ErlValueType True = DataRuntimeLanguage::ErlValueType( - DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true); // special "True" Erl variable value instance, gets reset + DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true, true); // special "True" Erl variable value instance, gets reset std::map, int> EMSActuatorAvailableMap; @@ -866,9 +870,9 @@ struct RuntimeLanguageData : BaseGlobalStruct this->EMSInternalVarsAvailable.deallocate(); this->EMSInternalVarsUsed.deallocate(); this->EMSProgramCallManager.deallocate(); - this->Null = DataRuntimeLanguage::ErlValueType(DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true); - this->False = DataRuntimeLanguage::ErlValueType(DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true); - this->True = DataRuntimeLanguage::ErlValueType(DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true); + this->Null = DataRuntimeLanguage::ErlValueType(DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true, true); + this->False = DataRuntimeLanguage::ErlValueType(DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true, true); + this->True = DataRuntimeLanguage::ErlValueType(DataRuntimeLanguage::Value::Null, 0.0, "", 0, 0, false, 0, "", true, true); this->EMSActuatorAvailableMap.clear(); } diff --git a/src/EnergyPlus/RuntimeLanguageProcessor.cc b/src/EnergyPlus/RuntimeLanguageProcessor.cc index ae624e5333d..f79dbec390a 100644 --- a/src/EnergyPlus/RuntimeLanguageProcessor.cc +++ b/src/EnergyPlus/RuntimeLanguageProcessor.cc @@ -310,6 +310,10 @@ void BeginEnvrnInitializeRuntimeLanguage(EnergyPlusData &state) if (state.dataRuntimeLang->ErlVariable(ErlVariableNum).Value.initialized) { state.dataRuntimeLang->ErlVariable(ErlVariableNum).Value = SetErlValueNumber(0.0, state.dataRuntimeLang->ErlVariable(ErlVariableNum).Value); + + if (!state.dataRuntimeLang->ErlVariable(ErlVariableNum).Value.SetupInit) { + state.dataRuntimeLang->ErlVariable(ErlVariableNum).Value.initialized = false; + } } } // reinitialize state of actuators @@ -976,7 +980,7 @@ void WriteTrace(EnergyPlusData &state, int const StackNum, int const Instruction std::string LineString; std::string cValueString; std::string TimeString; - std::string DuringWarmup; + std::string OccurrenceTimingInfo; if ((!state.dataRuntimeLang->OutputFullEMSTrace) && (!state.dataRuntimeLang->OutputEMSErrors) && (!seriousErrorFound)) { return; @@ -1004,19 +1008,27 @@ void WriteTrace(EnergyPlusData &state, int const StackNum, int const Instruction // put together timestamp info if (state.dataGlobal->WarmupFlag) { - if (!state.dataGlobal->DoingSizing) { - DuringWarmup = " During Warmup, Occurrence info="; + if (!state.dataGlobal->SetupFlag) { + if (!state.dataGlobal->DoingSizing) { + OccurrenceTimingInfo = " During Warmup, Occurrence info="; + } else { + OccurrenceTimingInfo = " During Warmup & Sizing, Occurrence info="; + } } else { - DuringWarmup = " During Warmup & Sizing, Occurrence info="; + if (!state.dataGlobal->DoingSizing) { + OccurrenceTimingInfo = " During Setup, Occurrence info="; + } else { + OccurrenceTimingInfo = " During Setup & Sizing, Occurrence info="; + } } } else { if (!state.dataGlobal->DoingSizing) { - DuringWarmup = " Occurrence info="; + OccurrenceTimingInfo = " Occurrence info="; } else { - DuringWarmup = " During Sizing, Occurrence info="; + OccurrenceTimingInfo = " During Sizing, Occurrence info="; } } - TimeString = DuringWarmup + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' + CreateSysTimeIntervalString(state); + TimeString = OccurrenceTimingInfo + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' + CreateSysTimeIntervalString(state); if (state.dataRuntimeLang->OutputFullEMSTrace || (state.dataRuntimeLang->OutputEMSErrors && (ReturnValue.Type == Value::Error))) { print(state.files.edd, "{},Line {},{},{},{}\n", NameString, LineNumString, LineString, cValueString, TimeString); @@ -1806,19 +1818,17 @@ ErlValueType EvaluateExpression(EnergyPlusData &state, int const ExpressionNum, } } else if (thisOperand.Type == Value::Variable) { - auto const &thisErlVar = state.dataRuntimeLang->ErlVariable(thisOperand.Variable); + auto &thisErlVar = state.dataRuntimeLang->ErlVariable(thisOperand.Variable); if (thisErlVar.Value.initialized) { // check that value has been initialized thisOperand = thisErlVar.Value; } else { // value has never been set - // During setup (before simulation), we want to avoid initializing variables to zero without throwing an error. - // Throw the error, and write it to edd file, if variable is uninitialized and is *not* a global or internal variable. - // The assumption is that if we made it here for a global variable, it is initialized in another program. - // E.g., if it's initialized in a program with BeginNewEnvironment calling point, setup won't set it but simulation will. - if ((!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation && !state.dataEMSMgr->FinishProcessingUserInput) || - (!(thisErlVar.SetByGlobalVariable || thisErlVar.SetByInternalVariable))) { - ReturnValue.Type = Value::Error; - ReturnValue.Error = "EvaluateExpression: Variable = '" + thisErlVar.Name + "' used in expression has not been initialized!"; + ReturnValue.Type = Value::Error; + ReturnValue.Error = "EvaluateExpression: Variable = '" + thisErlVar.Name + "' used in expression has not been initialized!"; + // Use SetupInit in BeginEnvrnInitializeRuntimeLanguage for "un-initializing" Erl variables that may have been + // initialized to zero during setup. This can happen since SetupSimulation does not call BeginNewEnvironment. + thisErlVar.Value.SetupInit = false; + if (!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation && !state.dataEMSMgr->FinishProcessingUserInput) { // check if this is an arg in CurveValue, if (thisErlExpression.Operator != diff --git a/src/EnergyPlus/SimulationManager.cc b/src/EnergyPlus/SimulationManager.cc index 69e61049cc9..b7e6dfd61d9 100644 --- a/src/EnergyPlus/SimulationManager.cc +++ b/src/EnergyPlus/SimulationManager.cc @@ -276,6 +276,7 @@ namespace SimulationManager { state.dataErrTracking->AskForConnectionsReport = true; // set to true now that input processing and sizing is done. state.dataGlobal->KickOffSimulation = false; + state.dataGlobal->SetupFlag = false; state.dataGlobal->WarmupFlag = false; state.dataReportFlag->DoWeatherInitReporting = true; @@ -1991,6 +1992,7 @@ namespace SimulationManager { state.dataGlobal->BeginEnvrnFlag = true; state.dataGlobal->EndEnvrnFlag = false; state.dataEnvrn->EndMonthFlag = false; + state.dataGlobal->SetupFlag = true; state.dataGlobal->WarmupFlag = true; state.dataGlobal->DayOfSim = 0; diff --git a/src/EnergyPlus/UtilityRoutines.cc b/src/EnergyPlus/UtilityRoutines.cc index ca36e25a8dc..f593bd4303b 100644 --- a/src/EnergyPlus/UtilityRoutines.cc +++ b/src/EnergyPlus/UtilityRoutines.cc @@ -905,10 +905,18 @@ void ShowContinueErrorTimeStamp(EnergyPlusData &state, std::string const &Messag std::string cEnvHeader; if (state.dataGlobal->WarmupFlag) { - if (!state.dataGlobal->DoingSizing) { - cEnvHeader = " During Warmup, Environment="; + if (!state.dataGlobal->SetupFlag) { + if (!state.dataGlobal->DoingSizing) { + cEnvHeader = " During Warmup, Environment="; + } else { + cEnvHeader = " During Warmup & Sizing, Environment="; + } } else { - cEnvHeader = " During Warmup & Sizing, Environment="; + if (!state.dataGlobal->DoingSizing) { + cEnvHeader = " During Setup, Environment="; + } else { + cEnvHeader = " During Setup & Sizing, Environment="; + } } } else { if (!state.dataGlobal->DoingSizing) { diff --git a/testfiles/HospitalBaselineReheatReportEMS.idf b/testfiles/HospitalBaselineReheatReportEMS.idf index 6b49a598d50..93fec4aed5e 100644 --- a/testfiles/HospitalBaselineReheatReportEMS.idf +++ b/testfiles/HospitalBaselineReheatReportEMS.idf @@ -77655,43 +77655,6 @@ Flr_1_Stor_DT2, !- Flr_1_Waiting_DT2; !- - EnergyManagementSystem:GlobalVariable, - A, !- Erl Variable 1 Name - B, !- Erl Variable 2 Name - C, !- Erl Variable 3 Name - D, !- - E, !- - F, !- - G, !- - H, !- - I, !- - J, !- - K, !- - L, !- - M, !- - N, !- - O, !- - P, !- - Q, !- - R, !- - S, !- - T, !- - U, !- - V, !- - W, !- - X, !- - Y, !- - Z, !- - AA, !- - BB, !- - CC, !- - DD, !- - EE, !- - FF, !- - GG, !- - HH, !- - II; !- - !- =========== ALL OBJECTS IN CLASS: ENERGYMANAGEMENTSYSTEM:OUTPUTVARIABLE =========== EnergyManagementSystem:OutputVariable, diff --git a/testfiles/RetailPackagedTESCoil.idf b/testfiles/RetailPackagedTESCoil.idf index 448a8b1c096..9ae5a346889 100644 --- a/testfiles/RetailPackagedTESCoil.idf +++ b/testfiles/RetailPackagedTESCoil.idf @@ -7948,6 +7948,10 @@ SET SumReliefMCT = SumReliefMCT + (h_Relief_3 * mdotRelief_3 ), !- SET SumReliefMCT = SumReliefMCT + (h_Relief_4 * mdotRelief_4 ); !- + EnergyManagementSystem:Program, + InitializeRoofTemperature, !- Name + Set Troof = 0.0; !- Program Line 1 + EnergyManagementSystem:Program, InitializeParameters, !- Name Set CV_Height = 1.0, !- Program Line 1 @@ -8066,10 +8070,8 @@ EnergyManagementSystem:GlobalVariable, Troof, !- Erl Variable 1 Name - DeltaT, !- Erl Variable 2 Name - ratioT, !- Erl Variable 3 Name - CV_Height, !- - CV_crossSectArea, !- + CV_Height, !- Erl Variable 2 Name + CV_crossSectArea, !- Erl Variable 3 Name C_v, !- rhoAir, !- CpAir, !- @@ -8100,6 +8102,11 @@ Set NatBouyMC = rhoAir * C_d * A_roof * temp2 * CpAir, !- Set NatBouyMCT = NatBouyMC * Ta; !- + EnergyManagementSystem:ProgramCallingManager, + InitializeRoofTemperatureOnBeginNewEnvironment, !- Name + BeginNewEnvironment, !- EnergyPlus Model Calling Point + InitializeRoofTemperature; !- Program Name 1 + EnergyManagementSystem:ProgramCallingManager, Model Flat Roof Microclimate, !- Name BeginTimestepBeforePredictor, !- EnergyPlus Model Calling Point diff --git a/testfiles/_ResidentialBase.idf b/testfiles/_ResidentialBase.idf index ea295fa1e61..aee659c62ac 100644 --- a/testfiles/_ResidentialBase.idf +++ b/testfiles/_ResidentialBase.idf @@ -7279,6 +7279,11 @@ !- =========== ALL OBJECTS IN CLASS: ENERGYMANAGEMENTSYSTEM:PROGRAMCALLINGMANAGER =========== + EnergyManagementSystem:ProgramCallingManager, + init calling manager, !- Name + BeginNewEnvironment, !- EnergyPlus Model Calling Point + init; !- Program Name 1 + EnergyManagementSystem:ProgramCallingManager, attic_unvented_1_duct_leakage_imbalance_infil_program calling manager, !- Name BeginZoneTimestepAfterInitHeatBalance, !- EnergyPlus Model Calling Point @@ -7336,6 +7341,13 @@ !- =========== ALL OBJECTS IN CLASS: ENERGYMANAGEMENTSYSTEM:PROGRAM =========== + EnergyManagementSystem:Program, + init, !- Name + Set CENTRAL_AC_AND_FURNACE_AIRLOOP_0_DUCTIMBALLKSUPFANEQUIVDZ = 0.0, !- Program Line 1 + Set CENTRAL_AC_AND_FURNACE_AIRLOOP_0_DUCTIMBALLKEXHFANEQUIVDZ = 0.0, !- Program Line 2 + Set CENTRAL_AC_AND_FURNACE_AIRLOOP_0_DUCTIMBALLKSUPFANEQUIVCOND = 0.0, !- + Set CENTRAL_AC_AND_FURNACE_AIRLOOP_0_DUCTIMBALLKEXHFANEQUIVCOND = 0.0; !- + EnergyManagementSystem:Program, attic_unvented_1_duct_leakage_imbalance_infil_program, !- Name Set Qducts = 0, !- Program Line 1 @@ -7785,11 +7797,6 @@ 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 - !- =========== ALL OBJECTS IN CLASS: ENERGYMANAGEMENTSYSTEM:OUTPUTVARIABLE =========== EnergyManagementSystem:OutputVariable, diff --git a/tst/EnergyPlus/unit/EMSManager.unit.cc b/tst/EnergyPlus/unit/EMSManager.unit.cc index e702e24bbd5..d9ea51ee70a 100644 --- a/tst/EnergyPlus/unit/EMSManager.unit.cc +++ b/tst/EnergyPlus/unit/EMSManager.unit.cc @@ -970,6 +970,8 @@ TEST_F(EnergyPlusFixture, TestEMSVariableInitAfterRef1) ASSERT_TRUE(process_idf(idf_objects)); state->init_state(*state); + state->dataGlobal->WarmupFlag = true; + state->dataGlobal->SetupFlag = true; int internalVarNum = RuntimeLanguageProcessor::FindEMSVariable(*state, "site_temp_adj", 1); EXPECT_EQ(internalVarNum, 0); @@ -1012,7 +1014,7 @@ TEST_F(EnergyPlusFixture, TestEMSVariableInitAfterRef1) " ** ~~~ ** 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", + " ** ~~~ ** During Setup, 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",