diff --git a/doc/input-output-reference/src/overview/group-simulation-parameters.tex b/doc/input-output-reference/src/overview/group-simulation-parameters.tex index a8483b4722b..3a0e41df0f0 100644 --- a/doc/input-output-reference/src/overview/group-simulation-parameters.tex +++ b/doc/input-output-reference/src/overview/group-simulation-parameters.tex @@ -470,10 +470,10 @@ \subsubsection{Inputs}\label{inputs-8-023} Three choices are allowed to select which solution algorithm will be used. The \textbf{ThirdOrderBackwardDifference} selection is the default selection and uses the third order finite difference approximation to solve the zone air energy and moisture balance equations. The \textbf{AnalyticalSolution} selection uses the integration approach to solve the zone air energy and moisture balance equations. The \textbf{EulerMethod} selection uses the first order finite backward difference approximation to solve the zone air energy and moisture balance equations. \paragraph{Field: Do Space Heat Balance for Sizing}\label{field-do-space-heat-balance-sizing} -If yes, space-level heat balance will be calculated and reported during sizing, and space sizing results will be reported along with zone sizing results. If no, then only zone-level heat balance will be calculated. This field defaults to No. For zones with more than one space, the zone sizing results are calculated for the whole zone and represent the coincident peak for the spaces in the zone. Note that space heat balance is not supported for \hyperref[inputs-hm]{HybridModel:Zone}, \hyperref[roomairmodeltype]{RoomAirModelType} other than Mixing, \hyperref[heatbalancealgorithm]{HeatBalanceAlgorithm} MoisturePenetrationDepthConductionTransferFunction and CombinedHeatAndMoistureFiniteElement. +If yes, the space-level heat balance will be calculated and reported during sizing for spaces that are in a controlled zone (i.e. the zone has a \hyperref[zonehvacequipmentconnections]{ZoneHVAC:EquipmentConnections} object). Space sizing results will be reported along with zone sizing results. If no, then only the zone-level heat balance will be calculated. This field defaults to No. For zones with more than one space, the zone sizing results are either the coincident (default) or non-coincident peak for the spaces in the zone (see \hyperref[field-type-of-space-sum-to-use]{Sizing:Zone}). Note that space heat balance is not supported for \hyperref[inputs-hm]{HybridModel:Zone}, \hyperref[roomairmodeltype]{RoomAirModelType} other than Mixing, \hyperref[heatbalancealgorithm]{HeatBalanceAlgorithm} MoisturePenetrationDepthConductionTransferFunction and CombinedHeatAndMoistureFiniteElement. \paragraph{Field: Do Space Heat Balance for Simulation}\label{field-do-space-heat-balance-simulation} -If yes, space-level heat balance will be calculated and reported during the simulation. If no, then only zone-level heat balance will be calculated. This field defaults to No. When this field is Yes, optional SpaceHVAC objects may be used to distribute zone HVAC equipment output to the spaces in the zone. See \hyperref[spacehvacequipmentconnections]{SpaceHVAC:EquipmentConnections}, \hyperref[spacehvaczoneequipmentsplitter]{SpaceHVAC:ZoneEquipmentSplitter}, \hyperref[spacehvaczoneequipmentmixer]{SpaceHVAC:ZoneEquipmentMixer} and \hyperref[spacehvaczonereturnmixer]{SpaceHVAC:ZoneReturnMixer}. +If yes, the space-level heat balance will be calculated and reported during the simulation. If no, then only the zone-level heat balance will be calculated. This field defaults to No. When this field is Yes, optional SpaceHVAC objects may be used to distribute zone HVAC equipment output to the spaces in the zone. See \hyperref[spacehvacequipmentconnections]{SpaceHVAC:EquipmentConnections}, \hyperref[spacehvaczoneequipmentsplitter]{SpaceHVAC:ZoneEquipmentSplitter}, \hyperref[spacehvaczoneequipmentmixer]{SpaceHVAC:ZoneEquipmentMixer} and \hyperref[spacehvaczonereturnmixer]{SpaceHVAC:ZoneReturnMixer}. And, a default IDF example is shown below: diff --git a/src/EnergyPlus/DataZoneEquipment.cc b/src/EnergyPlus/DataZoneEquipment.cc index c316d5f89f4..a109989cf71 100644 --- a/src/EnergyPlus/DataZoneEquipment.cc +++ b/src/EnergyPlus/DataZoneEquipment.cc @@ -315,38 +315,40 @@ void GetZoneEquipmentData(EnergyPlusData &state) cAlphaFields, cNumericFields); // Get Equipment | data for one zone - int zoneOrSpaceNum = Util::FindItemInList(AlphArray(1), state.dataHeatBal->Zone); + int zoneNum = Util::FindItemInList(AlphArray(1), state.dataHeatBal->Zone); std::string_view zsString = "Zone"; - if (zoneOrSpaceNum == 0) { + if (zoneNum == 0) { ShowSevereError(state, format("{}{}: {}=\"{}\"", RoutineName, CurrentModuleObject, cAlphaFields(1), AlphArray(1))); ShowContinueError(state, format("..Requested Controlled {} not among {}s, remaining items for this object not processed.", zsString, zsString)); state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; continue; } - bool isControlledAlready = state.dataHeatBal->Zone(zoneOrSpaceNum).IsControlled; - if (isControlledAlready) { + auto &thisZone = state.dataHeatBal->Zone(zoneNum); + // Is this a duplicate for the same zone? + if (thisZone.IsControlled) { ShowSevereError(state, format("{}{}: {}=\"{}\"", RoutineName, CurrentModuleObject, cAlphaFields(1), AlphArray(1))); ShowContinueError(state, format("..Duplicate Controlled {} entered, only one {} per {} is allowed.", zsString, CurrentModuleObject, zsString)); state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; continue; } - state.dataHeatBal->Zone(zoneOrSpaceNum).IsControlled = true; + thisZone.IsControlled = true; bool isSpace = false; + auto &thisZoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(zoneNum); processZoneEquipmentInput(state, CurrentModuleObject, - zoneOrSpaceNum, + zoneNum, isSpace, locTermUnitSizingCounter, overallEquipCount, - state.dataZoneEquip->ZoneEquipConfig(zoneOrSpaceNum), + thisZoneEquipConfig, AlphArray, cAlphaFields, lAlphaBlanks, NodeNums); - state.dataHeatBal->Zone(zoneOrSpaceNum).SystemZoneNodeNumber = state.dataZoneEquip->ZoneEquipConfig(zoneOrSpaceNum).ZoneNode; + thisZone.SystemZoneNodeNumber = thisZoneEquipConfig.ZoneNode; } // end loop over controlled zones for (int controlledSpaceLoop = 1; controlledSpaceLoop <= numControlledSpaces; ++controlledSpaceLoop) { CurrentModuleObject = "SpaceHVAC:EquipmentConnections"; @@ -363,38 +365,49 @@ void GetZoneEquipmentData(EnergyPlusData &state) cAlphaFields, cNumericFields); // Get Equipment | data for one zone - int zoneOrSpaceNum = Util::FindItemInList(AlphArray(1), state.dataHeatBal->space); + int spaceNum = Util::FindItemInList(AlphArray(1), state.dataHeatBal->space); std::string_view zsString = "Space"; - if (zoneOrSpaceNum == 0) { + if (spaceNum == 0) { ShowSevereError(state, format("{}{}: {}=\"{}\"", RoutineName, CurrentModuleObject, cAlphaFields(1), AlphArray(1))); ShowContinueError(state, format("..Requested Controlled {} not among {}s, remaining items for this object not processed.", zsString, zsString)); state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; continue; } - bool isControlledAlready = state.dataHeatBal->space(zoneOrSpaceNum).IsControlled; - if (isControlledAlready) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int zoneNum = thisSpace.zoneNum; + if (!state.dataHeatBal->Zone(zoneNum).IsControlled) { + ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisSpace.Name)); + ShowContinueError(state, + format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConnections object is required for this zone.", + state.dataHeatBal->Zone(zoneNum).Name)); + state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; + continue; + } + // Is this a duplicate for the same space? + if (thisSpace.IsControlled) { ShowSevereError(state, format("{}{}: {}=\"{}\"", RoutineName, CurrentModuleObject, cAlphaFields(1), AlphArray(1))); ShowContinueError(state, format("..Duplicate Controlled {} entered, only one {} per {} is allowed.", zsString, CurrentModuleObject, zsString)); state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; continue; } - state.dataHeatBal->space(zoneOrSpaceNum).IsControlled = true; + thisSpace.IsControlled = true; bool isSpace = true; + auto &thisSpaceEquipConfig = state.dataZoneEquip->spaceEquipConfig(spaceNum); processZoneEquipmentInput(state, CurrentModuleObject, - zoneOrSpaceNum, + spaceNum, isSpace, locTermUnitSizingCounter, overallEquipCount, - state.dataZoneEquip->spaceEquipConfig(zoneOrSpaceNum), + thisSpaceEquipConfig, AlphArray, cAlphaFields, lAlphaBlanks, NodeNums); - state.dataHeatBal->space(zoneOrSpaceNum).SystemZoneNodeNumber = state.dataZoneEquip->spaceEquipConfig(zoneOrSpaceNum).ZoneNode; + thisSpace.SystemZoneNodeNumber = thisSpaceEquipConfig.ZoneNode; } // end loop over controlled spaces if (state.dataHeatBal->doSpaceHeatBalanceSizing || state.dataHeatBal->doSpaceHeatBalanceSimulation) { @@ -510,7 +523,7 @@ void GetZoneEquipmentData(EnergyPlusData &state) ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisZeqSplitter.Name)); ShowContinueError( state, - format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConfiguration object is required for this zone.", zoneName)); + format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConnections object is required for this zone.", zoneName)); state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; continue; } @@ -547,7 +560,7 @@ void GetZoneEquipmentData(EnergyPlusData &state) ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisZeqMixer.Name)); ShowContinueError( state, - format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConfiguration object is required for this zone.", zoneName)); + format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConnections object is required for this zone.", zoneName)); state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; continue; } @@ -584,7 +597,7 @@ void GetZoneEquipmentData(EnergyPlusData &state) ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisZretMixer.Name)); ShowContinueError( state, - format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConfiguration object is required for this zone.", zoneName)); + format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConnections object is required for this zone.", zoneName)); state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true; continue; } diff --git a/src/EnergyPlus/SizingManager.cc b/src/EnergyPlus/SizingManager.cc index 4b1d3a2dfd4..226d8e311dc 100644 --- a/src/EnergyPlus/SizingManager.cc +++ b/src/EnergyPlus/SizingManager.cc @@ -219,25 +219,6 @@ void ManageSizing(EnergyPlusData &state) state.dataGlobal->ZoneSizingCalc = true; Available = true; - if (state.dataSize->SizingFileColSep == CharComma) { - state.files.zsz.filePath = state.files.outputZszCsvFilePath; - } else if (state.dataSize->SizingFileColSep == CharTab) { - state.files.zsz.filePath = state.files.outputZszTabFilePath; - } else { - state.files.zsz.filePath = state.files.outputZszTxtFilePath; - } - - if (state.dataSize->SizingFileColSep == CharComma) { - state.files.spsz.filePath = state.files.outputSpszCsvFilePath; - } else if (state.dataSize->SizingFileColSep == CharTab) { - state.files.spsz.filePath = state.files.outputSpszTabFilePath; - } else { - state.files.spsz.filePath = state.files.outputSpszTxtFilePath; - } - - state.files.zsz.ensure_open(state, "ManageSizing", state.files.outputControl.zsz); - state.files.spsz.ensure_open(state, "ManageSizing", state.files.outputControl.spsz); - ShowMessage(state, "Beginning Zone Sizing Calculations"); Weather::ResetEnvironmentCounter(state); diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index 259926441bd..bc985e0849e 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -2346,14 +2346,15 @@ std::string sizingPeakTimeStamp(EnergyPlusData const &state, int timeStepIndex) void writeZszSpsz(EnergyPlusData &state, EnergyPlus::InputOutputFile &outputFile, int const numSpacesOrZones, - Array1D const &zsEquipConfig, EPVector const &zsCalcFinalSizing, - Array2D const &zsCalcSizing) + Array2D const &zsCalcSizing, + bool const forSpaces) { char const colSep = state.dataSize->SizingFileColSep; print(outputFile, "Time"); for (int i = 1; i <= numSpacesOrZones; ++i) { - if (!zsEquipConfig(i).IsControlled) continue; + int zoneNum = (forSpaces) ? state.dataHeatBal->space(i).zoneNum : i; + if (!state.dataHeatBal->Zone(zoneNum).IsControlled) continue; auto &thisCalcFS = zsCalcFinalSizing(i); static constexpr std::string_view ZSizeFmt11("{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{" @@ -2441,7 +2442,8 @@ void writeZszSpsz(EnergyPlusData &state, static constexpr std::string_view ZSizeFmt20("{:02}:{:02}:00"); print(outputFile, ZSizeFmt20, HourPrint, Minutes); for (int i = 1; i <= numSpacesOrZones; ++i) { - if (!zsEquipConfig(i).IsControlled) continue; + int zoneNum = (forSpaces) ? state.dataHeatBal->space(i).zoneNum : i; + if (!state.dataHeatBal->Zone(zoneNum).IsControlled) continue; auto &thisCalcFS = zsCalcFinalSizing(i); static constexpr std::string_view ZSizeFmt21("{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12." "6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}"); @@ -2506,7 +2508,8 @@ void writeZszSpsz(EnergyPlusData &state, print(outputFile, "Peak"); for (int i = 1; i <= numSpacesOrZones; ++i) { - if (!zsEquipConfig(i).IsControlled) continue; + int zoneNum = (forSpaces) ? state.dataHeatBal->space(i).zoneNum : i; + if (!state.dataHeatBal->Zone(zoneNum).IsControlled) continue; auto &thisCalcFS = zsCalcFinalSizing(i); static constexpr std::string_view ZSizeFmt31("{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12." @@ -2546,7 +2549,8 @@ void writeZszSpsz(EnergyPlusData &state, print(outputFile, "\nPeak Vol Flow (m3/s)"); for (int i = 1; i <= numSpacesOrZones; ++i) { - if (!zsEquipConfig(i).IsControlled) continue; + int zoneNum = (forSpaces) ? state.dataHeatBal->space(i).zoneNum : i; + if (!state.dataHeatBal->Zone(zoneNum).IsControlled) continue; auto &thisCalcFS = zsCalcFinalSizing(i); static constexpr std::string_view ZSizeFmt41("{}{}{}{:12.6E}{}{:12.6E}{}{}{}{:12.6E}{}{:12.6E}{}{}{}{}{}{}{}{}"); print(outputFile, @@ -3302,19 +3306,37 @@ void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallI } } - writeZszSpsz(state, - state.files.zsz, - state.dataGlobal->NumOfZones, - state.dataZoneEquip->ZoneEquipConfig, - state.dataSize->CalcFinalZoneSizing, - state.dataSize->CalcZoneSizing); + // Write zone sizing (zsz) and space sizing (spsz) outputs + if (state.dataSize->SizingFileColSep == DataStringGlobals::CharComma) { + state.files.zsz.filePath = state.files.outputZszCsvFilePath; + } else if (state.dataSize->SizingFileColSep == DataStringGlobals::CharTab) { + state.files.zsz.filePath = state.files.outputZszTabFilePath; + } else { + state.files.zsz.filePath = state.files.outputZszTxtFilePath; + } + state.files.zsz.ensure_open(state, "UpdateZoneSizing", state.files.outputControl.zsz); + + bool forSpaces = false; + writeZszSpsz( + state, state.files.zsz, state.dataGlobal->NumOfZones, state.dataSize->CalcFinalZoneSizing, state.dataSize->CalcZoneSizing, forSpaces); + if (state.dataHeatBal->doSpaceHeatBalanceSizing) { + if (state.dataSize->SizingFileColSep == DataStringGlobals::CharComma) { + state.files.spsz.filePath = state.files.outputSpszCsvFilePath; + } else if (state.dataSize->SizingFileColSep == DataStringGlobals::CharTab) { + state.files.spsz.filePath = state.files.outputSpszTabFilePath; + } else { + state.files.spsz.filePath = state.files.outputSpszTxtFilePath; + } + state.files.spsz.ensure_open(state, "UpdateZoneSizing", state.files.outputControl.spsz); + + forSpaces = true; writeZszSpsz(state, state.files.spsz, state.dataGlobal->numSpaces, - state.dataZoneEquip->spaceEquipConfig, state.dataSize->CalcFinalSpaceSizing, - state.dataSize->CalcSpaceSizing); + state.dataSize->CalcSpaceSizing, + forSpaces); } // Move sizing data into final sizing array according to sizing method diff --git a/src/EnergyPlus/ZoneEquipmentManager.hh b/src/EnergyPlus/ZoneEquipmentManager.hh index 98b51b6b4e4..3ca0d69f956 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.hh +++ b/src/EnergyPlus/ZoneEquipmentManager.hh @@ -155,9 +155,9 @@ namespace ZoneEquipmentManager { void writeZszSpsz(EnergyPlusData &state, EnergyPlus::InputOutputFile &outputFile, int const numSpacesOrZones, - Array1D const &zsEquipConfig, EPVector const &zsCalcFinalSizing, - Array2D const &zsCalcSizing); + Array2D const &zsCalcSizing, + bool const forSpaces); std::string sizingPeakTimeStamp(EnergyPlusData const &state, int timeStepIndex);