diff --git a/src/EnergyPlus/HeatBalanceInternalHeatGains.cc b/src/EnergyPlus/HeatBalanceInternalHeatGains.cc index 54c196713a6..20070569e6d 100644 --- a/src/EnergyPlus/HeatBalanceInternalHeatGains.cc +++ b/src/EnergyPlus/HeatBalanceInternalHeatGains.cc @@ -154,6 +154,15 @@ void SetupSpaceInternalGain(EnergyPlusData &state, thisIntGain.device(thisIntGain.numberOfDevices).CompObjectName = UpperCaseObjectName; thisIntGain.device(thisIntGain.numberOfDevices).CompType = IntGainCompType; + + // Tank losses should be distributed across multiplied zones/spaces - adjust the space gain fraction to account for this + if (std::find(AdjustTankLossMultipliers.begin(), AdjustTankLossMultipliers.end(), IntGainCompType) != AdjustTankLossMultipliers.end()) { + const int zoneNum = state.dataHeatBal->space(spaceNum).zoneNum; + const int multiplier = state.dataHeatBal->Zone(zoneNum).Multiplier * state.dataHeatBal->Zone(zoneNum).ListMultiplier; + if (multiplier > 1) { + spaceGainFraction /= multiplier; + } + } thisIntGain.device(thisIntGain.numberOfDevices).spaceGainFrac = spaceGainFraction; // note pointer assignments in code below! diff --git a/src/EnergyPlus/HeatBalanceInternalHeatGains.hh b/src/EnergyPlus/HeatBalanceInternalHeatGains.hh index eeafc2ff5c3..ea2dab8c1d4 100644 --- a/src/EnergyPlus/HeatBalanceInternalHeatGains.hh +++ b/src/EnergyPlus/HeatBalanceInternalHeatGains.hh @@ -83,6 +83,13 @@ void SetupSpaceInternalGain(EnergyPlusData &state, int RetNodeNum = 0 // for return air heat gains ); +// Tank losses should be distributed across multiplied zones/spaces - these are the internal gains that need adjust for this +static constexpr std::array AdjustTankLossMultipliers = { + DataHeatBalance::IntGainType::WaterHeaterMixed, + DataHeatBalance::IntGainType::WaterHeaterStratified, + DataHeatBalance::IntGainType::ThermalStorageChilledWaterMixed, + DataHeatBalance::IntGainType::ThermalStorageChilledWaterStratified}; + struct HeatBalInternalHeatGainsData : BaseGlobalStruct { diff --git a/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc b/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc index db18cbebb3b..5013815ca80 100644 --- a/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc +++ b/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc @@ -6721,6 +6721,43 @@ TEST_F(EnergyPlusFixture, MixedTank_PVT_Per_VolumeSizing_PerSolarCollectorArea) EXPECT_DOUBLE_EQ(0.0, Tank.AmbientZoneGain); // Didn't define on/off cycle losses } +TEST_F(EnergyPlusFixture, WaterThermalTankData_AdjustTankLossMultipliers) +{ + constexpr int ZONES = 1; + constexpr int SPACES = 5; + constexpr int FLOOR_AREA = 1000; + constexpr int MULTIPLIER = 10; + + state->dataHeatBal->Zone.allocate(ZONES); + state->dataHeatBal->Zone(ZONES).numSpaces = SPACES; + state->dataHeatBal->Zone(ZONES).FloorArea = FLOOR_AREA; + state->dataHeatBal->Zone(ZONES).ListMultiplier = MULTIPLIER; + state->dataHeatBal->Zone(ZONES).Multiplier = MULTIPLIER; + state->dataHeatBal->Zone(ZONES).spaceIndexes.allocate(SPACES); + + state->dataHeatBal->space.allocate(SPACES); + state->dataHeatBal->spaceIntGainDevices.allocate(SPACES); + + for (int spaceNum = 1; spaceNum <= SPACES; spaceNum++) { + state->dataHeatBal->Zone(ZONES).spaceIndexes(spaceNum) = spaceNum; + state->dataHeatBal->space(spaceNum).FloorArea = static_cast(FLOOR_AREA) / SPACES; + state->dataHeatBal->space(spaceNum).zoneNum = ZONES; + } + + WaterThermalTanks::WaterThermalTankData tank; + tank.Name = "Water Heater"; + tank.WaterThermalTankType = DataPlant::PlantEquipmentType::WtrHeaterMixed; + tank.AmbientTempZone = ZONES; + tank.setupZoneInternalGains(*state); + + Real64 spaceGainFracTotal(0); + for (int spaceNum = 1; spaceNum <= SPACES; spaceNum++) { + spaceGainFracTotal += state->dataHeatBal->spaceIntGainDevices(spaceNum).device(1).spaceGainFrac * state->dataHeatBal->Zone(ZONES).Multiplier * + state->dataHeatBal->Zone(ZONES).ListMultiplier; + } + EXPECT_NEAR(spaceGainFracTotal, 1, 0.001); +} + TEST_F(EnergyPlusFixture, thermalStorageTankInputReading_Autocalculate) { // Test for #11282