diff --git a/src/EnergyPlus/HeatBalanceManager.cc b/src/EnergyPlus/HeatBalanceManager.cc index 55b1b1c57ca..446a7db4305 100644 --- a/src/EnergyPlus/HeatBalanceManager.cc +++ b/src/EnergyPlus/HeatBalanceManager.cc @@ -2612,6 +2612,11 @@ namespace HeatBalanceManager { using OutAirNodeManager::SetOutAirNodes; using WindowEquivalentLayer::InitEquivalentLayerWindowCalculations; + if (state.dataGlobal->AnyEnergyManagementSystemInModel) { + HeatBalanceSurfaceManager::InitEMSControlledConstructions(state); + HeatBalanceSurfaceManager::InitEMSControlledSurfaceProperties(state); + } + if (state.dataGlobal->BeginSimFlag) { AllocateHeatBalArrays(state); // Allocate the Module Arrays if (state.dataHeatBal->AnyCTF || state.dataHeatBal->AnyEMPD) { @@ -2656,11 +2661,6 @@ namespace HeatBalanceManager { } } - if (state.dataGlobal->AnyEnergyManagementSystemInModel) { - HeatBalanceSurfaceManager::InitEMSControlledConstructions(state); - HeatBalanceSurfaceManager::InitEMSControlledSurfaceProperties(state); - } - // Init storm window pointers if (state.dataSurface->TotStormWin > 0) { if (state.dataGlobal->BeginDayFlag) { diff --git a/testfiles/HeatPumpWaterToAirWithHumControlDewPoint.idf b/testfiles/HeatPumpWaterToAirWithHumControlDewPoint.idf index f036eed7afa..8ac1ceaf327 100644 --- a/testfiles/HeatPumpWaterToAirWithHumControlDewPoint.idf +++ b/testfiles/HeatPumpWaterToAirWithHumControlDewPoint.idf @@ -103,7 +103,7 @@ ! Environmental Emissions: None ! Utility Tariffs: None - Version,26.1; + Version,26.2; Building, Building, !- Name diff --git a/testfiles/PythonPluginCondFD_Enet.idf b/testfiles/PythonPluginCondFD_Enet.idf index 76ea8618f99..af2ae9f4511 100644 --- a/testfiles/PythonPluginCondFD_Enet.idf +++ b/testfiles/PythonPluginCondFD_Enet.idf @@ -4,7 +4,7 @@ ! Python plugin test for CondFD sky LW radiation override. ! Based on 1ZoneCondFD_Enet_Test.idf with PythonPlugin setting Enet = -200 W/m2. - Version,26.1; + Version,26.2; !- =========== ALL OBJECTS IN CLASS: SIMULATIONCONTROL =========== diff --git a/testfiles/PythonPluginCondFD_Enet.py b/testfiles/PythonPluginCondFD_Enet.py index 459f9d5d1b5..6b8b5fe316c 100644 --- a/testfiles/PythonPluginCondFD_Enet.py +++ b/testfiles/PythonPluginCondFD_Enet.py @@ -79,6 +79,8 @@ # === Configuration === SURFACE_NAME = "Zn001:Roof001" ENET_VALUE = -200.0 # W/m2 +MATERIAL_NAME = "C5 - 4 IN HW CONCRETE" +THERMAL_ABSORPTANCE_VALUE = 0.75 class EnetSkyOverride(EnergyPlusPlugin): @@ -86,7 +88,32 @@ class EnetSkyOverride(EnergyPlusPlugin): def __init__(self): super().__init__() self.need_to_get_handles = True + self.need_to_get_material_handle = True self.enet_handle = None + self.thermal_absorptance_handle = None + + def on_begin_zone_timestep_before_init_heat_balance(self, state) -> int: + if self.need_to_get_material_handle: + self.thermal_absorptance_handle = self.api.exchange.get_actuator_handle( + state, + "Material", + "Surface Property Thermal Absorptance", + MATERIAL_NAME, + ) + if self.thermal_absorptance_handle == -1: + self.api.runtime.issue_severe( + state, + f"EnetSkyOverride: no thermal absorptance actuator for material '{MATERIAL_NAME}'.", + ) + return 1 + self.need_to_get_material_handle = False + + self.api.exchange.set_actuator_value( + state, + self.thermal_absorptance_handle, + THERMAL_ABSORPTANCE_VALUE, + ) + return 0 def on_begin_timestep_before_predictor(self, state) -> int: if self.need_to_get_handles: diff --git a/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc b/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc index 77fd88bdd03..6c228b06d78 100644 --- a/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc +++ b/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -2400,6 +2401,38 @@ TEST_F(EnergyPlusFixture, HeatBalanceManager_EMSConstructionSwitchTestCondFD) EXPECT_TRUE(state->dataSurface->SurfEMSConstructionOverrideON(surfNum)); } +TEST_F(EnergyPlusFixture, HeatBalanceManager_EMSMaterialThermalAbsorptanceUpdatesConstructionProperties) +{ + constexpr Real64 initialThermalAbsorptance = 0.9; + constexpr Real64 emsThermalAbsorptance = 0.35; + + state->dataMaterial->materials.allocate(1); + auto *mat = new Material::MaterialBase; + mat->Name = "ROOF MATERIAL"; + mat->group = Material::Group::Regular; + mat->AbsorpThermal = initialThermalAbsorptance; + mat->AbsorpThermalInput = initialThermalAbsorptance; + mat->AbsorpThermalEMSOverrideOn = true; + mat->AbsorpThermalEMSOverride = emsThermalAbsorptance; + state->dataMaterial->materials(1) = mat; + + state->dataHeatBal->TotConstructs = 1; + state->dataConstruction->Construct.allocate(1); + auto &construction = state->dataConstruction->Construct(1); + construction.Name = "ROOF CONSTRUCTION"; + construction.TotLayers = 1; + construction.LayerPoint.allocate(1); + construction.LayerPoint(1) = 1; + construction.InsideAbsorpThermal = initialThermalAbsorptance; + construction.OutsideAbsorpThermal = initialThermalAbsorptance; + + HeatBalanceSurfaceManager::InitEMSControlledSurfaceProperties(*state); + + EXPECT_EQ(mat->AbsorpThermal, emsThermalAbsorptance); + EXPECT_EQ(construction.InsideAbsorpThermal, emsThermalAbsorptance); + EXPECT_EQ(construction.OutsideAbsorpThermal, emsThermalAbsorptance); +} + TEST_F(EnergyPlusFixture, HeatBalanceManager_GetSpaceData) { // Test input processing of Space object