Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <algorithm>
50 : #include <cmath>
51 : #include <string>
52 :
53 : // ObjexxFCL Headers
54 : #include <ObjexxFCL/Array.functions.hh>
55 :
56 : // EnergyPlus Headers
57 : #include <AirflowNetwork/Solver.hpp>
58 : #include <EnergyPlus/BaseboardElectric.hh>
59 : #include <EnergyPlus/BaseboardRadiator.hh>
60 : #include <EnergyPlus/ChilledCeilingPanelSimple.hh>
61 : #include <EnergyPlus/CoolTower.hh>
62 : #include <EnergyPlus/Data/EnergyPlusData.hh>
63 : #include <EnergyPlus/DataAirLoop.hh>
64 : #include <EnergyPlus/DataAirSystems.hh>
65 : #include <EnergyPlus/DataContaminantBalance.hh>
66 : #include <EnergyPlus/DataConvergParams.hh>
67 : #include <EnergyPlus/DataDefineEquip.hh>
68 : #include <EnergyPlus/DataEnvironment.hh>
69 : #include <EnergyPlus/DataHVACGlobals.hh>
70 : #include <EnergyPlus/DataHeatBalFanSys.hh>
71 : #include <EnergyPlus/DataLoopNode.hh>
72 : #include <EnergyPlus/DataRoomAirModel.hh>
73 : #include <EnergyPlus/DataSurfaces.hh>
74 : #include <EnergyPlus/DataZoneEquipment.hh>
75 : #include <EnergyPlus/DisplayRoutines.hh>
76 : #include <EnergyPlus/EMSManager.hh>
77 : #include <EnergyPlus/EarthTube.hh>
78 : #include <EnergyPlus/ElectricBaseboardRadiator.hh>
79 : #include <EnergyPlus/EvaporativeCoolers.hh>
80 : #include <EnergyPlus/ExhaustAirSystemManager.hh>
81 : #include <EnergyPlus/FanCoilUnits.hh>
82 : #include <EnergyPlus/Fans.hh>
83 : #include <EnergyPlus/General.hh>
84 : #include <EnergyPlus/HVACInterfaceManager.hh>
85 : #include <EnergyPlus/HVACStandAloneERV.hh>
86 : #include <EnergyPlus/HVACVariableRefrigerantFlow.hh>
87 : #include <EnergyPlus/HWBaseboardRadiator.hh>
88 : #include <EnergyPlus/HeatRecovery.hh>
89 : #include <EnergyPlus/HighTempRadiantSystem.hh>
90 : #include <EnergyPlus/HybridUnitaryAirConditioners.hh>
91 : #include <EnergyPlus/InternalHeatGains.hh>
92 : #include <EnergyPlus/LowTempRadiantSystem.hh>
93 : #include <EnergyPlus/OutdoorAirUnit.hh>
94 : #include <EnergyPlus/Psychrometrics.hh>
95 : #include <EnergyPlus/PurchasedAirManager.hh>
96 : #include <EnergyPlus/RefrigeratedCase.hh>
97 : #include <EnergyPlus/ReturnAirPathManager.hh>
98 : #include <EnergyPlus/ScheduleManager.hh>
99 : #include <EnergyPlus/SplitterComponent.hh>
100 : #include <EnergyPlus/SteamBaseboardRadiator.hh>
101 : #include <EnergyPlus/SystemAvailabilityManager.hh>
102 : #include <EnergyPlus/ThermalChimney.hh>
103 : #include <EnergyPlus/UnitHeater.hh>
104 : #include <EnergyPlus/UnitVentilator.hh>
105 : #include <EnergyPlus/UserDefinedComponents.hh>
106 : #include <EnergyPlus/UtilityRoutines.hh>
107 : #include <EnergyPlus/VentilatedSlab.hh>
108 : #include <EnergyPlus/WaterThermalTanks.hh>
109 : #include <EnergyPlus/WindowAC.hh>
110 : #include <EnergyPlus/ZoneAirLoopEquipmentManager.hh>
111 : #include <EnergyPlus/ZoneDehumidifier.hh>
112 : #include <EnergyPlus/ZoneEquipmentManager.hh>
113 : #include <EnergyPlus/ZonePlenum.hh>
114 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
115 :
116 : namespace EnergyPlus::ZoneEquipmentManager {
117 :
118 : // Module containing the routines dealing with the Zone Equipment Manager.
119 :
120 : // MODULE INFORMATION:
121 : // AUTHOR Russ Taylor
122 : // DATE WRITTEN Unknown
123 : // MODIFIED na
124 : // RE-ENGINEERED na
125 :
126 : // PURPOSE OF THIS MODULE:
127 : // This module manages the zone equipment.
128 :
129 : // Using/Aliasing
130 : using namespace DataSizing;
131 : using namespace DataZoneEquipment;
132 : // Use statements for access to subroutines in other modules
133 : using Psychrometrics::PsyCpAirFnW;
134 : using Psychrometrics::PsyHFnTdbW;
135 : using Psychrometrics::PsyHgAirFnWTdb;
136 : using Psychrometrics::PsyRhoAirFnPbTdbW;
137 : using Psychrometrics::PsyWFnTdbRhPb;
138 : using Psychrometrics::PsyWFnTdpPb;
139 :
140 513265 : void ManageZoneEquipment(EnergyPlusData &state,
141 : bool const FirstHVACIteration,
142 : bool &SimZone, // Set to false at the end of the routine
143 : bool &SimAir // Eventually set to true via SimZoneEquipment if AirLoop must be resimulated
144 : )
145 : {
146 :
147 : // SUBROUTINE INFORMATION:
148 : // AUTHOR Russ Taylor
149 : // DATE WRITTEN May 1997
150 :
151 : // PURPOSE OF THIS SUBROUTINE:
152 : // Calls the zone thermal control simulations and the interfaces (water-air, refrigerant-air, steam-air, electric-electric, water-water, etc)
153 :
154 513265 : InitZoneEquipment(state, FirstHVACIteration);
155 :
156 513265 : if (state.dataGlobal->ZoneSizingCalc) {
157 88803 : SizeZoneEquipment(state);
158 : } else {
159 424462 : SimZoneEquipment(state, FirstHVACIteration, SimAir);
160 424461 : state.dataZoneEquip->ZoneEquipSimulatedOnce = true;
161 : }
162 :
163 513264 : UpdateZoneEquipment(state, SimAir);
164 :
165 513264 : SimZone = false;
166 513264 : }
167 :
168 215 : void GetZoneEquipment(EnergyPlusData &state)
169 : {
170 :
171 : // SUBROUTINE INFORMATION:
172 : // AUTHOR Russ Taylor
173 : // DATE WRITTEN June 1997
174 : // MODIFIED Aug 2003, FCW: set ZoneEquipConfig number for each zone
175 :
176 : // PURPOSE OF THIS SUBROUTINE:
177 : // Get all the system related equipment which may be attached to a zone
178 :
179 215 : if (state.dataZoneEquipmentManager->GetZoneEquipmentInputFlag) {
180 209 : GetZoneEquipmentData(state);
181 209 : state.dataZoneEquipmentManager->GetZoneEquipmentInputFlag = false;
182 209 : state.dataZoneEquip->ZoneEquipInputsFilled = true;
183 :
184 209 : state.dataZoneEquipmentManager->NumOfTimeStepInDay = state.dataGlobal->TimeStepsInHour * Constant::iHoursInDay;
185 :
186 209 : int MaxNumOfEquipTypes = 0;
187 519 : for (int Counter = 1; Counter <= state.dataGlobal->NumOfZones; ++Counter) {
188 310 : if (!state.dataZoneEquip->ZoneEquipConfig(Counter).IsControlled) continue;
189 123 : MaxNumOfEquipTypes = max(MaxNumOfEquipTypes, state.dataZoneEquip->ZoneEquipList(Counter).NumOfEquipTypes);
190 : }
191 :
192 209 : state.dataZoneEquipmentManager->PrioritySimOrder.allocate(MaxNumOfEquipTypes);
193 : }
194 215 : }
195 :
196 513265 : void InitZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration) // unused 1208
197 : {
198 :
199 : // SUBROUTINE INFORMATION:
200 : // AUTHOR Russ Taylor
201 : // DATE WRITTEN Nov 1997
202 :
203 : // PURPOSE OF THIS SUBROUTINE:
204 : // This subroutine initializes the zone equipment prior to simulation.
205 :
206 513265 : if (state.dataZoneEquipmentManager->InitZoneEquipmentOneTimeFlag) {
207 109 : state.dataZoneEquipmentManager->InitZoneEquipmentOneTimeFlag = false;
208 109 : state.dataSize->ZoneEqSizing.allocate(state.dataGlobal->NumOfZones);
209 : // setup zone equipment sequenced demand storage
210 245 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
211 136 : if (!state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).IsControlled) continue;
212 84 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).EquipListIndex == 0) continue;
213 : int ZoneEquipCount =
214 84 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).EquipListIndex).NumOfEquipTypes;
215 84 : auto &thisZoneSysEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum);
216 84 : thisZoneSysEnergyDemand.NumZoneEquipment = ZoneEquipCount;
217 84 : thisZoneSysEnergyDemand.SequencedOutputRequired.allocate(ZoneEquipCount);
218 84 : thisZoneSysEnergyDemand.SequencedOutputRequiredToHeatingSP.allocate(ZoneEquipCount);
219 84 : thisZoneSysEnergyDemand.SequencedOutputRequiredToCoolingSP.allocate(ZoneEquipCount);
220 84 : auto &thisZoneSysMoistureDemand = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum);
221 84 : thisZoneSysMoistureDemand.NumZoneEquipment = ZoneEquipCount;
222 84 : thisZoneSysMoistureDemand.SequencedOutputRequired.allocate(ZoneEquipCount);
223 84 : thisZoneSysMoistureDemand.SequencedOutputRequiredToHumidSP.allocate(ZoneEquipCount);
224 84 : thisZoneSysMoistureDemand.SequencedOutputRequiredToDehumidSP.allocate(ZoneEquipCount);
225 84 : state.dataSize->ZoneEqSizing(ControlledZoneNum).SizingMethod.allocate(HVAC::NumOfSizingTypes);
226 84 : state.dataSize->ZoneEqSizing(ControlledZoneNum).SizingMethod = 0;
227 84 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation || state.dataHeatBal->doSpaceHeatBalanceSizing) {
228 28 : for (int spaceNum : state.dataHeatBal->Zone(ControlledZoneNum).spaceIndexes) {
229 21 : auto &thisSpaceSysEnergyDemand = state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum);
230 21 : thisSpaceSysEnergyDemand.NumZoneEquipment = ZoneEquipCount;
231 21 : thisSpaceSysEnergyDemand.SequencedOutputRequired.allocate(ZoneEquipCount);
232 21 : thisSpaceSysEnergyDemand.SequencedOutputRequiredToHeatingSP.allocate(ZoneEquipCount);
233 21 : thisSpaceSysEnergyDemand.SequencedOutputRequiredToCoolingSP.allocate(ZoneEquipCount);
234 21 : auto &thisSpaceSysMoistureDemand = state.dataZoneEnergyDemand->spaceSysMoistureDemand(spaceNum);
235 21 : thisSpaceSysMoistureDemand.NumZoneEquipment = ZoneEquipCount;
236 21 : thisSpaceSysMoistureDemand.SequencedOutputRequired.allocate(ZoneEquipCount);
237 21 : thisSpaceSysMoistureDemand.SequencedOutputRequiredToHumidSP.allocate(ZoneEquipCount);
238 21 : thisSpaceSysMoistureDemand.SequencedOutputRequiredToDehumidSP.allocate(ZoneEquipCount);
239 : }
240 : }
241 : }
242 : }
243 :
244 : // Do the Begin Environment initializations
245 513265 : if (state.dataZoneEquipmentManager->InitZoneEquipmentEnvrnFlag && state.dataGlobal->BeginEnvrnFlag) {
246 :
247 479 : state.dataZoneEquip->ZoneEquipAvail = Avail::Status::NoAction;
248 :
249 479 : if (allocated(state.dataAvail->ZoneComp)) {
250 4845 : for (int ZoneEquipType = 1; ZoneEquipType <= NumValidSysAvailZoneComponents; ++ZoneEquipType) {
251 4522 : if (allocated(state.dataAvail->ZoneComp(ZoneEquipType).ZoneCompAvailMgrs)) {
252 49 : auto &zoneComp = state.dataAvail->ZoneComp(ZoneEquipType);
253 142 : for (int ZoneCompNum = 1; ZoneCompNum <= zoneComp.TotalNumComp; ++ZoneCompNum) {
254 93 : zoneComp.ZoneCompAvailMgrs(ZoneCompNum).availStatus = Avail::Status::NoAction;
255 93 : zoneComp.ZoneCompAvailMgrs(ZoneCompNum).StartTime = 0;
256 93 : zoneComp.ZoneCompAvailMgrs(ZoneCompNum).StopTime = 0;
257 : }
258 : }
259 : }
260 : }
261 1154 : for (auto &thisZoneEquipConfig : state.dataZoneEquip->ZoneEquipConfig) {
262 675 : if (!thisZoneEquipConfig.IsControlled) continue;
263 476 : thisZoneEquipConfig.beginEnvirnInit(state);
264 : }
265 479 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation) {
266 8 : for (auto &thisSpaceEquipConfig : state.dataZoneEquip->spaceEquipConfig) {
267 6 : if (!thisSpaceEquipConfig.IsControlled) continue;
268 0 : thisSpaceEquipConfig.beginEnvirnInit(state);
269 : }
270 : }
271 :
272 479 : state.dataZoneEquipmentManager->InitZoneEquipmentEnvrnFlag = false;
273 : }
274 :
275 513265 : if (!state.dataGlobal->BeginEnvrnFlag) {
276 510959 : state.dataZoneEquipmentManager->InitZoneEquipmentEnvrnFlag = true;
277 : }
278 :
279 : // do the HVAC time step initializations
280 :
281 1215406 : for (auto &thisZoneEquipConfig : state.dataZoneEquip->ZoneEquipConfig) {
282 702141 : if (!thisZoneEquipConfig.IsControlled) continue;
283 276964 : thisZoneEquipConfig.hvacTimeStepInit(state, FirstHVACIteration);
284 : }
285 513265 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation) {
286 147488 : for (auto &thisSpaceEquipConfig : state.dataZoneEquip->spaceEquipConfig) {
287 110616 : if (!thisSpaceEquipConfig.IsControlled) continue;
288 0 : thisSpaceEquipConfig.hvacTimeStepInit(state, FirstHVACIteration);
289 : }
290 : }
291 :
292 589078 : for (int airLoop = 1; airLoop <= state.dataHVACGlobal->NumPrimaryAirSys; ++airLoop) {
293 75813 : auto &airLoopFlow = state.dataAirLoop->AirLoopFlow(airLoop);
294 75813 : airLoopFlow.SupFlow = 0.0;
295 75813 : airLoopFlow.ZoneRetFlow = 0.0;
296 75813 : airLoopFlow.SysRetFlow = 0.0;
297 75813 : airLoopFlow.RecircFlow = 0.0;
298 75813 : airLoopFlow.LeakFlow = 0.0;
299 75813 : airLoopFlow.ExcessZoneExhFlow = 0.0;
300 : }
301 513265 : }
302 175387 : void sizeZoneSpaceEquipmentPart1(EnergyPlusData &state,
303 : DataZoneEquipment::EquipConfiguration &zoneEquipConfig,
304 : DataSizing::ZoneSizingData &zsCalcSizing,
305 : DataZoneEnergyDemands::ZoneSystemSensibleDemand &zsEnergyDemand,
306 : DataZoneEnergyDemands::ZoneSystemMoistureDemand &zsMoistureDemand,
307 : DataHeatBalance::ZoneData const &zoneOrSpace,
308 : int zoneNum,
309 : int spaceNum)
310 : {
311 : static constexpr std::string_view RoutineName("sizeZoneSpaceEquipmentPart1");
312 : // set up references for space vs zoneHeatBalance
313 44487 : auto &nonAirSystemResponse = (spaceNum > 0) ? state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).NonAirSystemResponse
314 219874 : : state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).NonAirSystemResponse;
315 44487 : auto &sysDepZoneLoads = (spaceNum > 0) ? state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).SysDepZoneLoads
316 219874 : : state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).SysDepZoneLoads;
317 : auto &zoneNodeNum =
318 175387 : (spaceNum > 0) ? state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber : state.dataHeatBal->Zone(zoneNum).SystemZoneNodeNumber;
319 175387 : nonAirSystemResponse = 0.0;
320 175387 : sysDepZoneLoads = 0.0;
321 175387 : auto &zoneNode = state.dataLoopNodes->Node(zoneNodeNum);
322 :
323 : // InitSystemOutputRequired(state, zoneNum, true);
324 175387 : initOutputRequired(state, zoneNum, zsEnergyDemand, zsMoistureDemand, true, false, spaceNum);
325 :
326 : // save raw zone loads without impact of outdoor air
327 175387 : Real64 LatOutputProvidedNoDOAS = zsMoistureDemand.RemainingOutputRequired;
328 175387 : Real64 SysOutputProvidedNoDOAS = zsEnergyDemand.RemainingOutputRequired;
329 : // if Tstat deadband is true then load will be reported as 0
330 175387 : if (state.dataZoneEnergyDemand->DeadBandOrSetback(zoneNum)) SysOutputProvidedNoDOAS = 0.0;
331 : // replicate deadband flag - zone condition is either below the humidistat or above the dehumidistat set point
332 : // using logic: NOT (!) (there is a load)
333 : // Pretty sure this could just be if (OutputRequiredToHumidifyingSP < 0 && OutputRequiredToDehumidifyingSP > 0)
334 175387 : if (!((zsMoistureDemand.OutputRequiredToHumidifyingSP > 0.0 && zsMoistureDemand.OutputRequiredToDehumidifyingSP > 0.0) ||
335 170251 : (zsMoistureDemand.OutputRequiredToHumidifyingSP < 0.0 && zsMoistureDemand.OutputRequiredToDehumidifyingSP < 0.0))) {
336 146330 : LatOutputProvidedNoDOAS = 0.0;
337 : }
338 :
339 : // calculate DOAS heating/cooling effect
340 175387 : int supplyAirNodeNum = 0;
341 175387 : if (zsCalcSizing.AccountForDOAS) {
342 14221 : Real64 DOASMassFlowRate = 0.0; // DOAS air mass flow rate for sizing [kg/s]
343 14221 : Real64 DOASSupplyTemp = 0.0; // DOAS supply air temperature [C]
344 14221 : Real64 DOASSupplyHumRat = 0.0; // DOAS supply air humidity ratio [kgWater/kgDryAir]
345 14221 : Real64 DOASCpAir = 0.0; // heat capacity of DOAS air [J/kg-C]
346 14221 : Real64 DOASSysOutputProvided = 0.0; // heating / cooling provided by DOAS system [W]
347 14221 : Real64 DOASLatOutputProvided = 0.0; // DOAS system latent output [kg/s]
348 14221 : Real64 TotDOASSysOutputProvided = 0.0; // total DOAS load on the zone [W]
349 14221 : Real64 HR90H = 0.0; // humidity ratio at DOAS high setpoint temperature and 90% relative humidity [kg Water / kg Dry Air]
350 14221 : Real64 HR90L = 0.0; // humidity ratio at DOAS low setpoint temperature and 90% relative humidity [kg Water / kg Dry Air]
351 : // check for adequate number of supply nodes
352 14221 : int supplyAirNodeNum1 = 0;
353 14221 : int supplyAirNodeNum2 = 0;
354 14221 : if (zoneEquipConfig.NumInletNodes >= 2) {
355 11483 : supplyAirNodeNum1 = zoneEquipConfig.InletNode(1);
356 11483 : supplyAirNodeNum2 = zoneEquipConfig.InletNode(2);
357 2738 : } else if (zoneEquipConfig.NumInletNodes >= 1) {
358 2738 : supplyAirNodeNum1 = zoneEquipConfig.InletNode(1);
359 2738 : supplyAirNodeNum2 = 0;
360 : } else {
361 0 : ShowSevereError(state, format("{}: to account for the effect a Dedicated Outside Air System on zone equipment sizing", RoutineName));
362 0 : ShowContinueError(state, "there must be at least one zone air inlet node");
363 0 : ShowFatalError(state, "Previous severe error causes abort ");
364 : }
365 : // set the DOAS mass flow rate and supply temperature and humidity ratio
366 14221 : HR90H = PsyWFnTdbRhPb(state, zsCalcSizing.DOASHighSetpoint, 0.9, state.dataEnvrn->StdBaroPress);
367 14221 : HR90L = PsyWFnTdbRhPb(state, zsCalcSizing.DOASLowSetpoint, 0.9, state.dataEnvrn->StdBaroPress);
368 14221 : DOASMassFlowRate = state.dataSize->CalcFinalZoneSizing(zoneNum).MinOA * state.dataEnvrn->StdRhoAir;
369 14221 : CalcDOASSupCondsForSizing(state,
370 14221 : state.dataEnvrn->OutDryBulbTemp,
371 14221 : state.dataEnvrn->OutHumRat,
372 : zsCalcSizing.DOASControlStrategy,
373 : zsCalcSizing.DOASLowSetpoint,
374 : zsCalcSizing.DOASHighSetpoint,
375 : HR90H,
376 : HR90L,
377 : DOASSupplyTemp,
378 : DOASSupplyHumRat);
379 14221 : DOASCpAir = PsyCpAirFnW(DOASSupplyHumRat);
380 14221 : DOASSysOutputProvided = DOASMassFlowRate * DOASCpAir * (DOASSupplyTemp - zoneNode.Temp);
381 14221 : TotDOASSysOutputProvided = DOASMassFlowRate * (PsyHFnTdbW(DOASSupplyTemp, DOASSupplyHumRat) - PsyHFnTdbW(zoneNode.Temp, zoneNode.HumRat));
382 14221 : if (zsCalcSizing.zoneLatentSizing) {
383 0 : DOASLatOutputProvided = DOASMassFlowRate * (DOASSupplyHumRat - zoneNode.HumRat); // kgw/s
384 : }
385 :
386 14221 : updateSystemOutputRequired(state, zoneNum, DOASSysOutputProvided, DOASLatOutputProvided, zsEnergyDemand, zsMoistureDemand);
387 14221 : auto &supplyAirNode1 = state.dataLoopNodes->Node(supplyAirNodeNum1);
388 14221 : supplyAirNode1.Temp = DOASSupplyTemp;
389 14221 : supplyAirNode1.HumRat = DOASSupplyHumRat;
390 14221 : supplyAirNode1.MassFlowRate = DOASMassFlowRate;
391 14221 : supplyAirNode1.Enthalpy = PsyHFnTdbW(DOASSupplyTemp, DOASSupplyHumRat);
392 14221 : zsCalcSizing.DOASHeatAdd = DOASSysOutputProvided;
393 14221 : zsCalcSizing.DOASLatAdd = TotDOASSysOutputProvided - DOASSysOutputProvided;
394 14221 : supplyAirNodeNum = supplyAirNodeNum2;
395 14221 : zsCalcSizing.DOASSupMassFlow = DOASMassFlowRate;
396 14221 : zsCalcSizing.DOASSupTemp = DOASSupplyTemp;
397 14221 : zsCalcSizing.DOASSupHumRat = DOASSupplyHumRat;
398 14221 : if (DOASSysOutputProvided > 0.0) {
399 1368 : zsCalcSizing.DOASHeatLoad = DOASSysOutputProvided;
400 1368 : zsCalcSizing.DOASCoolLoad = 0.0;
401 1368 : zsCalcSizing.DOASTotCoolLoad = 0.0;
402 : } else {
403 12853 : zsCalcSizing.DOASCoolLoad = DOASSysOutputProvided;
404 12853 : zsCalcSizing.DOASTotCoolLoad = TotDOASSysOutputProvided;
405 12853 : zsCalcSizing.DOASHeatLoad = 0.0;
406 : }
407 :
408 : } else {
409 161166 : if (zoneEquipConfig.NumInletNodes > 0) {
410 108265 : supplyAirNodeNum = zoneEquipConfig.InletNode(1);
411 : } else {
412 52901 : supplyAirNodeNum = 0;
413 : }
414 : }
415 :
416 175387 : Real64 DeltaTemp = 0.0; // difference between supply air temp and zone temp [C]
417 175387 : Real64 CpAir = 0.0; // heat capacity of air [J/kg-C]
418 175387 : Real64 SysOutputProvided = 0.0; // system sensible output [W]
419 175387 : Real64 LatOutputProvided = 0.0; // system latent output [kg/s]
420 175387 : Real64 Temp = 0.0; // inlet temperature [C]
421 175387 : Real64 HumRat = 0.0; // inlet humidity ratio [kg water/kg dry air]
422 175387 : Real64 Enthalpy = 0.0; // inlet specific enthalpy [J/kg]
423 175387 : Real64 MassFlowRate = 0.0; // inlet mass flow rate [kg/s]
424 : // Sign convention: SysOutputProvided <0 Supply air is heated on entering zone (zone is cooled)
425 : // SysOutputProvided >0 Supply air is cooled on entering zone (zone is heated)
426 175387 : if (!state.dataZoneEnergyDemand->DeadBandOrSetback(zoneNum) && std::abs(zsEnergyDemand.RemainingOutputRequired) > HVAC::SmallLoad) {
427 : // Determine design supply air temperature and design supply air temperature difference
428 156368 : if (zsEnergyDemand.RemainingOutputRequired < 0.0) { // Cooling case
429 : // If the user specify the design cooling supply air temperature, then
430 86555 : if (zsCalcSizing.ZnCoolDgnSAMethod == SupplyAirTemperature) {
431 86554 : Temp = zsCalcSizing.CoolDesTemp;
432 86554 : HumRat = zsCalcSizing.CoolDesHumRat;
433 86554 : DeltaTemp = Temp - zoneNode.Temp;
434 86554 : if (zoneOrSpace.HasAdjustedReturnTempByITE && !(state.dataGlobal->BeginSimFlag)) {
435 0 : DeltaTemp = Temp - zoneOrSpace.AdjustedReturnTempByITE;
436 : }
437 : // If the user specify the design cooling supply air temperature difference, then
438 : } else {
439 1 : DeltaTemp = -std::abs(zsCalcSizing.CoolDesTempDiff);
440 1 : Temp = DeltaTemp + zoneNode.Temp;
441 1 : if (zoneOrSpace.HasAdjustedReturnTempByITE && !(state.dataGlobal->BeginSimFlag)) {
442 0 : Temp = DeltaTemp + zoneOrSpace.AdjustedReturnTempByITE;
443 : }
444 1 : HumRat = zsCalcSizing.CoolDesHumRat;
445 : }
446 : } else { // Heating Case
447 : // If the user specify the design heating supply air temperature, then
448 69813 : if (zsCalcSizing.ZnHeatDgnSAMethod == SupplyAirTemperature) {
449 69813 : Temp = zsCalcSizing.HeatDesTemp;
450 69813 : HumRat = zsCalcSizing.HeatDesHumRat;
451 69813 : DeltaTemp = Temp - zoneNode.Temp;
452 : // If the user specify the design heating supply air temperature difference, then
453 : } else {
454 0 : DeltaTemp = std::abs(zsCalcSizing.HeatDesTempDiff);
455 0 : Temp = DeltaTemp + zoneNode.Temp;
456 0 : HumRat = zsCalcSizing.HeatDesHumRat;
457 : }
458 : }
459 :
460 156368 : Enthalpy = PsyHFnTdbW(Temp, HumRat);
461 156368 : SysOutputProvided = zsEnergyDemand.RemainingOutputRequired;
462 156368 : CpAir = PsyCpAirFnW(HumRat);
463 156368 : if (std::abs(DeltaTemp) > HVAC::SmallTempDiff) {
464 : //!!PH/WFB/LKL (UCDV model) MassFlowRate = SysOutputProvided / (CpAir*DeltaTemp)
465 156368 : MassFlowRate = max(SysOutputProvided / (CpAir * DeltaTemp), 0.0);
466 : } else {
467 0 : MassFlowRate = 0.0;
468 : }
469 :
470 156368 : if (zsCalcSizing.SupplyAirAdjustFactor > 1.0) {
471 0 : MassFlowRate *= zsCalcSizing.SupplyAirAdjustFactor;
472 : }
473 : } else {
474 :
475 19019 : Temp = zoneNode.Temp;
476 19019 : HumRat = zoneNode.HumRat;
477 19019 : Enthalpy = zoneNode.Enthalpy;
478 19019 : MassFlowRate = 0.0;
479 : }
480 :
481 175387 : if (SysOutputProvided > 0.0) {
482 69813 : zsCalcSizing.HeatLoad = SysOutputProvided;
483 69813 : zsCalcSizing.HeatMassFlow = MassFlowRate;
484 69813 : zsCalcSizing.CoolLoad = 0.0;
485 69813 : zsCalcSizing.CoolMassFlow = 0.0;
486 105574 : } else if (SysOutputProvided < 0.0) {
487 86555 : zsCalcSizing.CoolLoad = -SysOutputProvided;
488 86555 : zsCalcSizing.CoolMassFlow = MassFlowRate;
489 86555 : zsCalcSizing.HeatLoad = 0.0;
490 86555 : zsCalcSizing.HeatMassFlow = 0.0;
491 : } else {
492 19019 : zsCalcSizing.CoolLoad = 0.0;
493 19019 : zsCalcSizing.CoolMassFlow = 0.0;
494 19019 : zsCalcSizing.HeatLoad = 0.0;
495 19019 : zsCalcSizing.HeatMassFlow = 0.0;
496 : }
497 175387 : zsCalcSizing.HeatZoneTemp = zoneNode.Temp;
498 175387 : zsCalcSizing.HeatZoneHumRat = zoneNode.HumRat;
499 175387 : zsCalcSizing.CoolZoneTemp = zoneNode.Temp;
500 175387 : zsCalcSizing.CoolZoneHumRat = zoneNode.HumRat;
501 175387 : zsCalcSizing.HeatOutTemp = state.dataEnvrn->OutDryBulbTemp;
502 175387 : zsCalcSizing.HeatOutHumRat = state.dataEnvrn->OutHumRat;
503 175387 : zsCalcSizing.CoolOutTemp = state.dataEnvrn->OutDryBulbTemp;
504 175387 : zsCalcSizing.CoolOutHumRat = state.dataEnvrn->OutHumRat;
505 :
506 175387 : Real64 LatentAirMassFlow = 0.0;
507 175387 : Real64 MoistureLoad = 0.0;
508 175387 : Real64 HgAir = PsyHgAirFnWTdb(zoneNode.HumRat, zoneNode.Temp);
509 175387 : if (zsCalcSizing.zoneLatentSizing) {
510 : // replicate deadband flag - zone condition is either below the humidistat or above the dehumidistat set point
511 27496 : if ((zsMoistureDemand.OutputRequiredToHumidifyingSP > 0.0 && zsMoistureDemand.OutputRequiredToDehumidifyingSP > 0.0) ||
512 22374 : (zsMoistureDemand.OutputRequiredToHumidifyingSP < 0.0 && zsMoistureDemand.OutputRequiredToDehumidifyingSP < 0.0)) {
513 20537 : LatOutputProvided = zsMoistureDemand.RemainingOutputRequired;
514 : }
515 27496 : Real64 DeltaHumRat = 0.0; // positive LatOutputProvided means humidification load
516 27496 : if (LatOutputProvided < 0.0) { // use SA humrat - zone humrat, or delta humrat based on user choice
517 30830 : DeltaHumRat = (zsCalcSizing.ZnLatCoolDgnSAMethod == SupplyAirHumidityRatio) ? (zsCalcSizing.LatentCoolDesHumRat - zoneNode.HumRat)
518 15415 : : -zsCalcSizing.CoolDesHumRatDiff;
519 12081 : } else if (LatOutputProvided > 0.0) {
520 5122 : DeltaHumRat = (zsCalcSizing.ZnLatHeatDgnSAMethod == SupplyAirHumidityRatio) ? (zsCalcSizing.LatentHeatDesHumRat - zoneNode.HumRat)
521 : : zsCalcSizing.HeatDesHumRatDiff;
522 : }
523 27496 : if (std::abs(DeltaHumRat) > HVAC::VerySmallMassFlow) LatentAirMassFlow = std::max(0.0, LatOutputProvided / DeltaHumRat);
524 27496 : MoistureLoad = LatOutputProvided * HgAir;
525 :
526 27496 : if (MassFlowRate > 0.0) {
527 25500 : HumRat = zoneNode.HumRat + LatOutputProvided / MassFlowRate;
528 25500 : CpAir = PsyCpAirFnW(HumRat);
529 25500 : Temp = (SysOutputProvided / (MassFlowRate * CpAir)) + zoneNode.Temp;
530 25500 : Enthalpy = PsyHFnTdbW(Temp, HumRat);
531 1996 : } else if (LatentAirMassFlow > 0.0) {
532 : // if there is no sensible load then still need to hold zone RH at set point
533 : // no need to recalculate T, Sensible load = 0 so T = T,zone
534 1996 : HumRat = zoneNode.HumRat + LatOutputProvided / LatentAirMassFlow;
535 1996 : Enthalpy = PsyHFnTdbW(Temp, HumRat);
536 1996 : MassFlowRate = (LatentAirMassFlow > HVAC::VerySmallMassFlow) ? LatentAirMassFlow : 0.0;
537 : }
538 :
539 27496 : zsCalcSizing.HeatLatentLoad = (LatOutputProvided > 0.0) ? MoistureLoad : 0.0;
540 27496 : zsCalcSizing.ZoneHeatLatentMassFlow = (LatOutputProvided > 0.0) ? LatentAirMassFlow : 0.0;
541 27496 : zsCalcSizing.CoolLatentLoad = (LatOutputProvided < 0.0) ? -MoistureLoad : 0.0;
542 27496 : zsCalcSizing.ZoneCoolLatentMassFlow = (LatOutputProvided < 0.0) ? LatentAirMassFlow : 0.0;
543 27496 : zsCalcSizing.HeatLoadNoDOAS = (SysOutputProvidedNoDOAS > 0.0) ? SysOutputProvidedNoDOAS : 0.0;
544 27496 : zsCalcSizing.CoolLoadNoDOAS = (SysOutputProvidedNoDOAS < 0.0) ? -SysOutputProvidedNoDOAS : 0.0;
545 27496 : zsCalcSizing.HeatLatentLoadNoDOAS = (LatOutputProvidedNoDOAS > 0.0) ? LatOutputProvidedNoDOAS * HgAir : 0.0;
546 27496 : zsCalcSizing.CoolLatentLoadNoDOAS = (LatOutputProvidedNoDOAS < 0.0) ? -LatOutputProvidedNoDOAS * HgAir : 0.0;
547 : }
548 :
549 175387 : if (supplyAirNodeNum > 0) {
550 119748 : auto &supplyAirNode = state.dataLoopNodes->Node(supplyAirNodeNum);
551 119748 : supplyAirNode.Temp = Temp;
552 119748 : supplyAirNode.HumRat = HumRat;
553 119748 : supplyAirNode.Enthalpy = Enthalpy;
554 119748 : supplyAirNode.MassFlowRate = MassFlowRate;
555 : } else {
556 55639 : nonAirSystemResponse = SysOutputProvided;
557 55639 : if (zsCalcSizing.zoneLatentSizing) {
558 27494 : int zoneMult = zoneOrSpace.Multiplier * zoneOrSpace.ListMultiplier;
559 19080 : auto &zoneLatentGain = (spaceNum > 0) ? state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).latentGain
560 46574 : : state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).latentGain;
561 27494 : zoneLatentGain += (LatOutputProvided * HgAir) / zoneMult;
562 : }
563 55639 : if (state.dataHeatBal->doSpaceHeatBalance && spaceNum == 0) {
564 25440 : for (int spaceNum2 : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
565 : // SpaceHB ToDo: For now allocate by space volume frac
566 19080 : auto &spHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum2);
567 19080 : spHB.NonAirSystemResponse = nonAirSystemResponse * state.dataHeatBal->space(spaceNum2).fracZoneVolume;
568 19080 : if (zsCalcSizing.zoneLatentSizing) {
569 19080 : int zoneMult = zoneOrSpace.Multiplier * zoneOrSpace.ListMultiplier;
570 19080 : spHB.latentGain += (LatOutputProvided * HgAir) * state.dataHeatBal->space(spaceNum2).fracZoneVolume / zoneMult;
571 : }
572 : }
573 : }
574 : }
575 :
576 175387 : updateSystemOutputRequired(state, zoneNum, SysOutputProvided, LatOutputProvided, zsEnergyDemand, zsMoistureDemand);
577 175387 : }
578 :
579 175387 : void sizeZoneSpaceEquipmentPart2(EnergyPlusData &state,
580 : DataZoneEquipment::EquipConfiguration &zoneEquipConfig,
581 : DataSizing::ZoneSizingData &zsCalcSizing,
582 : int zoneNum,
583 : int spaceNum)
584 : {
585 : // MJW for now - use first return node, make a separate commit to add a dimension to all of the sizing rettemp variables
586 175387 : int returnNodeNum = (zoneEquipConfig.NumReturnNodes > 0) ? zoneEquipConfig.ReturnNode(1) : 0;
587 : int zoneNodeNum =
588 175387 : (spaceNum > 0) ? state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber : state.dataHeatBal->Zone(zoneNum).SystemZoneNodeNumber;
589 175387 : Real64 RetTemp = (returnNodeNum > 0) ? state.dataLoopNodes->Node(returnNodeNum).Temp : state.dataLoopNodes->Node(zoneNodeNum).Temp;
590 :
591 175387 : auto &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(zoneNum);
592 175387 : if (zsCalcSizing.HeatLoad > 0.0) {
593 69813 : zsCalcSizing.HeatZoneRetTemp = RetTemp;
594 69813 : zsCalcSizing.HeatTstatTemp = (zoneTstatSetpt.setpt > 0.0) ? zoneTstatSetpt.setpt : zoneTstatSetpt.setptLo;
595 69813 : zsCalcSizing.CoolTstatTemp = zoneTstatSetpt.setptHi;
596 105574 : } else if (zsCalcSizing.CoolLoad > 0.0) {
597 86555 : zsCalcSizing.CoolZoneRetTemp = RetTemp;
598 86555 : zsCalcSizing.CoolTstatTemp = (zoneTstatSetpt.setpt > 0.0) ? zoneTstatSetpt.setpt : zoneTstatSetpt.setptHi;
599 86555 : zsCalcSizing.HeatTstatTemp = zoneTstatSetpt.setptLo;
600 : } else {
601 19019 : zsCalcSizing.CoolZoneRetTemp = RetTemp;
602 19019 : zsCalcSizing.HeatTstatTemp = zoneTstatSetpt.setptLo;
603 19019 : zsCalcSizing.CoolTstatTemp = zoneTstatSetpt.setptHi;
604 : }
605 175387 : }
606 :
607 88809 : void SizeZoneEquipment(EnergyPlusData &state)
608 : {
609 :
610 : // SUBROUTINE INFORMATION:
611 : // AUTHOR Fred Buhl
612 : // DATE WRITTEN December 2000
613 :
614 : // PURPOSE OF THIS SUBROUTINE:
615 : // Performs the zone sizing calculations and fills the zone sizing
616 : // data arrays with the results of the calculation.
617 :
618 : // METHODOLOGY EMPLOYED:
619 : // Using the input from Zone Sizing objects and the Zone Equipment input,
620 : // for each controlled zone this subroutine performs a "purchased air" calculation
621 : // and saves the results in the zone sizing data arrays.
622 :
623 88809 : if (state.dataZoneEquipmentManager->SizeZoneEquipmentOneTimeFlag) {
624 49 : SetUpZoneSizingArrays(state);
625 49 : state.dataZoneEquipmentManager->SizeZoneEquipmentOneTimeFlag = false;
626 : }
627 :
628 243279 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
629 154470 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum);
630 154470 : if (!zoneEquipConfig.IsControlled) continue;
631 :
632 : // use reference to eliminate lots of long lines in this function, after initial commit, so reviewers can see changes
633 130900 : auto &calcZoneSizing = state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, ControlledZoneNum);
634 130900 : auto &zoneSysEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum);
635 130900 : auto &zoneSysMoistureDemand = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum);
636 130900 : auto &zone = state.dataHeatBal->Zone(ControlledZoneNum);
637 :
638 130900 : sizeZoneSpaceEquipmentPart1(state, zoneEquipConfig, calcZoneSizing, zoneSysEnergyDemand, zoneSysMoistureDemand, zone, ControlledZoneNum);
639 130900 : if (state.dataHeatBal->doSpaceHeatBalance) {
640 59316 : for (int spaceNum : state.dataHeatBal->Zone(ControlledZoneNum).spaceIndexes) {
641 177948 : sizeZoneSpaceEquipmentPart1(state,
642 44487 : state.dataZoneEquip->spaceEquipConfig(spaceNum),
643 44487 : state.dataSize->CalcSpaceSizing(state.dataSize->CurOverallSimDay, spaceNum),
644 44487 : state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum),
645 44487 : state.dataZoneEnergyDemand->spaceSysMoistureDemand(spaceNum),
646 : zone,
647 : ControlledZoneNum,
648 : spaceNum);
649 : }
650 : }
651 : }
652 :
653 88809 : CalcZoneMassBalance(state, true);
654 :
655 88809 : CalcZoneLeavingConditions(state, true);
656 :
657 243279 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
658 :
659 154470 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum);
660 154470 : if (!zoneEquipConfig.IsControlled) continue;
661 130900 : sizeZoneSpaceEquipmentPart2(
662 130900 : state, zoneEquipConfig, state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, ControlledZoneNum), ControlledZoneNum);
663 130900 : if (state.dataHeatBal->doSpaceHeatBalance) {
664 59316 : for (int spaceNum : state.dataHeatBal->Zone(ControlledZoneNum).spaceIndexes) {
665 44487 : sizeZoneSpaceEquipmentPart2(
666 44487 : state, zoneEquipConfig, state.dataSize->CalcSpaceSizing(state.dataSize->CurOverallSimDay, spaceNum), ControlledZoneNum, spaceNum);
667 : }
668 : }
669 : }
670 88809 : }
671 :
672 14228 : void CalcDOASSupCondsForSizing(EnergyPlusData &state,
673 : Real64 OutDB, // outside air temperature [C]
674 : Real64 OutHR, // outside humidity ratio [kg Water / kg Dry Air]
675 : DataSizing::DOASControl DOASControl, // dedicated outside air control strategy
676 : Real64 DOASLowTemp, // DOAS low setpoint [C]
677 : Real64 DOASHighTemp, // DOAS high setpoint [C]
678 : Real64 W90H, // humidity ratio at DOAS high setpoint temperature and 90% relative humidity [kg Water / kg Dry Air]
679 : Real64 W90L, // humidity ratio at DOAS low setpoint temperature and 90% relative humidity [kg Water / kg Dry Air]
680 : Real64 &DOASSupTemp, // DOAS supply temperature [C]
681 : Real64 &DOASSupHR // DOAS Supply Humidity ratio [kg Water / kg Dry Air]
682 : )
683 : {
684 : // FUNCTION INFORMATION:
685 : // AUTHOR Fred Buhl
686 : // DATE WRITTEN March 2015
687 :
688 : // PURPOSE OF THIS FUNCTION:
689 : // This function calculates supply conditions for the direct outside air system (DOAS) sizing calculations
690 :
691 : // METHODOLOGY EMPLOYED:
692 : // the supply temperature and humidity ratio are set depending on the design control method and the outside air temperature
693 :
694 : // REFERENCES:
695 : // Consult the "DOAS Effect On Zone Sizing" new feature proposal and design documents
696 :
697 : // SUBROUTINE PARAMETER DEFINITIONS:
698 : static constexpr std::string_view RoutineName("CalcDOASSupCondsForSizing");
699 :
700 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
701 :
702 14228 : DOASSupTemp = 0.0;
703 14228 : DOASSupHR = 0.0;
704 : // neutral supply air
705 14228 : if (DOASControl == DataSizing::DOASControl::NeutralSup) {
706 2742 : if (OutDB < DOASLowTemp) {
707 1374 : DOASSupTemp = DOASLowTemp;
708 1374 : DOASSupHR = OutHR;
709 1368 : } else if (OutDB > DOASHighTemp) {
710 1367 : DOASSupTemp = DOASHighTemp;
711 1367 : DOASSupHR = min(OutHR, W90H);
712 : } else {
713 1 : DOASSupTemp = OutDB;
714 1 : DOASSupHR = OutHR;
715 : }
716 : }
717 :
718 : // neutral dehumidified supply air
719 11486 : else if (DOASControl == DataSizing::DOASControl::NeutralDehumSup) { //
720 2 : if (OutDB < DOASLowTemp) {
721 1 : DOASSupTemp = DOASHighTemp;
722 1 : DOASSupHR = OutHR;
723 : } else {
724 1 : DOASSupTemp = DOASHighTemp;
725 1 : DOASSupHR = min(OutHR, W90L);
726 : }
727 : }
728 :
729 : // cold supply air
730 11484 : else if (DOASControl == DataSizing::DOASControl::CoolSup) {
731 11484 : if (OutDB < DOASLowTemp) {
732 3571 : DOASSupTemp = DOASHighTemp;
733 3571 : DOASSupHR = OutHR;
734 : } else {
735 7913 : DOASSupTemp = DOASLowTemp;
736 7913 : DOASSupHR = min(OutHR, W90L);
737 : }
738 : } else {
739 0 : ShowFatalError(state, format("{}:illegal DOAS design control strategy", RoutineName));
740 : }
741 14228 : }
742 :
743 52 : void SetUpZoneSizingArrays(EnergyPlusData &state)
744 : {
745 :
746 : // SUBROUTINE INFORMATION:
747 : // AUTHOR Fred Buhl
748 : // DATE WRITTEN December 2000
749 :
750 : // PURPOSE OF THIS SUBROUTINE:
751 : // Allocate and fill the ZoneSizing data array.
752 :
753 : // METHODOLOGY EMPLOYED:
754 : // Obtains data from Zone Sizing and Zone Equipment objects already input.
755 :
756 52 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
757 :
758 : // TODO MJW: Punt for now, sometimes unit test will get here and need these to be allocated, but simulations need them sooner
759 52 : if (!state.dataHeatBal->ZoneIntGain.allocated()) {
760 2 : DataHeatBalance::AllocateIntGains(state);
761 : }
762 :
763 124 : for (int ZoneSizIndex = 1; ZoneSizIndex <= state.dataSize->NumZoneSizingInput; ++ZoneSizIndex) {
764 72 : int ZoneIndex = Util::FindItemInList(state.dataSize->ZoneSizingInput(ZoneSizIndex).ZoneName, state.dataHeatBal->Zone);
765 72 : if (ZoneIndex == 0) {
766 0 : ShowSevereError(
767 : state,
768 0 : format("SetUpZoneSizingArrays: Sizing:Zone=\"{}\" references unknown zone", state.dataSize->ZoneSizingInput(ZoneSizIndex).ZoneName));
769 0 : ErrorsFound = true;
770 : }
771 72 : if (std::any_of(state.dataZoneEquip->ZoneEquipConfig.begin(), state.dataZoneEquip->ZoneEquipConfig.end(), [](EquipConfiguration const &e) {
772 87 : return e.IsControlled;
773 : })) {
774 72 : ZoneIndex = Util::FindItemInList(
775 72 : state.dataSize->ZoneSizingInput(ZoneSizIndex).ZoneName, state.dataZoneEquip->ZoneEquipConfig, &EquipConfiguration::ZoneName);
776 72 : if (ZoneIndex == 0) {
777 0 : if (!state.dataGlobal->isPulseZoneSizing) {
778 0 : ShowWarningError(state,
779 0 : format("SetUpZoneSizingArrays: Requested Sizing for Zone=\"{}\", Zone is not found in the Controlled Zones List",
780 0 : state.dataSize->ZoneSizingInput(ZoneSizIndex).ZoneName));
781 : }
782 : } else {
783 72 : state.dataSize->ZoneSizingInput(ZoneSizIndex).ZoneNum = ZoneIndex;
784 : }
785 79 : if (state.dataSize->ZoneSizingInput(ZoneSizIndex).CoolAirDesMethod == AirflowSizingMethod::FromDDCalc ||
786 7 : state.dataSize->ZoneSizingInput(ZoneSizIndex).HeatAirDesMethod == AirflowSizingMethod::FromDDCalc) {
787 72 : if (!ZoneTempPredictorCorrector::VerifyThermostatInZone(state, state.dataSize->ZoneSizingInput(ZoneSizIndex).ZoneName)) {
788 2 : if (!state.dataGlobal->isPulseZoneSizing) {
789 4 : ShowWarningError(state,
790 4 : format("SetUpZoneSizingArrays: Requested Sizing for Zone=\"{}\", Zone has no thermostat (ref: "
791 : "ZoneControl:Thermostat, et al)",
792 2 : state.dataSize->ZoneSizingInput(ZoneSizIndex).ZoneName));
793 : }
794 : }
795 : }
796 : } else {
797 0 : ShowSevereError(state, "SetUpZoneSizingArrays: Zone Sizing is requested but there are no ZoneHVAC:EquipmentConnections statements.");
798 0 : ErrorsFound = true;
799 : }
800 : }
801 :
802 : // Put Auto Sizing of Sizing:Zone inputs here!
803 52 : AutoCalcDOASControlStrategy(state);
804 :
805 52 : state.dataSize->ZoneSizing.allocate(state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays, state.dataGlobal->NumOfZones);
806 52 : state.dataSize->FinalZoneSizing.allocate(state.dataGlobal->NumOfZones);
807 52 : state.dataSize->CalcZoneSizing.allocate(state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays, state.dataGlobal->NumOfZones);
808 52 : state.dataSize->CalcFinalZoneSizing.allocate(state.dataGlobal->NumOfZones);
809 52 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
810 7 : state.dataSize->SpaceSizing.allocate(state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays, state.dataGlobal->numSpaces);
811 7 : state.dataSize->FinalSpaceSizing.allocate(state.dataGlobal->numSpaces);
812 7 : state.dataSize->CalcSpaceSizing.allocate(state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays, state.dataGlobal->numSpaces);
813 7 : state.dataSize->CalcFinalSpaceSizing.allocate(state.dataGlobal->numSpaces);
814 : }
815 52 : state.dataSize->TermUnitFinalZoneSizing.allocate(state.dataSize->NumAirTerminalUnits);
816 125 : for (auto &tufzs : state.dataSize->TermUnitFinalZoneSizing) {
817 73 : tufzs.allocateMemberArrays(state.dataZoneEquipmentManager->NumOfTimeStepInDay);
818 : }
819 52 : state.dataSize->DesDayWeath.allocate(state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays);
820 52 : state.dataZoneEquipmentManager->AvgData.allocate(state.dataZoneEquipmentManager->NumOfTimeStepInDay);
821 142 : for (int DesDayNum = 1; DesDayNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DesDayNum) {
822 90 : auto &thisDesDayWeather = state.dataSize->DesDayWeath(DesDayNum);
823 90 : thisDesDayWeather.Temp.allocate(state.dataGlobal->TimeStepsInHour * Constant::iHoursInDay);
824 90 : thisDesDayWeather.HumRat.allocate(state.dataGlobal->TimeStepsInHour * Constant::iHoursInDay);
825 90 : thisDesDayWeather.Press.allocate(state.dataGlobal->TimeStepsInHour * Constant::iHoursInDay);
826 90 : thisDesDayWeather.Temp = 0.0;
827 90 : thisDesDayWeather.HumRat = 0.0;
828 90 : thisDesDayWeather.Press = 0.0;
829 : }
830 :
831 : // Fill zone sizing arrays from input array
832 136 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
833 84 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum);
834 84 : if (!zoneEquipConfig.IsControlled) continue;
835 :
836 : // For each Zone Sizing object, find the corresponding controlled zone
837 72 : int ZoneSizNum = Util::FindItemInList(zoneEquipConfig.ZoneName, state.dataSize->ZoneSizingInput, &ZoneSizingInputData::ZoneName);
838 72 : auto &zoneSizingInput = (ZoneSizNum > 0) ? state.dataSize->ZoneSizingInput(ZoneSizNum) : state.dataSize->ZoneSizingInput(1);
839 72 : if (ZoneSizNum == 0) { // LKL I think this is sufficient for warning -- no need for array
840 0 : if (!state.dataGlobal->isPulseZoneSizing) {
841 0 : ShowWarningError(state,
842 0 : format("SetUpZoneSizingArrays: Sizing for Zone=\"{}\" will use Sizing:Zone specifications listed for Zone=\"{}\".",
843 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ZoneName,
844 0 : zoneSizingInput.ZoneName));
845 : }
846 : }
847 :
848 144 : fillZoneSizingFromInput(state,
849 : zoneSizingInput,
850 72 : state.dataSize->ZoneSizing,
851 72 : state.dataSize->CalcZoneSizing,
852 72 : state.dataSize->FinalZoneSizing(CtrlZoneNum),
853 72 : state.dataSize->CalcFinalZoneSizing(CtrlZoneNum),
854 72 : state.dataHeatBal->Zone(CtrlZoneNum).Name,
855 : CtrlZoneNum);
856 72 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
857 28 : for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) {
858 42 : fillZoneSizingFromInput(state,
859 : zoneSizingInput,
860 21 : state.dataSize->SpaceSizing,
861 21 : state.dataSize->CalcSpaceSizing,
862 21 : state.dataSize->FinalSpaceSizing(spaceNum),
863 21 : state.dataSize->CalcFinalSpaceSizing(spaceNum),
864 21 : state.dataHeatBal->space(spaceNum).Name,
865 : spaceNum);
866 : }
867 : }
868 :
869 : // setup CalcFinalZoneSizing structure for use with EMS, some as sensors, some as actuators
870 72 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
871 3 : auto &finalZoneSizing = state.dataSize->FinalZoneSizing(CtrlZoneNum);
872 3 : auto &calcFinalZoneSizing = state.dataSize->CalcFinalZoneSizing(CtrlZoneNum);
873 :
874 3 : SetupEMSInternalVariable(
875 3 : state, "Final Zone Design Heating Air Mass Flow Rate", finalZoneSizing.ZoneName, "[kg/s]", finalZoneSizing.DesHeatMassFlow);
876 3 : SetupEMSInternalVariable(state,
877 : "Intermediate Zone Design Heating Air Mass Flow Rate",
878 : calcFinalZoneSizing.ZoneName,
879 : "[kg/s]",
880 3 : calcFinalZoneSizing.DesHeatMassFlow);
881 3 : SetupEMSActuator(state,
882 : "Sizing:Zone",
883 : calcFinalZoneSizing.ZoneName,
884 : "Zone Design Heating Air Mass Flow Rate",
885 : "[kg/s]",
886 3 : calcFinalZoneSizing.EMSOverrideDesHeatMassOn,
887 3 : calcFinalZoneSizing.EMSValueDesHeatMassFlow);
888 :
889 3 : SetupEMSInternalVariable(
890 3 : state, "Final Zone Design Cooling Air Mass Flow Rate", finalZoneSizing.ZoneName, "[kg/s]", finalZoneSizing.DesCoolMassFlow);
891 3 : SetupEMSInternalVariable(state,
892 : "Intermediate Zone Design Cooling Air Mass Flow Rate",
893 : calcFinalZoneSizing.ZoneName,
894 : "[kg/s]",
895 3 : calcFinalZoneSizing.DesCoolMassFlow);
896 3 : SetupEMSActuator(state,
897 : "Sizing:Zone",
898 : calcFinalZoneSizing.ZoneName,
899 : "Zone Design Cooling Air Mass Flow Rate",
900 : "[kg/s]",
901 3 : calcFinalZoneSizing.EMSOverrideDesCoolMassOn,
902 3 : calcFinalZoneSizing.EMSValueDesCoolMassFlow);
903 :
904 3 : SetupEMSInternalVariable(state, "Final Zone Design Heating Load", finalZoneSizing.ZoneName, "[W]", finalZoneSizing.DesHeatLoad);
905 3 : SetupEMSInternalVariable(
906 3 : state, "Intermediate Zone Design Heating Load", calcFinalZoneSizing.ZoneName, "[W]", calcFinalZoneSizing.DesHeatLoad);
907 3 : SetupEMSActuator(state,
908 : "Sizing:Zone",
909 : calcFinalZoneSizing.ZoneName,
910 : "Zone Design Heating Load",
911 : "[W]",
912 3 : calcFinalZoneSizing.EMSOverrideDesHeatLoadOn,
913 3 : calcFinalZoneSizing.EMSValueDesHeatLoad);
914 :
915 3 : SetupEMSInternalVariable(state, "Final Zone Design Cooling Load", finalZoneSizing.ZoneName, "[W]", finalZoneSizing.DesCoolLoad);
916 3 : SetupEMSInternalVariable(
917 3 : state, "Intermediate Zone Design Cooling Load", calcFinalZoneSizing.ZoneName, "[W]", calcFinalZoneSizing.DesCoolLoad);
918 3 : SetupEMSActuator(state,
919 : "Sizing:Zone",
920 : calcFinalZoneSizing.ZoneName,
921 : "Zone Design Cooling Load",
922 : "[W]",
923 3 : calcFinalZoneSizing.EMSOverrideDesCoolLoadOn,
924 3 : calcFinalZoneSizing.EMSValueDesCoolLoad);
925 :
926 3 : SetupEMSInternalVariable(
927 3 : state, "Final Zone Design Heating Air Density", finalZoneSizing.ZoneName, "[kg/m3]", finalZoneSizing.DesHeatDens);
928 3 : SetupEMSInternalVariable(
929 3 : state, "Intermediate Zone Design Heating Air Density", calcFinalZoneSizing.ZoneName, "[kg/m3]", calcFinalZoneSizing.DesHeatDens);
930 3 : SetupEMSInternalVariable(
931 3 : state, "Final Zone Design Cooling Air Density", finalZoneSizing.ZoneName, "[kg/m3]", finalZoneSizing.DesCoolDens);
932 3 : SetupEMSInternalVariable(
933 3 : state, "Intermediate Zone Design Cooling Air Density", calcFinalZoneSizing.ZoneName, "[kg/m3]", calcFinalZoneSizing.DesCoolDens);
934 :
935 3 : SetupEMSInternalVariable(
936 3 : state, "Final Zone Design Heating Volume Flow", finalZoneSizing.ZoneName, "[m3/s]", finalZoneSizing.DesHeatVolFlow);
937 3 : SetupEMSInternalVariable(
938 3 : state, "Intermediate Zone Design Heating Volume Flow", calcFinalZoneSizing.ZoneName, "[m3/s]", calcFinalZoneSizing.DesHeatVolFlow);
939 3 : SetupEMSActuator(state,
940 : "Sizing:Zone",
941 : calcFinalZoneSizing.ZoneName,
942 : "Zone Design Heating Vol Flow",
943 : "[m3/s]",
944 3 : calcFinalZoneSizing.EMSOverrideDesHeatVolOn,
945 3 : calcFinalZoneSizing.EMSValueDesHeatVolFlow);
946 :
947 3 : SetupEMSInternalVariable(
948 3 : state, "Final Zone Design Cooling Volume Flow", finalZoneSizing.ZoneName, "[m3/s]", finalZoneSizing.DesCoolVolFlow);
949 3 : SetupEMSInternalVariable(
950 3 : state, "Intermediate Zone Design Cooling Volume Flow", calcFinalZoneSizing.ZoneName, "[m3/s]", calcFinalZoneSizing.DesCoolVolFlow);
951 3 : SetupEMSActuator(state,
952 : "Sizing:Zone",
953 : calcFinalZoneSizing.ZoneName,
954 : "Zone Design Cooling Vol Flow",
955 : "[m3/s]",
956 3 : calcFinalZoneSizing.EMSOverrideDesCoolVolOn,
957 3 : calcFinalZoneSizing.EMSValueDesCoolVolFlow);
958 :
959 3 : SetupEMSInternalVariable(
960 3 : state, "Zone Outdoor Air Design Volume Flow Rate", calcFinalZoneSizing.ZoneName, "[m3/s]", calcFinalZoneSizing.MinOA);
961 : }
962 : }
963 :
964 : // Populate DesignSpecification:OutdoorAir:SpaceList spaces
965 52 : bool dsoaError = false;
966 186 : for (int oaIndex = 1; oaIndex <= state.dataSize->NumOARequirements; ++oaIndex) {
967 134 : auto &thisOAReq = state.dataSize->OARequirements(oaIndex);
968 : // If this is a DesignSpecification:OutdoorAir:SpaceList check to make sure spaces are valid and belong to this zone
969 134 : if (thisOAReq.numDSOA > 0) {
970 15 : for (int spaceCounter = 1; spaceCounter <= thisOAReq.numDSOA; ++spaceCounter) {
971 12 : std::string thisSpaceName = thisOAReq.dsoaSpaceNames(spaceCounter);
972 12 : int thisSpaceNum = Util::FindItemInList(thisSpaceName, state.dataHeatBal->space);
973 12 : if (thisSpaceNum > 0) {
974 12 : thisOAReq.dsoaSpaceIndexes.emplace_back(thisSpaceNum);
975 : } else {
976 0 : ShowSevereError(state, format("SetUpZoneSizingArrays: DesignSpecification:OutdoorAir:SpaceList={}", thisOAReq.Name));
977 0 : ShowContinueError(state, format("Space Name={} not found.", thisSpaceName));
978 0 : dsoaError = true;
979 0 : ErrorsFound = true;
980 : }
981 : // Check for duplicate spaces
982 34 : for (int loop = 1; loop <= int(thisOAReq.dsoaSpaceIndexes.size()) - 1; ++loop) {
983 22 : if (thisSpaceNum == thisOAReq.dsoaSpaceIndexes(loop)) {
984 0 : ShowSevereError(state, format("SetUpZoneSizingArrays: DesignSpecification:OutdoorAir:SpaceList={}", thisOAReq.Name));
985 0 : ShowContinueError(state, format("Space Name={} appears more than once in the list.", thisSpaceName));
986 0 : dsoaError = true;
987 0 : ErrorsFound = true;
988 : }
989 : }
990 12 : }
991 : }
992 : }
993 :
994 : // Use the max occupancy data from the PEOPLE structure to calculate design min OA for each zone
995 : // Calculate the zone design minimum outside air flow rate from the 3 Zone Sizing OA inputs and
996 : // from the specified OA method
997 136 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
998 84 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
999 72 : auto &finalZoneSizing = state.dataSize->FinalZoneSizing(CtrlZoneNum);
1000 72 : auto &calcFinalZoneSizing = state.dataSize->CalcFinalZoneSizing(CtrlZoneNum);
1001 72 : calcSizingOA(state, finalZoneSizing, calcFinalZoneSizing, dsoaError, ErrorsFound, CtrlZoneNum);
1002 : }
1003 52 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
1004 28 : for (int spaceNum = 1; spaceNum <= state.dataGlobal->numSpaces; ++spaceNum) {
1005 21 : int zoneNum = state.dataHeatBal->space(spaceNum).zoneNum;
1006 21 : if (!state.dataZoneEquip->ZoneEquipConfig(zoneNum).IsControlled) continue;
1007 21 : auto &finalSpaceSizing = state.dataSize->FinalSpaceSizing(spaceNum);
1008 21 : auto &calcFinalSpaceSizing = state.dataSize->CalcFinalSpaceSizing(spaceNum);
1009 21 : calcSizingOA(state, finalSpaceSizing, calcFinalSpaceSizing, dsoaError, ErrorsFound, zoneNum, spaceNum);
1010 : }
1011 : }
1012 : // Formats
1013 52 : print(state.files.eio, "! <Load Timesteps in Zone Design Calculation Averaging Window>, Value\n");
1014 : static constexpr std::string_view Format_891(" Load Timesteps in Zone Design Calculation Averaging Window, {:4}\n");
1015 52 : print(state.files.eio, Format_891, state.dataSize->NumTimeStepsInAvg);
1016 52 : print(state.files.eio, "! <Heating Sizing Factor Information>, Sizing Factor ID, Value\n");
1017 : static constexpr std::string_view Format_991(" Heating Sizing Factor Information, Global, {:12.5N}\n");
1018 52 : print(state.files.eio, Format_991, state.dataSize->GlobalHeatSizingFactor);
1019 136 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
1020 84 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
1021 72 : if (state.dataSize->FinalZoneSizing(CtrlZoneNum).HeatSizingFactor != 1.0) {
1022 : static constexpr std::string_view Format_992(" Heating Sizing Factor Information, Zone {}, {:12.5N}\n");
1023 16 : print(state.files.eio,
1024 : Format_992,
1025 16 : state.dataSize->FinalZoneSizing(CtrlZoneNum).ZoneName,
1026 16 : state.dataSize->FinalZoneSizing(CtrlZoneNum).HeatSizingFactor);
1027 : }
1028 : }
1029 52 : print(state.files.eio, "! <Cooling Sizing Factor Information>, Sizing Factor ID, Value\n");
1030 : static constexpr std::string_view Format_994(" Cooling Sizing Factor Information, Global, {:12.5N}\n");
1031 52 : print(state.files.eio, Format_994, state.dataSize->GlobalCoolSizingFactor);
1032 136 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
1033 84 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
1034 72 : if (state.dataSize->FinalZoneSizing(CtrlZoneNum).CoolSizingFactor != 1.0) {
1035 : static constexpr std::string_view Format_995(" Cooling Sizing Factor Information, Zone {}, {:12.5N}\n");
1036 16 : print(state.files.eio,
1037 : Format_995,
1038 16 : state.dataSize->FinalZoneSizing(CtrlZoneNum).ZoneName,
1039 16 : state.dataSize->FinalZoneSizing(CtrlZoneNum).CoolSizingFactor);
1040 : }
1041 : }
1042 52 : if (ErrorsFound) {
1043 0 : ShowFatalError(state, "SetUpZoneSizingArrays: Errors found in Sizing:Zone input");
1044 : }
1045 52 : }
1046 :
1047 93 : void calcSizingOA(EnergyPlusData &state,
1048 : DataSizing::ZoneSizingData &zsFinalSizing,
1049 : DataSizing::ZoneSizingData &zsCalcFinalSizing,
1050 : bool &dsoaError,
1051 : bool &ErrorsFound,
1052 : int const zoneNum,
1053 : int const spaceNum)
1054 : {
1055 : // Use the max occupancy PEOPLE structure to calculate design min OA for each zone from the outside air flow per person input
1056 93 : Real64 TotPeopleInZone = 0.0;
1057 93 : Real64 ZoneMinOccupancy = 0.;
1058 93 : int DSOAPtr = zsFinalSizing.ZoneDesignSpecOAIndex; // index to DesignSpecification:OutdoorAir object
1059 93 : auto const &thisZone = state.dataHeatBal->Zone(zoneNum);
1060 93 : int zoneMult = thisZone.Multiplier * thisZone.ListMultiplier;
1061 93 : Real64 floorArea = (spaceNum == 0) ? thisZone.FloorArea : state.dataHeatBal->space(spaceNum).FloorArea;
1062 93 : if ((DSOAPtr > 0) && !dsoaError) {
1063 92 : auto &thisOAReq = state.dataSize->OARequirements(DSOAPtr);
1064 : // If this is a DesignSpecification:OutdoorAir:SpaceList check to make sure spaces are valid and belong to this zone
1065 92 : if (thisOAReq.numDSOA > 0) {
1066 3 : for (int spaceCounter = 1; spaceCounter <= thisOAReq.numDSOA; ++spaceCounter) {
1067 2 : int thisSpaceNum = thisOAReq.dsoaSpaceIndexes(spaceCounter);
1068 2 : if (thisSpaceNum > 0) {
1069 2 : if (state.dataHeatBal->space(thisSpaceNum).zoneNum != zoneNum) {
1070 0 : ShowSevereError(state, format("SetUpZoneSizingArrays: DesignSpecification:OutdoorAir:SpaceList={}", thisOAReq.Name));
1071 0 : ShowContinueError(state, format("is invalid for Sizing:Zone={}", zsFinalSizing.ZoneName));
1072 0 : ShowContinueError(state, "All spaces in the list must be part of this zone.");
1073 0 : ErrorsFound = true;
1074 : }
1075 : }
1076 : }
1077 : }
1078 :
1079 92 : zsFinalSizing.DesOAFlowPPer = thisOAReq.desFlowPerZonePerson(state, zoneNum, spaceNum);
1080 92 : zsFinalSizing.DesOAFlowPerArea = thisOAReq.desFlowPerZoneArea(state, zoneNum, spaceNum);
1081 : }
1082 :
1083 197 : for (int PeopleNum = 1; PeopleNum <= state.dataHeatBal->TotPeople; ++PeopleNum) {
1084 104 : auto &people = state.dataHeatBal->People(PeopleNum);
1085 104 : if (((spaceNum == 0) && (people.ZonePtr == zoneNum)) || ((spaceNum > 0) && (people.spaceIndex == spaceNum))) {
1086 45 : Real64 numPeople = people.NumberOfPeople * zoneMult;
1087 45 : TotPeopleInZone += numPeople;
1088 45 : Real64 SchMax = people.sched->getMaxVal(state);
1089 45 : if (SchMax > 0) {
1090 45 : zsFinalSizing.ZonePeakOccupancy += numPeople * SchMax;
1091 : } else {
1092 0 : zsFinalSizing.ZonePeakOccupancy += numPeople;
1093 : }
1094 45 : ZoneMinOccupancy += numPeople * people.sched->getMinVal(state);
1095 : }
1096 : }
1097 93 : zsFinalSizing.TotalZoneFloorArea = (floorArea * zoneMult);
1098 93 : Real64 OAFromPeople = zsFinalSizing.DesOAFlowPPer * TotPeopleInZone;
1099 93 : Real64 OAFromArea = zsFinalSizing.DesOAFlowPerArea * zsFinalSizing.TotalZoneFloorArea;
1100 93 : zsFinalSizing.TotPeopleInZone = TotPeopleInZone;
1101 93 : zsFinalSizing.TotalOAFromPeople = OAFromPeople;
1102 93 : zsFinalSizing.TotalOAFromArea = OAFromArea;
1103 :
1104 : // save Voz for predefined outdoor air summary report
1105 93 : Real64 MinEz = std::min(zsFinalSizing.ZoneADEffCooling, zsFinalSizing.ZoneADEffHeating);
1106 93 : if (MinEz == 0) {
1107 0 : MinEz = 1.0; // if not calculated assume 1.0 ventilation effectiveness
1108 : }
1109 93 : Real64 vozMin = (ZoneMinOccupancy * zsFinalSizing.DesOAFlowPPer + OAFromArea) / MinEz;
1110 93 : if (spaceNum == 0) {
1111 : // Space TODO: There is no equivalent for spaces
1112 72 : state.dataHeatBal->ZonePreDefRep(zoneNum).VozMin = vozMin;
1113 : }
1114 :
1115 : // Calculate the design min OA flow rate for this zone
1116 : // flag to use occupancy schedule when calculating OA
1117 : // flag to use min OA schedule when calculating OA
1118 93 : auto &equipConfig = (spaceNum == 0) ? state.dataZoneEquip->ZoneEquipConfig(zoneNum) : state.dataZoneEquip->spaceEquipConfig(spaceNum);
1119 93 : equipConfig.ZoneDesignSpecOAIndex = DSOAPtr; // store for later use
1120 93 : equipConfig.ZoneAirDistributionIndex = zsFinalSizing.ZoneAirDistributionIndex; // store for later use
1121 93 : Real64 OAVolumeFlowRate = 0.0;
1122 93 : if (!dsoaError) {
1123 93 : bool UseOccSchFlag = false;
1124 93 : bool UseMinOASchFlag = false;
1125 93 : bool PerPersonNotSet = false;
1126 93 : bool MaxOAVolFlowFlag = false;
1127 93 : OAVolumeFlowRate = DataSizing::calcDesignSpecificationOutdoorAir(
1128 : state, DSOAPtr, zoneNum, UseOccSchFlag, UseMinOASchFlag, PerPersonNotSet, MaxOAVolFlowFlag, spaceNum);
1129 : }
1130 :
1131 : // Zone(ZoneIndex)%Multiplier and Zone(ZoneIndex)%ListMultiplier applied in CalcDesignSpecificationOutdoorAir
1132 93 : zsFinalSizing.MinOA = OAVolumeFlowRate;
1133 93 : zsCalcFinalSizing.MinOA = OAVolumeFlowRate;
1134 93 : if (zsFinalSizing.ZoneADEffCooling > 0.0 || zsFinalSizing.ZoneADEffHeating > 0.0) {
1135 93 : zsFinalSizing.MinOA /= min(zsFinalSizing.ZoneADEffCooling, zsFinalSizing.ZoneADEffHeating);
1136 93 : zsCalcFinalSizing.MinOA = zsFinalSizing.MinOA;
1137 : }
1138 : // calculated zone design flow rates automatically take into account zone multipliers, since the zone
1139 : // loads are multiplied (in ZoneTempPredictorCorrector.cc). Flow rates derived directly from
1140 : // user inputs need to be explicitly multiplied by the zone multipliers.
1141 93 : zsFinalSizing.DesCoolMinAirFlow2 = zsFinalSizing.DesCoolMinAirFlowPerArea * floorArea * zoneMult;
1142 93 : zsCalcFinalSizing.DesCoolMinAirFlow2 = zsCalcFinalSizing.DesCoolMinAirFlowPerArea * floorArea * zoneMult;
1143 93 : zsFinalSizing.DesHeatMaxAirFlow2 = zsFinalSizing.DesHeatMaxAirFlowPerArea * floorArea * zoneMult;
1144 93 : zsCalcFinalSizing.DesHeatMaxAirFlow2 = zsCalcFinalSizing.DesHeatMaxAirFlowPerArea * floorArea * zoneMult;
1145 93 : int zoneMultiplier = zoneMult;
1146 93 : zsFinalSizing.DesCoolMinAirFlow *= zoneMultiplier;
1147 93 : zsCalcFinalSizing.DesCoolMinAirFlow *= zoneMultiplier;
1148 93 : zsFinalSizing.DesHeatMaxAirFlow *= zoneMultiplier;
1149 93 : zsCalcFinalSizing.DesHeatMaxAirFlow *= zoneMultiplier;
1150 93 : zsFinalSizing.InpDesCoolAirFlow *= zoneMultiplier;
1151 93 : zsCalcFinalSizing.InpDesCoolAirFlow *= zoneMultiplier;
1152 93 : zsFinalSizing.InpDesHeatAirFlow *= zoneMultiplier;
1153 93 : zsCalcFinalSizing.InpDesHeatAirFlow *= zoneMultiplier;
1154 :
1155 267 : for (int DesDayNum = 1; DesDayNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DesDayNum) {
1156 174 : auto &zoneSizing = state.dataSize->ZoneSizing(DesDayNum, zoneNum);
1157 174 : zoneSizing.MinOA = zsFinalSizing.MinOA;
1158 174 : state.dataSize->CalcZoneSizing(DesDayNum, zoneNum).MinOA = zsCalcFinalSizing.MinOA;
1159 174 : zoneSizing.DesCoolMinAirFlow2 = zsFinalSizing.DesCoolMinAirFlow2;
1160 174 : state.dataSize->CalcZoneSizing(DesDayNum, zoneNum).DesCoolMinAirFlow2 = zsCalcFinalSizing.DesCoolMinAirFlow2;
1161 174 : zoneSizing.DesCoolMinAirFlow = zsFinalSizing.DesCoolMinAirFlow;
1162 174 : state.dataSize->CalcZoneSizing(DesDayNum, zoneNum).DesCoolMinAirFlow = zsCalcFinalSizing.DesCoolMinAirFlow;
1163 174 : zoneSizing.DesHeatMaxAirFlow2 = zsFinalSizing.DesHeatMaxAirFlow2;
1164 174 : state.dataSize->CalcZoneSizing(DesDayNum, zoneNum).DesHeatMaxAirFlow2 = zsCalcFinalSizing.DesHeatMaxAirFlow2;
1165 174 : zoneSizing.DesHeatMaxAirFlow = zsFinalSizing.DesHeatMaxAirFlow;
1166 174 : state.dataSize->CalcZoneSizing(DesDayNum, zoneNum).DesHeatMaxAirFlow = zsCalcFinalSizing.DesHeatMaxAirFlow;
1167 : }
1168 93 : }
1169 :
1170 93 : void fillZoneSizingFromInput(EnergyPlusData &state,
1171 : DataSizing::ZoneSizingInputData const &zoneSizingInput,
1172 : Array2D<DataSizing::ZoneSizingData> &zsSizing,
1173 : Array2D<DataSizing::ZoneSizingData> &zsCalcSizing,
1174 : DataSizing::ZoneSizingData &zsFinalSizing,
1175 : DataSizing::ZoneSizingData &zsCalcFinalSizing,
1176 : std::string_view const zoneOrSpaceName,
1177 : int const zoneOrSpaceNum)
1178 : {
1179 267 : for (int DesDayNum = 1; DesDayNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DesDayNum) {
1180 174 : auto &zoneSizing = zsSizing(DesDayNum, zoneOrSpaceNum);
1181 174 : auto &calcZoneSizing = zsCalcSizing(DesDayNum, zoneOrSpaceNum);
1182 174 : zoneSizing.ZoneName = zoneOrSpaceName;
1183 174 : zoneSizing.ZoneNum = zoneOrSpaceNum;
1184 174 : calcZoneSizing.ZoneName = zoneOrSpaceName;
1185 174 : calcZoneSizing.ZoneNum = zoneOrSpaceNum;
1186 :
1187 174 : zoneSizing.ZnCoolDgnSAMethod = zoneSizingInput.ZnCoolDgnSAMethod;
1188 174 : zoneSizing.ZnHeatDgnSAMethod = zoneSizingInput.ZnHeatDgnSAMethod;
1189 174 : zoneSizing.CoolDesTemp = zoneSizingInput.CoolDesTemp;
1190 174 : zoneSizing.HeatDesTemp = zoneSizingInput.HeatDesTemp;
1191 174 : zoneSizing.CoolDesTempDiff = zoneSizingInput.CoolDesTempDiff;
1192 174 : zoneSizing.HeatDesTempDiff = zoneSizingInput.HeatDesTempDiff;
1193 174 : zoneSizing.CoolDesHumRat = zoneSizingInput.CoolDesHumRat;
1194 174 : zoneSizing.HeatDesHumRat = zoneSizingInput.HeatDesHumRat;
1195 174 : zoneSizing.CoolAirDesMethod = zoneSizingInput.CoolAirDesMethod;
1196 174 : zoneSizing.HeatAirDesMethod = zoneSizingInput.HeatAirDesMethod;
1197 174 : zoneSizing.InpDesCoolAirFlow = zoneSizingInput.DesCoolAirFlow;
1198 174 : zoneSizing.DesCoolMinAirFlowPerArea = zoneSizingInput.DesCoolMinAirFlowPerArea;
1199 174 : zoneSizing.DesCoolMinAirFlow = zoneSizingInput.DesCoolMinAirFlow;
1200 174 : zoneSizing.DesCoolMinAirFlowFrac = zoneSizingInput.DesCoolMinAirFlowFrac;
1201 174 : zoneSizing.InpDesHeatAirFlow = zoneSizingInput.DesHeatAirFlow;
1202 174 : zoneSizing.DesHeatMaxAirFlowPerArea = zoneSizingInput.DesHeatMaxAirFlowPerArea;
1203 174 : zoneSizing.DesHeatMaxAirFlow = zoneSizingInput.DesHeatMaxAirFlow;
1204 174 : zoneSizing.DesHeatMaxAirFlowFrac = zoneSizingInput.DesHeatMaxAirFlowFrac;
1205 174 : zoneSizing.HeatSizingFactor = zoneSizingInput.HeatSizingFactor;
1206 174 : zoneSizing.CoolSizingFactor = zoneSizingInput.CoolSizingFactor;
1207 174 : zoneSizing.AccountForDOAS = zoneSizingInput.AccountForDOAS;
1208 174 : zoneSizing.DOASControlStrategy = zoneSizingInput.DOASControlStrategy;
1209 174 : zoneSizing.DOASLowSetpoint = zoneSizingInput.DOASLowSetpoint;
1210 174 : zoneSizing.DOASHighSetpoint = zoneSizingInput.DOASHighSetpoint;
1211 174 : zoneSizing.spaceConcurrence = zoneSizingInput.spaceConcurrence;
1212 174 : zoneSizing.zoneSizingMethod = zoneSizingInput.zoneSizingMethod;
1213 174 : zoneSizing.zoneLatentSizing = zoneSizingInput.zoneLatentSizing;
1214 174 : zoneSizing.zoneRHDehumidifySetPoint = zoneSizingInput.zoneRHDehumidifySetPoint;
1215 174 : zoneSizing.zoneRHHumidifySetPoint = zoneSizingInput.zoneRHHumidifySetPoint;
1216 174 : zoneSizing.zoneRHDehumidifySched = zoneSizingInput.zoneRHDehumidifySched;
1217 174 : zoneSizing.zoneRHHumidifySched = zoneSizingInput.zoneRHHumidifySched;
1218 174 : zoneSizing.ZnLatCoolDgnSAMethod = zoneSizingInput.ZnLatCoolDgnSAMethod;
1219 174 : zoneSizing.ZnLatHeatDgnSAMethod = zoneSizingInput.ZnLatHeatDgnSAMethod;
1220 174 : calcZoneSizing.ZnCoolDgnSAMethod = zoneSizingInput.ZnCoolDgnSAMethod;
1221 174 : calcZoneSizing.ZnHeatDgnSAMethod = zoneSizingInput.ZnHeatDgnSAMethod;
1222 174 : calcZoneSizing.CoolDesTemp = zoneSizingInput.CoolDesTemp;
1223 174 : calcZoneSizing.HeatDesTemp = zoneSizingInput.HeatDesTemp;
1224 174 : calcZoneSizing.CoolDesTempDiff = zoneSizingInput.CoolDesTempDiff;
1225 174 : calcZoneSizing.HeatDesTempDiff = zoneSizingInput.HeatDesTempDiff;
1226 174 : calcZoneSizing.CoolDesHumRat = zoneSizingInput.CoolDesHumRat;
1227 174 : calcZoneSizing.HeatDesHumRat = zoneSizingInput.HeatDesHumRat;
1228 174 : calcZoneSizing.CoolAirDesMethod = zoneSizingInput.CoolAirDesMethod;
1229 174 : calcZoneSizing.HeatAirDesMethod = zoneSizingInput.HeatAirDesMethod;
1230 174 : calcZoneSizing.InpDesCoolAirFlow = zoneSizingInput.DesCoolAirFlow;
1231 174 : calcZoneSizing.DesCoolMinAirFlowPerArea = zoneSizingInput.DesCoolMinAirFlowPerArea;
1232 174 : calcZoneSizing.DesCoolMinAirFlow = zoneSizingInput.DesCoolMinAirFlow;
1233 174 : calcZoneSizing.DesCoolMinAirFlowFrac = zoneSizingInput.DesCoolMinAirFlowFrac;
1234 174 : calcZoneSizing.InpDesHeatAirFlow = zoneSizingInput.DesHeatAirFlow;
1235 174 : calcZoneSizing.DesHeatMaxAirFlowPerArea = zoneSizingInput.DesHeatMaxAirFlowPerArea;
1236 174 : calcZoneSizing.DesHeatMaxAirFlow = zoneSizingInput.DesHeatMaxAirFlow;
1237 174 : calcZoneSizing.DesHeatMaxAirFlowFrac = zoneSizingInput.DesHeatMaxAirFlowFrac;
1238 174 : calcZoneSizing.HeatSizingFactor = zoneSizingInput.HeatSizingFactor;
1239 174 : calcZoneSizing.CoolSizingFactor = zoneSizingInput.CoolSizingFactor;
1240 174 : calcZoneSizing.AccountForDOAS = zoneSizingInput.AccountForDOAS;
1241 174 : calcZoneSizing.DOASControlStrategy = zoneSizingInput.DOASControlStrategy;
1242 174 : calcZoneSizing.DOASLowSetpoint = zoneSizingInput.DOASLowSetpoint;
1243 174 : calcZoneSizing.DOASHighSetpoint = zoneSizingInput.DOASHighSetpoint;
1244 174 : calcZoneSizing.spaceConcurrence = zoneSizingInput.spaceConcurrence;
1245 174 : calcZoneSizing.zoneSizingMethod = zoneSizingInput.zoneSizingMethod;
1246 174 : calcZoneSizing.zoneLatentSizing = zoneSizingInput.zoneLatentSizing;
1247 174 : calcZoneSizing.zoneRHDehumidifySetPoint = zoneSizingInput.zoneRHDehumidifySetPoint;
1248 174 : calcZoneSizing.zoneRHHumidifySetPoint = zoneSizingInput.zoneRHHumidifySetPoint;
1249 174 : calcZoneSizing.zoneRHDehumidifySched = zoneSizingInput.zoneRHDehumidifySched;
1250 174 : calcZoneSizing.zoneRHHumidifySched = zoneSizingInput.zoneRHHumidifySched;
1251 174 : calcZoneSizing.ZnLatCoolDgnSAMethod = zoneSizingInput.ZnLatCoolDgnSAMethod;
1252 174 : calcZoneSizing.LatentCoolDesHumRat = zoneSizingInput.LatentCoolDesHumRat;
1253 174 : calcZoneSizing.CoolDesHumRatDiff = zoneSizingInput.CoolDesHumRatDiff;
1254 174 : calcZoneSizing.ZnLatHeatDgnSAMethod = zoneSizingInput.ZnLatHeatDgnSAMethod;
1255 174 : calcZoneSizing.LatentHeatDesHumRat = zoneSizingInput.LatentHeatDesHumRat;
1256 174 : calcZoneSizing.HeatDesHumRatDiff = zoneSizingInput.HeatDesHumRatDiff;
1257 :
1258 174 : zoneSizing.allocateMemberArrays(state.dataZoneEquipmentManager->NumOfTimeStepInDay);
1259 174 : calcZoneSizing.allocateMemberArrays(state.dataZoneEquipmentManager->NumOfTimeStepInDay);
1260 : }
1261 :
1262 93 : zsFinalSizing.ZoneName = zoneOrSpaceName;
1263 93 : zsFinalSizing.ZoneNum = zoneOrSpaceNum;
1264 93 : zsCalcFinalSizing.ZoneName = zoneOrSpaceName;
1265 93 : zsCalcFinalSizing.ZoneNum = zoneOrSpaceNum;
1266 :
1267 93 : zsFinalSizing.ZnCoolDgnSAMethod = zoneSizingInput.ZnCoolDgnSAMethod;
1268 93 : zsFinalSizing.ZnHeatDgnSAMethod = zoneSizingInput.ZnHeatDgnSAMethod;
1269 93 : zsFinalSizing.CoolDesTemp = zoneSizingInput.CoolDesTemp;
1270 93 : zsFinalSizing.HeatDesTemp = zoneSizingInput.HeatDesTemp;
1271 93 : zsFinalSizing.CoolDesTempDiff = zoneSizingInput.CoolDesTempDiff;
1272 93 : zsFinalSizing.HeatDesTempDiff = zoneSizingInput.HeatDesTempDiff;
1273 93 : zsFinalSizing.CoolDesHumRat = zoneSizingInput.CoolDesHumRat;
1274 93 : zsFinalSizing.HeatDesHumRat = zoneSizingInput.HeatDesHumRat;
1275 93 : zsFinalSizing.ZoneAirDistributionIndex = zoneSizingInput.ZoneAirDistributionIndex;
1276 93 : zsFinalSizing.ZoneDesignSpecOAIndex = zoneSizingInput.ZoneDesignSpecOAIndex;
1277 93 : zsFinalSizing.CoolAirDesMethod = zoneSizingInput.CoolAirDesMethod;
1278 93 : zsFinalSizing.HeatAirDesMethod = zoneSizingInput.HeatAirDesMethod;
1279 93 : zsFinalSizing.InpDesCoolAirFlow = zoneSizingInput.DesCoolAirFlow;
1280 93 : zsFinalSizing.DesCoolMinAirFlowPerArea = zoneSizingInput.DesCoolMinAirFlowPerArea;
1281 93 : zsFinalSizing.DesCoolMinAirFlow = zoneSizingInput.DesCoolMinAirFlow;
1282 93 : zsFinalSizing.DesCoolMinAirFlowFrac = zoneSizingInput.DesCoolMinAirFlowFrac;
1283 93 : zsFinalSizing.InpDesHeatAirFlow = zoneSizingInput.DesHeatAirFlow;
1284 93 : zsFinalSizing.DesHeatMaxAirFlowPerArea = zoneSizingInput.DesHeatMaxAirFlowPerArea;
1285 93 : zsFinalSizing.DesHeatMaxAirFlow = zoneSizingInput.DesHeatMaxAirFlow;
1286 93 : zsFinalSizing.DesHeatMaxAirFlowFrac = zoneSizingInput.DesHeatMaxAirFlowFrac;
1287 93 : zsFinalSizing.HeatSizingFactor = zoneSizingInput.HeatSizingFactor;
1288 93 : zsFinalSizing.CoolSizingFactor = zoneSizingInput.CoolSizingFactor;
1289 93 : zsFinalSizing.AccountForDOAS = zoneSizingInput.AccountForDOAS;
1290 93 : zsFinalSizing.DOASControlStrategy = zoneSizingInput.DOASControlStrategy;
1291 93 : zsFinalSizing.DOASLowSetpoint = zoneSizingInput.DOASLowSetpoint;
1292 93 : zsFinalSizing.DOASHighSetpoint = zoneSizingInput.DOASHighSetpoint;
1293 93 : zsFinalSizing.ZoneADEffCooling = zoneSizingInput.ZoneADEffCooling;
1294 93 : zsFinalSizing.ZoneADEffHeating = zoneSizingInput.ZoneADEffHeating;
1295 93 : zsFinalSizing.ZoneSecondaryRecirculation = zoneSizingInput.ZoneSecondaryRecirculation;
1296 93 : zsFinalSizing.ZoneVentilationEff = zoneSizingInput.ZoneVentilationEff;
1297 93 : zsFinalSizing.spaceConcurrence = zoneSizingInput.spaceConcurrence;
1298 93 : zsFinalSizing.zoneSizingMethod = zoneSizingInput.zoneSizingMethod;
1299 93 : zsFinalSizing.zoneLatentSizing = zoneSizingInput.zoneLatentSizing;
1300 93 : zsFinalSizing.zoneRHDehumidifySetPoint = zoneSizingInput.zoneRHDehumidifySetPoint;
1301 93 : zsFinalSizing.zoneRHHumidifySetPoint = zoneSizingInput.zoneRHHumidifySetPoint;
1302 93 : zsFinalSizing.zoneRHDehumidifySched = zoneSizingInput.zoneRHDehumidifySched;
1303 93 : zsFinalSizing.zoneRHHumidifySched = zoneSizingInput.zoneRHHumidifySched;
1304 93 : zsFinalSizing.ZnLatCoolDgnSAMethod = zoneSizingInput.ZnLatCoolDgnSAMethod;
1305 93 : zsFinalSizing.LatentCoolDesHumRat = zoneSizingInput.LatentCoolDesHumRat;
1306 93 : zsFinalSizing.CoolDesHumRatDiff = zoneSizingInput.CoolDesHumRatDiff;
1307 93 : zsFinalSizing.ZnLatHeatDgnSAMethod = zoneSizingInput.ZnLatHeatDgnSAMethod;
1308 93 : zsFinalSizing.LatentHeatDesHumRat = zoneSizingInput.LatentHeatDesHumRat;
1309 93 : zsFinalSizing.HeatDesHumRatDiff = zoneSizingInput.HeatDesHumRatDiff;
1310 93 : zsCalcFinalSizing.ZnCoolDgnSAMethod = zoneSizingInput.ZnCoolDgnSAMethod;
1311 93 : zsCalcFinalSizing.ZnHeatDgnSAMethod = zoneSizingInput.ZnHeatDgnSAMethod;
1312 93 : zsCalcFinalSizing.CoolDesTemp = zoneSizingInput.CoolDesTemp;
1313 93 : zsCalcFinalSizing.HeatDesTemp = zoneSizingInput.HeatDesTemp;
1314 93 : zsCalcFinalSizing.CoolDesTempDiff = zoneSizingInput.CoolDesTempDiff;
1315 93 : zsCalcFinalSizing.HeatDesTempDiff = zoneSizingInput.HeatDesTempDiff;
1316 93 : zsCalcFinalSizing.CoolDesHumRat = zoneSizingInput.CoolDesHumRat;
1317 93 : zsCalcFinalSizing.HeatDesHumRat = zoneSizingInput.HeatDesHumRat;
1318 93 : zsCalcFinalSizing.ZoneAirDistributionIndex = zoneSizingInput.ZoneAirDistributionIndex;
1319 93 : zsCalcFinalSizing.ZoneDesignSpecOAIndex = zoneSizingInput.ZoneDesignSpecOAIndex;
1320 93 : zsCalcFinalSizing.CoolAirDesMethod = zoneSizingInput.CoolAirDesMethod;
1321 93 : zsCalcFinalSizing.HeatAirDesMethod = zoneSizingInput.HeatAirDesMethod;
1322 93 : zsCalcFinalSizing.InpDesCoolAirFlow = zoneSizingInput.DesCoolAirFlow;
1323 93 : zsCalcFinalSizing.DesCoolMinAirFlowPerArea = zoneSizingInput.DesCoolMinAirFlowPerArea;
1324 93 : zsCalcFinalSizing.DesCoolMinAirFlow = zoneSizingInput.DesCoolMinAirFlow;
1325 93 : zsCalcFinalSizing.DesCoolMinAirFlowFrac = zoneSizingInput.DesCoolMinAirFlowFrac;
1326 93 : zsCalcFinalSizing.InpDesHeatAirFlow = zoneSizingInput.DesHeatAirFlow;
1327 93 : zsCalcFinalSizing.DesHeatMaxAirFlowPerArea = zoneSizingInput.DesHeatMaxAirFlowPerArea;
1328 93 : zsCalcFinalSizing.DesHeatMaxAirFlow = zoneSizingInput.DesHeatMaxAirFlow;
1329 93 : zsCalcFinalSizing.DesHeatMaxAirFlowFrac = zoneSizingInput.DesHeatMaxAirFlowFrac;
1330 93 : zsCalcFinalSizing.HeatSizingFactor = zoneSizingInput.HeatSizingFactor;
1331 93 : zsCalcFinalSizing.CoolSizingFactor = zoneSizingInput.CoolSizingFactor;
1332 93 : zsCalcFinalSizing.AccountForDOAS = zoneSizingInput.AccountForDOAS;
1333 93 : zsCalcFinalSizing.DOASControlStrategy = zoneSizingInput.DOASControlStrategy;
1334 93 : zsCalcFinalSizing.DOASLowSetpoint = zoneSizingInput.DOASLowSetpoint;
1335 93 : zsCalcFinalSizing.DOASHighSetpoint = zoneSizingInput.DOASHighSetpoint;
1336 93 : zsCalcFinalSizing.ZoneADEffCooling = zoneSizingInput.ZoneADEffCooling;
1337 93 : zsCalcFinalSizing.ZoneADEffHeating = zoneSizingInput.ZoneADEffHeating;
1338 93 : zsCalcFinalSizing.spaceConcurrence = zoneSizingInput.spaceConcurrence;
1339 93 : zsCalcFinalSizing.zoneSizingMethod = zoneSizingInput.zoneSizingMethod;
1340 93 : zsCalcFinalSizing.zoneLatentSizing = zoneSizingInput.zoneLatentSizing;
1341 93 : zsCalcFinalSizing.zoneRHDehumidifySetPoint = zoneSizingInput.zoneRHDehumidifySetPoint;
1342 93 : zsCalcFinalSizing.zoneRHHumidifySetPoint = zoneSizingInput.zoneRHHumidifySetPoint;
1343 93 : zsCalcFinalSizing.zoneRHDehumidifySched = zoneSizingInput.zoneRHDehumidifySched;
1344 93 : zsCalcFinalSizing.zoneRHHumidifySched = zoneSizingInput.zoneRHHumidifySched;
1345 93 : zsCalcFinalSizing.ZnLatCoolDgnSAMethod = zoneSizingInput.ZnLatCoolDgnSAMethod;
1346 93 : zsCalcFinalSizing.LatentCoolDesHumRat = zoneSizingInput.LatentCoolDesHumRat;
1347 93 : zsCalcFinalSizing.CoolDesHumRatDiff = zoneSizingInput.CoolDesHumRatDiff;
1348 93 : zsCalcFinalSizing.ZnLatHeatDgnSAMethod = zoneSizingInput.ZnLatHeatDgnSAMethod;
1349 93 : zsCalcFinalSizing.LatentHeatDesHumRat = zoneSizingInput.LatentHeatDesHumRat;
1350 93 : zsCalcFinalSizing.HeatDesHumRatDiff = zoneSizingInput.HeatDesHumRatDiff;
1351 :
1352 93 : zsFinalSizing.allocateMemberArrays(state.dataZoneEquipmentManager->NumOfTimeStepInDay);
1353 93 : zsCalcFinalSizing.allocateMemberArrays(state.dataZoneEquipmentManager->NumOfTimeStepInDay);
1354 93 : }
1355 7 : void RezeroZoneSizingArrays(EnergyPlusData &state)
1356 : {
1357 : // Zero zone sizing arrays between the pulse and normal sizing.
1358 7 : DisplayString(state, "Re-zeroing zone sizing arrays");
1359 :
1360 23 : for (int ctrlZoneNum = 1; ctrlZoneNum <= state.dataGlobal->NumOfZones; ++ctrlZoneNum) {
1361 16 : if (!state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).IsControlled) continue;
1362 107 : for (int desDayNum = 1; desDayNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++desDayNum) {
1363 93 : state.dataSize->ZoneSizing(desDayNum, ctrlZoneNum).zeroMemberData();
1364 93 : state.dataSize->CalcZoneSizing(desDayNum, ctrlZoneNum).zeroMemberData();
1365 : }
1366 14 : state.dataSize->CalcFinalZoneSizing(ctrlZoneNum).zeroMemberData();
1367 14 : state.dataSize->FinalZoneSizing(ctrlZoneNum).zeroMemberData();
1368 : }
1369 7 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
1370 0 : for (int spaceNum = 1; spaceNum <= state.dataGlobal->numSpaces; ++spaceNum) {
1371 0 : if (!state.dataZoneEquip->ZoneEquipConfig(state.dataHeatBal->space(spaceNum).zoneNum).IsControlled) continue;
1372 0 : for (int desDayNum = 1; desDayNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++desDayNum) {
1373 0 : state.dataSize->SpaceSizing(desDayNum, spaceNum).zeroMemberData();
1374 0 : state.dataSize->CalcSpaceSizing(desDayNum, spaceNum).zeroMemberData();
1375 : }
1376 0 : state.dataSize->CalcFinalSpaceSizing(spaceNum).zeroMemberData();
1377 0 : state.dataSize->FinalSpaceSizing(spaceNum).zeroMemberData();
1378 : }
1379 : }
1380 7 : }
1381 194 : void updateZoneSizingBeginDay(EnergyPlusData const &state, DataSizing::ZoneSizingData &zsCalcSizing)
1382 : {
1383 194 : zsCalcSizing.CoolDesDay = state.dataEnvrn->EnvironmentName;
1384 194 : zsCalcSizing.HeatDesDay = state.dataEnvrn->EnvironmentName;
1385 194 : zsCalcSizing.DesHeatDens = state.dataEnvrn->StdRhoAir;
1386 194 : zsCalcSizing.DesCoolDens = state.dataEnvrn->StdRhoAir;
1387 194 : zsCalcSizing.HeatDDNum = state.dataSize->CurOverallSimDay;
1388 194 : zsCalcSizing.CoolDDNum = state.dataSize->CurOverallSimDay;
1389 194 : zsCalcSizing.CoolNoDOASDesDay = state.dataEnvrn->EnvironmentName;
1390 194 : zsCalcSizing.HeatNoDOASDesDay = state.dataEnvrn->EnvironmentName;
1391 194 : zsCalcSizing.LatCoolDesDay = state.dataEnvrn->EnvironmentName;
1392 194 : zsCalcSizing.LatHeatDesDay = state.dataEnvrn->EnvironmentName;
1393 194 : zsCalcSizing.LatCoolNoDOASDesDay = state.dataEnvrn->EnvironmentName;
1394 194 : zsCalcSizing.LatHeatNoDOASDesDay = state.dataEnvrn->EnvironmentName;
1395 194 : zsCalcSizing.CoolNoDOASDDNum = state.dataSize->CurOverallSimDay;
1396 194 : zsCalcSizing.HeatNoDOASDDNum = state.dataSize->CurOverallSimDay;
1397 194 : zsCalcSizing.LatentCoolDDNum = state.dataSize->CurOverallSimDay;
1398 194 : zsCalcSizing.LatentHeatDDNum = state.dataSize->CurOverallSimDay;
1399 194 : zsCalcSizing.LatentCoolNoDOASDDNum = state.dataSize->CurOverallSimDay;
1400 194 : zsCalcSizing.LatentHeatNoDOASDDNum = state.dataSize->CurOverallSimDay;
1401 194 : zsCalcSizing.CoolSizingType = "Cooling"; // string reported to eio
1402 194 : zsCalcSizing.HeatSizingType = "Heating"; // string reported to eio
1403 194 : }
1404 :
1405 23906 : void updateZoneSizingDuringDay(DataSizing::ZoneSizingData &zsSizing,
1406 : DataSizing::ZoneSizingData &zsCalcSizing,
1407 : Real64 const tstatHi,
1408 : Real64 const tstatLo,
1409 : Real64 &sizTstatHi,
1410 : Real64 &sizTstatLo,
1411 : int const timeStepInDay,
1412 : Real64 const fracTimeStepZone)
1413 : {
1414 23906 : if (tstatHi > 0.0 && tstatHi > sizTstatHi) {
1415 76 : sizTstatHi = tstatHi;
1416 : }
1417 23906 : if (tstatLo > 0.0 && tstatLo < sizTstatHi) {
1418 21266 : sizTstatLo = tstatLo;
1419 : }
1420 23906 : zsSizing.DesHeatSetPtSeq(timeStepInDay) = tstatLo;
1421 23906 : zsSizing.HeatTstatTempSeq(timeStepInDay) = zsCalcSizing.HeatTstatTemp;
1422 23906 : zsSizing.DesCoolSetPtSeq(timeStepInDay) = tstatHi;
1423 23906 : zsSizing.CoolTstatTempSeq(timeStepInDay) = zsCalcSizing.CoolTstatTemp;
1424 23906 : zsCalcSizing.HeatFlowSeq(timeStepInDay) += zsCalcSizing.HeatMassFlow * fracTimeStepZone;
1425 23906 : zsCalcSizing.HeatLoadSeq(timeStepInDay) += zsCalcSizing.HeatLoad * fracTimeStepZone;
1426 23906 : zsCalcSizing.HeatZoneTempSeq(timeStepInDay) += zsCalcSizing.HeatZoneTemp * fracTimeStepZone;
1427 23906 : zsCalcSizing.HeatOutTempSeq(timeStepInDay) += zsCalcSizing.HeatOutTemp * fracTimeStepZone;
1428 23906 : zsCalcSizing.HeatZoneRetTempSeq(timeStepInDay) += zsCalcSizing.HeatZoneRetTemp * fracTimeStepZone;
1429 23906 : zsCalcSizing.HeatZoneHumRatSeq(timeStepInDay) += zsCalcSizing.HeatZoneHumRat * fracTimeStepZone;
1430 23906 : zsCalcSizing.HeatOutHumRatSeq(timeStepInDay) += zsCalcSizing.HeatOutHumRat * fracTimeStepZone;
1431 23906 : zsCalcSizing.CoolFlowSeq(timeStepInDay) += zsCalcSizing.CoolMassFlow * fracTimeStepZone;
1432 23906 : zsCalcSizing.CoolLoadSeq(timeStepInDay) += zsCalcSizing.CoolLoad * fracTimeStepZone;
1433 23906 : zsCalcSizing.CoolZoneTempSeq(timeStepInDay) += zsCalcSizing.CoolZoneTemp * fracTimeStepZone;
1434 23906 : zsCalcSizing.CoolOutTempSeq(timeStepInDay) += zsCalcSizing.CoolOutTemp * fracTimeStepZone;
1435 23906 : zsCalcSizing.CoolZoneRetTempSeq(timeStepInDay) += zsCalcSizing.CoolZoneRetTemp * fracTimeStepZone;
1436 23906 : zsCalcSizing.CoolZoneHumRatSeq(timeStepInDay) += zsCalcSizing.CoolZoneHumRat * fracTimeStepZone;
1437 23906 : zsCalcSizing.CoolOutHumRatSeq(timeStepInDay) += zsCalcSizing.CoolOutHumRat * fracTimeStepZone;
1438 23906 : zsCalcSizing.DOASHeatLoadSeq(timeStepInDay) += zsCalcSizing.DOASHeatLoad * fracTimeStepZone;
1439 23906 : zsCalcSizing.DOASCoolLoadSeq(timeStepInDay) += zsCalcSizing.DOASCoolLoad * fracTimeStepZone;
1440 23906 : zsCalcSizing.DOASHeatAddSeq(timeStepInDay) += zsCalcSizing.DOASHeatAdd * fracTimeStepZone;
1441 23906 : zsCalcSizing.DOASLatAddSeq(timeStepInDay) += zsCalcSizing.DOASLatAdd * fracTimeStepZone;
1442 23906 : zsCalcSizing.DOASSupMassFlowSeq(timeStepInDay) += zsCalcSizing.DOASSupMassFlow * fracTimeStepZone;
1443 23906 : zsCalcSizing.DOASSupTempSeq(timeStepInDay) += zsCalcSizing.DOASSupTemp * fracTimeStepZone;
1444 23906 : zsCalcSizing.DOASSupHumRatSeq(timeStepInDay) += zsCalcSizing.DOASSupHumRat * fracTimeStepZone;
1445 23906 : zsCalcSizing.DOASTotCoolLoadSeq(timeStepInDay) += zsCalcSizing.DOASTotCoolLoad * fracTimeStepZone;
1446 23906 : if (zsCalcSizing.zoneLatentSizing) {
1447 3744 : zsCalcSizing.LatentHeatLoadSeq(timeStepInDay) += zsCalcSizing.HeatLatentLoad * fracTimeStepZone;
1448 3744 : zsCalcSizing.LatentHeatFlowSeq(timeStepInDay) += zsCalcSizing.ZoneHeatLatentMassFlow * fracTimeStepZone;
1449 3744 : zsCalcSizing.LatentCoolLoadSeq(timeStepInDay) += zsCalcSizing.CoolLatentLoad * fracTimeStepZone;
1450 3744 : zsCalcSizing.LatentCoolFlowSeq(timeStepInDay) += zsCalcSizing.ZoneCoolLatentMassFlow * fracTimeStepZone;
1451 3744 : zsCalcSizing.CoolLatentLoadNoDOASSeq(timeStepInDay) += zsCalcSizing.CoolLatentLoadNoDOAS * fracTimeStepZone;
1452 3744 : zsCalcSizing.HeatLatentLoadNoDOASSeq(timeStepInDay) += zsCalcSizing.HeatLatentLoadNoDOAS * fracTimeStepZone;
1453 3744 : zsCalcSizing.CoolLoadNoDOASSeq(timeStepInDay) += zsCalcSizing.CoolLoadNoDOAS * fracTimeStepZone;
1454 3744 : zsCalcSizing.HeatLoadNoDOASSeq(timeStepInDay) += zsCalcSizing.HeatLoadNoDOAS * fracTimeStepZone;
1455 : }
1456 23906 : }
1457 :
1458 386 : void updateZoneSizingEndDayMovingAvg(DataSizing::ZoneSizingData &zsCalcSizing, int const numTimeStepsInAvg)
1459 : {
1460 386 : General::MovingAvg(zsCalcSizing.CoolFlowSeq, numTimeStepsInAvg);
1461 386 : General::MovingAvg(zsCalcSizing.CoolLoadSeq, numTimeStepsInAvg);
1462 386 : General::MovingAvg(zsCalcSizing.HeatFlowSeq, numTimeStepsInAvg);
1463 386 : General::MovingAvg(zsCalcSizing.HeatLoadSeq, numTimeStepsInAvg);
1464 386 : General::MovingAvg(zsCalcSizing.CoolZoneRetTempSeq, numTimeStepsInAvg);
1465 386 : General::MovingAvg(zsCalcSizing.HeatZoneRetTempSeq, numTimeStepsInAvg);
1466 386 : General::MovingAvg(zsCalcSizing.DOASHeatAddSeq, numTimeStepsInAvg);
1467 386 : General::MovingAvg(zsCalcSizing.DOASLatAddSeq, numTimeStepsInAvg);
1468 386 : General::MovingAvg(zsCalcSizing.CoolLatentLoadNoDOASSeq, numTimeStepsInAvg);
1469 386 : General::MovingAvg(zsCalcSizing.HeatLatentLoadNoDOASSeq, numTimeStepsInAvg);
1470 386 : General::MovingAvg(zsCalcSizing.CoolLoadNoDOASSeq, numTimeStepsInAvg);
1471 386 : General::MovingAvg(zsCalcSizing.HeatLoadNoDOASSeq, numTimeStepsInAvg);
1472 :
1473 386 : if (zsCalcSizing.zoneLatentSizing) {
1474 52 : General::MovingAvg(zsCalcSizing.LatentHeatLoadSeq, numTimeStepsInAvg);
1475 52 : General::MovingAvg(zsCalcSizing.LatentHeatFlowSeq, numTimeStepsInAvg);
1476 52 : General::MovingAvg(zsCalcSizing.LatentCoolLoadSeq, numTimeStepsInAvg);
1477 52 : General::MovingAvg(zsCalcSizing.LatentCoolFlowSeq, numTimeStepsInAvg);
1478 : }
1479 386 : }
1480 :
1481 386 : void updateZoneSizingEndDay(DataSizing::ZoneSizingData &zsCalcSizing,
1482 : DataSizing::ZoneSizingData &zsCalcFinalSizing,
1483 : int const numTimeStepInDay,
1484 : DataSizing::DesDayWeathData const &desDayWeath,
1485 : Real64 const stdRhoAir)
1486 : {
1487 386 : zsCalcFinalSizing.CoolSizingType = zsCalcSizing.CoolSizingType;
1488 386 : zsCalcFinalSizing.HeatSizingType = zsCalcSizing.HeatSizingType;
1489 :
1490 : // save the sequence values at the heating peak
1491 46660 : for (int TimeStepIndex = 1; TimeStepIndex <= numTimeStepInDay; ++TimeStepIndex) {
1492 46274 : if (zsCalcSizing.HeatLoadSeq(TimeStepIndex) > zsCalcSizing.DesHeatLoad) {
1493 3356 : zsCalcSizing.DesHeatLoad = zsCalcSizing.HeatLoadSeq(TimeStepIndex);
1494 3356 : zsCalcSizing.DesHeatMassFlow = zsCalcSizing.HeatFlowSeq(TimeStepIndex);
1495 3356 : zsCalcSizing.ZoneTempAtHeatPeak = zsCalcSizing.HeatZoneTempSeq(TimeStepIndex);
1496 3356 : zsCalcSizing.OutTempAtHeatPeak = zsCalcSizing.HeatOutTempSeq(TimeStepIndex);
1497 3356 : zsCalcSizing.ZoneRetTempAtHeatPeak = zsCalcSizing.HeatZoneRetTempSeq(TimeStepIndex);
1498 3356 : zsCalcSizing.ZoneHumRatAtHeatPeak = zsCalcSizing.HeatZoneHumRatSeq(TimeStepIndex);
1499 3356 : zsCalcSizing.OutHumRatAtHeatPeak = zsCalcSizing.HeatOutHumRatSeq(TimeStepIndex);
1500 3356 : zsCalcSizing.TimeStepNumAtHeatMax = TimeStepIndex;
1501 : }
1502 : }
1503 : // save the sequence values at the latent heating peak
1504 386 : if (zsCalcSizing.zoneLatentSizing) {
1505 7540 : for (int TimeStepIndex = 1; TimeStepIndex <= numTimeStepInDay; ++TimeStepIndex) {
1506 7488 : if (zsCalcSizing.LatentHeatLoadSeq(TimeStepIndex) > zsCalcSizing.DesLatentHeatLoad) {
1507 48 : zsCalcSizing.DesLatentHeatLoad = zsCalcSizing.LatentHeatLoadSeq(TimeStepIndex);
1508 48 : zsCalcSizing.DesLatentHeatMassFlow = zsCalcSizing.LatentHeatFlowSeq(TimeStepIndex);
1509 48 : zsCalcSizing.ZoneHeatLatentMassFlow = zsCalcSizing.LatentHeatFlowSeq(TimeStepIndex);
1510 48 : zsCalcSizing.ZoneTempAtLatentHeatPeak = zsCalcSizing.HeatZoneTempSeq(TimeStepIndex);
1511 48 : zsCalcSizing.OutTempAtLatentHeatPeak = zsCalcSizing.HeatOutTempSeq(TimeStepIndex);
1512 48 : zsCalcSizing.ZoneHumRatAtLatentHeatPeak = zsCalcSizing.HeatZoneHumRatSeq(TimeStepIndex);
1513 48 : zsCalcSizing.OutHumRatAtLatentHeatPeak = zsCalcSizing.HeatOutHumRatSeq(TimeStepIndex);
1514 48 : zsCalcSizing.ZoneRetTempAtLatentHeatPeak = zsCalcSizing.HeatZoneRetTempSeq(TimeStepIndex);
1515 48 : zsCalcSizing.TimeStepNumAtLatentHeatMax = TimeStepIndex;
1516 : }
1517 : }
1518 : }
1519 46660 : for (int TimeStepIndex = 1; TimeStepIndex <= numTimeStepInDay; ++TimeStepIndex) {
1520 : // select largest load from NoDOAS arrays
1521 46274 : if (zsCalcSizing.HeatLoadNoDOASSeq(TimeStepIndex) > zsCalcSizing.DesHeatLoadNoDOAS) {
1522 768 : zsCalcSizing.DesHeatLoadNoDOAS = zsCalcSizing.HeatLoadNoDOASSeq(TimeStepIndex);
1523 768 : zsCalcSizing.TimeStepNumAtHeatNoDOASMax = TimeStepIndex;
1524 : }
1525 46274 : if (zsCalcSizing.HeatLatentLoadNoDOASSeq(TimeStepIndex) > zsCalcSizing.DesLatentHeatLoadNoDOAS) {
1526 48 : zsCalcSizing.DesLatentHeatLoadNoDOAS = zsCalcSizing.HeatLatentLoadNoDOASSeq(TimeStepIndex);
1527 48 : zsCalcSizing.TimeStepNumAtLatentHeatNoDOASMax = TimeStepIndex;
1528 : }
1529 46274 : if (zsCalcSizing.CoolLoadNoDOASSeq(TimeStepIndex) > zsCalcSizing.DesCoolLoadNoDOAS) {
1530 386 : zsCalcSizing.DesCoolLoadNoDOAS = zsCalcSizing.CoolLoadNoDOASSeq(TimeStepIndex);
1531 386 : zsCalcSizing.TimeStepNumAtCoolNoDOASMax = TimeStepIndex;
1532 : }
1533 46274 : if (zsCalcSizing.CoolLatentLoadNoDOASSeq(TimeStepIndex) > zsCalcSizing.DesLatentCoolLoadNoDOAS) {
1534 148 : zsCalcSizing.DesLatentCoolLoadNoDOAS = zsCalcSizing.CoolLatentLoadNoDOASSeq(TimeStepIndex);
1535 148 : zsCalcSizing.TimeStepNumAtLatentCoolNoDOASMax = TimeStepIndex;
1536 : }
1537 : }
1538 386 : if (zsCalcSizing.DesHeatMassFlow > 0.0) {
1539 89 : zsCalcSizing.DesHeatVolFlow = zsCalcSizing.DesHeatMassFlow / zsCalcSizing.DesHeatDens;
1540 89 : Real64 OAFrac = zsCalcSizing.MinOA / max(zsCalcSizing.DesHeatVolFlow, HVAC::SmallMassFlow);
1541 89 : OAFrac = min(1.0, max(0.0, OAFrac));
1542 89 : int TimeStepAtPeak = zsCalcSizing.TimeStepNumAtHeatMax;
1543 89 : zsCalcSizing.DesHeatCoilInTemp = OAFrac * desDayWeath.Temp(TimeStepAtPeak) + (1.0 - OAFrac) * zsCalcSizing.ZoneTempAtHeatPeak;
1544 89 : zsCalcSizing.DesHeatCoilInHumRat = OAFrac * desDayWeath.HumRat(TimeStepAtPeak) + (1.0 - OAFrac) * zsCalcSizing.ZoneHumRatAtHeatPeak;
1545 : }
1546 386 : if (zsCalcSizing.zoneLatentSizing && zsCalcSizing.DesLatentHeatMassFlow > 0.0) {
1547 13 : zsCalcSizing.DesLatentHeatVolFlow = zsCalcSizing.DesLatentHeatMassFlow / stdRhoAir;
1548 13 : Real64 OAFrac = zsCalcSizing.MinOA / max(zsCalcSizing.DesHeatVolFlow, HVAC::SmallMassFlow);
1549 13 : OAFrac = min(1.0, max(0.0, OAFrac));
1550 13 : int TimeStepAtPeak = zsCalcSizing.TimeStepNumAtLatentHeatMax;
1551 13 : zsCalcSizing.DesLatentHeatCoilInTemp = OAFrac * desDayWeath.Temp(TimeStepAtPeak) + (1.0 - OAFrac) * zsCalcSizing.ZoneTempAtHeatPeak;
1552 13 : zsCalcSizing.DesLatentHeatCoilInHumRat = OAFrac * desDayWeath.HumRat(TimeStepAtPeak) + (1.0 - OAFrac) * zsCalcSizing.ZoneHumRatAtHeatPeak;
1553 : }
1554 : // save the sequence values at the cooling peak
1555 46660 : for (int TimeStepIndex = 1; TimeStepIndex <= numTimeStepInDay; ++TimeStepIndex) {
1556 46274 : if (zsCalcSizing.CoolLoadSeq(TimeStepIndex) > zsCalcSizing.DesCoolLoad) {
1557 3113 : zsCalcSizing.DesCoolLoad = zsCalcSizing.CoolLoadSeq(TimeStepIndex);
1558 3113 : zsCalcSizing.DesCoolMassFlow = zsCalcSizing.CoolFlowSeq(TimeStepIndex);
1559 3113 : zsCalcSizing.ZoneTempAtCoolPeak = zsCalcSizing.CoolZoneTempSeq(TimeStepIndex);
1560 3113 : zsCalcSizing.OutTempAtCoolPeak = zsCalcSizing.CoolOutTempSeq(TimeStepIndex);
1561 3113 : zsCalcSizing.ZoneRetTempAtCoolPeak = zsCalcSizing.CoolZoneRetTempSeq(TimeStepIndex);
1562 3113 : zsCalcSizing.ZoneHumRatAtCoolPeak = zsCalcSizing.CoolZoneHumRatSeq(TimeStepIndex);
1563 3113 : zsCalcSizing.OutHumRatAtCoolPeak = zsCalcSizing.CoolOutHumRatSeq(TimeStepIndex);
1564 3113 : zsCalcSizing.TimeStepNumAtCoolMax = TimeStepIndex;
1565 : }
1566 : }
1567 386 : if (zsCalcSizing.zoneLatentSizing) {
1568 7540 : for (int TimeStepIndex = 1; TimeStepIndex <= numTimeStepInDay; ++TimeStepIndex) {
1569 7488 : if (zsCalcSizing.LatentCoolLoadSeq(TimeStepIndex) > zsCalcSizing.DesLatentCoolLoad) {
1570 148 : zsCalcSizing.DesLatentCoolLoad = zsCalcSizing.LatentCoolLoadSeq(TimeStepIndex);
1571 148 : zsCalcSizing.DesLatentCoolMassFlow = zsCalcSizing.LatentCoolFlowSeq(TimeStepIndex);
1572 148 : zsCalcSizing.ZoneTempAtLatentCoolPeak = zsCalcSizing.CoolZoneTempSeq(TimeStepIndex);
1573 148 : zsCalcSizing.OutTempAtLatentCoolPeak = zsCalcSizing.CoolOutTempSeq(TimeStepIndex);
1574 148 : zsCalcSizing.ZoneHumRatAtLatentCoolPeak = zsCalcSizing.CoolZoneHumRatSeq(TimeStepIndex);
1575 148 : zsCalcSizing.OutHumRatAtLatentCoolPeak = zsCalcSizing.CoolOutHumRatSeq(TimeStepIndex);
1576 148 : zsCalcSizing.ZoneRetTempAtLatentCoolPeak = zsCalcSizing.CoolZoneRetTempSeq(TimeStepIndex);
1577 148 : zsCalcSizing.TimeStepNumAtLatentCoolMax = TimeStepIndex;
1578 : }
1579 : }
1580 : }
1581 386 : if (zsCalcSizing.DesCoolMassFlow > 0.0) {
1582 108 : zsCalcSizing.DesCoolVolFlow = zsCalcSizing.DesCoolMassFlow / zsCalcSizing.DesCoolDens;
1583 108 : Real64 OAFrac = zsCalcSizing.MinOA / max(zsCalcSizing.DesCoolVolFlow, HVAC::SmallMassFlow);
1584 108 : OAFrac = min(1.0, max(0.0, OAFrac));
1585 108 : int TimeStepAtPeak = zsCalcSizing.TimeStepNumAtCoolMax;
1586 108 : zsCalcSizing.DesCoolCoilInTemp = OAFrac * desDayWeath.Temp(TimeStepAtPeak) + (1.0 - OAFrac) * zsCalcSizing.ZoneTempAtCoolPeak;
1587 108 : zsCalcSizing.DesCoolCoilInHumRat = OAFrac * desDayWeath.HumRat(TimeStepAtPeak) + (1.0 - OAFrac) * zsCalcSizing.ZoneHumRatAtCoolPeak;
1588 : }
1589 386 : if (zsCalcSizing.zoneLatentSizing && zsCalcSizing.DesLatentCoolMassFlow > 0.0) {
1590 25 : zsCalcSizing.DesLatentCoolVolFlow = zsCalcSizing.DesLatentCoolMassFlow / stdRhoAir;
1591 25 : Real64 OAFrac = zsCalcSizing.MinOA / max(zsCalcSizing.DesCoolVolFlow, HVAC::SmallMassFlow);
1592 25 : OAFrac = min(1.0, max(0.0, OAFrac));
1593 25 : int TimeStepAtPeak = zsCalcSizing.TimeStepNumAtLatentCoolMax;
1594 25 : zsCalcSizing.DesLatentCoolCoilInTemp = OAFrac * desDayWeath.Temp(TimeStepAtPeak) + (1.0 - OAFrac) * zsCalcSizing.ZoneTempAtCoolPeak;
1595 25 : zsCalcSizing.DesLatentCoolCoilInHumRat = OAFrac * desDayWeath.HumRat(TimeStepAtPeak) + (1.0 - OAFrac) * zsCalcSizing.ZoneHumRatAtCoolPeak;
1596 : }
1597 : // from all the design periods, choose the one needing the most heating and save all its design variables in zsCalcFinalSizing
1598 386 : if (zsCalcSizing.DesHeatVolFlow > zsCalcFinalSizing.DesHeatVolFlow) {
1599 89 : zsCalcFinalSizing.DesHeatVolFlow = zsCalcSizing.DesHeatVolFlow;
1600 89 : zsCalcFinalSizing.DesHeatLoad = zsCalcSizing.DesHeatLoad;
1601 89 : zsCalcFinalSizing.DesHeatMassFlow = zsCalcSizing.DesHeatMassFlow;
1602 89 : zsCalcFinalSizing.HeatDesDay = zsCalcSizing.HeatDesDay;
1603 89 : zsCalcFinalSizing.DesHeatDens = zsCalcSizing.DesHeatDens;
1604 89 : zsCalcFinalSizing.HeatFlowSeq = zsCalcSizing.HeatFlowSeq;
1605 89 : zsCalcFinalSizing.HeatLoadSeq = zsCalcSizing.HeatLoadSeq;
1606 89 : zsCalcFinalSizing.HeatZoneTempSeq = zsCalcSizing.HeatZoneTempSeq;
1607 89 : zsCalcFinalSizing.HeatOutTempSeq = zsCalcSizing.HeatOutTempSeq;
1608 89 : zsCalcFinalSizing.HeatZoneRetTempSeq = zsCalcSizing.HeatZoneRetTempSeq;
1609 89 : zsCalcFinalSizing.HeatZoneHumRatSeq = zsCalcSizing.HeatZoneHumRatSeq;
1610 89 : zsCalcFinalSizing.HeatOutHumRatSeq = zsCalcSizing.HeatOutHumRatSeq;
1611 89 : zsCalcFinalSizing.ZoneTempAtHeatPeak = zsCalcSizing.ZoneTempAtHeatPeak;
1612 89 : zsCalcFinalSizing.OutTempAtHeatPeak = zsCalcSizing.OutTempAtHeatPeak;
1613 89 : zsCalcFinalSizing.ZoneRetTempAtHeatPeak = zsCalcSizing.ZoneRetTempAtHeatPeak;
1614 89 : zsCalcFinalSizing.ZoneHumRatAtHeatPeak = zsCalcSizing.ZoneHumRatAtHeatPeak;
1615 89 : zsCalcFinalSizing.OutHumRatAtHeatPeak = zsCalcSizing.OutHumRatAtHeatPeak;
1616 89 : zsCalcFinalSizing.HeatDDNum = zsCalcSizing.HeatDDNum;
1617 89 : zsCalcFinalSizing.cHeatDDDate = desDayWeath.DateString;
1618 89 : zsCalcFinalSizing.TimeStepNumAtHeatMax = zsCalcSizing.TimeStepNumAtHeatMax;
1619 89 : zsCalcFinalSizing.DesHeatCoilInTemp = zsCalcSizing.DesHeatCoilInTemp;
1620 89 : zsCalcFinalSizing.DesHeatCoilInHumRat = zsCalcSizing.DesHeatCoilInHumRat;
1621 : } else {
1622 297 : zsCalcFinalSizing.DesHeatDens = stdRhoAir;
1623 : // save design heating load when the there is design heating load and the design heating volume flow rate is zero, i.e., when
1624 : // design heating volume flow rate is set to zero due to heating supply air temp less than zone thermostat temperature
1625 297 : if (zsCalcSizing.DesHeatLoad > zsCalcFinalSizing.DesHeatLoad) {
1626 2 : zsCalcFinalSizing.DesHeatLoad = zsCalcSizing.DesHeatLoad;
1627 2 : zsCalcFinalSizing.HeatDesDay = zsCalcSizing.HeatDesDay;
1628 2 : zsCalcFinalSizing.HeatLoadSeq = zsCalcSizing.HeatLoadSeq;
1629 2 : zsCalcFinalSizing.HeatZoneTempSeq = zsCalcSizing.HeatZoneTempSeq;
1630 2 : zsCalcFinalSizing.HeatOutTempSeq = zsCalcSizing.HeatOutTempSeq;
1631 2 : zsCalcFinalSizing.HeatZoneRetTempSeq = zsCalcSizing.HeatZoneRetTempSeq;
1632 2 : zsCalcFinalSizing.HeatZoneHumRatSeq = zsCalcSizing.HeatZoneHumRatSeq;
1633 2 : zsCalcFinalSizing.HeatOutHumRatSeq = zsCalcSizing.HeatOutHumRatSeq;
1634 2 : zsCalcFinalSizing.ZoneTempAtHeatPeak = zsCalcSizing.ZoneTempAtHeatPeak;
1635 2 : zsCalcFinalSizing.OutTempAtHeatPeak = zsCalcSizing.OutTempAtHeatPeak;
1636 2 : zsCalcFinalSizing.ZoneRetTempAtHeatPeak = zsCalcSizing.ZoneRetTempAtHeatPeak;
1637 2 : zsCalcFinalSizing.ZoneHumRatAtHeatPeak = zsCalcSizing.ZoneHumRatAtHeatPeak;
1638 2 : zsCalcFinalSizing.OutHumRatAtHeatPeak = zsCalcSizing.OutHumRatAtHeatPeak;
1639 2 : zsCalcFinalSizing.HeatDDNum = zsCalcSizing.HeatDDNum;
1640 2 : zsCalcFinalSizing.cHeatDDDate = desDayWeath.DateString;
1641 2 : zsCalcFinalSizing.TimeStepNumAtHeatMax = zsCalcSizing.TimeStepNumAtHeatMax;
1642 2 : zsCalcFinalSizing.DesHeatCoilInTemp = zsCalcSizing.DesHeatCoilInTemp;
1643 2 : zsCalcFinalSizing.DesHeatCoilInHumRat = zsCalcSizing.DesHeatCoilInHumRat;
1644 2 : zsCalcFinalSizing.HeatTstatTemp = zsCalcSizing.HeatTstatTemp;
1645 : }
1646 : }
1647 386 : if (zsCalcSizing.zoneLatentSizing) {
1648 : // from all the design periods, choose the one needing the most latent heating and save all its design variables in
1649 : // zsCalcFinalSizing
1650 52 : if (zsCalcSizing.DesLatentHeatVolFlow > zsCalcFinalSizing.DesLatentHeatVolFlow) {
1651 13 : zsCalcFinalSizing.DesLatentHeatVolFlow = zsCalcSizing.DesLatentHeatVolFlow;
1652 13 : zsCalcFinalSizing.DesLatentHeatMassFlow = zsCalcSizing.ZoneHeatLatentMassFlow;
1653 13 : zsCalcFinalSizing.DesLatentHeatLoad = zsCalcSizing.DesLatentHeatLoad;
1654 13 : zsCalcFinalSizing.ZoneTempAtLatentHeatPeak = zsCalcSizing.ZoneTempAtLatentHeatPeak;
1655 13 : zsCalcFinalSizing.ZoneHumRatAtLatentHeatPeak = zsCalcSizing.ZoneHumRatAtLatentHeatPeak;
1656 13 : zsCalcFinalSizing.ZoneRetTempAtLatentHeatPeak = zsCalcSizing.ZoneRetTempAtLatentHeatPeak;
1657 13 : zsCalcFinalSizing.DesLatentHeatCoilInTemp = zsCalcSizing.DesLatentHeatCoilInTemp;
1658 13 : zsCalcFinalSizing.DesLatentHeatCoilInHumRat = zsCalcSizing.DesLatentHeatCoilInHumRat;
1659 13 : zsCalcFinalSizing.LatHeatDesDay = zsCalcSizing.LatHeatDesDay;
1660 13 : zsCalcFinalSizing.cLatentHeatDDDate = desDayWeath.DateString;
1661 13 : zsCalcFinalSizing.LatentHeatDDNum = zsCalcSizing.LatentHeatDDNum;
1662 13 : zsCalcFinalSizing.TimeStepNumAtLatentHeatMax = zsCalcSizing.TimeStepNumAtLatentHeatMax;
1663 13 : zsCalcFinalSizing.LatentHeatLoadSeq = zsCalcSizing.LatentHeatLoadSeq;
1664 13 : zsCalcFinalSizing.LatentHeatFlowSeq = zsCalcSizing.LatentHeatFlowSeq;
1665 : } else {
1666 : // save design latent heating load when the there is design load and the design volume flow rate is zero, i.e., when
1667 : // design latent heating volume flow rate is set to zero due to heating supply air humrat is less than zone humidistat humrat
1668 39 : if (zsCalcSizing.DesLatentHeatLoad > zsCalcFinalSizing.DesLatentHeatLoad) {
1669 0 : zsCalcFinalSizing.DesLatentHeatLoad = zsCalcSizing.DesLatentHeatLoad;
1670 0 : zsCalcFinalSizing.cLatentHeatDDDate = desDayWeath.DateString;
1671 0 : zsCalcFinalSizing.LatentHeatDDNum = zsCalcSizing.LatentHeatDDNum;
1672 0 : zsCalcFinalSizing.TimeStepNumAtLatentHeatMax = zsCalcSizing.TimeStepNumAtLatentHeatMax;
1673 0 : zsCalcFinalSizing.LatentHeatLoadSeq = zsCalcSizing.LatentHeatLoadSeq;
1674 0 : zsCalcFinalSizing.LatentHeatFlowSeq = zsCalcSizing.LatentHeatFlowSeq;
1675 : }
1676 : }
1677 : }
1678 : // select largest load from NoDOAS arrays
1679 386 : if (zsCalcSizing.DesHeatLoadNoDOAS > zsCalcFinalSizing.DesHeatLoadNoDOAS) {
1680 13 : zsCalcFinalSizing.DesHeatLoadNoDOAS = zsCalcSizing.DesHeatLoadNoDOAS;
1681 13 : zsCalcFinalSizing.HeatLoadNoDOASSeq = zsCalcSizing.HeatLoadNoDOASSeq;
1682 13 : zsCalcFinalSizing.HeatNoDOASDDNum = zsCalcSizing.HeatNoDOASDDNum;
1683 13 : zsCalcFinalSizing.HeatNoDOASDesDay = zsCalcSizing.HeatNoDOASDesDay;
1684 13 : zsCalcFinalSizing.TimeStepNumAtHeatNoDOASMax = zsCalcSizing.TimeStepNumAtHeatNoDOASMax;
1685 : }
1686 386 : if (zsCalcSizing.DesLatentHeatLoadNoDOAS > zsCalcFinalSizing.DesLatentHeatLoadNoDOAS) {
1687 13 : zsCalcFinalSizing.DesLatentHeatLoadNoDOAS = zsCalcSizing.DesLatentHeatLoadNoDOAS;
1688 13 : zsCalcFinalSizing.HeatLatentLoadNoDOASSeq = zsCalcSizing.HeatLatentLoadNoDOASSeq;
1689 13 : zsCalcFinalSizing.LatentHeatNoDOASDDNum = zsCalcSizing.LatentHeatNoDOASDDNum;
1690 13 : zsCalcFinalSizing.LatHeatNoDOASDesDay = zsCalcSizing.LatHeatNoDOASDesDay;
1691 13 : zsCalcFinalSizing.TimeStepNumAtLatentHeatNoDOASMax = zsCalcSizing.TimeStepNumAtLatentHeatNoDOASMax;
1692 : }
1693 : // from all the design periods, choose the one needing the most Cooling and save all its design variables in zsCalcFinalSizing
1694 386 : if (zsCalcSizing.DesCoolVolFlow > zsCalcFinalSizing.DesCoolVolFlow) {
1695 102 : zsCalcFinalSizing.DesCoolVolFlow = zsCalcSizing.DesCoolVolFlow;
1696 102 : zsCalcFinalSizing.DesCoolLoad = zsCalcSizing.DesCoolLoad;
1697 102 : zsCalcFinalSizing.DesCoolMassFlow = zsCalcSizing.DesCoolMassFlow;
1698 102 : zsCalcFinalSizing.CoolDesDay = zsCalcSizing.CoolDesDay;
1699 102 : zsCalcFinalSizing.DesCoolDens = zsCalcSizing.DesCoolDens;
1700 102 : zsCalcFinalSizing.CoolFlowSeq = zsCalcSizing.CoolFlowSeq;
1701 102 : zsCalcFinalSizing.CoolLoadSeq = zsCalcSizing.CoolLoadSeq;
1702 102 : zsCalcFinalSizing.CoolZoneTempSeq = zsCalcSizing.CoolZoneTempSeq;
1703 102 : zsCalcFinalSizing.CoolOutTempSeq = zsCalcSizing.CoolOutTempSeq;
1704 102 : zsCalcFinalSizing.CoolZoneRetTempSeq = zsCalcSizing.CoolZoneRetTempSeq;
1705 102 : zsCalcFinalSizing.CoolZoneHumRatSeq = zsCalcSizing.CoolZoneHumRatSeq;
1706 102 : zsCalcFinalSizing.CoolOutHumRatSeq = zsCalcSizing.CoolOutHumRatSeq;
1707 102 : zsCalcFinalSizing.ZoneTempAtCoolPeak = zsCalcSizing.ZoneTempAtCoolPeak;
1708 102 : zsCalcFinalSizing.OutTempAtCoolPeak = zsCalcSizing.OutTempAtCoolPeak;
1709 102 : zsCalcFinalSizing.ZoneRetTempAtCoolPeak = zsCalcSizing.ZoneRetTempAtCoolPeak;
1710 102 : zsCalcFinalSizing.ZoneHumRatAtCoolPeak = zsCalcSizing.ZoneHumRatAtCoolPeak;
1711 102 : zsCalcFinalSizing.OutHumRatAtCoolPeak = zsCalcSizing.OutHumRatAtCoolPeak;
1712 102 : zsCalcFinalSizing.CoolDDNum = zsCalcSizing.CoolDDNum;
1713 102 : zsCalcFinalSizing.cCoolDDDate = desDayWeath.DateString;
1714 102 : zsCalcFinalSizing.TimeStepNumAtCoolMax = zsCalcSizing.TimeStepNumAtCoolMax;
1715 102 : zsCalcFinalSizing.DesCoolCoilInTemp = zsCalcSizing.DesCoolCoilInTemp;
1716 102 : zsCalcFinalSizing.DesCoolCoilInHumRat = zsCalcSizing.DesCoolCoilInHumRat;
1717 : } else {
1718 284 : zsCalcFinalSizing.DesCoolDens = stdRhoAir;
1719 : // save design cooling load when the there is design cooling load and the design cooling volume flow rate is zero, i.e., when
1720 : // design cooling volume flow rate is set to zero due to cooling supply air temp greater than zone thermostat temperature
1721 284 : if (zsCalcSizing.DesCoolLoad > zsCalcFinalSizing.DesCoolLoad) {
1722 0 : zsCalcFinalSizing.DesCoolLoad = zsCalcSizing.DesCoolLoad;
1723 0 : zsCalcFinalSizing.CoolDesDay = zsCalcSizing.CoolDesDay;
1724 0 : zsCalcFinalSizing.CoolLoadSeq = zsCalcSizing.CoolLoadSeq;
1725 0 : zsCalcFinalSizing.CoolZoneTempSeq = zsCalcSizing.CoolZoneTempSeq;
1726 0 : zsCalcFinalSizing.CoolOutTempSeq = zsCalcSizing.CoolOutTempSeq;
1727 0 : zsCalcFinalSizing.CoolZoneRetTempSeq = zsCalcSizing.CoolZoneRetTempSeq;
1728 0 : zsCalcFinalSizing.CoolZoneHumRatSeq = zsCalcSizing.CoolZoneHumRatSeq;
1729 0 : zsCalcFinalSizing.CoolOutHumRatSeq = zsCalcSizing.CoolOutHumRatSeq;
1730 0 : zsCalcFinalSizing.ZoneTempAtCoolPeak = zsCalcSizing.ZoneTempAtCoolPeak;
1731 0 : zsCalcFinalSizing.OutTempAtCoolPeak = zsCalcSizing.OutTempAtCoolPeak;
1732 0 : zsCalcFinalSizing.ZoneRetTempAtCoolPeak = zsCalcSizing.ZoneRetTempAtCoolPeak;
1733 0 : zsCalcFinalSizing.ZoneHumRatAtCoolPeak = zsCalcSizing.ZoneHumRatAtCoolPeak;
1734 0 : zsCalcFinalSizing.OutHumRatAtCoolPeak = zsCalcSizing.OutHumRatAtCoolPeak;
1735 0 : zsCalcFinalSizing.CoolDDNum = zsCalcSizing.CoolDDNum;
1736 0 : zsCalcFinalSizing.cCoolDDDate = desDayWeath.DateString;
1737 0 : zsCalcFinalSizing.TimeStepNumAtCoolMax = zsCalcSizing.TimeStepNumAtCoolMax;
1738 0 : zsCalcFinalSizing.DesCoolCoilInTemp = zsCalcSizing.DesCoolCoilInTemp;
1739 0 : zsCalcFinalSizing.DesCoolCoilInHumRat = zsCalcSizing.DesCoolCoilInHumRat;
1740 0 : zsCalcFinalSizing.CoolTstatTemp = zsCalcSizing.CoolTstatTemp;
1741 : }
1742 : }
1743 386 : if (zsCalcSizing.zoneLatentSizing) {
1744 : // from all the design periods, choose the one needing the most Latent Cooling and save all its design variables in
1745 : // zsCalcFinalSizing
1746 52 : if (zsCalcSizing.DesLatentCoolVolFlow > zsCalcFinalSizing.DesLatentCoolVolFlow) {
1747 20 : zsCalcFinalSizing.DesLatentCoolVolFlow = zsCalcSizing.DesLatentCoolVolFlow;
1748 20 : zsCalcFinalSizing.DesLatentCoolMassFlow = zsCalcSizing.DesLatentCoolMassFlow;
1749 20 : zsCalcFinalSizing.DesLatentCoolLoad = zsCalcSizing.DesLatentCoolLoad;
1750 20 : zsCalcFinalSizing.ZoneTempAtLatentCoolPeak = zsCalcSizing.ZoneTempAtLatentCoolPeak;
1751 20 : zsCalcFinalSizing.ZoneHumRatAtLatentCoolPeak = zsCalcSizing.ZoneHumRatAtLatentCoolPeak;
1752 20 : zsCalcFinalSizing.ZoneRetTempAtLatentCoolPeak = zsCalcSizing.ZoneRetTempAtLatentCoolPeak;
1753 20 : zsCalcFinalSizing.DesLatentCoolCoilInTemp = zsCalcSizing.DesLatentCoolCoilInTemp;
1754 20 : zsCalcFinalSizing.DesLatentCoolCoilInHumRat = zsCalcSizing.DesLatentCoolCoilInHumRat;
1755 20 : zsCalcFinalSizing.LatCoolDesDay = zsCalcSizing.LatCoolDesDay;
1756 20 : zsCalcFinalSizing.cLatentCoolDDDate = desDayWeath.DateString;
1757 20 : zsCalcFinalSizing.LatentCoolDDNum = zsCalcSizing.LatentCoolDDNum;
1758 20 : zsCalcFinalSizing.TimeStepNumAtLatentCoolMax = zsCalcSizing.TimeStepNumAtLatentCoolMax;
1759 20 : zsCalcFinalSizing.LatentCoolLoadSeq = zsCalcSizing.LatentCoolLoadSeq;
1760 20 : zsCalcFinalSizing.LatentCoolFlowSeq = zsCalcSizing.LatentCoolFlowSeq;
1761 : } else {
1762 : // save design latent cooling load when the there is design load and the design volume flow rate is zero, i.e., when
1763 : // design latent cooling volume flow rate is set to zero due to cooling supply air humrat is greater than zone humidistat humrat
1764 32 : if (zsCalcSizing.DesLatentCoolLoad > zsCalcFinalSizing.DesLatentCoolLoad) {
1765 5 : zsCalcFinalSizing.DesLatentCoolLoad = zsCalcSizing.DesLatentCoolLoad;
1766 5 : zsCalcFinalSizing.cLatentCoolDDDate = desDayWeath.DateString;
1767 5 : zsCalcFinalSizing.LatentCoolDDNum = zsCalcSizing.LatentCoolDDNum;
1768 5 : zsCalcFinalSizing.LatCoolDesDay = zsCalcSizing.LatCoolDesDay;
1769 5 : zsCalcFinalSizing.TimeStepNumAtLatentCoolMax = zsCalcSizing.TimeStepNumAtLatentCoolMax;
1770 5 : zsCalcFinalSizing.LatentCoolLoadSeq = zsCalcSizing.LatentCoolLoadSeq;
1771 : }
1772 : }
1773 : }
1774 386 : if (zsCalcSizing.DesCoolLoadNoDOAS > zsCalcFinalSizing.DesCoolLoadNoDOAS) {
1775 13 : zsCalcFinalSizing.DesCoolLoadNoDOAS = zsCalcSizing.DesCoolLoadNoDOAS;
1776 13 : zsCalcFinalSizing.CoolLoadNoDOASSeq = zsCalcSizing.CoolLoadNoDOASSeq;
1777 13 : zsCalcFinalSizing.CoolNoDOASDDNum = zsCalcSizing.CoolNoDOASDDNum;
1778 13 : zsCalcFinalSizing.CoolNoDOASDesDay = zsCalcSizing.CoolNoDOASDesDay;
1779 13 : zsCalcFinalSizing.TimeStepNumAtCoolNoDOASMax = zsCalcSizing.TimeStepNumAtCoolNoDOASMax;
1780 : }
1781 386 : if (zsCalcSizing.DesLatentCoolLoadNoDOAS > zsCalcFinalSizing.DesLatentCoolLoadNoDOAS) {
1782 25 : zsCalcFinalSizing.DesLatentCoolLoadNoDOAS = zsCalcSizing.DesLatentCoolLoadNoDOAS;
1783 25 : zsCalcFinalSizing.CoolLatentLoadNoDOASSeq = zsCalcSizing.CoolLatentLoadNoDOASSeq;
1784 25 : zsCalcFinalSizing.LatentCoolNoDOASDDNum = zsCalcSizing.LatentCoolNoDOASDDNum;
1785 25 : zsCalcFinalSizing.LatCoolNoDOASDesDay = zsCalcSizing.LatCoolNoDOASDesDay;
1786 25 : zsCalcFinalSizing.TimeStepNumAtLatentCoolNoDOASMax = zsCalcSizing.TimeStepNumAtLatentCoolNoDOASMax;
1787 : }
1788 : // save heat peak conditions when there is no design heating load or design heating volume flow rate, i.e., when
1789 : // zone temperature is always greater than the zone heating thermostat temperature
1790 386 : if (zsCalcFinalSizing.DesHeatLoad == 0) {
1791 200 : bool FirstIteration = true; // declare as static to save for next iteration? but needs to be space/zone specific?
1792 22762 : for (int TimeStepIndex = 1; TimeStepIndex <= numTimeStepInDay; ++TimeStepIndex) {
1793 22562 : if ((zsCalcSizing.HeatZoneTempSeq(TimeStepIndex) < zsCalcSizing.ZoneTempAtHeatPeak) || FirstIteration) {
1794 912 : zsCalcSizing.ZoneTempAtHeatPeak = zsCalcSizing.HeatZoneTempSeq(TimeStepIndex);
1795 912 : zsCalcSizing.OutTempAtHeatPeak = zsCalcSizing.HeatOutTempSeq(TimeStepIndex);
1796 912 : zsCalcSizing.ZoneRetTempAtHeatPeak = zsCalcSizing.HeatZoneRetTempSeq(TimeStepIndex);
1797 912 : zsCalcSizing.ZoneHumRatAtHeatPeak = zsCalcSizing.HeatZoneHumRatSeq(TimeStepIndex);
1798 912 : zsCalcSizing.OutHumRatAtHeatPeak = zsCalcSizing.HeatOutHumRatSeq(TimeStepIndex);
1799 912 : zsCalcSizing.TimeStepNumAtHeatMax = TimeStepIndex;
1800 912 : FirstIteration = false;
1801 : }
1802 : }
1803 200 : if (zsCalcSizing.OutTempAtHeatPeak <= zsCalcFinalSizing.OutTempAtHeatPeak) {
1804 144 : zsCalcFinalSizing.HeatDesDay = zsCalcSizing.HeatDesDay;
1805 144 : zsCalcFinalSizing.HeatZoneTempSeq = zsCalcSizing.HeatZoneTempSeq;
1806 144 : zsCalcFinalSizing.HeatOutTempSeq = zsCalcSizing.HeatOutTempSeq;
1807 144 : zsCalcFinalSizing.HeatZoneRetTempSeq = zsCalcSizing.HeatZoneRetTempSeq;
1808 144 : zsCalcFinalSizing.HeatZoneHumRatSeq = zsCalcSizing.HeatZoneHumRatSeq;
1809 144 : zsCalcFinalSizing.HeatOutHumRatSeq = zsCalcSizing.HeatOutHumRatSeq;
1810 144 : zsCalcFinalSizing.ZoneTempAtHeatPeak = zsCalcSizing.ZoneTempAtHeatPeak;
1811 144 : zsCalcFinalSizing.OutTempAtHeatPeak = zsCalcSizing.OutTempAtHeatPeak;
1812 144 : zsCalcFinalSizing.ZoneRetTempAtHeatPeak = zsCalcSizing.ZoneRetTempAtHeatPeak;
1813 144 : zsCalcFinalSizing.ZoneHumRatAtHeatPeak = zsCalcSizing.ZoneHumRatAtHeatPeak;
1814 144 : zsCalcFinalSizing.OutHumRatAtHeatPeak = zsCalcSizing.OutHumRatAtHeatPeak;
1815 144 : zsCalcFinalSizing.HeatDDNum = zsCalcSizing.HeatDDNum;
1816 144 : zsCalcFinalSizing.cHeatDDDate = desDayWeath.DateString;
1817 144 : zsCalcFinalSizing.TimeStepNumAtHeatMax = zsCalcSizing.TimeStepNumAtHeatMax;
1818 144 : zsCalcFinalSizing.DesHeatCoilInTemp = zsCalcSizing.DesHeatCoilInTemp;
1819 144 : zsCalcFinalSizing.DesHeatCoilInHumRat = zsCalcSizing.DesHeatCoilInHumRat;
1820 144 : zsCalcFinalSizing.HeatTstatTemp = zsCalcSizing.HeatTstatTemp;
1821 144 : FirstIteration = false;
1822 : }
1823 : }
1824 386 : if (zsCalcFinalSizing.zoneLatentSizing && zsCalcFinalSizing.DesLatentHeatLoad == 0) {
1825 39 : bool FirstIteration = true;
1826 5655 : for (int TimeStepIndex = 1; TimeStepIndex <= numTimeStepInDay; ++TimeStepIndex) {
1827 5616 : if (zsCalcSizing.HeatZoneTempSeq(TimeStepIndex) < zsCalcSizing.ZoneTempAtLatentHeatPeak || FirstIteration) {
1828 39 : zsCalcSizing.ZoneTempAtLatentHeatPeak = zsCalcSizing.HeatZoneTempSeq(TimeStepIndex);
1829 39 : zsCalcSizing.OutTempAtLatentHeatPeak = zsCalcSizing.HeatOutTempSeq(TimeStepIndex);
1830 39 : zsCalcSizing.OutHumRatAtLatentHeatPeak = zsCalcSizing.HeatOutHumRatSeq(TimeStepIndex);
1831 : }
1832 5616 : if (zsCalcSizing.HeatOutTempSeq(TimeStepIndex) <= zsCalcFinalSizing.OutTempAtLatentHeatPeak) {
1833 3744 : zsCalcFinalSizing.OutTempAtLatentHeatPeak = zsCalcSizing.HeatOutTempSeq(TimeStepIndex);
1834 3744 : zsCalcFinalSizing.OutHumRatAtLatentHeatPeak = zsCalcSizing.HeatOutHumRatSeq(TimeStepIndex);
1835 3744 : zsCalcFinalSizing.LatHeatDesDay = zsCalcSizing.LatHeatDesDay;
1836 3744 : zsCalcFinalSizing.LatentHeatDDNum = zsCalcSizing.LatentHeatDDNum;
1837 3744 : zsCalcFinalSizing.cLatentHeatDDDate = desDayWeath.DateString;
1838 3744 : zsCalcFinalSizing.TimeStepNumAtLatentHeatMax = zsCalcSizing.TimeStepNumAtLatentHeatMax;
1839 : }
1840 5616 : FirstIteration = false;
1841 : }
1842 : }
1843 : // save cool peak conditions when there is no design cooling load or design cooling volume flow rate, i.e., when
1844 : // zone temperature is always less than the zone cooling thermostat temperature
1845 386 : if (zsCalcFinalSizing.DesCoolLoad == 0) {
1846 194 : bool FirstIteration = true;
1847 25156 : for (int TimeStepIndex = 1; TimeStepIndex <= numTimeStepInDay; ++TimeStepIndex) {
1848 24962 : if ((zsCalcSizing.CoolZoneTempSeq(TimeStepIndex) > zsCalcSizing.ZoneTempAtCoolPeak) || FirstIteration) {
1849 1286 : zsCalcSizing.ZoneTempAtCoolPeak = zsCalcSizing.CoolZoneTempSeq(TimeStepIndex);
1850 1286 : zsCalcSizing.OutTempAtCoolPeak = zsCalcSizing.CoolOutTempSeq(TimeStepIndex);
1851 1286 : zsCalcSizing.ZoneRetTempAtCoolPeak = zsCalcSizing.CoolZoneRetTempSeq(TimeStepIndex);
1852 1286 : zsCalcSizing.ZoneHumRatAtCoolPeak = zsCalcSizing.CoolZoneHumRatSeq(TimeStepIndex);
1853 1286 : zsCalcSizing.OutHumRatAtCoolPeak = zsCalcSizing.CoolOutHumRatSeq(TimeStepIndex);
1854 1286 : zsCalcSizing.TimeStepNumAtCoolMax = TimeStepIndex;
1855 1286 : FirstIteration = false;
1856 : }
1857 : }
1858 194 : if (zsCalcSizing.OutTempAtCoolPeak > zsCalcFinalSizing.OutTempAtCoolPeak) {
1859 12 : zsCalcFinalSizing.CoolDesDay = zsCalcSizing.CoolDesDay;
1860 12 : zsCalcFinalSizing.CoolZoneTempSeq = zsCalcSizing.CoolZoneTempSeq;
1861 12 : zsCalcFinalSizing.CoolOutTempSeq = zsCalcSizing.CoolOutTempSeq;
1862 12 : zsCalcFinalSizing.CoolZoneRetTempSeq = zsCalcSizing.CoolZoneRetTempSeq;
1863 12 : zsCalcFinalSizing.CoolZoneHumRatSeq = zsCalcSizing.CoolZoneHumRatSeq;
1864 12 : zsCalcFinalSizing.CoolOutHumRatSeq = zsCalcSizing.CoolOutHumRatSeq;
1865 12 : zsCalcFinalSizing.ZoneTempAtCoolPeak = zsCalcSizing.ZoneTempAtCoolPeak;
1866 12 : zsCalcFinalSizing.OutTempAtCoolPeak = zsCalcSizing.OutTempAtCoolPeak;
1867 12 : zsCalcFinalSizing.ZoneRetTempAtCoolPeak = zsCalcSizing.ZoneRetTempAtCoolPeak;
1868 12 : zsCalcFinalSizing.ZoneHumRatAtCoolPeak = zsCalcSizing.ZoneHumRatAtCoolPeak;
1869 12 : zsCalcFinalSizing.OutHumRatAtCoolPeak = zsCalcSizing.OutHumRatAtCoolPeak;
1870 12 : zsCalcFinalSizing.CoolDDNum = zsCalcSizing.CoolDDNum;
1871 12 : zsCalcFinalSizing.cCoolDDDate = desDayWeath.DateString;
1872 12 : zsCalcFinalSizing.TimeStepNumAtCoolMax = zsCalcSizing.TimeStepNumAtCoolMax;
1873 12 : zsCalcFinalSizing.DesCoolCoilInTemp = zsCalcSizing.DesCoolCoilInTemp;
1874 12 : zsCalcFinalSizing.DesCoolCoilInHumRat = zsCalcSizing.DesCoolCoilInHumRat;
1875 12 : zsCalcFinalSizing.CoolTstatTemp = zsCalcSizing.CoolTstatTemp;
1876 : }
1877 : }
1878 386 : if (zsCalcFinalSizing.zoneLatentSizing && zsCalcFinalSizing.DesLatentCoolLoad == 0) {
1879 15 : bool FirstIteration = true;
1880 2175 : for (int TimeStepIndex = 1; TimeStepIndex <= numTimeStepInDay; ++TimeStepIndex) {
1881 2160 : if (zsCalcSizing.CoolZoneTempSeq(TimeStepIndex) > zsCalcSizing.ZoneTempAtLatentCoolPeak || FirstIteration) {
1882 15 : zsCalcSizing.ZoneTempAtLatentCoolPeak = zsCalcSizing.CoolZoneTempSeq(TimeStepIndex);
1883 15 : zsCalcSizing.OutTempAtLatentCoolPeak = zsCalcSizing.CoolOutTempSeq(TimeStepIndex);
1884 15 : zsCalcSizing.OutHumRatAtLatentCoolPeak = zsCalcSizing.CoolOutHumRatSeq(TimeStepIndex);
1885 15 : FirstIteration = false;
1886 : }
1887 2160 : if (zsCalcSizing.OutTempAtLatentCoolPeak >= zsCalcFinalSizing.OutTempAtLatentCoolPeak) {
1888 2016 : zsCalcFinalSizing.LatCoolDesDay = zsCalcSizing.LatCoolDesDay;
1889 2016 : zsCalcFinalSizing.LatentCoolDDNum = zsCalcSizing.LatentCoolDDNum;
1890 2016 : zsCalcFinalSizing.cLatentCoolDDDate = desDayWeath.DateString;
1891 2016 : zsCalcFinalSizing.TimeStepNumAtLatentCoolMax = zsCalcSizing.TimeStepNumAtLatentCoolMax;
1892 : }
1893 : }
1894 : }
1895 386 : }
1896 :
1897 7 : void updateZoneSizingEndZoneSizingCalc1(EnergyPlusData &state, int const zoneNum)
1898 : {
1899 : // Set or override finalzonesizing data for non-coincident sizing
1900 7 : auto &zoneCFS = state.dataSize->CalcFinalZoneSizing(zoneNum);
1901 7 : if (zoneCFS.spaceConcurrence == DataSizing::SizingConcurrence::Coincident) return;
1902 : // Zero out simple sums
1903 2 : zoneCFS.DesHeatVolFlow = 0.0;
1904 2 : zoneCFS.DesHeatLoad = 0.0;
1905 2 : zoneCFS.DesHeatMassFlow = 0.0;
1906 2 : zoneCFS.DesHeatLoadNoDOAS = 0.0;
1907 2 : zoneCFS.DesCoolVolFlow = 0.0;
1908 2 : zoneCFS.DesCoolLoad = 0.0;
1909 2 : zoneCFS.DesCoolMassFlow = 0.0;
1910 2 : zoneCFS.DesCoolLoadNoDOAS = 0.0;
1911 :
1912 : // Zero out weighted averages
1913 2 : zoneCFS.DesHeatDens = 0.0;
1914 2 : zoneCFS.ZoneTempAtHeatPeak = 0.0;
1915 2 : zoneCFS.OutTempAtHeatPeak = 0.0;
1916 2 : zoneCFS.ZoneRetTempAtHeatPeak = 0.0;
1917 2 : zoneCFS.ZoneHumRatAtHeatPeak = 0.0;
1918 2 : zoneCFS.OutHumRatAtHeatPeak = 0.0;
1919 2 : zoneCFS.DesHeatCoilInTemp = 0.0;
1920 2 : zoneCFS.DesHeatCoilInHumRat = 0.0;
1921 2 : zoneCFS.DesCoolDens = 0.0;
1922 2 : zoneCFS.ZoneTempAtCoolPeak = 0.0;
1923 2 : zoneCFS.OutTempAtCoolPeak = 0.0;
1924 2 : zoneCFS.ZoneRetTempAtCoolPeak = 0.0;
1925 2 : zoneCFS.ZoneHumRatAtCoolPeak = 0.0;
1926 2 : zoneCFS.OutHumRatAtCoolPeak = 0.0;
1927 2 : zoneCFS.DesCoolCoilInTemp = 0.0;
1928 2 : zoneCFS.DesCoolCoilInHumRat = 0.0;
1929 :
1930 : // Zero out time-series sums and averages
1931 290 : for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) {
1932 288 : zoneCFS.HeatFlowSeq(ts) = 0.0;
1933 288 : zoneCFS.HeatLoadSeq(ts) = 0.0;
1934 288 : zoneCFS.HeatZoneTempSeq(ts) = 0.0;
1935 288 : zoneCFS.HeatOutTempSeq(ts) = 0.0;
1936 288 : zoneCFS.HeatZoneRetTempSeq(ts) = 0.0;
1937 288 : zoneCFS.HeatZoneHumRatSeq(ts) = 0.0;
1938 288 : zoneCFS.HeatOutHumRatSeq(ts) = 0.0;
1939 288 : zoneCFS.HeatLoadNoDOASSeq(ts) = 0.0;
1940 288 : zoneCFS.CoolFlowSeq(ts) = 0.0;
1941 288 : zoneCFS.CoolLoadSeq(ts) = 0.0;
1942 288 : zoneCFS.CoolZoneTempSeq(ts) = 0.0;
1943 288 : zoneCFS.CoolOutTempSeq(ts) = 0.0;
1944 288 : zoneCFS.CoolZoneRetTempSeq(ts) = 0.0;
1945 288 : zoneCFS.CoolZoneHumRatSeq(ts) = 0.0;
1946 288 : zoneCFS.CoolOutHumRatSeq(ts) = 0.0;
1947 288 : zoneCFS.CoolLoadNoDOASSeq(ts) = 0.0;
1948 : }
1949 :
1950 2 : if (zoneCFS.zoneLatentSizing) {
1951 : // Zero out latent simple sums
1952 0 : zoneCFS.DesLatentHeatVolFlow = 0.0;
1953 0 : zoneCFS.DesLatentHeatMassFlow = 0.0;
1954 0 : zoneCFS.DesLatentHeatLoad = 0.0;
1955 0 : zoneCFS.DesLatentHeatLoadNoDOAS = 0.0;
1956 0 : zoneCFS.DesLatentCoolVolFlow = 0.0;
1957 0 : zoneCFS.DesLatentCoolMassFlow = 0.0;
1958 0 : zoneCFS.DesLatentCoolLoad = 0.0;
1959 0 : zoneCFS.DesLatentCoolLoadNoDOAS = 0.0;
1960 :
1961 : // Zero out latent weighted averages
1962 0 : zoneCFS.ZoneTempAtLatentHeatPeak = 0.0;
1963 0 : zoneCFS.ZoneHumRatAtLatentHeatPeak = 0.0;
1964 0 : zoneCFS.ZoneRetTempAtLatentHeatPeak = 0.0;
1965 0 : zoneCFS.DesLatentHeatCoilInTemp = 0.0;
1966 0 : zoneCFS.DesLatentHeatCoilInHumRat = 0.0;
1967 0 : zoneCFS.ZoneTempAtLatentCoolPeak = 0.0;
1968 0 : zoneCFS.ZoneHumRatAtLatentCoolPeak = 0.0;
1969 0 : zoneCFS.ZoneRetTempAtLatentCoolPeak = 0.0;
1970 0 : zoneCFS.DesLatentCoolCoilInTemp = 0.0;
1971 0 : zoneCFS.DesLatentCoolCoilInHumRat = 0.0;
1972 :
1973 : // Zero out latent time-series sums
1974 0 : for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) {
1975 0 : zoneCFS.LatentHeatLoadSeq(ts) = 0.0;
1976 0 : zoneCFS.LatentHeatFlowSeq(ts) = 0.0;
1977 0 : zoneCFS.HeatLatentLoadNoDOASSeq(ts) = 0.0;
1978 0 : zoneCFS.LatentCoolLoadSeq(ts) = 0.0;
1979 0 : zoneCFS.LatentCoolFlowSeq(ts) = 0.0;
1980 0 : zoneCFS.CoolLatentLoadNoDOASSeq(ts) = 0.0;
1981 : }
1982 : }
1983 :
1984 : // Other - Initialize to first space values (clear later if not all the same)
1985 2 : int firstSpace = state.dataHeatBal->Zone(zoneNum).spaceIndexes[0];
1986 2 : auto const &firstSpaceCFS = state.dataSize->CalcFinalSpaceSizing(firstSpace);
1987 2 : zoneCFS.HeatDesDay = firstSpaceCFS.HeatDesDay;
1988 2 : zoneCFS.HeatDDNum = firstSpaceCFS.HeatDDNum;
1989 2 : zoneCFS.cHeatDDDate = firstSpaceCFS.cHeatDDDate;
1990 2 : zoneCFS.TimeStepNumAtHeatMax = firstSpaceCFS.TimeStepNumAtHeatMax;
1991 2 : zoneCFS.HeatNoDOASDDNum = firstSpaceCFS.HeatNoDOASDDNum;
1992 2 : zoneCFS.HeatNoDOASDesDay = firstSpaceCFS.HeatNoDOASDesDay;
1993 2 : zoneCFS.TimeStepNumAtHeatNoDOASMax = firstSpaceCFS.TimeStepNumAtHeatNoDOASMax;
1994 2 : zoneCFS.CoolDesDay = firstSpaceCFS.CoolDesDay;
1995 2 : zoneCFS.CoolDDNum = firstSpaceCFS.CoolDDNum;
1996 2 : zoneCFS.cCoolDDDate = firstSpaceCFS.cCoolDDDate;
1997 2 : zoneCFS.TimeStepNumAtCoolMax = firstSpaceCFS.TimeStepNumAtCoolMax;
1998 2 : if (zoneCFS.zoneLatentSizing) {
1999 0 : zoneCFS.LatHeatDesDay = firstSpaceCFS.LatHeatDesDay;
2000 0 : zoneCFS.cLatentHeatDDDate = firstSpaceCFS.cLatentHeatDDDate;
2001 0 : zoneCFS.LatentHeatDDNum = firstSpaceCFS.LatentHeatDDNum;
2002 0 : zoneCFS.TimeStepNumAtLatentHeatMax = firstSpaceCFS.TimeStepNumAtLatentHeatMax;
2003 0 : zoneCFS.LatentHeatNoDOASDDNum = firstSpaceCFS.LatentHeatNoDOASDDNum;
2004 0 : zoneCFS.LatHeatNoDOASDesDay = firstSpaceCFS.LatHeatNoDOASDesDay;
2005 0 : zoneCFS.TimeStepNumAtLatentHeatNoDOASMax = firstSpaceCFS.TimeStepNumAtLatentHeatNoDOASMax;
2006 0 : zoneCFS.LatCoolDesDay = firstSpaceCFS.LatCoolDesDay;
2007 0 : zoneCFS.cLatentCoolDDDate = firstSpaceCFS.cLatentCoolDDDate;
2008 0 : zoneCFS.LatentCoolDDNum = firstSpaceCFS.LatentCoolDDNum;
2009 0 : zoneCFS.TimeStepNumAtLatentCoolMax = firstSpaceCFS.TimeStepNumAtLatentCoolMax;
2010 0 : zoneCFS.CoolNoDOASDDNum = firstSpaceCFS.CoolNoDOASDDNum;
2011 0 : zoneCFS.CoolNoDOASDesDay = firstSpaceCFS.CoolNoDOASDesDay;
2012 0 : zoneCFS.TimeStepNumAtCoolNoDOASMax = firstSpaceCFS.TimeStepNumAtCoolNoDOASMax;
2013 0 : zoneCFS.LatentCoolNoDOASDDNum = firstSpaceCFS.LatentCoolNoDOASDDNum;
2014 0 : zoneCFS.LatCoolNoDOASDesDay = firstSpaceCFS.LatCoolNoDOASDesDay;
2015 0 : zoneCFS.TimeStepNumAtLatentCoolNoDOASMax = firstSpaceCFS.TimeStepNumAtLatentCoolNoDOASMax;
2016 : }
2017 :
2018 2 : int numSpaces = 0; // Track this for averages later
2019 8 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
2020 6 : auto &spaceCFS = state.dataSize->CalcFinalSpaceSizing(spaceNum);
2021 6 : ++numSpaces;
2022 :
2023 : // Simple sums
2024 6 : zoneCFS.DesHeatVolFlow += spaceCFS.DesHeatVolFlow;
2025 6 : zoneCFS.DesHeatLoad += spaceCFS.DesHeatLoad;
2026 6 : zoneCFS.DesHeatMassFlow += spaceCFS.DesHeatMassFlow;
2027 6 : zoneCFS.DesHeatLoadNoDOAS += spaceCFS.DesHeatLoadNoDOAS;
2028 6 : zoneCFS.DesCoolVolFlow += spaceCFS.DesCoolVolFlow;
2029 6 : zoneCFS.DesCoolLoad += spaceCFS.DesCoolLoad;
2030 6 : zoneCFS.DesCoolMassFlow += spaceCFS.DesCoolMassFlow;
2031 6 : zoneCFS.DesCoolLoadNoDOAS += spaceCFS.DesCoolLoadNoDOAS;
2032 :
2033 : // Weighted averages
2034 6 : zoneCFS.DesHeatDens += spaceCFS.DesHeatDens * spaceCFS.DesHeatMassFlow;
2035 6 : zoneCFS.ZoneTempAtHeatPeak += spaceCFS.ZoneTempAtHeatPeak * spaceCFS.DesHeatMassFlow;
2036 6 : zoneCFS.OutTempAtHeatPeak += spaceCFS.OutTempAtHeatPeak * spaceCFS.DesHeatMassFlow;
2037 6 : zoneCFS.ZoneRetTempAtHeatPeak += spaceCFS.ZoneRetTempAtHeatPeak * spaceCFS.DesHeatMassFlow;
2038 6 : zoneCFS.ZoneHumRatAtHeatPeak += spaceCFS.ZoneHumRatAtHeatPeak * spaceCFS.DesHeatMassFlow;
2039 6 : zoneCFS.OutHumRatAtHeatPeak += spaceCFS.OutHumRatAtHeatPeak * spaceCFS.DesHeatMassFlow;
2040 6 : zoneCFS.DesHeatCoilInTemp += spaceCFS.DesHeatCoilInTemp * spaceCFS.DesHeatMassFlow;
2041 6 : zoneCFS.DesHeatCoilInHumRat += spaceCFS.DesHeatCoilInHumRat * spaceCFS.DesHeatMassFlow;
2042 6 : zoneCFS.DesCoolDens += spaceCFS.DesCoolDens * spaceCFS.DesCoolMassFlow;
2043 6 : zoneCFS.ZoneTempAtCoolPeak += spaceCFS.ZoneTempAtCoolPeak * spaceCFS.DesCoolMassFlow;
2044 6 : zoneCFS.OutTempAtCoolPeak += spaceCFS.OutTempAtCoolPeak * spaceCFS.DesCoolMassFlow;
2045 6 : zoneCFS.ZoneRetTempAtCoolPeak += spaceCFS.ZoneRetTempAtCoolPeak * spaceCFS.DesCoolMassFlow;
2046 6 : zoneCFS.ZoneHumRatAtCoolPeak += spaceCFS.ZoneHumRatAtCoolPeak * spaceCFS.DesCoolMassFlow;
2047 6 : zoneCFS.OutHumRatAtCoolPeak += spaceCFS.OutHumRatAtCoolPeak * spaceCFS.DesCoolMassFlow;
2048 6 : zoneCFS.DesCoolCoilInTemp += spaceCFS.DesCoolCoilInTemp * spaceCFS.DesCoolMassFlow;
2049 6 : zoneCFS.DesCoolCoilInHumRat += spaceCFS.DesCoolCoilInHumRat * spaceCFS.DesCoolMassFlow;
2050 :
2051 870 : for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) {
2052 : // Time-series sums
2053 864 : zoneCFS.HeatFlowSeq(ts) += spaceCFS.HeatFlowSeq(ts);
2054 864 : zoneCFS.HeatLoadSeq(ts) += spaceCFS.HeatLoadSeq(ts);
2055 864 : zoneCFS.HeatLoadNoDOASSeq(ts) += spaceCFS.HeatLoadNoDOASSeq(ts);
2056 864 : zoneCFS.CoolFlowSeq(ts) += spaceCFS.CoolFlowSeq(ts);
2057 864 : zoneCFS.CoolLoadSeq(ts) += spaceCFS.CoolLoadSeq(ts);
2058 864 : zoneCFS.CoolLoadNoDOASSeq(ts) += spaceCFS.CoolLoadNoDOASSeq(ts);
2059 :
2060 : // Time-series weighted averages
2061 864 : zoneCFS.HeatZoneTempSeq(ts) += spaceCFS.HeatZoneTempSeq(ts) * spaceCFS.HeatFlowSeq(ts);
2062 864 : zoneCFS.HeatOutTempSeq(ts) += spaceCFS.HeatOutTempSeq(ts) * spaceCFS.HeatFlowSeq(ts);
2063 864 : zoneCFS.HeatZoneRetTempSeq(ts) += spaceCFS.HeatZoneRetTempSeq(ts) * spaceCFS.HeatFlowSeq(ts);
2064 864 : zoneCFS.HeatZoneHumRatSeq(ts) += spaceCFS.HeatZoneHumRatSeq(ts) * spaceCFS.HeatFlowSeq(ts);
2065 864 : zoneCFS.HeatOutHumRatSeq(ts) += spaceCFS.HeatOutHumRatSeq(ts) * spaceCFS.HeatFlowSeq(ts);
2066 864 : zoneCFS.CoolZoneTempSeq(ts) += spaceCFS.CoolZoneTempSeq(ts) * spaceCFS.CoolFlowSeq(ts);
2067 864 : zoneCFS.CoolOutTempSeq(ts) += spaceCFS.CoolOutTempSeq(ts) * spaceCFS.CoolFlowSeq(ts);
2068 864 : zoneCFS.CoolZoneRetTempSeq(ts) += spaceCFS.CoolZoneRetTempSeq(ts) * spaceCFS.CoolFlowSeq(ts);
2069 864 : zoneCFS.CoolZoneHumRatSeq(ts) += spaceCFS.CoolZoneHumRatSeq(ts) * spaceCFS.CoolFlowSeq(ts);
2070 864 : zoneCFS.CoolOutHumRatSeq(ts) += spaceCFS.CoolOutHumRatSeq(ts) * spaceCFS.CoolFlowSeq(ts);
2071 : }
2072 :
2073 : // Other
2074 6 : if ((zoneCFS.HeatDDNum != 0) && (zoneCFS.HeatDDNum != spaceCFS.HeatDDNum)) {
2075 0 : zoneCFS.HeatDesDay = "N/A";
2076 0 : zoneCFS.HeatDDNum = 0;
2077 0 : zoneCFS.cHeatDDDate = "";
2078 : }
2079 6 : if ((zoneCFS.HeatNoDOASDDNum != 0) && (zoneCFS.HeatNoDOASDDNum != spaceCFS.HeatNoDOASDDNum)) {
2080 0 : zoneCFS.HeatNoDOASDDNum = 0;
2081 0 : zoneCFS.HeatNoDOASDesDay = "N/A";
2082 : }
2083 6 : if ((zoneCFS.CoolDDNum != 0) && (zoneCFS.CoolDDNum != spaceCFS.CoolDDNum)) {
2084 1 : zoneCFS.CoolDesDay = "N/A";
2085 1 : zoneCFS.CoolDDNum = 0;
2086 1 : zoneCFS.cCoolDDDate = "";
2087 : }
2088 6 : if ((zoneCFS.CoolNoDOASDDNum != 0) && (zoneCFS.CoolNoDOASDDNum != spaceCFS.CoolNoDOASDDNum)) {
2089 0 : zoneCFS.CoolNoDOASDDNum = 0;
2090 0 : zoneCFS.CoolNoDOASDesDay = "N/A";
2091 : }
2092 :
2093 6 : if (zoneCFS.zoneLatentSizing) {
2094 : // Simple sums
2095 0 : zoneCFS.DesLatentHeatVolFlow += spaceCFS.DesLatentHeatVolFlow;
2096 0 : zoneCFS.DesLatentHeatMassFlow += spaceCFS.ZoneHeatLatentMassFlow;
2097 0 : zoneCFS.DesLatentHeatLoad += spaceCFS.DesLatentHeatLoad;
2098 0 : zoneCFS.DesLatentHeatLoadNoDOAS += spaceCFS.DesLatentHeatLoadNoDOAS;
2099 0 : zoneCFS.DesLatentCoolVolFlow += spaceCFS.DesLatentCoolVolFlow;
2100 0 : zoneCFS.DesLatentCoolMassFlow += spaceCFS.DesLatentCoolMassFlow;
2101 0 : zoneCFS.DesLatentCoolLoad += spaceCFS.DesLatentCoolLoad;
2102 0 : zoneCFS.DesLatentCoolLoadNoDOAS += spaceCFS.DesLatentCoolLoadNoDOAS;
2103 :
2104 : // Weighted averages
2105 0 : zoneCFS.ZoneTempAtLatentHeatPeak += spaceCFS.ZoneTempAtLatentHeatPeak * spaceCFS.ZoneHeatLatentMassFlow;
2106 0 : zoneCFS.ZoneHumRatAtLatentHeatPeak += spaceCFS.ZoneHumRatAtLatentHeatPeak * spaceCFS.ZoneHeatLatentMassFlow;
2107 0 : zoneCFS.ZoneRetTempAtLatentHeatPeak += spaceCFS.ZoneRetTempAtLatentHeatPeak * spaceCFS.ZoneHeatLatentMassFlow;
2108 0 : zoneCFS.DesLatentHeatCoilInTemp += spaceCFS.DesLatentHeatCoilInTemp * spaceCFS.ZoneHeatLatentMassFlow;
2109 0 : zoneCFS.DesLatentHeatCoilInHumRat += spaceCFS.DesLatentHeatCoilInHumRat * spaceCFS.ZoneHeatLatentMassFlow;
2110 0 : zoneCFS.ZoneTempAtLatentCoolPeak += spaceCFS.ZoneTempAtLatentCoolPeak * spaceCFS.DesLatentCoolVolFlow;
2111 0 : zoneCFS.ZoneHumRatAtLatentCoolPeak += spaceCFS.ZoneHumRatAtLatentCoolPeak * spaceCFS.DesLatentCoolVolFlow;
2112 0 : zoneCFS.ZoneRetTempAtLatentCoolPeak += spaceCFS.ZoneRetTempAtLatentCoolPeak * spaceCFS.DesLatentCoolVolFlow;
2113 0 : zoneCFS.DesLatentCoolCoilInTemp += spaceCFS.DesLatentCoolCoilInTemp * spaceCFS.DesLatentCoolVolFlow;
2114 0 : zoneCFS.DesLatentCoolCoilInHumRat += spaceCFS.DesLatentCoolCoilInHumRat * spaceCFS.DesLatentCoolVolFlow;
2115 :
2116 : // Other
2117 0 : if ((zoneCFS.LatentHeatDDNum != 0) && (zoneCFS.LatentHeatDDNum != spaceCFS.LatentHeatDDNum)) {
2118 0 : zoneCFS.LatHeatDesDay = "N/A";
2119 0 : zoneCFS.cLatentHeatDDDate = "";
2120 0 : zoneCFS.LatentHeatDDNum = 0;
2121 : }
2122 0 : if ((zoneCFS.LatentHeatNoDOASDDNum != 0) && (zoneCFS.LatentHeatNoDOASDDNum != spaceCFS.LatentHeatNoDOASDDNum)) {
2123 0 : zoneCFS.LatentHeatNoDOASDDNum = 0;
2124 0 : zoneCFS.LatHeatNoDOASDesDay = "N/A";
2125 : }
2126 0 : if ((zoneCFS.LatentCoolDDNum != 0) && (zoneCFS.LatentCoolDDNum != spaceCFS.LatentCoolDDNum)) {
2127 0 : zoneCFS.LatCoolDesDay = "N/A";
2128 0 : zoneCFS.cLatentCoolDDDate = "";
2129 0 : zoneCFS.LatentCoolDDNum = 0;
2130 : }
2131 0 : if ((zoneCFS.LatentCoolNoDOASDDNum != 0) && (zoneCFS.LatentCoolNoDOASDDNum != spaceCFS.LatentCoolNoDOASDDNum)) {
2132 0 : zoneCFS.LatentCoolNoDOASDDNum = 0;
2133 0 : zoneCFS.LatCoolNoDOASDesDay = "N/A";
2134 : }
2135 :
2136 : // Time-series sums
2137 0 : for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) {
2138 0 : zoneCFS.LatentHeatLoadSeq(ts) += spaceCFS.LatentHeatLoadSeq(ts);
2139 0 : zoneCFS.LatentHeatFlowSeq(ts) += spaceCFS.LatentHeatFlowSeq(ts);
2140 0 : zoneCFS.HeatLatentLoadNoDOASSeq(ts) += spaceCFS.HeatLatentLoadNoDOASSeq(ts);
2141 0 : zoneCFS.LatentCoolLoadSeq(ts) += spaceCFS.LatentCoolLoadSeq(ts);
2142 0 : zoneCFS.LatentCoolFlowSeq(ts) += spaceCFS.LatentCoolFlowSeq(ts);
2143 0 : zoneCFS.CoolLatentLoadNoDOASSeq(ts) += spaceCFS.CoolLatentLoadNoDOASSeq(ts);
2144 : }
2145 : }
2146 : }
2147 :
2148 : // Compute weighted averages
2149 2 : if (zoneCFS.DesHeatMassFlow > 0) {
2150 0 : zoneCFS.DesHeatDens /= zoneCFS.DesHeatMassFlow;
2151 0 : zoneCFS.ZoneTempAtHeatPeak /= zoneCFS.DesHeatMassFlow;
2152 0 : zoneCFS.OutTempAtHeatPeak /= zoneCFS.DesHeatMassFlow;
2153 0 : zoneCFS.ZoneRetTempAtHeatPeak /= zoneCFS.DesHeatMassFlow;
2154 0 : zoneCFS.ZoneHumRatAtHeatPeak /= zoneCFS.DesHeatMassFlow;
2155 0 : zoneCFS.OutHumRatAtHeatPeak /= zoneCFS.DesHeatMassFlow;
2156 0 : zoneCFS.DesHeatCoilInTemp /= zoneCFS.DesHeatMassFlow;
2157 0 : zoneCFS.DesHeatCoilInHumRat /= zoneCFS.DesHeatMassFlow;
2158 : }
2159 2 : if (zoneCFS.DesCoolMassFlow > 0) {
2160 2 : zoneCFS.DesCoolDens /= zoneCFS.DesCoolMassFlow;
2161 2 : zoneCFS.ZoneTempAtCoolPeak /= zoneCFS.DesCoolMassFlow;
2162 2 : zoneCFS.OutTempAtCoolPeak /= zoneCFS.DesCoolMassFlow;
2163 2 : zoneCFS.ZoneRetTempAtCoolPeak /= zoneCFS.DesCoolMassFlow;
2164 2 : zoneCFS.ZoneHumRatAtCoolPeak /= zoneCFS.DesCoolMassFlow;
2165 2 : zoneCFS.OutHumRatAtCoolPeak /= zoneCFS.DesCoolMassFlow;
2166 2 : zoneCFS.DesCoolCoilInTemp /= zoneCFS.DesCoolMassFlow;
2167 2 : zoneCFS.DesCoolCoilInHumRat /= zoneCFS.DesCoolMassFlow;
2168 : }
2169 290 : for (int ts = 1; ts <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++ts) {
2170 288 : Real64 tsHeatFlow = zoneCFS.HeatFlowSeq(ts);
2171 288 : if (tsHeatFlow > 0) {
2172 0 : zoneCFS.HeatZoneTempSeq(ts) /= tsHeatFlow;
2173 0 : zoneCFS.HeatOutTempSeq(ts) /= tsHeatFlow;
2174 0 : zoneCFS.HeatZoneRetTempSeq(ts) /= tsHeatFlow;
2175 0 : zoneCFS.HeatZoneHumRatSeq(ts) /= tsHeatFlow;
2176 0 : zoneCFS.HeatOutHumRatSeq(ts) /= tsHeatFlow;
2177 : }
2178 :
2179 288 : Real64 tsCoolFlow = zoneCFS.CoolFlowSeq(ts);
2180 288 : if (tsCoolFlow > 0) {
2181 288 : zoneCFS.CoolZoneTempSeq(ts) /= tsCoolFlow;
2182 288 : zoneCFS.CoolOutTempSeq(ts) /= tsCoolFlow;
2183 288 : zoneCFS.CoolZoneRetTempSeq(ts) /= tsCoolFlow;
2184 288 : zoneCFS.CoolZoneHumRatSeq(ts) /= tsCoolFlow;
2185 288 : zoneCFS.CoolOutHumRatSeq(ts) /= tsCoolFlow;
2186 : }
2187 : }
2188 : // Timestep at max
2189 2 : zoneCFS.TimeStepNumAtHeatMax =
2190 2 : 1 + std::distance(zoneCFS.HeatLoadSeq.begin(), std::max_element(zoneCFS.HeatLoadSeq.begin(), zoneCFS.HeatLoadSeq.end()));
2191 2 : zoneCFS.TimeStepNumAtHeatNoDOASMax =
2192 2 : 1 + std::distance(zoneCFS.HeatLoadNoDOASSeq.begin(), std::max_element(zoneCFS.HeatLoadNoDOASSeq.begin(), zoneCFS.HeatLoadNoDOASSeq.end()));
2193 2 : zoneCFS.TimeStepNumAtCoolMax =
2194 2 : 1 + std::distance(zoneCFS.CoolLoadSeq.begin(), std::max_element(zoneCFS.CoolLoadSeq.begin(), zoneCFS.CoolLoadSeq.end()));
2195 2 : zoneCFS.TimeStepNumAtCoolNoDOASMax =
2196 2 : 1 + std::distance(zoneCFS.CoolLoadNoDOASSeq.begin(), std::max_element(zoneCFS.CoolLoadNoDOASSeq.begin(), zoneCFS.CoolLoadNoDOASSeq.end()));
2197 :
2198 2 : if (zoneCFS.zoneLatentSizing) {
2199 0 : if (zoneCFS.DesLatentHeatMassFlow > 0) {
2200 0 : zoneCFS.ZoneTempAtLatentHeatPeak /= zoneCFS.DesLatentHeatMassFlow;
2201 0 : zoneCFS.ZoneHumRatAtLatentHeatPeak /= zoneCFS.DesLatentHeatMassFlow;
2202 0 : zoneCFS.ZoneRetTempAtLatentHeatPeak /= zoneCFS.DesLatentHeatMassFlow;
2203 0 : zoneCFS.DesLatentHeatCoilInTemp /= zoneCFS.DesLatentHeatMassFlow;
2204 0 : zoneCFS.DesLatentHeatCoilInHumRat /= zoneCFS.DesLatentHeatMassFlow;
2205 : }
2206 0 : if (zoneCFS.DesLatentCoolMassFlow > 0) {
2207 0 : zoneCFS.ZoneTempAtLatentCoolPeak /= zoneCFS.DesLatentCoolMassFlow;
2208 0 : zoneCFS.ZoneHumRatAtLatentCoolPeak /= zoneCFS.DesLatentCoolMassFlow;
2209 0 : zoneCFS.ZoneRetTempAtLatentCoolPeak /= zoneCFS.DesLatentCoolMassFlow;
2210 0 : zoneCFS.DesLatentCoolCoilInTemp /= zoneCFS.DesLatentCoolMassFlow;
2211 0 : zoneCFS.DesLatentCoolCoilInHumRat /= zoneCFS.DesLatentCoolMassFlow;
2212 : }
2213 : // Timestep at max
2214 0 : zoneCFS.TimeStepNumAtLatentHeatMax = 1 + std::distance(zoneCFS.LatentHeatFlowSeq.begin(),
2215 : std::max_element(zoneCFS.LatentHeatFlowSeq.begin(), zoneCFS.LatentHeatFlowSeq.end()));
2216 0 : zoneCFS.TimeStepNumAtLatentHeatNoDOASMax =
2217 0 : 1 + std::distance(zoneCFS.HeatLatentLoadNoDOASSeq.begin(),
2218 : std::max_element(zoneCFS.HeatLatentLoadNoDOASSeq.begin(), zoneCFS.HeatLatentLoadNoDOASSeq.end()));
2219 0 : zoneCFS.TimeStepNumAtLatentCoolMax = 1 + std::distance(zoneCFS.LatentCoolLoadSeq.begin(),
2220 : std::max_element(zoneCFS.LatentCoolLoadSeq.begin(), zoneCFS.LatentCoolLoadSeq.end()));
2221 0 : zoneCFS.TimeStepNumAtLatentCoolNoDOASMax =
2222 0 : 1 + std::distance(zoneCFS.CoolLatentLoadNoDOASSeq.begin(),
2223 : std::max_element(zoneCFS.CoolLatentLoadNoDOASSeq.begin(), zoneCFS.CoolLatentLoadNoDOASSeq.end()));
2224 : }
2225 :
2226 2 : return;
2227 : }
2228 :
2229 91 : void updateZoneSizingEndZoneSizingCalc2(EnergyPlusData &state, DataSizing::ZoneSizingData &zsCalcSizing)
2230 : {
2231 91 : if (std::abs(zsCalcSizing.DesCoolLoad) <= 1.e-8) {
2232 4 : ShowWarningError(state, format("Calculated design cooling load for zone={} is zero.", zsCalcSizing.ZoneName));
2233 12 : ShowContinueError(state, "Check Sizing:Zone and ZoneControl:Thermostat inputs.");
2234 : }
2235 91 : if (std::abs(zsCalcSizing.DesHeatLoad) <= 1.e-8) {
2236 15 : ShowWarningError(state, format("Calculated design heating load for zone={} is zero.", zsCalcSizing.ZoneName));
2237 45 : ShowContinueError(state, "Check Sizing:Zone and ZoneControl:Thermostat inputs.");
2238 : }
2239 :
2240 91 : Real64 SupplyTemp = 0.0;
2241 91 : Real64 DeltaTemp = 0.0;
2242 : // Should this be done only if there is a cooling load? Or would this message help determine why there was no load?
2243 91 : if (std::abs(zsCalcSizing.DesCoolLoad) > 1.e-8) {
2244 : // check for low cooling delta T from supply to zone to see if air volume flow rate might be excessively high
2245 87 : if (zsCalcSizing.ZnCoolDgnSAMethod == SupplyAirTemperature) {
2246 87 : SupplyTemp = zsCalcSizing.CoolDesTemp;
2247 87 : DeltaTemp = SupplyTemp - zsCalcSizing.ZoneTempAtCoolPeak;
2248 : } else {
2249 0 : DeltaTemp = -std::abs(zsCalcSizing.CoolDesTempDiff);
2250 0 : SupplyTemp = DeltaTemp + zsCalcSizing.ZoneTempAtCoolPeak;
2251 : }
2252 :
2253 : // check for low delta T to avoid very high flow rates
2254 87 : if (std::abs(DeltaTemp) < 5.0 && std::abs(DeltaTemp) > HVAC::SmallTempDiff) { // Vdot exceeds 1200 cfm/ton @ DT=5
2255 0 : if (std::abs(DeltaTemp) >= 2.0) { // Vdot exceeds 3000 cfm/ton @ DT=2
2256 0 : ShowWarningError(state, "UpdateZoneSizing: Cooling supply air temperature (calculated) within 5C of zone temperature");
2257 : } else {
2258 0 : ShowSevereError(state, "UpdateZoneSizing: Cooling supply air temperature (calculated) within 2C of zone temperature");
2259 : }
2260 0 : ShowContinueError(state, "...check zone thermostat set point and design supply air temperatures");
2261 0 : ShowContinueError(state, format("...zone name = {}", zsCalcSizing.ZoneName));
2262 0 : ShowContinueError(state, format("...design sensible cooling load = {:.2R} W", zsCalcSizing.DesCoolLoad));
2263 0 : ShowContinueError(state, format("...thermostat set point temp = {:.3R} C", zsCalcSizing.CoolTstatTemp));
2264 0 : ShowContinueError(state, format("...zone temperature = {:.3R} C", zsCalcSizing.ZoneTempAtCoolPeak));
2265 0 : ShowContinueError(state, format("...supply air temperature = {:.3R} C", SupplyTemp));
2266 0 : ShowContinueError(state, format("...temperature difference = {:.5R} C", DeltaTemp));
2267 0 : ShowContinueError(state, format("...calculated volume flow rate = {:.5R} m3/s", (zsCalcSizing.DesCoolVolFlow)));
2268 0 : ShowContinueError(state, format("...calculated mass flow rate = {:.5R} kg/s", (zsCalcSizing.DesCoolMassFlow)));
2269 0 : if (SupplyTemp > zsCalcSizing.ZoneTempAtCoolPeak)
2270 0 : ShowContinueError(state, "...Note: supply air temperature should be less than zone temperature during cooling air flow calculations");
2271 87 : } else if (std::abs(DeltaTemp) > HVAC::SmallTempDiff && SupplyTemp > zsCalcSizing.ZoneTempAtCoolPeak) {
2272 0 : ShowSevereError(state, "UpdateZoneSizing: Supply air temperature is greater than zone temperature during cooling air flow calculations");
2273 0 : ShowContinueError(state, format("...calculated volume flow rate = {:.5R} m3/s", (zsCalcSizing.DesCoolVolFlow)));
2274 0 : ShowContinueError(state, format("...calculated mass flow rate = {:.5R} kg/s", (zsCalcSizing.DesCoolMassFlow)));
2275 0 : ShowContinueError(state, format("...thermostat set point temp = {:.3R} C", zsCalcSizing.CoolTstatTemp));
2276 0 : ShowContinueError(state, format("...zone temperature = {:.3R} C", zsCalcSizing.ZoneTempAtCoolPeak));
2277 0 : ShowContinueError(state, format("...supply air temperature = {:.3R} C", SupplyTemp));
2278 0 : ShowContinueError(state, format("...occurs in zone = {}", zsCalcSizing.ZoneName));
2279 0 : ShowContinueError(state, "...Note: supply air temperature should be less than zone temperature during cooling air flow calculations");
2280 : }
2281 : }
2282 : // Should this be done only if there is a heating load? Or would this message help determine why there was no load?
2283 91 : if (std::abs(zsCalcSizing.DesHeatLoad) > 1.e-8) { // ABS() ?
2284 : // check for low cooling delta T from supply to zone to see if air volume flow rate might be excessively high
2285 76 : if (zsCalcSizing.ZnHeatDgnSAMethod == SupplyAirTemperature) {
2286 76 : SupplyTemp = zsCalcSizing.HeatDesTemp;
2287 76 : DeltaTemp = SupplyTemp - zsCalcSizing.ZoneTempAtHeatPeak;
2288 : } else {
2289 0 : DeltaTemp = zsCalcSizing.HeatDesTempDiff;
2290 0 : SupplyTemp = DeltaTemp + zsCalcSizing.ZoneTempAtHeatPeak;
2291 : }
2292 :
2293 76 : if (std::abs(DeltaTemp) < 5.0 && std::abs(DeltaTemp) > HVAC::SmallTempDiff) { // Vdot exceeds 1200 cfm/ton @ DT=5
2294 0 : if (std::abs(DeltaTemp) >= 2.0) { // Vdot exceeds 3000 cfm/ton @ DT=2
2295 0 : ShowWarningError(state, "UpdateZoneSizing: Heating supply air temperature (calculated) within 5C of zone temperature");
2296 : } else {
2297 0 : ShowSevereError(state, "UpdateZoneSizing: Heating supply air temperature (calculated) within 2C of zone temperature");
2298 : }
2299 0 : ShowContinueError(state, "...check zone thermostat set point and design supply air temperatures");
2300 0 : ShowContinueError(state, format("...zone name = {}", zsCalcSizing.ZoneName));
2301 0 : ShowContinueError(state, format("...design heating load = {:.2R} W", zsCalcSizing.DesHeatLoad));
2302 0 : ShowContinueError(state, format("...thermostat set point temp = {:.3R} C", zsCalcSizing.HeatTstatTemp));
2303 0 : ShowContinueError(state, format("...zone temperature = {:.3R} C", zsCalcSizing.ZoneTempAtHeatPeak));
2304 0 : ShowContinueError(state, format("...supply air temperature = {:.3R} C", SupplyTemp));
2305 0 : ShowContinueError(state, format("...temperature difference = {:.5R} C", DeltaTemp));
2306 0 : ShowContinueError(state, format("...calculated volume flow rate = {:.5R} m3/s", (zsCalcSizing.DesHeatVolFlow)));
2307 0 : ShowContinueError(state, format("...calculated mass flow rate = {:.5R} kg/s", (zsCalcSizing.DesHeatMassFlow)));
2308 0 : if (SupplyTemp < zsCalcSizing.ZoneTempAtHeatPeak)
2309 0 : ShowContinueError(state,
2310 : "...Note: supply air temperature should be greater than zone temperature during heating air "
2311 : "flow calculations");
2312 76 : } else if (std::abs(DeltaTemp) > HVAC::SmallTempDiff && SupplyTemp < zsCalcSizing.ZoneTempAtHeatPeak) {
2313 2 : ShowSevereError(state, "UpdateZoneSizing: Supply air temperature is less than zone temperature during heating air flow calculations");
2314 1 : ShowContinueError(state, format("...calculated design heating volume flow rate = {:.5R} m3/s", (zsCalcSizing.DesHeatVolFlow)));
2315 1 : ShowContinueError(state, format("...calculated design heating mass flow rate = {:.5R} kg/s", (zsCalcSizing.DesHeatMassFlow)));
2316 1 : ShowContinueError(state, format("...thermostat set point temp = {:.3R} C", zsCalcSizing.HeatTstatTemp));
2317 1 : ShowContinueError(state, format("...zone temperature = {:.3R} C", zsCalcSizing.ZoneTempAtHeatPeak));
2318 1 : ShowContinueError(state, format("...supply air temperature = {:.3R} C", SupplyTemp));
2319 1 : ShowContinueError(state, format("...occurs in zone = {}", zsCalcSizing.ZoneName));
2320 3 : ShowContinueError(state,
2321 : "...Note: supply air temperature should be greater than zone temperature during heating air "
2322 : "flow calculations");
2323 : }
2324 : }
2325 91 : zsCalcSizing.HeatPeakDateHrMin = zsCalcSizing.cHeatDDDate + ' ' + sizingPeakTimeStamp(state, zsCalcSizing.TimeStepNumAtHeatMax);
2326 :
2327 91 : zsCalcSizing.CoolPeakDateHrMin = zsCalcSizing.cCoolDDDate + ' ' + sizingPeakTimeStamp(state, zsCalcSizing.TimeStepNumAtCoolMax);
2328 :
2329 91 : zsCalcSizing.LatHeatPeakDateHrMin = zsCalcSizing.cLatentHeatDDDate + ' ' + sizingPeakTimeStamp(state, zsCalcSizing.TimeStepNumAtLatentHeatMax);
2330 :
2331 91 : zsCalcSizing.LatCoolPeakDateHrMin = zsCalcSizing.cLatentCoolDDDate + ' ' + sizingPeakTimeStamp(state, zsCalcSizing.TimeStepNumAtLatentCoolMax);
2332 91 : }
2333 :
2334 364 : std::string sizingPeakTimeStamp(EnergyPlusData const &state, int timeStepIndex)
2335 : {
2336 364 : int constexpr minToSec = 60;
2337 364 : int hour = 0;
2338 364 : int minute = 0;
2339 364 : Real64 second = 0;
2340 :
2341 364 : Real64 timeInSeconds = timeStepIndex * state.dataGlobal->MinutesInTimeStep * minToSec;
2342 364 : General::ParseTime(timeInSeconds, hour, minute, second);
2343 728 : return format(PeakHrMinFmt, hour, minute);
2344 : }
2345 :
2346 56 : void writeZszSpsz(EnergyPlusData &state,
2347 : EnergyPlus::InputOutputFile &outputFile,
2348 : int const numSpacesOrZones,
2349 : EPVector<DataSizing::ZoneSizingData> const &zsCalcFinalSizing,
2350 : Array2D<DataSizing::ZoneSizingData> const &zsCalcSizing,
2351 : bool const forSpaces)
2352 : {
2353 56 : char const colSep = state.dataSize->SizingFileColSep;
2354 56 : print(outputFile, "Time");
2355 156 : for (int i = 1; i <= numSpacesOrZones; ++i) {
2356 100 : int zoneNum = (forSpaces) ? state.dataHeatBal->space(i).zoneNum : i;
2357 100 : if (!state.dataHeatBal->Zone(zoneNum).IsControlled) continue;
2358 91 : auto &thisCalcFS = zsCalcFinalSizing(i);
2359 :
2360 : static constexpr std::string_view ZSizeFmt11("{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{"
2361 : "}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}{}{}:{}{}");
2362 91 : print(outputFile,
2363 : ZSizeFmt11,
2364 : colSep,
2365 91 : thisCalcFS.ZoneName,
2366 91 : thisCalcFS.HeatDesDay,
2367 : ":Des Heat Load [W]",
2368 : colSep,
2369 91 : thisCalcFS.ZoneName,
2370 91 : thisCalcFS.CoolDesDay,
2371 : ":Des Sens Cool Load [W]",
2372 : colSep,
2373 91 : thisCalcFS.ZoneName,
2374 91 : thisCalcFS.HeatDesDay,
2375 : ":Des Heat Mass Flow [kg/s]",
2376 : colSep,
2377 91 : thisCalcFS.ZoneName,
2378 91 : thisCalcFS.CoolDesDay,
2379 : ":Des Cool Mass Flow [kg/s]",
2380 : colSep,
2381 91 : thisCalcFS.ZoneName,
2382 91 : thisCalcFS.LatHeatDesDay,
2383 : ":Des Latent Heat Load [W]",
2384 : colSep,
2385 91 : thisCalcFS.ZoneName,
2386 91 : thisCalcFS.LatCoolDesDay,
2387 : ":Des Latent Cool Load [W]",
2388 : colSep,
2389 91 : thisCalcFS.ZoneName,
2390 91 : thisCalcFS.LatHeatDesDay,
2391 : ":Des Latent Heat Mass Flow [kg/s]",
2392 : colSep,
2393 91 : thisCalcFS.ZoneName,
2394 91 : thisCalcFS.LatCoolDesDay,
2395 : ":Des Latent Cool Mass Flow [kg/s]",
2396 : colSep,
2397 91 : thisCalcFS.ZoneName,
2398 91 : thisCalcFS.HeatNoDOASDesDay,
2399 : ":Des Heat Load No DOAS [W]",
2400 : colSep,
2401 91 : thisCalcFS.ZoneName,
2402 91 : thisCalcFS.CoolNoDOASDesDay,
2403 : ":Des Sens Cool Load No DOAS [W]",
2404 : colSep,
2405 91 : thisCalcFS.ZoneName,
2406 91 : thisCalcFS.LatHeatNoDOASDesDay,
2407 : ":Des Latent Heat Load No DOAS [W]",
2408 : colSep,
2409 91 : thisCalcFS.ZoneName,
2410 91 : thisCalcFS.LatCoolNoDOASDesDay,
2411 : ":Des Latent Cool Load No DOAS [W]",
2412 : colSep,
2413 91 : thisCalcFS.ZoneName,
2414 91 : thisCalcFS.HeatDesDay,
2415 : ":Heating Zone Temperature [C]",
2416 : colSep,
2417 91 : thisCalcFS.ZoneName,
2418 91 : thisCalcFS.HeatDesDay,
2419 : ":Heating Zone Relative Humidity [%]",
2420 : colSep,
2421 91 : thisCalcFS.ZoneName,
2422 91 : thisCalcFS.CoolDesDay,
2423 : ":Cooling Zone Temperature [C]",
2424 : colSep,
2425 91 : thisCalcFS.ZoneName,
2426 91 : thisCalcFS.CoolDesDay,
2427 : ":Cooling Zone Relative Humidity [%]");
2428 : }
2429 56 : print(outputFile, "\n");
2430 : // HourFrac = 0.0
2431 56 : int Minutes = 0;
2432 56 : int TimeStepIndex = 0;
2433 1400 : for (int HourCounter = 1; HourCounter <= 24; ++HourCounter) {
2434 8376 : for (int TimeStepCounter = 1; TimeStepCounter <= state.dataGlobal->TimeStepsInHour; ++TimeStepCounter) {
2435 7032 : ++TimeStepIndex;
2436 7032 : Minutes += state.dataGlobal->MinutesInTimeStep;
2437 7032 : int HourPrint = HourCounter - 1;
2438 7032 : if (Minutes == 60) {
2439 1344 : Minutes = 0;
2440 1344 : HourPrint = HourCounter;
2441 : }
2442 : static constexpr std::string_view ZSizeFmt20("{:02}:{:02}:00");
2443 7032 : print(outputFile, ZSizeFmt20, HourPrint, Minutes);
2444 19392 : for (int i = 1; i <= numSpacesOrZones; ++i) {
2445 12360 : int zoneNum = (forSpaces) ? state.dataHeatBal->space(i).zoneNum : i;
2446 12360 : if (!state.dataHeatBal->Zone(zoneNum).IsControlled) continue;
2447 11304 : auto &thisCalcFS = zsCalcFinalSizing(i);
2448 : static constexpr std::string_view ZSizeFmt21("{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12."
2449 : "6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}");
2450 11304 : Real64 ZoneRHHeat = 0.0;
2451 11304 : Real64 ZoneRHCool = 0.0;
2452 11304 : Real64 ZoneTHeat = 0.0;
2453 11304 : Real64 ZoneTCool = 0.0;
2454 11304 : if (thisCalcFS.HeatDDNum > 0) {
2455 9384 : ZoneTHeat = zsCalcSizing(thisCalcFS.HeatDDNum, i).HeatZoneTempSeq(TimeStepIndex);
2456 9384 : ZoneRHHeat = Psychrometrics::PsyRhFnTdbWPb(state,
2457 9384 : zsCalcSizing(thisCalcFS.HeatDDNum, i).HeatZoneTempSeq(TimeStepIndex),
2458 9384 : zsCalcSizing(thisCalcFS.HeatDDNum, i).HeatZoneHumRatSeq(TimeStepIndex),
2459 18768 : state.dataEnvrn->OutBaroPress) *
2460 : 100.0;
2461 : }
2462 11304 : if (thisCalcFS.CoolDDNum > 0) {
2463 10824 : ZoneTCool = zsCalcSizing(thisCalcFS.CoolDDNum, i).CoolZoneTempSeq(TimeStepIndex);
2464 10824 : ZoneRHCool = Psychrometrics::PsyRhFnTdbWPb(state,
2465 10824 : zsCalcSizing(thisCalcFS.CoolDDNum, i).CoolZoneTempSeq(TimeStepIndex),
2466 10824 : zsCalcSizing(thisCalcFS.CoolDDNum, i).CoolZoneHumRatSeq(TimeStepIndex),
2467 21648 : state.dataEnvrn->OutBaroPress) *
2468 : 100.0;
2469 : }
2470 11304 : print(outputFile,
2471 : ZSizeFmt21,
2472 : colSep,
2473 : thisCalcFS.HeatLoadSeq(TimeStepIndex),
2474 : colSep,
2475 : thisCalcFS.CoolLoadSeq(TimeStepIndex),
2476 : colSep,
2477 : thisCalcFS.HeatFlowSeq(TimeStepIndex),
2478 : colSep,
2479 : thisCalcFS.CoolFlowSeq(TimeStepIndex),
2480 : colSep,
2481 : thisCalcFS.LatentHeatLoadSeq(TimeStepIndex),
2482 : colSep,
2483 : thisCalcFS.LatentCoolLoadSeq(TimeStepIndex),
2484 : colSep,
2485 : thisCalcFS.LatentHeatFlowSeq(TimeStepIndex),
2486 : colSep,
2487 : thisCalcFS.LatentCoolFlowSeq(TimeStepIndex),
2488 : colSep,
2489 : thisCalcFS.HeatLoadNoDOASSeq(TimeStepIndex),
2490 : colSep,
2491 : thisCalcFS.CoolLoadNoDOASSeq(TimeStepIndex),
2492 : colSep,
2493 : thisCalcFS.HeatLatentLoadNoDOASSeq(TimeStepIndex),
2494 : colSep,
2495 : thisCalcFS.CoolLatentLoadNoDOASSeq(TimeStepIndex),
2496 : colSep,
2497 : ZoneTHeat,
2498 : colSep,
2499 : ZoneRHHeat,
2500 : colSep,
2501 : ZoneTCool,
2502 : colSep,
2503 : ZoneRHCool);
2504 : }
2505 7032 : print(outputFile, "\n");
2506 : }
2507 : }
2508 56 : print(outputFile, "Peak");
2509 :
2510 156 : for (int i = 1; i <= numSpacesOrZones; ++i) {
2511 100 : int zoneNum = (forSpaces) ? state.dataHeatBal->space(i).zoneNum : i;
2512 100 : if (!state.dataHeatBal->Zone(zoneNum).IsControlled) continue;
2513 91 : auto &thisCalcFS = zsCalcFinalSizing(i);
2514 :
2515 : static constexpr std::string_view ZSizeFmt31("{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12."
2516 : "6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{}{}{}");
2517 91 : print(outputFile,
2518 : ZSizeFmt31,
2519 : colSep,
2520 91 : thisCalcFS.DesHeatLoad,
2521 : colSep,
2522 91 : thisCalcFS.DesCoolLoad,
2523 : colSep,
2524 91 : thisCalcFS.DesHeatMassFlow,
2525 : colSep,
2526 91 : thisCalcFS.DesCoolMassFlow,
2527 : colSep,
2528 91 : thisCalcFS.DesLatentHeatLoad,
2529 : colSep,
2530 91 : thisCalcFS.DesLatentCoolLoad,
2531 : colSep,
2532 91 : thisCalcFS.DesLatentHeatMassFlow,
2533 : colSep,
2534 91 : thisCalcFS.DesLatentCoolMassFlow,
2535 : colSep,
2536 91 : thisCalcFS.DesHeatLoadNoDOAS,
2537 : colSep,
2538 91 : thisCalcFS.DesCoolLoadNoDOAS,
2539 : colSep,
2540 91 : thisCalcFS.DesLatentHeatLoadNoDOAS,
2541 : colSep,
2542 91 : thisCalcFS.DesLatentCoolLoadNoDOAS,
2543 : colSep,
2544 : colSep,
2545 : colSep,
2546 : colSep);
2547 : }
2548 56 : print(outputFile, "\n");
2549 :
2550 56 : print(outputFile, "\nPeak Vol Flow (m3/s)");
2551 156 : for (int i = 1; i <= numSpacesOrZones; ++i) {
2552 100 : int zoneNum = (forSpaces) ? state.dataHeatBal->space(i).zoneNum : i;
2553 100 : if (!state.dataHeatBal->Zone(zoneNum).IsControlled) continue;
2554 91 : auto &thisCalcFS = zsCalcFinalSizing(i);
2555 : static constexpr std::string_view ZSizeFmt41("{}{}{}{:12.6E}{}{:12.6E}{}{}{}{:12.6E}{}{:12.6E}{}{}{}{}{}{}{}{}");
2556 91 : print(outputFile,
2557 : ZSizeFmt41,
2558 : colSep,
2559 : colSep,
2560 : colSep,
2561 91 : thisCalcFS.DesHeatVolFlow,
2562 : colSep,
2563 91 : thisCalcFS.DesCoolVolFlow,
2564 : colSep,
2565 : colSep,
2566 : colSep,
2567 91 : thisCalcFS.DesLatentHeatVolFlow,
2568 : colSep,
2569 91 : thisCalcFS.DesLatentCoolVolFlow,
2570 : colSep,
2571 : colSep,
2572 : colSep,
2573 : colSep,
2574 : colSep,
2575 : colSep,
2576 : colSep,
2577 : colSep);
2578 : }
2579 56 : print(outputFile, "\n");
2580 56 : outputFile.close();
2581 56 : }
2582 :
2583 13 : void updateZoneSizingEndZoneSizingCalc3(DataSizing::ZoneSizingData &zsCalcFinalSizing,
2584 : Array2D<DataSizing::ZoneSizingData> &zsCalcSizing,
2585 : bool &anyLatentLoad,
2586 : int const zoneOrSpaceNum)
2587 : {
2588 : // latent sizing data has the same variables as sensible sizing data
2589 : // if the user has specified latent sizing, move the latent sizing data into the final calc arrays
2590 : // this method allows all upstream sizing functions to use the same data as before (e.g., DesCoolVolFlow)
2591 : // if sensible sizing, use sensible data. if latent sizing, use latent data (if there is latent data).
2592 : // if sensible or latent sizing, use larger of sensible and latent based on volume flow rate
2593 :
2594 13 : if ((zsCalcFinalSizing.zoneSizingMethod == ZoneSizing::Latent && zsCalcFinalSizing.DesLatentCoolVolFlow > 0.0) ||
2595 13 : (zsCalcFinalSizing.zoneSizingMethod == ZoneSizing::SensibleAndLatent &&
2596 4 : zsCalcFinalSizing.DesLatentCoolLoad > zsCalcFinalSizing.DesCoolLoad)) {
2597 1 : anyLatentLoad = true;
2598 1 : zsCalcFinalSizing.CoolSizingType = "Latent Cooling"; // string reported to eio
2599 1 : zsCalcFinalSizing.DesCoolVolFlow = zsCalcFinalSizing.DesLatentCoolVolFlow;
2600 1 : zsCalcFinalSizing.DesCoolMassFlow = zsCalcFinalSizing.DesLatentCoolMassFlow;
2601 1 : zsCalcFinalSizing.DesCoolLoad = zsCalcFinalSizing.DesLatentCoolLoad;
2602 1 : zsCalcFinalSizing.CoolDesDay = zsCalcFinalSizing.LatCoolDesDay;
2603 1 : zsCalcFinalSizing.cCoolDDDate = zsCalcFinalSizing.cLatentCoolDDDate;
2604 1 : zsCalcFinalSizing.CoolDDNum = zsCalcFinalSizing.LatentCoolDDNum;
2605 1 : zsCalcFinalSizing.TimeStepNumAtCoolMax = zsCalcFinalSizing.TimeStepNumAtLatentCoolMax;
2606 1 : zsCalcFinalSizing.CoolFlowSeq = zsCalcFinalSizing.LatentCoolFlowSeq;
2607 1 : zsCalcFinalSizing.DesCoolCoilInTemp = zsCalcFinalSizing.DesLatentCoolCoilInTemp;
2608 1 : zsCalcFinalSizing.DesCoolCoilInHumRat = zsCalcFinalSizing.DesLatentCoolCoilInHumRat;
2609 1 : zsCalcFinalSizing.ZoneRetTempAtCoolPeak = zsCalcFinalSizing.ZoneRetTempAtLatentCoolPeak;
2610 1 : zsCalcFinalSizing.ZoneTempAtCoolPeak = zsCalcFinalSizing.ZoneTempAtLatentCoolPeak;
2611 1 : zsCalcFinalSizing.ZoneHumRatAtCoolPeak = zsCalcFinalSizing.ZoneHumRatAtLatentCoolPeak;
2612 1 : zsCalcFinalSizing.CoolPeakDateHrMin = zsCalcFinalSizing.LatCoolPeakDateHrMin;
2613 :
2614 : // the zone supply air humrat used for latent sizing is required to adequately size coil capacity
2615 1 : if (zsCalcFinalSizing.ZnLatCoolDgnSAMethod == SupplyAirHumidityRatio) {
2616 0 : zsCalcFinalSizing.CoolDesHumRat = zsCalcFinalSizing.LatentCoolDesHumRat;
2617 : } else {
2618 1 : zsCalcFinalSizing.CoolDesHumRat = zsCalcFinalSizing.ZoneHumRatAtLatentCoolPeak - zsCalcFinalSizing.CoolDesHumRatDiff;
2619 : }
2620 :
2621 1 : if (zsCalcFinalSizing.LatentCoolDDNum > 0) {
2622 1 : auto &calcZoneSizing = zsCalcSizing(zsCalcFinalSizing.LatentCoolDDNum, zoneOrSpaceNum);
2623 1 : calcZoneSizing.DesCoolVolFlow = calcZoneSizing.DesLatentCoolVolFlow;
2624 1 : calcZoneSizing.DesCoolMassFlow = calcZoneSizing.DesLatentCoolMassFlow;
2625 1 : calcZoneSizing.DesCoolLoad = calcZoneSizing.DesLatentCoolLoad;
2626 1 : calcZoneSizing.CoolDesDay = calcZoneSizing.LatCoolDesDay;
2627 1 : calcZoneSizing.cCoolDDDate = zsCalcFinalSizing.cLatentCoolDDDate; // this has correct CoolDDDate
2628 1 : calcZoneSizing.CoolDDNum = calcZoneSizing.LatentCoolDDNum;
2629 1 : calcZoneSizing.TimeStepNumAtCoolMax = calcZoneSizing.TimeStepNumAtLatentCoolMax;
2630 1 : calcZoneSizing.CoolFlowSeq = calcZoneSizing.LatentCoolFlowSeq;
2631 1 : calcZoneSizing.DesCoolCoilInTemp = calcZoneSizing.DesLatentCoolCoilInTemp;
2632 1 : calcZoneSizing.DesCoolCoilInHumRat = calcZoneSizing.DesLatentCoolCoilInHumRat;
2633 1 : calcZoneSizing.ZoneRetTempAtCoolPeak = calcZoneSizing.ZoneRetTempAtLatentCoolPeak;
2634 1 : calcZoneSizing.ZoneTempAtCoolPeak = calcZoneSizing.ZoneTempAtLatentCoolPeak;
2635 1 : calcZoneSizing.ZoneHumRatAtCoolPeak = calcZoneSizing.ZoneHumRatAtLatentCoolPeak;
2636 1 : calcZoneSizing.CoolPeakDateHrMin = zsCalcFinalSizing.LatCoolPeakDateHrMin;
2637 :
2638 : // the zone supply air humrat used for latent sizing is required to adequately size coil capacity
2639 1 : if (calcZoneSizing.ZnLatCoolDgnSAMethod == SupplyAirHumidityRatio) {
2640 0 : calcZoneSizing.CoolDesHumRat = calcZoneSizing.LatentCoolDesHumRat;
2641 : } else {
2642 1 : calcZoneSizing.CoolDesHumRat = calcZoneSizing.ZoneHumRatAtLatentCoolPeak - calcZoneSizing.CoolDesHumRatDiff;
2643 : }
2644 : }
2645 : }
2646 13 : if ((zsCalcFinalSizing.zoneSizingMethod == ZoneSizing::Latent && zsCalcFinalSizing.DesLatentHeatVolFlow > 0.0) ||
2647 13 : (zsCalcFinalSizing.zoneSizingMethod == ZoneSizing::SensibleAndLatent &&
2648 4 : zsCalcFinalSizing.DesLatentHeatLoad > zsCalcFinalSizing.DesHeatLoad)) {
2649 :
2650 0 : zsCalcFinalSizing.HeatSizingType = "Latent Heating"; // string reported to eio
2651 0 : zsCalcFinalSizing.DesHeatVolFlow = zsCalcFinalSizing.DesLatentHeatVolFlow;
2652 0 : zsCalcFinalSizing.DesHeatMassFlow = zsCalcFinalSizing.DesLatentHeatMassFlow;
2653 0 : zsCalcFinalSizing.DesHeatLoad = zsCalcFinalSizing.DesLatentHeatLoad;
2654 0 : zsCalcFinalSizing.HeatDesDay = zsCalcFinalSizing.LatHeatDesDay;
2655 0 : zsCalcFinalSizing.cHeatDDDate = zsCalcFinalSizing.cLatentHeatDDDate;
2656 0 : zsCalcFinalSizing.HeatDDNum = zsCalcFinalSizing.LatentHeatDDNum;
2657 0 : zsCalcFinalSizing.TimeStepNumAtHeatMax = zsCalcFinalSizing.TimeStepNumAtLatentHeatMax;
2658 0 : zsCalcFinalSizing.HeatFlowSeq = zsCalcFinalSizing.LatentHeatFlowSeq;
2659 0 : zsCalcFinalSizing.DesHeatCoilInTemp = zsCalcFinalSizing.DesLatentHeatCoilInTemp;
2660 0 : zsCalcFinalSizing.DesHeatCoilInHumRat = zsCalcFinalSizing.DesLatentHeatCoilInHumRat;
2661 0 : zsCalcFinalSizing.ZoneRetTempAtHeatPeak = zsCalcFinalSizing.ZoneRetTempAtLatentHeatPeak;
2662 0 : zsCalcFinalSizing.ZoneTempAtHeatPeak = zsCalcFinalSizing.ZoneTempAtLatentHeatPeak;
2663 0 : zsCalcFinalSizing.ZoneHumRatAtHeatPeak = zsCalcFinalSizing.ZoneHumRatAtLatentHeatPeak;
2664 0 : zsCalcFinalSizing.HeatPeakDateHrMin = zsCalcFinalSizing.LatHeatPeakDateHrMin;
2665 :
2666 : // will this cause sizing issues with heating coils since SA humrat is higher than zone humrat?
2667 : // use zone humrat instead? this value would size humidifiers well, but what about heating coils?
2668 : // not sure at this point if heating should reset HeatDesHumRat
2669 0 : if (zsCalcFinalSizing.ZnLatHeatDgnSAMethod == SupplyAirHumidityRatio) {
2670 0 : zsCalcFinalSizing.HeatDesHumRat = zsCalcFinalSizing.LatentHeatDesHumRat;
2671 : } else {
2672 0 : zsCalcFinalSizing.HeatDesHumRat = zsCalcFinalSizing.ZoneHumRatAtLatentHeatPeak + zsCalcFinalSizing.HeatDesHumRatDiff;
2673 : }
2674 :
2675 0 : if (zsCalcFinalSizing.LatentHeatDDNum > 0) {
2676 0 : auto &calcZoneSizing = zsCalcSizing(zsCalcFinalSizing.LatentHeatDDNum, zoneOrSpaceNum);
2677 0 : calcZoneSizing.DesHeatVolFlow = calcZoneSizing.DesLatentHeatVolFlow;
2678 0 : calcZoneSizing.DesHeatMassFlow = calcZoneSizing.DesLatentHeatMassFlow;
2679 0 : calcZoneSizing.DesHeatLoad = calcZoneSizing.DesLatentHeatLoad;
2680 0 : calcZoneSizing.HeatDesDay = calcZoneSizing.LatHeatDesDay;
2681 0 : calcZoneSizing.cHeatDDDate = zsCalcFinalSizing.cLatentHeatDDDate; // this has correct HeatDDDate
2682 0 : calcZoneSizing.HeatDDNum = calcZoneSizing.LatentHeatDDNum;
2683 0 : calcZoneSizing.TimeStepNumAtHeatMax = calcZoneSizing.TimeStepNumAtLatentHeatMax;
2684 0 : calcZoneSizing.HeatFlowSeq = calcZoneSizing.LatentHeatFlowSeq;
2685 0 : calcZoneSizing.DesHeatCoilInTemp = calcZoneSizing.DesLatentHeatCoilInTemp;
2686 0 : calcZoneSizing.DesHeatCoilInHumRat = calcZoneSizing.DesLatentHeatCoilInHumRat;
2687 0 : calcZoneSizing.ZoneRetTempAtHeatPeak = calcZoneSizing.ZoneRetTempAtLatentHeatPeak;
2688 0 : calcZoneSizing.ZoneTempAtHeatPeak = calcZoneSizing.ZoneTempAtLatentHeatPeak;
2689 0 : calcZoneSizing.ZoneHumRatAtHeatPeak = calcZoneSizing.ZoneHumRatAtLatentHeatPeak;
2690 0 : calcZoneSizing.HeatPeakDateHrMin = zsCalcFinalSizing.LatHeatPeakDateHrMin;
2691 :
2692 : // the zone supply air humrat used for latent sizing is required to adequately size coil capacity
2693 : // not sure at this point if heating should reset HeatDesHumRat
2694 0 : if (calcZoneSizing.ZnLatHeatDgnSAMethod == SupplyAirHumidityRatio) {
2695 0 : calcZoneSizing.HeatDesHumRat = calcZoneSizing.LatentHeatDesHumRat;
2696 : } else {
2697 0 : calcZoneSizing.HeatDesHumRat = calcZoneSizing.ZoneHumRatAtLatentHeatPeak + calcZoneSizing.HeatDesHumRatDiff;
2698 : }
2699 : }
2700 : }
2701 13 : }
2702 264 : void updateZoneSizingEndZoneSizingCalc4(DataSizing::ZoneSizingData &zsSizing, DataSizing::ZoneSizingData const &zsCalcSizing)
2703 : {
2704 : // Move data from Calc arrays to user modified arrays
2705 264 : zsSizing.CoolDesDay = zsCalcSizing.CoolDesDay;
2706 264 : zsSizing.HeatDesDay = zsCalcSizing.HeatDesDay;
2707 264 : zsSizing.DesHeatDens = zsCalcSizing.DesHeatDens;
2708 264 : zsSizing.DesCoolDens = zsCalcSizing.DesCoolDens;
2709 264 : zsSizing.HeatDDNum = zsCalcSizing.HeatDDNum;
2710 264 : zsSizing.CoolDDNum = zsCalcSizing.CoolDDNum;
2711 :
2712 264 : zsSizing.DesHeatLoad = zsCalcSizing.DesHeatLoad;
2713 264 : zsSizing.DesHeatMassFlow = zsCalcSizing.DesHeatMassFlow;
2714 264 : zsSizing.ZoneTempAtHeatPeak = zsCalcSizing.ZoneTempAtHeatPeak;
2715 264 : zsSizing.OutTempAtHeatPeak = zsCalcSizing.OutTempAtHeatPeak;
2716 264 : zsSizing.ZoneRetTempAtHeatPeak = zsCalcSizing.ZoneRetTempAtHeatPeak;
2717 264 : zsSizing.ZoneHumRatAtHeatPeak = zsCalcSizing.ZoneHumRatAtHeatPeak;
2718 264 : zsSizing.OutHumRatAtHeatPeak = zsCalcSizing.OutHumRatAtHeatPeak;
2719 264 : zsSizing.TimeStepNumAtHeatMax = zsCalcSizing.TimeStepNumAtHeatMax;
2720 264 : zsSizing.DesHeatVolFlow = zsCalcSizing.DesHeatVolFlow;
2721 264 : zsSizing.DesHeatCoilInTemp = zsCalcSizing.DesHeatCoilInTemp;
2722 264 : zsSizing.DesHeatCoilInHumRat = zsCalcSizing.DesHeatCoilInHumRat;
2723 264 : zsSizing.CoolDesHumRat = zsCalcSizing.CoolDesHumRat;
2724 :
2725 264 : zsSizing.DesCoolLoad = zsCalcSizing.DesCoolLoad;
2726 264 : zsSizing.DesCoolMassFlow = zsCalcSizing.DesCoolMassFlow;
2727 264 : zsSizing.ZoneTempAtCoolPeak = zsCalcSizing.ZoneTempAtCoolPeak;
2728 264 : zsSizing.OutTempAtCoolPeak = zsCalcSizing.OutTempAtCoolPeak;
2729 264 : zsSizing.ZoneRetTempAtCoolPeak = zsCalcSizing.ZoneRetTempAtCoolPeak;
2730 264 : zsSizing.ZoneHumRatAtCoolPeak = zsCalcSizing.ZoneHumRatAtCoolPeak;
2731 264 : zsSizing.OutHumRatAtCoolPeak = zsCalcSizing.OutHumRatAtCoolPeak;
2732 264 : zsSizing.TimeStepNumAtCoolMax = zsCalcSizing.TimeStepNumAtCoolMax;
2733 264 : zsSizing.DesCoolVolFlow = zsCalcSizing.DesCoolVolFlow;
2734 264 : zsSizing.DesCoolCoilInTemp = zsCalcSizing.DesCoolCoilInTemp;
2735 264 : zsSizing.DesCoolCoilInHumRat = zsCalcSizing.DesCoolCoilInHumRat;
2736 264 : }
2737 :
2738 113 : void updateZoneSizingEndZoneSizingCalc5(DataSizing::ZoneSizingData &zsFinalSizing, DataSizing::ZoneSizingData const &zsCalcFinalSizing)
2739 : {
2740 : // Move data from CalcFinal arrays to user modified final arrays
2741 : // SpaceSizing TODO: This is essentially the same as updateZoneSizingEndZoneSizingCalc4, except there are two extra fields copied here
2742 113 : zsFinalSizing.CoolDesDay = zsCalcFinalSizing.CoolDesDay;
2743 113 : zsFinalSizing.HeatDesDay = zsCalcFinalSizing.HeatDesDay;
2744 113 : zsFinalSizing.DesHeatDens = zsCalcFinalSizing.DesHeatDens;
2745 113 : zsFinalSizing.DesCoolDens = zsCalcFinalSizing.DesCoolDens;
2746 113 : zsFinalSizing.HeatDDNum = zsCalcFinalSizing.HeatDDNum;
2747 113 : zsFinalSizing.CoolDDNum = zsCalcFinalSizing.CoolDDNum;
2748 :
2749 113 : zsFinalSizing.DesHeatLoad = zsCalcFinalSizing.DesHeatLoad;
2750 113 : zsFinalSizing.NonAirSysDesHeatLoad = zsCalcFinalSizing.DesHeatLoad;
2751 113 : zsFinalSizing.DesHeatMassFlow = zsCalcFinalSizing.DesHeatMassFlow;
2752 113 : zsFinalSizing.ZoneTempAtHeatPeak = zsCalcFinalSizing.ZoneTempAtHeatPeak;
2753 113 : zsFinalSizing.OutTempAtHeatPeak = zsCalcFinalSizing.OutTempAtHeatPeak;
2754 113 : zsFinalSizing.ZoneRetTempAtHeatPeak = zsCalcFinalSizing.ZoneRetTempAtHeatPeak;
2755 113 : zsFinalSizing.ZoneHumRatAtHeatPeak = zsCalcFinalSizing.ZoneHumRatAtHeatPeak;
2756 113 : zsFinalSizing.OutHumRatAtHeatPeak = zsCalcFinalSizing.OutHumRatAtHeatPeak;
2757 113 : zsFinalSizing.TimeStepNumAtHeatMax = zsCalcFinalSizing.TimeStepNumAtHeatMax;
2758 113 : zsFinalSizing.DesHeatVolFlow = zsCalcFinalSizing.DesHeatVolFlow;
2759 113 : zsFinalSizing.NonAirSysDesHeatVolFlow = zsCalcFinalSizing.DesHeatVolFlow; // SpaceSizing TODO: Suspicious
2760 113 : zsFinalSizing.DesHeatCoilInTemp = zsCalcFinalSizing.DesHeatCoilInTemp;
2761 113 : zsFinalSizing.DesHeatCoilInHumRat = zsCalcFinalSizing.DesHeatCoilInHumRat;
2762 113 : zsFinalSizing.CoolDesHumRat = zsCalcFinalSizing.CoolDesHumRat;
2763 :
2764 113 : zsFinalSizing.DesCoolLoad = zsCalcFinalSizing.DesCoolLoad;
2765 113 : zsFinalSizing.NonAirSysDesCoolLoad = zsCalcFinalSizing.DesCoolLoad;
2766 113 : zsFinalSizing.DesCoolMassFlow = zsCalcFinalSizing.DesCoolMassFlow;
2767 113 : zsFinalSizing.ZoneTempAtCoolPeak = zsCalcFinalSizing.ZoneTempAtCoolPeak;
2768 113 : zsFinalSizing.OutTempAtCoolPeak = zsCalcFinalSizing.OutTempAtCoolPeak;
2769 113 : zsFinalSizing.ZoneRetTempAtCoolPeak = zsCalcFinalSizing.ZoneRetTempAtCoolPeak;
2770 113 : zsFinalSizing.ZoneHumRatAtCoolPeak = zsCalcFinalSizing.ZoneHumRatAtCoolPeak;
2771 113 : zsFinalSizing.OutHumRatAtCoolPeak = zsCalcFinalSizing.OutHumRatAtCoolPeak;
2772 113 : zsFinalSizing.TimeStepNumAtCoolMax = zsCalcFinalSizing.TimeStepNumAtCoolMax;
2773 113 : zsFinalSizing.DesCoolVolFlow = zsCalcFinalSizing.DesCoolVolFlow;
2774 113 : zsFinalSizing.NonAirSysDesCoolVolFlow = zsCalcFinalSizing.DesCoolVolFlow; // SpaceSizing TODO: Suspicious
2775 113 : zsFinalSizing.DesCoolCoilInTemp = zsCalcFinalSizing.DesCoolCoilInTemp;
2776 113 : zsFinalSizing.DesCoolCoilInHumRat = zsCalcFinalSizing.DesCoolCoilInHumRat;
2777 113 : }
2778 :
2779 296 : void updateZoneSizingEndZoneSizingCalc6(DataSizing::ZoneSizingData &zsSizing,
2780 : DataSizing::ZoneSizingData const &zsCalcSizing,
2781 : int const numTimeStepsInDay)
2782 : {
2783 : // This is called for all zsSizing/zsCalcSizing (2D arrays) and FinalZoneSizing/CalcFinalZoneSizing (1D arrays) for both zones and spaces
2784 35532 : for (int TimeStepIndex = 1; TimeStepIndex <= numTimeStepsInDay; ++TimeStepIndex) {
2785 35236 : zsSizing.HeatFlowSeq(TimeStepIndex) = zsCalcSizing.HeatFlowSeq(TimeStepIndex);
2786 35236 : zsSizing.HeatLoadSeq(TimeStepIndex) = zsCalcSizing.HeatLoadSeq(TimeStepIndex);
2787 35236 : zsSizing.CoolFlowSeq(TimeStepIndex) = zsCalcSizing.CoolFlowSeq(TimeStepIndex);
2788 35236 : zsSizing.CoolLoadSeq(TimeStepIndex) = zsCalcSizing.CoolLoadSeq(TimeStepIndex);
2789 35236 : zsSizing.HeatZoneTempSeq(TimeStepIndex) = zsCalcSizing.HeatZoneTempSeq(TimeStepIndex);
2790 35236 : zsSizing.HeatOutTempSeq(TimeStepIndex) = zsCalcSizing.HeatOutTempSeq(TimeStepIndex);
2791 35236 : zsSizing.HeatZoneRetTempSeq(TimeStepIndex) = zsCalcSizing.HeatZoneRetTempSeq(TimeStepIndex);
2792 35236 : zsSizing.HeatZoneHumRatSeq(TimeStepIndex) = zsCalcSizing.HeatZoneHumRatSeq(TimeStepIndex);
2793 35236 : zsSizing.HeatOutHumRatSeq(TimeStepIndex) = zsCalcSizing.HeatOutHumRatSeq(TimeStepIndex);
2794 35236 : zsSizing.CoolZoneTempSeq(TimeStepIndex) = zsCalcSizing.CoolZoneTempSeq(TimeStepIndex);
2795 35236 : zsSizing.CoolOutTempSeq(TimeStepIndex) = zsCalcSizing.CoolOutTempSeq(TimeStepIndex);
2796 35236 : zsSizing.CoolZoneRetTempSeq(TimeStepIndex) = zsCalcSizing.CoolZoneRetTempSeq(TimeStepIndex);
2797 35236 : zsSizing.CoolZoneHumRatSeq(TimeStepIndex) = zsCalcSizing.CoolZoneHumRatSeq(TimeStepIndex);
2798 35236 : zsSizing.CoolOutHumRatSeq(TimeStepIndex) = zsCalcSizing.CoolOutHumRatSeq(TimeStepIndex);
2799 : }
2800 296 : }
2801 :
2802 102 : void updateZoneSizingEndZoneSizingCalc7(EnergyPlusData &state,
2803 : DataSizing::ZoneSizingData &zsFinalSizing,
2804 : DataSizing::ZoneSizingData &zsCalcFinalSizing,
2805 : Array2D<DataSizing::ZoneSizingData> &zsSizing,
2806 : Array2D<DataSizing::ZoneSizingData> &zsCalcSizing,
2807 : int const zoneOrSpaceNum)
2808 : {
2809 : static constexpr std::string_view RoutineName("updateZoneSizingEndZoneSizingCalc7");
2810 : // update non air system design load and air flow to include the sizing factor
2811 102 : zsFinalSizing.NonAirSysDesCoolLoad *= zsFinalSizing.CoolSizingFactor;
2812 102 : zsFinalSizing.NonAirSysDesCoolVolFlow *= zsFinalSizing.CoolSizingFactor; // NonAirSysDesCoolVolFlow not currently used
2813 : // Now take into account the user specified sizing factor and user specified cooling design air flow rate
2814 102 : Real64 TotCoolSizMult = 0.0;
2815 : // Calculate a sizing factor from the user specified cooling design air flow rate
2816 102 : if (zsFinalSizing.InpDesCoolAirFlow > 0.0 && zsFinalSizing.CoolAirDesMethod == AirflowSizingMethod::InpDesAirFlow &&
2817 0 : zsFinalSizing.DesCoolVolFlow > 0.0) {
2818 0 : TotCoolSizMult = (zsFinalSizing.InpDesCoolAirFlow / zsFinalSizing.DesCoolVolFlow) * zsFinalSizing.CoolSizingFactor;
2819 : // If no user specified cooling design air flow rate input, use the user specified szing factor
2820 : } else {
2821 102 : TotCoolSizMult = zsFinalSizing.CoolSizingFactor;
2822 : }
2823 : // If the cooling sizing multiplier is not 1, adjust the cooling design data
2824 102 : if (std::abs(TotCoolSizMult - 1.0) > 0.00001) {
2825 16 : if (zsFinalSizing.DesCoolVolFlow > 0.0) {
2826 12 : int TimeStepAtPeak = zsFinalSizing.TimeStepNumAtCoolMax;
2827 12 : int DDNum = zsFinalSizing.CoolDDNum;
2828 12 : zsFinalSizing.DesCoolVolFlow = zsCalcFinalSizing.DesCoolVolFlow * TotCoolSizMult;
2829 12 : zsFinalSizing.DesCoolMassFlow = zsCalcFinalSizing.DesCoolMassFlow * TotCoolSizMult;
2830 12 : zsFinalSizing.DesCoolLoad = zsCalcFinalSizing.DesCoolLoad * TotCoolSizMult;
2831 1548 : for (int i = 0; i < (int)zsFinalSizing.CoolFlowSeq.size(); ++i) {
2832 1536 : zsFinalSizing.CoolFlowSeq[i] = zsCalcFinalSizing.CoolFlowSeq[i] * TotCoolSizMult;
2833 1536 : zsFinalSizing.CoolLoadSeq[i] = zsCalcFinalSizing.CoolLoadSeq[i] * TotCoolSizMult;
2834 : }
2835 12 : Real64 OAFrac = zsFinalSizing.MinOA / zsFinalSizing.DesCoolVolFlow;
2836 12 : OAFrac = min(1.0, max(0.0, OAFrac));
2837 12 : zsFinalSizing.DesCoolCoilInTemp =
2838 12 : OAFrac * state.dataSize->DesDayWeath(DDNum).Temp(TimeStepAtPeak) + (1.0 - OAFrac) * zsFinalSizing.ZoneTempAtCoolPeak;
2839 12 : zsFinalSizing.DesCoolCoilInHumRat =
2840 12 : OAFrac * state.dataSize->DesDayWeath(DDNum).HumRat(TimeStepAtPeak) + (1.0 - OAFrac) * zsFinalSizing.ZoneHumRatAtCoolPeak;
2841 : } else {
2842 4 : zsFinalSizing.DesCoolVolFlow = zsFinalSizing.InpDesCoolAirFlow;
2843 4 : zsFinalSizing.DesCoolMassFlow = zsFinalSizing.DesCoolVolFlow * zsFinalSizing.DesCoolDens;
2844 : }
2845 44 : for (int DDNum = 1; DDNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DDNum) {
2846 28 : auto &zoneSizing = zsSizing(DDNum, zoneOrSpaceNum);
2847 28 : if (zoneSizing.DesCoolVolFlow > 0.0) {
2848 12 : int TimeStepAtPeak = zoneSizing.TimeStepNumAtCoolMax;
2849 12 : auto &calcZoneSizing = zsCalcSizing(DDNum, zoneOrSpaceNum);
2850 12 : auto &desDayWeath = state.dataSize->DesDayWeath(DDNum);
2851 12 : zoneSizing.DesCoolVolFlow = calcZoneSizing.DesCoolVolFlow * TotCoolSizMult;
2852 12 : zoneSizing.DesCoolMassFlow = calcZoneSizing.DesCoolMassFlow * TotCoolSizMult;
2853 12 : zoneSizing.DesCoolLoad = calcZoneSizing.DesCoolLoad * TotCoolSizMult;
2854 1548 : for (int i = 0; i < (int)zoneSizing.CoolFlowSeq.size(); ++i) {
2855 1536 : zoneSizing.CoolFlowSeq[i] = calcZoneSizing.CoolFlowSeq[i] * TotCoolSizMult;
2856 1536 : zoneSizing.CoolLoadSeq[i] = calcZoneSizing.CoolLoadSeq[i] * TotCoolSizMult;
2857 : }
2858 12 : Real64 OAFrac = zoneSizing.MinOA / zoneSizing.DesCoolVolFlow;
2859 12 : OAFrac = min(1.0, max(0.0, OAFrac));
2860 12 : zoneSizing.DesCoolCoilInTemp = OAFrac * desDayWeath.Temp(TimeStepAtPeak) + (1.0 - OAFrac) * zoneSizing.ZoneTempAtCoolPeak;
2861 12 : zoneSizing.DesCoolCoilInHumRat = OAFrac * desDayWeath.HumRat(TimeStepAtPeak) + (1.0 - OAFrac) * zoneSizing.ZoneHumRatAtCoolPeak;
2862 : } else {
2863 16 : zoneSizing.DesCoolVolFlow = zoneSizing.InpDesCoolAirFlow;
2864 16 : zoneSizing.DesCoolMassFlow = zoneSizing.DesCoolVolFlow * zoneSizing.DesCoolDens;
2865 : }
2866 : // Save cooling flows without MinOA for use later
2867 28 : zoneSizing.CoolFlowSeqNoOA = zoneSizing.CoolFlowSeq;
2868 28 : zoneSizing.DesCoolVolFlowNoOA = zoneSizing.DesCoolVolFlow;
2869 28 : zoneSizing.DesCoolMassFlowNoOA = zoneSizing.DesCoolMassFlow;
2870 : }
2871 : } else {
2872 252 : for (int DDNum = 1; DDNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DDNum) {
2873 : // initialize HeatFlowSeqNoOA before any adjustments to HeatFlowSeq
2874 166 : auto &zoneSizing = zsSizing(DDNum, zoneOrSpaceNum);
2875 166 : zoneSizing.CoolFlowSeqNoOA = zoneSizing.CoolFlowSeq;
2876 166 : zoneSizing.DesCoolVolFlowNoOA = zoneSizing.DesCoolVolFlow;
2877 166 : zoneSizing.DesCoolMassFlowNoOA = zoneSizing.DesCoolMassFlow;
2878 : }
2879 : }
2880 : // Save a set of design cooling air flow rates greater than or equal to the specified minimums without MinOA
2881 : {
2882 102 : Real64 MaxOfMinCoolVolFlowNoOA = 0.0; // max of the user specified design cooling minimum flows without min OA flow [m3/s]
2883 102 : if (zsFinalSizing.CoolAirDesMethod == AirflowSizingMethod::DesAirFlowWithLim) {
2884 7 : MaxOfMinCoolVolFlowNoOA = max(zsFinalSizing.DesCoolMinAirFlow, zsFinalSizing.DesCoolMinAirFlow2);
2885 : }
2886 102 : Real64 MaxOfMinCoolMassFlowNoOA =
2887 102 : MaxOfMinCoolVolFlowNoOA * zsFinalSizing.DesCoolDens; // max of the user specified design cooling minimum flows without min OA flow [m3/s]
2888 102 : zsFinalSizing.DesCoolVolFlowNoOA = zsFinalSizing.DesCoolVolFlow;
2889 102 : zsFinalSizing.DesCoolMassFlowNoOA = zsFinalSizing.DesCoolMassFlow;
2890 102 : if (MaxOfMinCoolVolFlowNoOA > zsFinalSizing.DesCoolVolFlowNoOA) {
2891 0 : zsFinalSizing.DesCoolVolFlowNoOA = MaxOfMinCoolVolFlowNoOA;
2892 0 : zsFinalSizing.DesCoolMassFlowNoOA = MaxOfMinCoolMassFlowNoOA;
2893 : }
2894 12200 : for (int TimeStepIndex = 1; TimeStepIndex <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++TimeStepIndex) {
2895 12098 : zsFinalSizing.CoolFlowSeqNoOA(TimeStepIndex) = zsFinalSizing.CoolFlowSeq(TimeStepIndex);
2896 12098 : if (MaxOfMinCoolMassFlowNoOA > zsFinalSizing.CoolFlowSeqNoOA(TimeStepIndex)) {
2897 334 : zsFinalSizing.CoolFlowSeqNoOA(TimeStepIndex) = MaxOfMinCoolMassFlowNoOA;
2898 : }
2899 : }
2900 296 : for (int DDNum = 1; DDNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DDNum) {
2901 194 : auto &zoneSizing = zsSizing(DDNum, zoneOrSpaceNum);
2902 194 : zoneSizing.DesCoolVolFlowNoOA = zoneSizing.DesCoolVolFlow;
2903 194 : zoneSizing.DesCoolMassFlowNoOA = zoneSizing.DesCoolMassFlow;
2904 194 : MaxOfMinCoolVolFlowNoOA = max(zoneSizing.DesCoolMinAirFlow, zoneSizing.DesCoolMinAirFlow);
2905 194 : MaxOfMinCoolMassFlowNoOA = MaxOfMinCoolVolFlowNoOA * zoneSizing.DesCoolDens;
2906 194 : if (MaxOfMinCoolVolFlowNoOA > zoneSizing.DesCoolVolFlow) {
2907 0 : zoneSizing.DesCoolVolFlowNoOA = MaxOfMinCoolVolFlowNoOA;
2908 0 : zoneSizing.DesCoolMassFlowNoOA = MaxOfMinCoolMassFlowNoOA;
2909 : }
2910 23332 : for (int TimeStepIndex = 1; TimeStepIndex <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++TimeStepIndex) {
2911 23138 : if (MaxOfMinCoolMassFlowNoOA > zoneSizing.CoolFlowSeq(TimeStepIndex)) {
2912 0 : zoneSizing.CoolFlowSeqNoOA(TimeStepIndex) = MaxOfMinCoolMassFlowNoOA;
2913 : }
2914 : }
2915 : }
2916 : }
2917 :
2918 : // Now make sure that the design cooling air flow rates are greater than or equal to the specified minimums including MinOA
2919 : {
2920 102 : Real64 MaxOfMinCoolVolFlow = 0.0; // max of the user specified design cooling minimum flows and min OA flow [m3/s]
2921 102 : if (zsFinalSizing.CoolAirDesMethod == AirflowSizingMethod::DesAirFlowWithLim) {
2922 7 : MaxOfMinCoolVolFlow = max(zsFinalSizing.DesCoolMinAirFlow, zsFinalSizing.DesCoolMinAirFlow2, zsFinalSizing.MinOA);
2923 : } else {
2924 95 : MaxOfMinCoolVolFlow = zsFinalSizing.MinOA;
2925 : }
2926 102 : Real64 MaxOfMinCoolMassFlow =
2927 102 : MaxOfMinCoolVolFlow * zsFinalSizing.DesCoolDens; // max of the user specified design cooling minimum flows and min OA flow [kg/s]
2928 102 : if (MaxOfMinCoolVolFlow > zsFinalSizing.DesCoolVolFlow) {
2929 5 : zsFinalSizing.DesCoolVolFlow = MaxOfMinCoolVolFlow;
2930 5 : zsFinalSizing.DesCoolMassFlow = MaxOfMinCoolMassFlow;
2931 : }
2932 12200 : for (int TimeStepIndex = 1; TimeStepIndex <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++TimeStepIndex) {
2933 12098 : if (MaxOfMinCoolMassFlow > zsFinalSizing.CoolFlowSeq(TimeStepIndex)) {
2934 2392 : zsFinalSizing.CoolFlowSeq(TimeStepIndex) = MaxOfMinCoolMassFlow;
2935 : }
2936 : }
2937 296 : for (int DDNum = 1; DDNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DDNum) {
2938 194 : auto &zoneSizing = zsSizing(DDNum, zoneOrSpaceNum);
2939 194 : MaxOfMinCoolVolFlow = max(zoneSizing.DesCoolMinAirFlow, zoneSizing.DesCoolMinAirFlow, zoneSizing.MinOA);
2940 194 : MaxOfMinCoolMassFlow = MaxOfMinCoolVolFlow * zoneSizing.DesCoolDens;
2941 194 : if (MaxOfMinCoolVolFlow > zoneSizing.DesCoolVolFlow) {
2942 61 : zoneSizing.DesCoolVolFlow = MaxOfMinCoolVolFlow;
2943 61 : zoneSizing.DesCoolMassFlow = MaxOfMinCoolMassFlow;
2944 : }
2945 23332 : for (int TimeStepIndex = 1; TimeStepIndex <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++TimeStepIndex) {
2946 23138 : if (MaxOfMinCoolMassFlow > zoneSizing.CoolFlowSeq(TimeStepIndex)) {
2947 8516 : zoneSizing.CoolFlowSeq(TimeStepIndex) = MaxOfMinCoolMassFlow;
2948 : }
2949 : }
2950 : }
2951 : }
2952 : // IF cooling flow rate is 0, this data may be used to size a HP so initialize DDNum, TimeStepatPeak, and sizing data (end of IF)
2953 102 : if (zsFinalSizing.DesCoolLoad == 0) {
2954 : // Check CoolDDNum and TimeStepNumAtCoolMax value and default to 1 if not set, carried over from previous code
2955 6 : if (zsCalcFinalSizing.CoolDDNum == 0) {
2956 4 : zsCalcFinalSizing.CoolDDNum = 1;
2957 : }
2958 6 : if (zsCalcFinalSizing.TimeStepNumAtCoolMax == 0) {
2959 4 : zsCalcFinalSizing.TimeStepNumAtCoolMax = 1;
2960 : }
2961 6 : zsFinalSizing.TimeStepNumAtCoolMax = zsCalcFinalSizing.TimeStepNumAtCoolMax;
2962 6 : zsFinalSizing.CoolDDNum = zsCalcFinalSizing.CoolDDNum;
2963 6 : zsFinalSizing.CoolDesDay = zsCalcFinalSizing.CoolDesDay;
2964 6 : int DDNumF = zsFinalSizing.CoolDDNum;
2965 6 : auto &zoneSizingF = zsSizing(DDNumF, zoneOrSpaceNum);
2966 6 : int TimeStepAtPeakF = zsFinalSizing.TimeStepNumAtCoolMax;
2967 :
2968 : // initialize sizing conditions if they have not been set (i.e., no corresponding load) to zone condition
2969 : // issue 6006, heating coils sizing to 0 when no heating load in zone
2970 6 : if (zoneSizingF.DesCoolSetPtSeq.empty()) {
2971 0 : ShowSevereError(
2972 : state,
2973 0 : format("{}: Thermostat cooling set point temperatures are not initialized for Zone = {}", RoutineName, zsFinalSizing.ZoneName));
2974 0 : ShowFatalError(state, "Please send your input file to the EnergyPlus support/development team for further investigation.");
2975 : } else {
2976 6 : zsFinalSizing.ZoneTempAtCoolPeak = *std::min_element(zoneSizingF.DesCoolSetPtSeq.begin(), zoneSizingF.DesCoolSetPtSeq.end());
2977 : }
2978 6 : zsFinalSizing.OutTempAtCoolPeak = *std::min_element(zoneSizingF.CoolOutTempSeq.begin(), zoneSizingF.CoolOutTempSeq.end());
2979 6 : zsFinalSizing.OutHumRatAtCoolPeak = zoneSizingF.CoolOutHumRatSeq(TimeStepAtPeakF);
2980 6 : zsFinalSizing.ZoneHumRatAtCoolPeak = zoneSizingF.CoolDesHumRat;
2981 6 : zsCalcFinalSizing.ZoneTempAtCoolPeak = zoneSizingF.CoolZoneTempSeq(TimeStepAtPeakF);
2982 6 : zsCalcFinalSizing.ZoneHumRatAtCoolPeak = zoneSizingF.CoolZoneHumRatSeq(TimeStepAtPeakF);
2983 6 : zsCalcFinalSizing.ZoneRetTempAtCoolPeak = zsCalcFinalSizing.ZoneTempAtCoolPeak;
2984 6 : zsFinalSizing.DesCoolCoilInTemp = zsFinalSizing.ZoneTempAtCoolPeak;
2985 6 : zsFinalSizing.DesCoolCoilInHumRat = zsFinalSizing.ZoneHumRatAtCoolPeak;
2986 6 : zsFinalSizing.ZoneRetTempAtCoolPeak = zsFinalSizing.ZoneTempAtCoolPeak;
2987 : }
2988 : // update non air system design load and air flow to include the sizing factor
2989 102 : zsFinalSizing.NonAirSysDesHeatLoad *= zsFinalSizing.HeatSizingFactor;
2990 102 : zsFinalSizing.NonAirSysDesHeatVolFlow *= zsFinalSizing.HeatSizingFactor;
2991 : // Now take into account the user specified sizing factor or user specified heating design air flow rate (which overrides the
2992 : // sizing factor)
2993 102 : Real64 TotHeatSizMult = 0.0;
2994 : // Calculate a sizing factor from the user specified heating design air flow rate
2995 102 : if (zsFinalSizing.InpDesHeatAirFlow > 0.0 && zsFinalSizing.HeatAirDesMethod == AirflowSizingMethod::InpDesAirFlow &&
2996 0 : zsFinalSizing.DesHeatVolFlow > 0.0) {
2997 0 : TotHeatSizMult = (zsFinalSizing.InpDesHeatAirFlow / zsFinalSizing.DesHeatVolFlow) * zsFinalSizing.HeatSizingFactor;
2998 : // Calculate a sizing factor from the user specified max heating design air flow rates
2999 102 : } else if (zsFinalSizing.HeatAirDesMethod == AirflowSizingMethod::DesAirFlowWithLim && zsFinalSizing.DesHeatVolFlow > 0.0) {
3000 0 : Real64 MaxHeatVolFlow = max(
3001 0 : zsFinalSizing.DesHeatMaxAirFlow, zsFinalSizing.DesHeatMaxAirFlow2, zsFinalSizing.DesCoolVolFlow * zsFinalSizing.DesHeatMaxAirFlowFrac);
3002 0 : if (MaxHeatVolFlow < zsFinalSizing.DesHeatVolFlow) {
3003 0 : TotHeatSizMult = (MaxHeatVolFlow / zsFinalSizing.DesHeatVolFlow) * zsFinalSizing.HeatSizingFactor;
3004 : } else {
3005 0 : TotHeatSizMult = zsFinalSizing.HeatSizingFactor;
3006 : }
3007 : // If no user specified heating design air flow rate input, use the user specified sizing factor
3008 0 : } else {
3009 102 : TotHeatSizMult = zsFinalSizing.HeatSizingFactor;
3010 : }
3011 :
3012 102 : if (std::abs(TotHeatSizMult - 1.0) > 0.00001) {
3013 16 : if (zsFinalSizing.DesHeatVolFlow > 0.0) {
3014 14 : auto &desDayWeath = state.dataSize->DesDayWeath(zsFinalSizing.HeatDDNum);
3015 14 : zsFinalSizing.DesHeatVolFlow = zsCalcFinalSizing.DesHeatVolFlow * TotHeatSizMult;
3016 14 : zsFinalSizing.DesHeatMassFlow = zsCalcFinalSizing.DesHeatMassFlow * TotHeatSizMult;
3017 14 : zsFinalSizing.DesHeatLoad = zsCalcFinalSizing.DesHeatLoad * TotHeatSizMult;
3018 1742 : for (int i = 0; i < (int)zsFinalSizing.HeatFlowSeq.size(); ++i) {
3019 1728 : zsFinalSizing.HeatFlowSeq[i] = zsCalcFinalSizing.HeatFlowSeq[i] * TotHeatSizMult;
3020 1728 : zsFinalSizing.HeatLoadSeq[i] = zsCalcFinalSizing.HeatLoadSeq[i] * TotHeatSizMult;
3021 : }
3022 14 : Real64 OAFrac = zsFinalSizing.MinOA / zsFinalSizing.DesHeatVolFlow;
3023 14 : OAFrac = min(1.0, max(0.0, OAFrac));
3024 14 : zsFinalSizing.DesHeatCoilInTemp =
3025 14 : OAFrac * desDayWeath.Temp(zsFinalSizing.TimeStepNumAtHeatMax) + (1.0 - OAFrac) * zsFinalSizing.ZoneTempAtHeatPeak;
3026 14 : zsFinalSizing.DesHeatCoilInHumRat =
3027 14 : OAFrac * desDayWeath.HumRat(zsFinalSizing.TimeStepNumAtHeatMax) + (1.0 - OAFrac) * zsFinalSizing.ZoneHumRatAtHeatPeak;
3028 : } else {
3029 2 : zsFinalSizing.DesHeatVolFlow = zsFinalSizing.InpDesHeatAirFlow;
3030 2 : zsFinalSizing.DesHeatMassFlow = zsFinalSizing.DesHeatVolFlow * zsFinalSizing.DesHeatDens;
3031 : }
3032 44 : for (int DDNum = 1; DDNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DDNum) {
3033 28 : auto &zoneSizingDD = zsSizing(DDNum, zoneOrSpaceNum);
3034 28 : if (zoneSizingDD.DesHeatVolFlow > 0.0) {
3035 14 : auto &calcZoneSizing = zsCalcSizing(DDNum, zoneOrSpaceNum);
3036 14 : int TimeStepAtPeak = zoneSizingDD.TimeStepNumAtHeatMax;
3037 14 : zoneSizingDD.DesHeatVolFlow = calcZoneSizing.DesHeatVolFlow * TotHeatSizMult;
3038 14 : zoneSizingDD.DesHeatMassFlow = calcZoneSizing.DesHeatMassFlow * TotHeatSizMult;
3039 14 : zoneSizingDD.DesHeatLoad = calcZoneSizing.DesHeatLoad * TotHeatSizMult;
3040 1742 : for (int i = 0; i < (int)zoneSizingDD.HeatFlowSeq.size(); ++i) {
3041 1728 : zoneSizingDD.HeatFlowSeq[i] = calcZoneSizing.HeatFlowSeq[i] * TotHeatSizMult;
3042 1728 : zoneSizingDD.HeatLoadSeq[i] = calcZoneSizing.HeatLoadSeq[i] * TotHeatSizMult;
3043 : }
3044 14 : Real64 OAFrac = zoneSizingDD.MinOA / zoneSizingDD.DesHeatVolFlow;
3045 14 : OAFrac = min(1.0, max(0.0, OAFrac));
3046 14 : zoneSizingDD.DesHeatCoilInTemp =
3047 14 : OAFrac * state.dataSize->DesDayWeath(DDNum).Temp(TimeStepAtPeak) + (1.0 - OAFrac) * zoneSizingDD.ZoneTempAtHeatPeak;
3048 14 : zoneSizingDD.DesHeatCoilInHumRat =
3049 14 : OAFrac * state.dataSize->DesDayWeath(DDNum).HumRat(TimeStepAtPeak) + (1.0 - OAFrac) * zoneSizingDD.ZoneHumRatAtHeatPeak;
3050 : } else {
3051 14 : zoneSizingDD.DesHeatVolFlow = zoneSizingDD.InpDesHeatAirFlow;
3052 14 : zoneSizingDD.DesHeatMassFlow = zoneSizingDD.DesHeatVolFlow * zoneSizingDD.DesHeatDens;
3053 : }
3054 : // Save heating flows without MinOA for use later
3055 28 : zoneSizingDD.HeatFlowSeqNoOA = zoneSizingDD.HeatFlowSeq;
3056 28 : zoneSizingDD.DesHeatVolFlowNoOA = zoneSizingDD.DesHeatVolFlow;
3057 28 : zoneSizingDD.DesHeatMassFlowNoOA = zoneSizingDD.DesHeatMassFlow;
3058 : }
3059 : } else {
3060 252 : for (int DDNum = 1; DDNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DDNum) {
3061 : // initialize HeatFlowSeqNoOA before any adjustments to HeatFlowSeq
3062 166 : auto &zoneSizing = zsSizing(DDNum, zoneOrSpaceNum);
3063 166 : zoneSizing.HeatFlowSeqNoOA = zoneSizing.HeatFlowSeq;
3064 166 : zoneSizing.DesHeatVolFlowNoOA = zoneSizing.DesHeatVolFlow;
3065 166 : zoneSizing.DesHeatMassFlowNoOA = zoneSizing.DesHeatMassFlow;
3066 : }
3067 : }
3068 :
3069 : // Save a set of design heating air flow rates before the MinOA adjustment
3070 : // just in zsFinalSizing to use for TermUnit sizing adjustments in SizingManager::UpdateTermUnitFinalZoneSizing
3071 102 : zsFinalSizing.DesHeatVolFlowNoOA = zsFinalSizing.DesHeatVolFlow;
3072 102 : zsFinalSizing.DesHeatMassFlowNoOA = zsFinalSizing.DesHeatMassFlow;
3073 12200 : for (int TimeStepIndex = 1; TimeStepIndex <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++TimeStepIndex) {
3074 12098 : zsFinalSizing.HeatFlowSeqNoOA(TimeStepIndex) = zsFinalSizing.HeatFlowSeq(TimeStepIndex);
3075 : }
3076 :
3077 : // Now make sure that the design heating air flow rates are greater than or equal to MinOA
3078 102 : Real64 MinOAMass = zsFinalSizing.MinOA * zsFinalSizing.DesHeatDens;
3079 102 : if (zsFinalSizing.MinOA > zsFinalSizing.DesHeatVolFlow) {
3080 39 : zsFinalSizing.DesHeatVolFlow = zsFinalSizing.MinOA;
3081 39 : zsFinalSizing.DesHeatMassFlow = MinOAMass;
3082 : }
3083 12200 : for (int TimeStepIndex = 1; TimeStepIndex <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++TimeStepIndex) {
3084 12098 : if (MinOAMass > zsFinalSizing.HeatFlowSeq(TimeStepIndex)) {
3085 4228 : zsFinalSizing.HeatFlowSeq(TimeStepIndex) = MinOAMass;
3086 : }
3087 : }
3088 296 : for (int DDNum = 1; DDNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DDNum) {
3089 194 : auto &zoneSizingDD = zsSizing(DDNum, zoneOrSpaceNum);
3090 194 : MinOAMass = zoneSizingDD.MinOA * zoneSizingDD.DesHeatDens;
3091 194 : if (zoneSizingDD.MinOA > zoneSizingDD.DesHeatVolFlow) {
3092 95 : zoneSizingDD.DesHeatVolFlow = zoneSizingDD.MinOA;
3093 95 : zoneSizingDD.DesHeatMassFlow = MinOAMass;
3094 : }
3095 23332 : for (int TimeStepIndex = 1; TimeStepIndex <= state.dataZoneEquipmentManager->NumOfTimeStepInDay; ++TimeStepIndex) {
3096 23138 : if (MinOAMass > zoneSizingDD.HeatFlowSeq(TimeStepIndex)) {
3097 10468 : zoneSizingDD.HeatFlowSeq(TimeStepIndex) = MinOAMass;
3098 : }
3099 : }
3100 : }
3101 : // IF heating flow rate is 0, this data may be used to size a HP so initialize DDNum, TimeStepatPeak, and sizing data
3102 102 : if (zsFinalSizing.DesHeatLoad == 0) {
3103 : // Check HDDNum and TimeStepNumAtHeatMax value and default to 1 if not set, carried over from previous code
3104 18 : if (zsCalcFinalSizing.HeatDDNum == 0) {
3105 15 : zsCalcFinalSizing.HeatDDNum = 1;
3106 : }
3107 18 : if (zsCalcFinalSizing.TimeStepNumAtHeatMax == 0) {
3108 1 : zsCalcFinalSizing.TimeStepNumAtHeatMax = 1;
3109 : }
3110 18 : zsFinalSizing.TimeStepNumAtHeatMax = zsCalcFinalSizing.TimeStepNumAtHeatMax;
3111 18 : zsFinalSizing.HeatDDNum = zsCalcFinalSizing.HeatDDNum;
3112 18 : zsFinalSizing.HeatDesDay = zsCalcFinalSizing.HeatDesDay;
3113 18 : int DDNumF = zsFinalSizing.HeatDDNum;
3114 18 : auto &zoneSizingDDF = zsSizing(DDNumF, zoneOrSpaceNum);
3115 18 : int TimeStepAtPeakF = zsFinalSizing.TimeStepNumAtHeatMax;
3116 :
3117 : // initialize sizing conditions if they have not been set (i.e., no corresponding load) to zone condition
3118 : // issue 6006, heating coils sizing to 0 when no heating load in zone
3119 18 : if (zoneSizingDDF.DesHeatSetPtSeq.empty()) {
3120 0 : ShowSevereError(
3121 0 : state, format("{}: Thermostat heating set point temperatures not initialized for Zone = {}", RoutineName, zsFinalSizing.ZoneName));
3122 0 : ShowFatalError(state, "Please send your input file to the EnergyPlus support/development team for further investigation.");
3123 : } else {
3124 18 : zsFinalSizing.ZoneTempAtHeatPeak = *std::max_element(zoneSizingDDF.DesHeatSetPtSeq.begin(), zoneSizingDDF.DesHeatSetPtSeq.end());
3125 : }
3126 18 : zsFinalSizing.OutTempAtHeatPeak = *std::min_element(zoneSizingDDF.HeatOutTempSeq.begin(), zoneSizingDDF.HeatOutTempSeq.end());
3127 18 : zsFinalSizing.OutHumRatAtHeatPeak = zoneSizingDDF.HeatOutHumRatSeq(TimeStepAtPeakF);
3128 18 : zsFinalSizing.ZoneHumRatAtHeatPeak = zoneSizingDDF.HeatDesHumRat;
3129 18 : zsCalcFinalSizing.ZoneTempAtHeatPeak = zoneSizingDDF.HeatZoneTempSeq(TimeStepAtPeakF);
3130 18 : zsCalcFinalSizing.ZoneHumRatAtHeatPeak = zoneSizingDDF.HeatZoneHumRatSeq(TimeStepAtPeakF);
3131 18 : zsCalcFinalSizing.ZoneRetTempAtHeatPeak = zsCalcFinalSizing.ZoneTempAtHeatPeak;
3132 18 : zsFinalSizing.DesHeatCoilInTemp = zsFinalSizing.ZoneTempAtHeatPeak;
3133 18 : zsFinalSizing.DesHeatCoilInHumRat = zsFinalSizing.ZoneHumRatAtHeatPeak;
3134 18 : zsFinalSizing.ZoneRetTempAtHeatPeak = zsFinalSizing.ZoneTempAtHeatPeak;
3135 : }
3136 :
3137 : // set the zone minimum cooling supply air flow rate. This will be used for autosizing VAV terminal unit
3138 : // minimum flow rates (comment seems incorrect, really used as a minimum lower limit for the maximum air flow)
3139 102 : zsFinalSizing.DesCoolVolFlowMin =
3140 102 : max(zsFinalSizing.DesCoolMinAirFlow, zsFinalSizing.DesCoolMinAirFlow2, zsFinalSizing.DesCoolVolFlow * zsFinalSizing.DesCoolMinAirFlowFrac);
3141 : // set the zone maximum heating supply air flow rate. This will be used for autosizing VAV terminal unit
3142 : // max heating flow rates
3143 204 : zsFinalSizing.DesHeatVolFlowMax = max(zsFinalSizing.DesHeatMaxAirFlow,
3144 : zsFinalSizing.DesHeatMaxAirFlow2,
3145 102 : max(zsFinalSizing.DesCoolVolFlow, zsFinalSizing.DesHeatVolFlow) * zsFinalSizing.DesHeatMaxAirFlowFrac);
3146 : // Determine the design cooling supply air temperature if the supply air temperature difference is specified by user.
3147 102 : if (zsFinalSizing.ZnCoolDgnSAMethod == TemperatureDifference) {
3148 0 : zsFinalSizing.CoolDesTemp = zsFinalSizing.ZoneTempAtCoolPeak - std::abs(zsFinalSizing.CoolDesTempDiff);
3149 : }
3150 : // Determine the design heating supply air temperature if the supply air temperature difference is specified by user.
3151 102 : if (zsFinalSizing.ZnHeatDgnSAMethod == TemperatureDifference) {
3152 0 : zsFinalSizing.HeatDesTemp = zsFinalSizing.ZoneTempAtHeatPeak + std::abs(zsFinalSizing.HeatDesTempDiff);
3153 : }
3154 102 : }
3155 :
3156 12685 : void UpdateZoneSizing(EnergyPlusData &state, Constant::CallIndicator const CallIndicator)
3157 : {
3158 :
3159 : // SUBROUTINE INFORMATION:
3160 : // AUTHOR Fred Buhl
3161 : // DATE WRITTEN December 2000
3162 :
3163 : // PURPOSE OF THIS SUBROUTINE:
3164 : // Update the result variables of the zone sizing calculation
3165 :
3166 : // METHODOLOGY EMPLOYED:
3167 : // CallIndicator = 1 (BeginDay) zero the result arrays
3168 : // CallIndicator = 2 (DuringDay) fill arrays, averaging over 1 zone time step
3169 : // CallIndicator = 3 (EndDay) calculate daily maxima
3170 : // CallIndicator = 4 (EndZoneSizingCalc) write out results
3171 :
3172 12685 : switch (CallIndicator) {
3173 104 : case Constant::CallIndicator::BeginDay: {
3174 278 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
3175 :
3176 174 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
3177 :
3178 : // auto &calcZoneSizing = state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum);
3179 152 : updateZoneSizingBeginDay(state, state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum));
3180 152 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3181 56 : for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) {
3182 42 : updateZoneSizingBeginDay(state, state.dataSize->CalcSpaceSizing(state.dataSize->CurOverallSimDay, spaceNum));
3183 : }
3184 : }
3185 : }
3186 104 : } break;
3187 12318 : case Constant::CallIndicator::DuringDay: {
3188 12318 : int timeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
3189 12318 : Real64 fracTimeStepZone = state.dataHVACGlobal->FracTimeStepZone;
3190 :
3191 : // save the results of the ideal zone component calculation in the CalcZoneSizing sequence variables
3192 32903 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
3193 20585 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
3194 :
3195 17858 : auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(CtrlZoneNum);
3196 : // auto &zoneSizing = state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum);
3197 : // auto &calcZoneSizing = state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum);
3198 : // auto const &zoneThermostatHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(CtrlZoneNum);
3199 : // auto const &zoneThermostatLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(CtrlZoneNum);
3200 17858 : updateZoneSizingDuringDay(state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum),
3201 17858 : state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum),
3202 17858 : zoneTstatSetpt.setptHi,
3203 17858 : zoneTstatSetpt.setptLo,
3204 17858 : state.dataSize->FinalZoneSizing(CtrlZoneNum).ZoneSizThermSetPtHi,
3205 17858 : state.dataSize->FinalZoneSizing(CtrlZoneNum).ZoneSizThermSetPtLo,
3206 : timeStepInDay,
3207 : fracTimeStepZone);
3208 17858 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3209 8064 : for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) {
3210 6048 : updateZoneSizingDuringDay(state.dataSize->SpaceSizing(state.dataSize->CurOverallSimDay, spaceNum),
3211 6048 : state.dataSize->CalcSpaceSizing(state.dataSize->CurOverallSimDay, spaceNum),
3212 6048 : zoneTstatSetpt.setptHi,
3213 6048 : zoneTstatSetpt.setptLo,
3214 6048 : state.dataSize->FinalZoneSizing(CtrlZoneNum).ZoneSizThermSetPtHi,
3215 6048 : state.dataSize->FinalZoneSizing(CtrlZoneNum).ZoneSizThermSetPtLo,
3216 : timeStepInDay,
3217 : fracTimeStepZone);
3218 : }
3219 : }
3220 : }
3221 12318 : } break;
3222 206 : case Constant::CallIndicator::EndDay: {
3223 : // average some of the zone sequences to reduce peakiness
3224 552 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
3225 346 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
3226 : // auto &calcZoneSizing(state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum));
3227 302 : updateZoneSizingEndDayMovingAvg(state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum),
3228 302 : state.dataSize->NumTimeStepsInAvg);
3229 302 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3230 112 : for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) {
3231 84 : updateZoneSizingEndDayMovingAvg(state.dataSize->CalcSpaceSizing(state.dataSize->CurOverallSimDay, spaceNum),
3232 84 : state.dataSize->NumTimeStepsInAvg);
3233 : }
3234 : }
3235 : }
3236 :
3237 : // auto &desDayWeath = state.dataSize->DesDayWeath(state.dataSize->CurOverallSimDay);
3238 552 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
3239 346 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
3240 : // auto &calcZoneSizing = state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum);
3241 : // auto &calcFinalZoneSizing = state.dataSize->CalcFinalZoneSizing(CtrlZoneNum);
3242 302 : updateZoneSizingEndDay(state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum),
3243 302 : state.dataSize->CalcFinalZoneSizing(CtrlZoneNum),
3244 302 : state.dataZoneEquipmentManager->NumOfTimeStepInDay,
3245 302 : state.dataSize->DesDayWeath(state.dataSize->CurOverallSimDay),
3246 302 : state.dataEnvrn->StdRhoAir);
3247 302 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3248 112 : for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) {
3249 84 : updateZoneSizingEndDay(state.dataSize->CalcSpaceSizing(state.dataSize->CurOverallSimDay, spaceNum),
3250 84 : state.dataSize->CalcFinalSpaceSizing(spaceNum),
3251 84 : state.dataZoneEquipmentManager->NumOfTimeStepInDay,
3252 84 : state.dataSize->DesDayWeath(state.dataSize->CurOverallSimDay),
3253 84 : state.dataEnvrn->StdRhoAir);
3254 : }
3255 : }
3256 : }
3257 206 : } break;
3258 57 : case Constant::CallIndicator::EndZoneSizingCalc: {
3259 : // candidate EMS calling point to customize CalcFinalZoneSizing
3260 : bool anyEMSRan;
3261 57 : EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::ZoneSizing, anyEMSRan, ObjexxFCL::Optional_int_const());
3262 :
3263 : // now apply EMS overrides (if any)
3264 57 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
3265 4 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
3266 3 : auto &calcFinalZoneSizing = state.dataSize->CalcFinalZoneSizing(CtrlZoneNum);
3267 3 : if (calcFinalZoneSizing.EMSOverrideDesHeatMassOn) {
3268 0 : if (calcFinalZoneSizing.DesHeatMassFlow > 0.0) calcFinalZoneSizing.DesHeatMassFlow = calcFinalZoneSizing.EMSValueDesHeatMassFlow;
3269 : }
3270 3 : if (calcFinalZoneSizing.EMSOverrideDesCoolMassOn) {
3271 0 : if (calcFinalZoneSizing.DesCoolMassFlow > 0.0) calcFinalZoneSizing.DesCoolMassFlow = calcFinalZoneSizing.EMSValueDesCoolMassFlow;
3272 : }
3273 3 : if (calcFinalZoneSizing.EMSOverrideDesHeatLoadOn) {
3274 0 : if (calcFinalZoneSizing.DesHeatLoad > 0.0) calcFinalZoneSizing.DesHeatLoad = calcFinalZoneSizing.EMSValueDesHeatLoad;
3275 : }
3276 3 : if (calcFinalZoneSizing.EMSOverrideDesCoolLoadOn) {
3277 0 : if (calcFinalZoneSizing.DesCoolLoad > 0.0) calcFinalZoneSizing.DesCoolLoad = calcFinalZoneSizing.EMSValueDesCoolLoad;
3278 : }
3279 3 : if (calcFinalZoneSizing.EMSOverrideDesHeatVolOn) {
3280 0 : if (calcFinalZoneSizing.DesHeatVolFlow > 0.0) calcFinalZoneSizing.DesHeatVolFlow = calcFinalZoneSizing.EMSValueDesHeatVolFlow;
3281 : }
3282 3 : if (calcFinalZoneSizing.EMSOverrideDesCoolVolOn) {
3283 0 : if (calcFinalZoneSizing.DesCoolVolFlow > 0.0) calcFinalZoneSizing.DesCoolVolFlow = calcFinalZoneSizing.EMSValueDesCoolVolFlow;
3284 : }
3285 : }
3286 : }
3287 :
3288 57 : if (!state.dataGlobal->isPulseZoneSizing) {
3289 :
3290 : // Apply non-coincident zone sizing - only if space sizing is active, and only if there is more than one space in the zone
3291 49 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3292 14 : for (int ctrlZoneNum = 1; ctrlZoneNum <= state.dataGlobal->NumOfZones; ++ctrlZoneNum) {
3293 7 : if (!state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum).IsControlled) continue;
3294 7 : if (state.dataHeatBal->Zone(ctrlZoneNum).numSpaces == 1) continue;
3295 7 : updateZoneSizingEndZoneSizingCalc1(state, ctrlZoneNum);
3296 : }
3297 : }
3298 :
3299 128 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
3300 79 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
3301 70 : updateZoneSizingEndZoneSizingCalc2(state, state.dataSize->CalcFinalZoneSizing(CtrlZoneNum));
3302 70 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3303 28 : for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) {
3304 21 : updateZoneSizingEndZoneSizingCalc2(state, state.dataSize->CalcFinalSpaceSizing(spaceNum));
3305 : }
3306 : }
3307 : }
3308 :
3309 : // Write zone sizing (zsz) and space sizing (spsz) outputs
3310 49 : if (state.dataSize->SizingFileColSep == DataStringGlobals::CharComma) {
3311 49 : state.files.zsz.filePath = state.files.outputZszCsvFilePath;
3312 0 : } else if (state.dataSize->SizingFileColSep == DataStringGlobals::CharTab) {
3313 0 : state.files.zsz.filePath = state.files.outputZszTabFilePath;
3314 : } else {
3315 0 : state.files.zsz.filePath = state.files.outputZszTxtFilePath;
3316 : }
3317 98 : state.files.zsz.ensure_open(state, "UpdateZoneSizing", state.files.outputControl.zsz);
3318 :
3319 49 : bool forSpaces = false;
3320 98 : writeZszSpsz(
3321 49 : state, state.files.zsz, state.dataGlobal->NumOfZones, state.dataSize->CalcFinalZoneSizing, state.dataSize->CalcZoneSizing, forSpaces);
3322 :
3323 49 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3324 7 : if (state.dataSize->SizingFileColSep == DataStringGlobals::CharComma) {
3325 7 : state.files.spsz.filePath = state.files.outputSpszCsvFilePath;
3326 0 : } else if (state.dataSize->SizingFileColSep == DataStringGlobals::CharTab) {
3327 0 : state.files.spsz.filePath = state.files.outputSpszTabFilePath;
3328 : } else {
3329 0 : state.files.spsz.filePath = state.files.outputSpszTxtFilePath;
3330 : }
3331 14 : state.files.spsz.ensure_open(state, "UpdateZoneSizing", state.files.outputControl.spsz);
3332 :
3333 7 : forSpaces = true;
3334 14 : writeZszSpsz(state,
3335 7 : state.files.spsz,
3336 7 : state.dataGlobal->numSpaces,
3337 7 : state.dataSize->CalcFinalSpaceSizing,
3338 7 : state.dataSize->CalcSpaceSizing,
3339 : forSpaces);
3340 : }
3341 :
3342 : // Move sizing data into final sizing array according to sizing method
3343 128 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
3344 79 : if (!state.dataZoneEquip->ZoneEquipConfig(zoneNum).IsControlled) continue;
3345 : // if this zone does not use latent sizing, skip zone and retain sensible load variables
3346 70 : if (!state.dataSize->CalcFinalZoneSizing(zoneNum).zoneLatentSizing) continue;
3347 4 : updateZoneSizingEndZoneSizingCalc3(
3348 4 : state.dataSize->CalcFinalZoneSizing(zoneNum), state.dataSize->CalcZoneSizing, state.dataHeatBal->isAnyLatentLoad, zoneNum);
3349 4 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3350 12 : for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
3351 9 : updateZoneSizingEndZoneSizingCalc3(state.dataSize->CalcFinalSpaceSizing(spaceNum),
3352 9 : state.dataSize->CalcSpaceSizing,
3353 9 : state.dataHeatBal->isAnyLatentLoad,
3354 : spaceNum);
3355 : }
3356 : }
3357 : }
3358 : }
3359 :
3360 : // Move data from Calc arrays to user modified arrays
3361 :
3362 231 : for (std::size_t i = 0; i < state.dataSize->ZoneSizing.size(); ++i) {
3363 174 : updateZoneSizingEndZoneSizingCalc4(state.dataSize->ZoneSizing[i], state.dataSize->CalcZoneSizing[i]);
3364 174 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3365 104 : for (std::size_t j = 0; j < state.dataSize->SpaceSizing.size(); ++j) {
3366 90 : updateZoneSizingEndZoneSizingCalc4(state.dataSize->SpaceSizing[j], state.dataSize->CalcSpaceSizing[j]);
3367 : }
3368 : }
3369 : }
3370 :
3371 149 : for (std::size_t i = 0; i < state.dataSize->FinalZoneSizing.size(); ++i) {
3372 92 : updateZoneSizingEndZoneSizingCalc5(state.dataSize->FinalZoneSizing[i], state.dataSize->CalcFinalZoneSizing[i]);
3373 92 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3374 28 : for (std::size_t j = 0; j < state.dataSize->FinalSpaceSizing.size(); ++j) {
3375 21 : updateZoneSizingEndZoneSizingCalc5(state.dataSize->FinalSpaceSizing[j], state.dataSize->CalcFinalSpaceSizing[j]);
3376 : }
3377 : }
3378 : }
3379 :
3380 161 : for (int DesDayNum = 1; DesDayNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DesDayNum) {
3381 278 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
3382 174 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
3383 152 : updateZoneSizingEndZoneSizingCalc6(state.dataSize->ZoneSizing(DesDayNum, CtrlZoneNum),
3384 152 : state.dataSize->CalcZoneSizing(DesDayNum, CtrlZoneNum),
3385 152 : state.dataZoneEquipmentManager->NumOfTimeStepInDay);
3386 152 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3387 56 : for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) {
3388 42 : updateZoneSizingEndZoneSizingCalc6(state.dataSize->SpaceSizing(DesDayNum, spaceNum),
3389 42 : state.dataSize->CalcSpaceSizing(DesDayNum, spaceNum),
3390 42 : state.dataZoneEquipmentManager->NumOfTimeStepInDay);
3391 : }
3392 : }
3393 : }
3394 : }
3395 :
3396 149 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
3397 92 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
3398 : // Yes, call updateZoneSizingEndZoneSizingCalc6 again here to copy the same fields
3399 81 : updateZoneSizingEndZoneSizingCalc6(state.dataSize->FinalZoneSizing(CtrlZoneNum),
3400 81 : state.dataSize->CalcFinalZoneSizing(CtrlZoneNum),
3401 81 : state.dataZoneEquipmentManager->NumOfTimeStepInDay);
3402 81 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3403 28 : for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) {
3404 21 : updateZoneSizingEndZoneSizingCalc6(state.dataSize->FinalSpaceSizing(spaceNum),
3405 21 : state.dataSize->CalcFinalSpaceSizing(spaceNum),
3406 21 : state.dataZoneEquipmentManager->NumOfTimeStepInDay);
3407 : }
3408 : }
3409 : }
3410 149 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
3411 92 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
3412 162 : updateZoneSizingEndZoneSizingCalc7(state,
3413 81 : state.dataSize->FinalZoneSizing(CtrlZoneNum),
3414 81 : state.dataSize->CalcFinalZoneSizing(CtrlZoneNum),
3415 81 : state.dataSize->ZoneSizing,
3416 81 : state.dataSize->CalcZoneSizing,
3417 : CtrlZoneNum);
3418 81 : if (state.dataHeatBal->doSpaceHeatBalanceSizing) {
3419 28 : for (int spaceNum : state.dataHeatBal->Zone(CtrlZoneNum).spaceIndexes) {
3420 42 : updateZoneSizingEndZoneSizingCalc7(state,
3421 21 : state.dataSize->FinalSpaceSizing(spaceNum),
3422 21 : state.dataSize->CalcFinalSpaceSizing(spaceNum),
3423 21 : state.dataSize->SpaceSizing,
3424 21 : state.dataSize->CalcSpaceSizing,
3425 : spaceNum);
3426 : }
3427 : }
3428 : }
3429 57 : } break;
3430 0 : default:
3431 0 : break;
3432 : }
3433 12685 : }
3434 :
3435 424466 : void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool &SimAir)
3436 : {
3437 :
3438 : // SUBROUTINE INFORMATION:
3439 : // AUTHOR Russ Taylor
3440 : // DATE WRITTEN May 1997
3441 : // MODIFIED Raustad/Shirey, FSEC, June 2003
3442 : // MODIFIED Gu, FSEC, Jan. 2004, Don Shirey, Aug 2009 (LatOutputProvided)
3443 : // July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
3444 :
3445 : // PURPOSE OF THIS SUBROUTINE:
3446 : // This subroutine is responsible for determining
3447 : // how much of each type of energy every zone requires.
3448 : // In effect, this subroutine defines and simulates all
3449 : // the system types and in the case of hybrid systems
3450 : // which use more than one type of energy must determine
3451 : // how to apportion the load. An example of a hybrid system
3452 : // is a water loop heat pump with supplemental air. In
3453 : // this case, a zone will require water from the loop and
3454 : // cooled or heated air from the air system. A simpler
3455 : // example would be a VAV system with baseboard heaters
3456 :
3457 : // METHODOLOGY EMPLOYED:
3458 : // 1. Determine zone load - this is zone temperature dependent
3459 : // 2. Determine balance point - the temperature at which the
3460 : // zone load is balanced by the system output. The way the
3461 : // balance point is determined will be different depending on
3462 : // the type of system being simulated.
3463 : // 3. Calculate zone energy requirements
3464 :
3465 424466 : bool SupPathInletChanged = false;
3466 424466 : Real64 SysOutputProvided = 0.0; // sensible output delivered by zone equipment (W)
3467 424466 : Real64 LatOutputProvided = 0.0; // latent output delivered by zone equipment (kg/s)
3468 424466 : Real64 AirSysOutput = 0.0;
3469 424466 : Real64 NonAirSysOutput = 0.0;
3470 :
3471 : // Determine flow rate and temperature of supply air based on type of damper
3472 :
3473 424466 : bool FirstCall = true; // indicates first call to supply air path components
3474 424466 : bool ErrorFlag = false;
3475 :
3476 500315 : for (int SupplyAirPathNum = 1; SupplyAirPathNum <= state.dataZoneEquip->NumSupplyAirPaths; ++SupplyAirPathNum) {
3477 :
3478 151699 : for (int CompNum = 1; CompNum <= state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).NumOfComponents; ++CompNum) {
3479 :
3480 75850 : switch (state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentTypeEnum(CompNum)) {
3481 75849 : case DataZoneEquipment::AirLoopHVACZone::Splitter: { // 'AirLoopHVAC:ZoneSplitter'
3482 :
3483 75849 : if (!(state.afn->AirflowNetworkFanActivated && state.afn->distribution_simulated)) {
3484 67556 : SplitterComponent::SimAirLoopSplitter(state,
3485 67556 : state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentName(CompNum),
3486 : FirstHVACIteration,
3487 : FirstCall,
3488 : SupPathInletChanged,
3489 67556 : state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentIndex(CompNum));
3490 : }
3491 :
3492 75849 : break;
3493 : }
3494 1 : case DataZoneEquipment::AirLoopHVACZone::SupplyPlenum: { // 'AirLoopHVAC:SupplyPlenum'
3495 :
3496 2 : ZonePlenum::SimAirZonePlenum(state,
3497 1 : state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentName(CompNum),
3498 : DataZoneEquipment::AirLoopHVACZone::SupplyPlenum,
3499 1 : state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentIndex(CompNum),
3500 : FirstHVACIteration,
3501 : FirstCall,
3502 : SupPathInletChanged);
3503 :
3504 1 : break;
3505 : }
3506 0 : default: {
3507 0 : ShowSevereError(state, format("Error found in Supply Air Path={}", state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).Name));
3508 0 : ShowContinueError(
3509 : state,
3510 0 : format("Invalid Supply Air Path Component={}", state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentType(CompNum)));
3511 0 : ShowFatalError(state, "Preceding condition causes termination.");
3512 :
3513 0 : break;
3514 : }
3515 : }
3516 : }
3517 : }
3518 :
3519 424466 : FirstCall = false;
3520 :
3521 : // Loop over all the primary air loop; simulate their components (equipment)
3522 : // and controllers
3523 424466 : if (state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) {
3524 0 : if (FirstHVACIteration) {
3525 0 : CalcAirFlowSimple(state, 0);
3526 : } else {
3527 0 : CalcAirFlowSimple(
3528 0 : state, 0, state.dataHeatBal->ZoneAirMassFlow.AdjustZoneMixingFlow, state.dataHeatBal->ZoneAirMassFlow.AdjustZoneInfiltrationFlow);
3529 : }
3530 : }
3531 :
3532 : // If SpaceHVAC is active calculate SpaceHVAC:EquipmentMixer outlet conditions before simulating zone equipment
3533 424466 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation && !state.dataGlobal->DoingSizing) {
3534 36872 : for (auto &thisSpaceHVACMixer : state.dataZoneEquip->zoneEquipMixer) {
3535 0 : thisSpaceHVACMixer.setOutletConditions(state);
3536 : }
3537 : }
3538 :
3539 972152 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
3540 :
3541 547687 : if (!state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).IsControlled) continue;
3542 146079 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ControlledZoneNum);
3543 :
3544 146079 : thisZoneHB.NonAirSystemResponse = 0.0;
3545 146079 : thisZoneHB.SysDepZoneLoads = 0.0;
3546 146079 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum);
3547 146079 : zoneEquipConfig.ZoneExh = 0.0;
3548 146079 : zoneEquipConfig.ZoneExhBalanced = 0.0;
3549 146079 : zoneEquipConfig.PlenumMassFlow = 0.0;
3550 146079 : state.dataSize->CurZoneEqNum = ControlledZoneNum;
3551 146079 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation && !state.dataGlobal->DoingSizing) {
3552 0 : for (int spaceNum : state.dataHeatBal->Zone(ControlledZoneNum).spaceIndexes) {
3553 0 : auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum);
3554 0 : thisSpaceHB.NonAirSystemResponse = 0.0;
3555 0 : thisSpaceHB.SysDepZoneLoads = 0.0;
3556 0 : auto &thisSpaceEquipConfig = state.dataZoneEquip->spaceEquipConfig(spaceNum);
3557 0 : if (!thisSpaceEquipConfig.IsControlled) continue;
3558 0 : thisSpaceEquipConfig.ZoneExh = 0.0;
3559 0 : thisSpaceEquipConfig.ZoneExhBalanced = 0.0;
3560 0 : thisSpaceEquipConfig.PlenumMassFlow = 0.0;
3561 : }
3562 : }
3563 :
3564 146079 : InitSystemOutputRequired(state, ControlledZoneNum, FirstHVACIteration, true);
3565 :
3566 354410 : for (int EquipTypeNum = 1; EquipTypeNum <= state.dataZoneEquip->ZoneEquipList(ControlledZoneNum).NumOfEquipTypes; ++EquipTypeNum) {
3567 :
3568 : // Air loop system availability manager status only applies to PIU and exhaust fans
3569 : // Reset fan SAM operation flags for zone fans.
3570 208332 : state.dataHVACGlobal->TurnFansOn = false;
3571 208332 : state.dataHVACGlobal->TurnFansOff = false;
3572 :
3573 208332 : state.dataHVACGlobal->UnbalExhMassFlow = 0.0;
3574 208332 : state.dataHVACGlobal->BalancedExhMassFlow = 0.0;
3575 208332 : state.dataHVACGlobal->PlenumInducedMassFlow = 0.0;
3576 208332 : const int EquipPtr = state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipPtr;
3577 208332 : SysOutputProvided = 0.0;
3578 208332 : LatOutputProvided = 0.0;
3579 208332 : NonAirSysOutput = 0.0;
3580 208332 : state.dataSize->DataCoolCoilCap = 0.0; // reset global variable used only for heat pumps (i.e., DX cooling and heating coils)
3581 :
3582 : // Reset ZoneEqSizing data (because these may change from one equipment type to the next)
3583 208332 : if (state.dataZoneEquipmentManager->FirstPassZoneEquipFlag) {
3584 103 : auto &zoneEqSizing = state.dataSize->ZoneEqSizing(ControlledZoneNum);
3585 :
3586 103 : zoneEqSizing.AirVolFlow = 0.0;
3587 103 : zoneEqSizing.MaxHWVolFlow = 0.0;
3588 103 : zoneEqSizing.MaxCWVolFlow = 0.0;
3589 103 : zoneEqSizing.OAVolFlow = 0.0;
3590 103 : zoneEqSizing.DesCoolingLoad = 0.0;
3591 103 : zoneEqSizing.DesHeatingLoad = 0.0;
3592 103 : zoneEqSizing.CoolingAirVolFlow = 0.0;
3593 103 : zoneEqSizing.HeatingAirVolFlow = 0.0;
3594 103 : zoneEqSizing.SystemAirVolFlow = 0.0;
3595 103 : zoneEqSizing.AirFlow = false;
3596 103 : zoneEqSizing.CoolingAirFlow = false;
3597 103 : zoneEqSizing.HeatingAirFlow = false;
3598 103 : zoneEqSizing.SystemAirFlow = false;
3599 103 : zoneEqSizing.Capacity = false;
3600 103 : zoneEqSizing.CoolingCapacity = false;
3601 103 : zoneEqSizing.HeatingCapacity = false;
3602 103 : zoneEqSizing.SystemCapacity = false;
3603 103 : zoneEqSizing.DesignSizeFromParent = false;
3604 : }
3605 :
3606 208332 : DataZoneEquipment::ZoneEquipType zoneEquipType = state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).equipType;
3607 :
3608 208332 : auto &zoneEquipList = state.dataZoneEquip->ZoneEquipList(state.dataSize->CurZoneEqNum);
3609 :
3610 208332 : const int ZoneCompNum = zoneEquipList.EquipIndex(EquipPtr);
3611 :
3612 208332 : bool ValidSAMComp = false;
3613 :
3614 208332 : if ((int)zoneEquipType <= NumValidSysAvailZoneComponents) ValidSAMComp = true;
3615 :
3616 208332 : if (ZoneCompNum > 0 && ValidSAMComp) {
3617 :
3618 40983 : Avail::GetZoneEqAvailabilityManager(state, zoneEquipType, ZoneCompNum, ErrorFlag);
3619 :
3620 40983 : if (state.dataAvail->ZoneComp((int)zoneEquipType).ZoneCompAvailMgrs(ZoneCompNum).availStatus == Avail::Status::CycleOn) {
3621 1 : state.dataHVACGlobal->TurnFansOn = true;
3622 1 : state.dataHVACGlobal->TurnFansOff = false;
3623 40982 : } else if (state.dataAvail->ZoneComp((int)zoneEquipType).ZoneCompAvailMgrs(ZoneCompNum).availStatus == Avail::Status::ForceOff) {
3624 0 : state.dataHVACGlobal->TurnFansOn = false;
3625 0 : state.dataHVACGlobal->TurnFansOff = true;
3626 : }
3627 : }
3628 :
3629 : // If SpaceHVAC is active and this equipment has a space splitter, scale the zone load if needed
3630 208332 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation && !state.dataGlobal->DoingSizing &&
3631 0 : zoneEquipList.zoneEquipSplitterIndex(EquipPtr) > -1) {
3632 0 : state.dataZoneEquip->zoneEquipSplitter[zoneEquipList.zoneEquipSplitterIndex(EquipPtr)].adjustLoads(
3633 : state, ControlledZoneNum, EquipTypeNum);
3634 : }
3635 :
3636 208332 : switch (zoneEquipType) {
3637 120333 : case ZoneEquipType::AirDistributionUnit: { // 'ZoneHVAC:AirDistributionUnit'
3638 : // Air loop system availability manager status only applies to PIU and exhaust fans
3639 : // Check to see if System Availability Managers are asking for fans to cycle on or shut off
3640 : // and set fan on/off flags accordingly.
3641 130289 : if (state.dataZoneEquip->ZoneEquipAvail(ControlledZoneNum) == Avail::Status::CycleOn ||
3642 9956 : state.dataZoneEquip->ZoneEquipAvail(ControlledZoneNum) == Avail::Status::CycleOnZoneFansOnly) {
3643 110377 : state.dataHVACGlobal->TurnFansOn = true;
3644 : }
3645 120333 : if (state.dataZoneEquip->ZoneEquipAvail(ControlledZoneNum) == Avail::Status::ForceOff) {
3646 0 : state.dataHVACGlobal->TurnFansOff = true;
3647 : }
3648 :
3649 120333 : ZoneAirLoopEquipmentManager::ManageZoneAirLoopEquipment(state,
3650 120333 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3651 : FirstHVACIteration,
3652 : AirSysOutput,
3653 : NonAirSysOutput,
3654 : LatOutputProvided,
3655 : ControlledZoneNum,
3656 : zoneEquipList.EquipIndex(EquipPtr));
3657 :
3658 120332 : SysOutputProvided = NonAirSysOutput + AirSysOutput;
3659 120332 : } break;
3660 :
3661 7069 : case ZoneEquipType::VariableRefrigerantFlowTerminal: { // 'ZoneHVAC:TerminalUnit:VariableRefrigerantFlow'
3662 7069 : bool HeatingActive = false;
3663 7069 : bool CoolingActive = false;
3664 7069 : int constexpr OAUnitNum = 0;
3665 7069 : Real64 constexpr OAUCoilOutTemp = 0.0;
3666 7069 : bool constexpr ZoneEquipment = true;
3667 14138 : HVACVariableRefrigerantFlow::SimulateVRF(state,
3668 7069 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3669 : FirstHVACIteration,
3670 : ControlledZoneNum,
3671 : zoneEquipList.EquipIndex(EquipPtr),
3672 : HeatingActive,
3673 : CoolingActive,
3674 : OAUnitNum,
3675 : OAUCoilOutTemp,
3676 : ZoneEquipment,
3677 : SysOutputProvided,
3678 : LatOutputProvided);
3679 7069 : } break;
3680 :
3681 5558 : case ZoneEquipType::WindowAirConditioner: { // 'ZoneHVAC:WindowAirConditioner'
3682 11116 : WindowAC::SimWindowAC(state,
3683 5558 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3684 : ControlledZoneNum,
3685 : FirstHVACIteration,
3686 : SysOutputProvided,
3687 : LatOutputProvided,
3688 : zoneEquipList.EquipIndex(EquipPtr));
3689 5558 : } break;
3690 :
3691 6961 : case ZoneEquipType::PackagedTerminalHeatPump: // 'ZoneHVAC:PackagedTerminalHeatPump'
3692 : case ZoneEquipType::PackagedTerminalAirConditioner: // 'ZoneHVAC:PackagedTerminalAirConditioner'
3693 : case ZoneEquipType::PackagedTerminalHeatPumpWaterToAir: // 'ZoneHVAC:WaterToAirHeatPump'
3694 : case ZoneEquipType::UnitarySystem: { // 'AirloopHVAC:UnitarySystem'
3695 6961 : int AirLoopNum = 0;
3696 6961 : bool HeatingActive = false;
3697 6961 : bool CoolingActive = false;
3698 6961 : int OAUnitNum = 0;
3699 6961 : Real64 OAUCoilOutTemp = 0.0;
3700 6961 : bool ZoneEquipFlag = true;
3701 13922 : zoneEquipList.compPointer[EquipPtr]->simulate(state,
3702 6961 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3703 : FirstHVACIteration,
3704 : AirLoopNum,
3705 : zoneEquipList.EquipIndex(EquipPtr),
3706 : HeatingActive,
3707 : CoolingActive,
3708 : OAUnitNum,
3709 : OAUCoilOutTemp,
3710 : ZoneEquipFlag,
3711 : SysOutputProvided,
3712 : LatOutputProvided);
3713 6961 : } break;
3714 11174 : case ZoneEquipType::DehumidifierDX: { // 'ZoneHVAC:Dehumidifier:DX'
3715 11174 : ZoneDehumidifier::SimZoneDehumidifier(state,
3716 11174 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3717 : ControlledZoneNum,
3718 : FirstHVACIteration,
3719 : SysOutputProvided,
3720 : LatOutputProvided,
3721 : zoneEquipList.EquipIndex(EquipPtr));
3722 :
3723 11174 : thisZoneHB.SysDepZoneLoads += SysOutputProvided;
3724 :
3725 11174 : SysOutputProvided = 0.0; // Reset to 0.0 since this equipment is controlled based on zone humidity level (not
3726 : // temperature) SysOutputProvided amount was already sent above to
3727 : // next Predict-Correct series of calcs via SysDepZoneLoads
3728 11174 : } break;
3729 :
3730 20300 : case ZoneEquipType::FourPipeFanCoil: { // 'ZoneHVAC:FourPipeFanCoil'
3731 40600 : FanCoilUnits::SimFanCoilUnit(state,
3732 20300 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3733 : ControlledZoneNum,
3734 : FirstHVACIteration,
3735 : SysOutputProvided,
3736 : LatOutputProvided,
3737 : zoneEquipList.EquipIndex(EquipPtr));
3738 20300 : } break;
3739 :
3740 0 : case ZoneEquipType::UnitVentilator: { // 'ZoneHVAC:UnitVentilator'
3741 0 : UnitVentilator::SimUnitVentilator(state,
3742 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3743 : ControlledZoneNum,
3744 : FirstHVACIteration,
3745 : SysOutputProvided,
3746 : LatOutputProvided,
3747 : zoneEquipList.EquipIndex(EquipPtr));
3748 0 : } break;
3749 :
3750 360 : case ZoneEquipType::UnitHeater: { // 'ZoneHVAC:UnitHeater'
3751 720 : UnitHeater::SimUnitHeater(state,
3752 360 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3753 : ControlledZoneNum,
3754 : FirstHVACIteration,
3755 : SysOutputProvided,
3756 : LatOutputProvided,
3757 : zoneEquipList.EquipIndex(EquipPtr));
3758 360 : } break;
3759 :
3760 761 : case ZoneEquipType::PurchasedAir: { // 'ZoneHVAC:IdealLoadsAirSystem'
3761 761 : PurchasedAirManager::SimPurchasedAir(state,
3762 761 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3763 : SysOutputProvided,
3764 : LatOutputProvided,
3765 : FirstHVACIteration,
3766 : ControlledZoneNum,
3767 : zoneEquipList.EquipIndex(EquipPtr));
3768 761 : } break;
3769 :
3770 0 : case ZoneEquipType::BaseboardWater: { // 'ZoneHVAC:Baseboard:RadiantConvective:Water'
3771 0 : HWBaseboardRadiator::SimHWBaseboard(state,
3772 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3773 : ControlledZoneNum,
3774 : FirstHVACIteration,
3775 : SysOutputProvided,
3776 : zoneEquipList.EquipIndex(EquipPtr));
3777 :
3778 0 : NonAirSysOutput = SysOutputProvided;
3779 0 : LatOutputProvided = 0.0; // This baseboard does not add/remove any latent heat
3780 0 : } break;
3781 :
3782 0 : case ZoneEquipType::BaseboardSteam: { // 'ZoneHVAC:Baseboard:RadiantConvective:Steam'
3783 0 : SteamBaseboardRadiator::SimSteamBaseboard(state,
3784 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3785 : ControlledZoneNum,
3786 : FirstHVACIteration,
3787 : SysOutputProvided,
3788 : zoneEquipList.EquipIndex(EquipPtr));
3789 :
3790 0 : NonAirSysOutput = SysOutputProvided;
3791 0 : LatOutputProvided = 0.0; // This baseboard does not add/remove any latent heat
3792 0 : } break;
3793 :
3794 12291 : case ZoneEquipType::BaseboardConvectiveWater: { // 'ZoneHVAC:Baseboard:Convective:Water'
3795 12291 : BaseboardRadiator::SimBaseboard(state,
3796 12291 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3797 : ControlledZoneNum,
3798 : FirstHVACIteration,
3799 : SysOutputProvided,
3800 : zoneEquipList.EquipIndex(EquipPtr));
3801 :
3802 12291 : NonAirSysOutput = SysOutputProvided;
3803 12291 : LatOutputProvided = 0.0; // This baseboard does not add/remove any latent heat
3804 12291 : } break;
3805 :
3806 0 : case ZoneEquipType::BaseboardConvectiveElectric: { // 'ZoneHVAC:Baseboard:Convective:Electric'
3807 0 : BaseboardElectric::SimElectricBaseboard(state,
3808 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3809 : ControlledZoneNum,
3810 : SysOutputProvided,
3811 : zoneEquipList.EquipIndex(EquipPtr));
3812 :
3813 0 : NonAirSysOutput = SysOutputProvided;
3814 0 : LatOutputProvided = 0.0; // This baseboard does not add/remove any latent heat
3815 0 : } break;
3816 :
3817 0 : case ZoneEquipType::CoolingPanel: { // 'ZoneHVAC:CoolingPanel:RadiantConvective:Water'
3818 0 : CoolingPanelSimple::SimCoolingPanel(state,
3819 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3820 : ControlledZoneNum,
3821 : FirstHVACIteration,
3822 : SysOutputProvided,
3823 : zoneEquipList.EquipIndex(EquipPtr));
3824 :
3825 0 : NonAirSysOutput = SysOutputProvided;
3826 0 : LatOutputProvided = 0.0; // This cooling panel does not add/remove any latent heat
3827 0 : } break;
3828 :
3829 0 : case ZoneEquipType::HighTemperatureRadiant: { // 'ZoneHVAC:HighTemperatureRadiant'
3830 0 : HighTempRadiantSystem::SimHighTempRadiantSystem(state,
3831 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3832 : FirstHVACIteration,
3833 : SysOutputProvided,
3834 : zoneEquipList.EquipIndex(EquipPtr));
3835 0 : LatOutputProvided = 0.0; // This baseboard currently sends its latent heat gain directly to predictor/corrector
3836 : // via SumLatentHTRadSys... so setting LatOutputProvided = 0.0
3837 0 : } break;
3838 :
3839 0 : case ZoneEquipType::LowTemperatureRadiantConstFlow:
3840 : case ZoneEquipType::LowTemperatureRadiantVarFlow:
3841 : case ZoneEquipType::LowTemperatureRadiantElectric: {
3842 0 : LowTempRadiantSystem::SimLowTempRadiantSystem(state,
3843 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3844 : FirstHVACIteration,
3845 : SysOutputProvided,
3846 : zoneEquipList.EquipIndex(EquipPtr));
3847 0 : LatOutputProvided = 0.0; // This baseboard does not add/remove any latent heat
3848 0 : } break;
3849 :
3850 11174 : case ZoneEquipType::ExhaustFan: { // 'Fan:ZoneExhaust'
3851 : // Air loop system availability manager status only applies to PIU and exhaust fans
3852 : // Check to see if System Availability Managers are asking for fans to cycle on or shut off
3853 : // and set fan on/off flags accordingly.
3854 11187 : if (state.dataZoneEquip->ZoneEquipAvail(ControlledZoneNum) == Avail::Status::CycleOn ||
3855 13 : state.dataZoneEquip->ZoneEquipAvail(ControlledZoneNum) == Avail::Status::CycleOnZoneFansOnly) {
3856 11161 : state.dataHVACGlobal->TurnFansOn = true;
3857 : }
3858 11174 : if (state.dataZoneEquip->ZoneEquipAvail(ControlledZoneNum) == Avail::Status::ForceOff) {
3859 0 : state.dataHVACGlobal->TurnFansOff = true;
3860 : }
3861 :
3862 11174 : if (zoneEquipList.EquipIndex(EquipPtr) == 0) { // TODO: Get rid of this
3863 1 : zoneEquipList.EquipIndex(EquipPtr) = Fans::GetFanIndex(state, zoneEquipList.EquipName(EquipPtr));
3864 : }
3865 :
3866 11174 : state.dataFans->fans(zoneEquipList.EquipIndex(EquipPtr))->simulate(state, FirstHVACIteration);
3867 :
3868 11174 : } break;
3869 :
3870 0 : case ZoneEquipType::HeatExchanger: { // 'HeatExchanger:AirToAir:FlatPlate'
3871 0 : HeatRecovery::SimHeatRecovery(state,
3872 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3873 : FirstHVACIteration,
3874 : zoneEquipList.EquipIndex(EquipPtr),
3875 : HVAC::FanOp::Continuous);
3876 0 : } break;
3877 :
3878 0 : case ZoneEquipType::EnergyRecoveryVentilator: { // 'ZoneHVAC:EnergyRecoveryVentilator'
3879 0 : HVACStandAloneERV::SimStandAloneERV(state,
3880 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3881 : ControlledZoneNum,
3882 : FirstHVACIteration,
3883 : SysOutputProvided,
3884 : LatOutputProvided,
3885 : zoneEquipList.EquipIndex(EquipPtr));
3886 0 : } break;
3887 :
3888 0 : case ZoneEquipType::HeatPumpWaterHeaterPumpedCondenser:
3889 : case ZoneEquipType::HeatPumpWaterHeaterWrappedCondenser: {
3890 0 : WaterThermalTanks::SimHeatPumpWaterHeater(state,
3891 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3892 : FirstHVACIteration,
3893 : SysOutputProvided,
3894 : LatOutputProvided,
3895 0 : state.dataZoneEquip->ZoneEquipList(ControlledZoneNum).EquipIndex(EquipPtr));
3896 0 : } break;
3897 :
3898 0 : case ZoneEquipType::VentilatedSlab: { // 'ZoneHVAC:VentilatedSlab'
3899 0 : VentilatedSlab::SimVentilatedSlab(state,
3900 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3901 : ControlledZoneNum,
3902 : FirstHVACIteration,
3903 : SysOutputProvided,
3904 : LatOutputProvided,
3905 : zoneEquipList.EquipIndex(EquipPtr));
3906 0 : } break;
3907 :
3908 0 : case ZoneEquipType::OutdoorAirUnit: { // 'ZoneHVAC:OutdoorAirUnit'
3909 0 : OutdoorAirUnit::SimOutdoorAirUnit(state,
3910 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3911 : ControlledZoneNum,
3912 : FirstHVACIteration,
3913 : SysOutputProvided,
3914 : LatOutputProvided,
3915 : zoneEquipList.EquipIndex(EquipPtr));
3916 0 : } break;
3917 :
3918 60 : case ZoneEquipType::BaseboardElectric: { // 'ZoneHVAC:Baseboard:RadiantConvective:Electric'
3919 60 : ElectricBaseboardRadiator::SimElecBaseboard(state,
3920 60 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3921 : ControlledZoneNum,
3922 : FirstHVACIteration,
3923 : SysOutputProvided,
3924 : zoneEquipList.EquipIndex(EquipPtr));
3925 :
3926 60 : NonAirSysOutput = SysOutputProvided;
3927 60 : LatOutputProvided = 0.0; // This baseboard does not add/remove any latent heat
3928 60 : } break;
3929 :
3930 0 : case ZoneEquipType::RefrigerationChillerSet: { // 'ZoneHVAC:RefrigerationChillerSet'
3931 0 : RefrigeratedCase::SimAirChillerSet(state,
3932 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3933 : ControlledZoneNum,
3934 : FirstHVACIteration,
3935 : SysOutputProvided,
3936 : LatOutputProvided,
3937 : zoneEquipList.EquipIndex(EquipPtr));
3938 :
3939 0 : NonAirSysOutput = SysOutputProvided;
3940 0 : } break;
3941 :
3942 12291 : case ZoneEquipType::UserDefinedHVACForcedAir: {
3943 24582 : UserDefinedComponents::SimZoneAirUserDefined(state,
3944 12291 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3945 : ControlledZoneNum,
3946 : SysOutputProvided,
3947 : LatOutputProvided,
3948 : zoneEquipList.EquipIndex(EquipPtr));
3949 12291 : } break;
3950 :
3951 0 : case ZoneEquipType::EvaporativeCooler: {
3952 0 : EvaporativeCoolers::SimZoneEvaporativeCoolerUnit(state,
3953 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3954 : ControlledZoneNum,
3955 : SysOutputProvided,
3956 : LatOutputProvided,
3957 : zoneEquipList.EquipIndex(EquipPtr));
3958 0 : } break;
3959 :
3960 0 : case ZoneEquipType::HybridEvaporativeCooler: {
3961 0 : HybridUnitaryAirConditioners::SimZoneHybridUnitaryAirConditioners(
3962 : state,
3963 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
3964 : ControlledZoneNum,
3965 : SysOutputProvided,
3966 : LatOutputProvided,
3967 : zoneEquipList.EquipIndex(EquipPtr));
3968 0 : } break;
3969 :
3970 0 : default:
3971 0 : break;
3972 : }
3973 :
3974 208331 : zoneEquipConfig.ZoneExh +=
3975 208331 : (state.dataHVACGlobal->UnbalExhMassFlow +
3976 208331 : state.dataHVACGlobal->BalancedExhMassFlow); // This is the total "exhaust" flow from equipment such as a zone exhaust fan
3977 208331 : zoneEquipConfig.ZoneExhBalanced += state.dataHVACGlobal->BalancedExhMassFlow;
3978 208331 : zoneEquipConfig.PlenumMassFlow += state.dataHVACGlobal->PlenumInducedMassFlow;
3979 :
3980 : // Store available capacities for load distribution calculations
3981 208331 : if (FirstHVACIteration && (zoneEquipList.LoadDistScheme != DataZoneEquipment::LoadDist::Sequential)) {
3982 0 : if (SysOutputProvided > 0.0) {
3983 0 : zoneEquipList.HeatingCapacity(EquipPtr) = SysOutputProvided;
3984 : } else {
3985 0 : zoneEquipList.CoolingCapacity(EquipPtr) = SysOutputProvided;
3986 : }
3987 : }
3988 :
3989 : // If SpaceHVAC is active and this equipment has a space splitter, distribute the equipment output and update the spaces
3990 208331 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation && !state.dataGlobal->DoingSizing &&
3991 0 : zoneEquipList.zoneEquipSplitterIndex(EquipPtr) > -1) {
3992 0 : state.dataZoneEquip->zoneEquipSplitter[zoneEquipList.zoneEquipSplitterIndex(EquipPtr)].distributeOutput(
3993 : state, ControlledZoneNum, SysOutputProvided, LatOutputProvided, NonAirSysOutput, EquipTypeNum);
3994 : } else {
3995 208331 : thisZoneHB.NonAirSystemResponse += NonAirSysOutput;
3996 : }
3997 : // Space HVAC TODO: For now, update both spaces and zone, but maybe ultimately update one or the other
3998 416662 : updateSystemOutputRequired(state,
3999 : ControlledZoneNum,
4000 : SysOutputProvided,
4001 : LatOutputProvided,
4002 208331 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum),
4003 208331 : state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum),
4004 : EquipTypeNum);
4005 :
4006 208331 : state.dataSize->CurTermUnitSizingNum = 0;
4007 : } // zone equipment loop
4008 : } // End of controlled zone loop
4009 :
4010 : // If SpaceHVAC is active calculate SpaceHVAC:EquipmentMixer inlet flow rates after simulating zone equipment
4011 424465 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation && !state.dataGlobal->DoingSizing) {
4012 36872 : for (auto &thisSpaceHVACMixer : state.dataZoneEquip->zoneEquipMixer) {
4013 0 : thisSpaceHVACMixer.setInletFlows(state);
4014 : }
4015 : }
4016 :
4017 424465 : state.dataSize->CurZoneEqNum = 0;
4018 424465 : state.dataZoneEquipmentManager->FirstPassZoneEquipFlag = false;
4019 :
4020 : // This is the call to the Supply Air Path after the components are simulated to update
4021 : // the path inlets
4022 :
4023 : // Process supply air path components in reverse order
4024 500313 : for (int SupplyAirPathNum = 1; SupplyAirPathNum <= state.dataZoneEquip->NumSupplyAirPaths; ++SupplyAirPathNum) {
4025 :
4026 75848 : SupPathInletChanged = false;
4027 :
4028 151697 : for (int CompNum = state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).NumOfComponents; CompNum >= 1; --CompNum) {
4029 75849 : switch (state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentTypeEnum(CompNum)) {
4030 75848 : case DataZoneEquipment::AirLoopHVACZone::Splitter: { // 'AirLoopHVAC:ZoneSplitter'
4031 75848 : if (!(state.afn->AirflowNetworkFanActivated && state.afn->distribution_simulated)) {
4032 67555 : SplitterComponent::SimAirLoopSplitter(state,
4033 67555 : state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentName(CompNum),
4034 : FirstHVACIteration,
4035 : FirstCall,
4036 : SupPathInletChanged,
4037 67555 : state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentIndex(CompNum));
4038 : }
4039 75848 : } break;
4040 1 : case DataZoneEquipment::AirLoopHVACZone::SupplyPlenum: { // 'AirLoopHVAC:SupplyPlenum'
4041 2 : ZonePlenum::SimAirZonePlenum(state,
4042 1 : state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentName(CompNum),
4043 : DataZoneEquipment::AirLoopHVACZone::SupplyPlenum,
4044 1 : state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentIndex(CompNum),
4045 : FirstHVACIteration,
4046 : FirstCall,
4047 : SupPathInletChanged);
4048 :
4049 1 : } break;
4050 0 : default: {
4051 0 : ShowSevereError(state, format("Error found in Supply Air Path={}", state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).Name));
4052 0 : ShowContinueError(
4053 : state,
4054 0 : format("Invalid Supply Air Path Component={}", state.dataZoneEquip->SupplyAirPath(SupplyAirPathNum).ComponentType(CompNum)));
4055 0 : ShowFatalError(state, "Preceding condition causes termination.");
4056 0 : } break;
4057 : }
4058 : }
4059 :
4060 75848 : if (SupPathInletChanged) {
4061 : // If the supply air path inlet conditions have been changed, the Air Loop must be resimulated
4062 11946 : SimAir = true;
4063 : }
4064 :
4065 : } // end of the Supply Air Path DO Loop
4066 :
4067 424465 : ExhaustAirSystemManager::SimZoneHVACExhaustControls(state);
4068 :
4069 424465 : ExhaustAirSystemManager::SimExhaustAirSystem(state, FirstHVACIteration);
4070 :
4071 424465 : CalcZoneMassBalance(state, FirstHVACIteration);
4072 :
4073 424465 : CalcZoneLeavingConditions(state, FirstHVACIteration);
4074 :
4075 424465 : ReturnAirPathManager::SimReturnAirPath(state);
4076 424465 : }
4077 :
4078 414585 : void SetZoneEquipSimOrder(EnergyPlusData &state, int const ControlledZoneNum)
4079 : {
4080 :
4081 : // SUBROUTINE INFORMATION:
4082 : // AUTHOR Russ Taylor
4083 : // DATE WRITTEN May 1997
4084 :
4085 : // PURPOSE OF THIS SUBROUTINE:
4086 : // Set simulation priorities based on user specified priorities and
4087 : // required conditions (heating or cooling).
4088 :
4089 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4090 414585 : auto &zeq(state.dataZoneEquip->ZoneEquipList(ControlledZoneNum));
4091 414585 : int const NumOfEquipTypes(zeq.NumOfEquipTypes);
4092 980519 : for (int EquipTypeNum = 1; EquipTypeNum <= NumOfEquipTypes; ++EquipTypeNum) {
4093 565934 : auto &pso(state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum));
4094 565934 : pso.EquipTypeName = zeq.EquipTypeName(EquipTypeNum);
4095 565934 : pso.EquipName = zeq.EquipName(EquipTypeNum);
4096 565934 : pso.equipType = zeq.EquipType(EquipTypeNum);
4097 565934 : pso.CoolingPriority = zeq.CoolingPriority(EquipTypeNum);
4098 565934 : pso.HeatingPriority = zeq.HeatingPriority(EquipTypeNum);
4099 565934 : pso.EquipPtr = EquipTypeNum;
4100 : }
4101 414585 : for (int EquipTypeNum = NumOfEquipTypes + 1, EquipTypeNum_end = state.dataZoneEquipmentManager->PrioritySimOrder.u();
4102 414585 : EquipTypeNum <= EquipTypeNum_end;
4103 : ++EquipTypeNum) { // Reset unused upper array portion
4104 0 : auto &pso(state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum));
4105 0 : pso.EquipTypeName.clear();
4106 0 : pso.EquipName.clear();
4107 0 : pso.equipType = DataZoneEquipment::ZoneEquipType::Invalid;
4108 0 : pso.EquipPtr = 0;
4109 : }
4110 :
4111 980519 : for (int EquipTypeNum = 1; EquipTypeNum <= NumOfEquipTypes; ++EquipTypeNum) {
4112 565934 : auto &pso(state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum));
4113 :
4114 565934 : int CurEqHeatingPriority = pso.HeatingPriority;
4115 565934 : int CurEqCoolingPriority = pso.CoolingPriority;
4116 :
4117 1308446 : for (int ComparedEquipTypeNum = EquipTypeNum; ComparedEquipTypeNum <= NumOfEquipTypes; ++ComparedEquipTypeNum) {
4118 742512 : auto &psc(state.dataZoneEquipmentManager->PrioritySimOrder(ComparedEquipTypeNum));
4119 :
4120 1485024 : if ((CurEqCoolingPriority > psc.CoolingPriority &&
4121 1485024 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputRequired < 0.0) ||
4122 742512 : (CurEqHeatingPriority > psc.HeatingPriority &&
4123 30750 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputRequired >= 0.0)) {
4124 :
4125 : // Tuned C++ string swap avoids copying
4126 15100 : pso.EquipTypeName.swap(psc.EquipTypeName);
4127 15100 : pso.EquipName.swap(psc.EquipName);
4128 15100 : std::swap(pso.EquipPtr, psc.EquipPtr);
4129 15100 : std::swap(pso.equipType, psc.equipType);
4130 15100 : std::swap(pso.CoolingPriority, psc.CoolingPriority);
4131 15100 : std::swap(pso.HeatingPriority, psc.HeatingPriority);
4132 :
4133 15100 : CurEqCoolingPriority = pso.CoolingPriority;
4134 15100 : CurEqHeatingPriority = pso.HeatingPriority;
4135 : }
4136 : }
4137 : }
4138 414585 : }
4139 :
4140 414601 : void InitSystemOutputRequired(EnergyPlusData &state, int const ZoneNum, bool const FirstHVACIteration, bool const ResetSimOrder)
4141 : {
4142 :
4143 : // SUBROUTINE INFORMATION:
4144 : // AUTHOR Russ Taylor
4145 : // DATE WRITTEN May 1997
4146 : // MODIFIED Don Shirey, Aug 2009 (latent/moisture additions)
4147 :
4148 : // PURPOSE OF THIS SUBROUTINE:
4149 : // Initialize remaining output required variables
4150 :
4151 : // METHODOLOGY EMPLOYED:
4152 : // Initialize remaining output variables using predictor calculations
4153 829202 : initOutputRequired(state,
4154 : ZoneNum,
4155 414601 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum),
4156 414601 : state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ZoneNum),
4157 : FirstHVACIteration,
4158 : ResetSimOrder);
4159 : // SpaceHB TODO: This may need more work
4160 414601 : if (state.dataHeatBal->doSpaceHeatBalance) {
4161 33920 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
4162 50880 : initOutputRequired(state,
4163 : ZoneNum,
4164 25440 : state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum),
4165 25440 : state.dataZoneEnergyDemand->spaceSysMoistureDemand(spaceNum),
4166 : FirstHVACIteration,
4167 : ResetSimOrder,
4168 : spaceNum);
4169 : }
4170 : }
4171 :
4172 414601 : DistributeSystemOutputRequired(state, ZoneNum, FirstHVACIteration);
4173 414601 : }
4174 :
4175 615428 : void initOutputRequired(EnergyPlusData &state,
4176 : int const ZoneNum,
4177 : DataZoneEnergyDemands::ZoneSystemSensibleDemand &energy,
4178 : DataZoneEnergyDemands::ZoneSystemMoistureDemand &moisture,
4179 : bool const FirstHVACIteration,
4180 : bool const ResetSimOrder,
4181 : int spaceNum)
4182 : {
4183 615428 : energy.RemainingOutputRequired = energy.TotalOutputRequired;
4184 615428 : energy.UnadjRemainingOutputRequired = energy.TotalOutputRequired;
4185 615428 : energy.RemainingOutputReqToHeatSP = energy.OutputRequiredToHeatingSP;
4186 615428 : energy.UnadjRemainingOutputReqToHeatSP = energy.OutputRequiredToHeatingSP;
4187 615428 : energy.RemainingOutputReqToCoolSP = energy.OutputRequiredToCoolingSP;
4188 615428 : energy.UnadjRemainingOutputReqToCoolSP = energy.OutputRequiredToCoolingSP;
4189 :
4190 615428 : moisture.RemainingOutputRequired = moisture.TotalOutputRequired;
4191 615428 : moisture.UnadjRemainingOutputRequired = moisture.TotalOutputRequired;
4192 615428 : moisture.RemainingOutputReqToHumidSP = moisture.OutputRequiredToHumidifyingSP;
4193 615428 : moisture.UnadjRemainingOutputReqToHumidSP = moisture.OutputRequiredToHumidifyingSP;
4194 615428 : moisture.RemainingOutputReqToDehumidSP = moisture.OutputRequiredToDehumidifyingSP;
4195 615428 : moisture.UnadjRemainingOutputReqToDehumidSP = moisture.OutputRequiredToDehumidifyingSP;
4196 :
4197 615428 : if (ResetSimOrder && spaceNum == 0) {
4198 414584 : SetZoneEquipSimOrder(state, ZoneNum);
4199 : }
4200 :
4201 : // If one sequenced load is allocated, then all have been allocated in InitZoneEquipment
4202 615428 : if (allocated(energy.SequencedOutputRequired)) {
4203 : // Check if controlled first, because if it's not, there is no zone equipment list
4204 615420 : if (!state.dataHeatBal->Zone(ZoneNum).IsControlled || state.dataGlobal->ZoneSizingCalc) {
4205 : // init each sequenced demand to the full output
4206 323266 : energy.SequencedOutputRequired = energy.TotalOutputRequired; // array assignment
4207 323266 : energy.SequencedOutputRequiredToHeatingSP = energy.OutputRequiredToHeatingSP; // array assignment
4208 323266 : energy.SequencedOutputRequiredToCoolingSP = energy.OutputRequiredToCoolingSP; // array assignment
4209 : // init each sequenced demand to the full output
4210 323266 : moisture.SequencedOutputRequired = moisture.TotalOutputRequired; // array assignment
4211 323266 : moisture.SequencedOutputRequiredToHumidSP = moisture.OutputRequiredToHumidifyingSP; // array assignment
4212 323266 : moisture.SequencedOutputRequiredToDehumidSP = moisture.OutputRequiredToDehumidifyingSP; // array assignment
4213 292154 : } else if (FirstHVACIteration) {
4214 137976 : DataZoneEquipment::LoadDist loadDistType = state.dataZoneEquip->ZoneEquipList(ZoneNum).LoadDistScheme;
4215 137976 : if ((loadDistType == DataZoneEquipment::LoadDist::Sequential) || (loadDistType == DataZoneEquipment::LoadDist::Uniform)) {
4216 : // init each sequenced demand to the full output
4217 137972 : energy.SequencedOutputRequired = energy.TotalOutputRequired; // array assignment
4218 137972 : energy.SequencedOutputRequiredToHeatingSP = energy.OutputRequiredToHeatingSP; // array assignment
4219 137972 : energy.SequencedOutputRequiredToCoolingSP = energy.OutputRequiredToCoolingSP; // array assignment
4220 : // init each sequenced demand to the full output
4221 137972 : moisture.SequencedOutputRequired = moisture.TotalOutputRequired; // array assignment
4222 137972 : moisture.SequencedOutputRequiredToHumidSP = moisture.OutputRequiredToHumidifyingSP; // array assignment
4223 137972 : moisture.SequencedOutputRequiredToDehumidSP = moisture.OutputRequiredToDehumidifyingSP; // array assignment
4224 4 : } else if ((loadDistType == DataZoneEquipment::LoadDist::UniformPLR) ||
4225 : (loadDistType == DataZoneEquipment::LoadDist::SequentialUniformPLR)) {
4226 : // init each sequenced demand to the zone design load in order to get available capacities from equipment
4227 : // SpaceHB TODO: This may need more work
4228 4 : if (energy.TotalOutputRequired >= 0.0) {
4229 2 : energy.SequencedOutputRequired = state.dataSize->FinalZoneSizing(ZoneNum).DesHeatLoad; // array assignment
4230 : } else {
4231 2 : energy.SequencedOutputRequired = -state.dataSize->FinalZoneSizing(ZoneNum).DesCoolLoad; // array assignment
4232 : }
4233 4 : if (energy.TotalOutputRequired >= 0.0) {
4234 2 : energy.SequencedOutputRequiredToHeatingSP = state.dataSize->FinalZoneSizing(ZoneNum).DesHeatLoad; // array assignment
4235 : } else {
4236 2 : energy.SequencedOutputRequiredToHeatingSP = -state.dataSize->FinalZoneSizing(ZoneNum).DesCoolLoad; // array assignment
4237 : }
4238 4 : if (energy.TotalOutputRequired >= 0.0) {
4239 2 : energy.SequencedOutputRequiredToCoolingSP = state.dataSize->FinalZoneSizing(ZoneNum).DesHeatLoad; // array assignment
4240 : } else {
4241 2 : energy.SequencedOutputRequiredToCoolingSP = -state.dataSize->FinalZoneSizing(ZoneNum).DesCoolLoad; // array assignment
4242 : }
4243 : // init each sequenced moisture demand to the full output
4244 4 : moisture.SequencedOutputRequired = moisture.TotalOutputRequired; // array assignment
4245 4 : moisture.SequencedOutputRequiredToHumidSP = moisture.OutputRequiredToHumidifyingSP; // array assignment
4246 4 : moisture.SequencedOutputRequiredToDehumidSP = moisture.OutputRequiredToDehumidifyingSP; // array assignment
4247 : }
4248 : } else {
4249 : // init first sequenced sensible demand to the full output
4250 154178 : energy.SequencedOutputRequired(1) = energy.TotalOutputRequired;
4251 154178 : energy.SequencedOutputRequiredToHeatingSP(1) = energy.OutputRequiredToHeatingSP;
4252 154178 : energy.SequencedOutputRequiredToCoolingSP(1) = energy.OutputRequiredToCoolingSP;
4253 : // init first sequenced moisture demand to the full output
4254 154178 : moisture.SequencedOutputRequired(1) = moisture.TotalOutputRequired;
4255 154178 : moisture.SequencedOutputRequiredToHumidSP(1) = moisture.OutputRequiredToHumidifyingSP;
4256 154178 : moisture.SequencedOutputRequiredToDehumidSP(1) = moisture.OutputRequiredToDehumidifyingSP;
4257 : }
4258 : }
4259 :
4260 615428 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) = state.dataZoneEnergyDemand->DeadBandOrSetback(ZoneNum);
4261 615428 : }
4262 :
4263 414618 : void DistributeSystemOutputRequired(EnergyPlusData &state, int const ZoneNum, bool const FirstHVACIteration)
4264 : {
4265 : // Distribute zone equipment loads according to load distribution scheme
4266 :
4267 : // Do nothing if this zone is uncontrolled or doing zone sizing
4268 414618 : if (!state.dataHeatBal->Zone(ZoneNum).IsControlled) return;
4269 414617 : if (state.dataGlobal->ZoneSizingCalc) return;
4270 :
4271 : // Do nothing on FirstHVACIteration if not UniformLoading and not SequentialLoading
4272 430083 : if (FirstHVACIteration && (state.dataZoneEquip->ZoneEquipList(ZoneNum).LoadDistScheme != DataZoneEquipment::LoadDist::Uniform) &&
4273 137945 : (state.dataZoneEquip->ZoneEquipList(ZoneNum).LoadDistScheme != DataZoneEquipment::LoadDist::Sequential)) {
4274 8 : return;
4275 : }
4276 :
4277 584260 : distributeOutputRequired(
4278 584260 : state, ZoneNum, state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum), state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ZoneNum));
4279 : // SpaceHB TODO: This may need more work
4280 292130 : if (state.dataHeatBal->doSpaceHeatBalance) {
4281 44 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
4282 66 : distributeOutputRequired(state,
4283 : ZoneNum,
4284 33 : state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum),
4285 33 : state.dataZoneEnergyDemand->spaceSysMoistureDemand(spaceNum));
4286 : }
4287 : }
4288 : }
4289 :
4290 292163 : void distributeOutputRequired(EnergyPlusData &state,
4291 : int const ZoneNum,
4292 : DataZoneEnergyDemands::ZoneSystemSensibleDemand &energy,
4293 : DataZoneEnergyDemands::ZoneSystemMoistureDemand &moisture)
4294 : {
4295 292163 : auto &thisZEqList(state.dataZoneEquip->ZoneEquipList(ZoneNum));
4296 292163 : Real64 heatLoadRatio = 1.0;
4297 292163 : Real64 coolLoadRatio = 1.0;
4298 292163 : Real64 availCap = 0.0;
4299 292163 : Real64 plr = 1.0;
4300 292163 : int numOperating = 0;
4301 :
4302 292163 : switch (thisZEqList.LoadDistScheme) {
4303 292139 : case DataZoneEquipment::LoadDist::Sequential:
4304 : // Nothing to do here for this case
4305 : {
4306 : // Set the load (with load fraction) for the first equipment in priority order
4307 292139 : constexpr int priorityNum = 1;
4308 292139 : const int &equipNum = state.dataZoneEquipmentManager->PrioritySimOrder(priorityNum).EquipPtr;
4309 :
4310 : // Determine whether we're heating or cooling and choose the appropriate fraction
4311 292139 : heatLoadRatio = thisZEqList.SequentialHeatingFraction(state, equipNum);
4312 292139 : coolLoadRatio = thisZEqList.SequentialCoolingFraction(state, equipNum);
4313 292139 : const Real64 loadRatio = (energy.TotalOutputRequired >= 0.0) ? heatLoadRatio : coolLoadRatio;
4314 :
4315 : // Energy loads
4316 292139 : energy.SequencedOutputRequired(priorityNum) = energy.TotalOutputRequired * loadRatio;
4317 292139 : energy.SequencedOutputRequiredToHeatingSP(priorityNum) = energy.OutputRequiredToHeatingSP * loadRatio;
4318 292139 : energy.SequencedOutputRequiredToCoolingSP(priorityNum) = energy.OutputRequiredToCoolingSP * loadRatio;
4319 292139 : energy.RemainingOutputRequired = energy.SequencedOutputRequired(priorityNum);
4320 292139 : energy.RemainingOutputReqToHeatSP = energy.SequencedOutputRequiredToHeatingSP(priorityNum);
4321 292139 : energy.RemainingOutputReqToCoolSP = energy.SequencedOutputRequiredToCoolingSP(priorityNum);
4322 :
4323 : // Moisture loads
4324 292139 : moisture.SequencedOutputRequired(priorityNum) = moisture.TotalOutputRequired * loadRatio;
4325 292139 : moisture.SequencedOutputRequiredToHumidSP(priorityNum) = moisture.OutputRequiredToHumidifyingSP * loadRatio;
4326 292139 : moisture.SequencedOutputRequiredToDehumidSP(priorityNum) = moisture.OutputRequiredToDehumidifyingSP * loadRatio;
4327 292139 : moisture.RemainingOutputRequired = moisture.SequencedOutputRequired(priorityNum);
4328 292139 : moisture.RemainingOutputReqToHumidSP = moisture.SequencedOutputRequiredToHumidSP(priorityNum);
4329 292139 : moisture.RemainingOutputReqToDehumidSP = moisture.SequencedOutputRequiredToDehumidSP(priorityNum);
4330 :
4331 292139 : break;
4332 : }
4333 8 : case DataZoneEquipment::LoadDist::Uniform:
4334 : // Distribute load uniformly across all active equipment
4335 8 : if (thisZEqList.NumAvailHeatEquip > 0) {
4336 8 : heatLoadRatio = 1.0 / thisZEqList.NumAvailHeatEquip;
4337 : } else {
4338 0 : heatLoadRatio = 1.0;
4339 : }
4340 8 : if (thisZEqList.NumAvailCoolEquip > 0) {
4341 8 : coolLoadRatio = 1.0 / thisZEqList.NumAvailCoolEquip;
4342 : } else {
4343 0 : coolLoadRatio = 1.0;
4344 : }
4345 32 : for (int equipNum = 1.0; equipNum <= thisZEqList.NumOfEquipTypes; ++equipNum) {
4346 24 : if (energy.TotalOutputRequired >= 0.0) {
4347 12 : if (thisZEqList.HeatingPriority(equipNum) > 0) {
4348 12 : energy.SequencedOutputRequired(equipNum) = energy.TotalOutputRequired * heatLoadRatio;
4349 12 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = energy.OutputRequiredToHeatingSP * heatLoadRatio;
4350 12 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = energy.OutputRequiredToCoolingSP * heatLoadRatio;
4351 12 : moisture.SequencedOutputRequired(equipNum) = moisture.TotalOutputRequired * heatLoadRatio;
4352 12 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = moisture.OutputRequiredToHumidifyingSP * heatLoadRatio;
4353 12 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = moisture.OutputRequiredToDehumidifyingSP * heatLoadRatio;
4354 : } else {
4355 0 : energy.SequencedOutputRequired(equipNum) = 0.0;
4356 0 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = 0.0;
4357 0 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = 0.0;
4358 0 : moisture.SequencedOutputRequired(equipNum) = 0.0;
4359 0 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = 0.0;
4360 0 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = 0.0;
4361 : }
4362 : } else {
4363 12 : if (thisZEqList.CoolingPriority(equipNum) > 0) {
4364 8 : energy.SequencedOutputRequired(equipNum) = energy.TotalOutputRequired * coolLoadRatio;
4365 8 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = energy.OutputRequiredToHeatingSP * coolLoadRatio;
4366 8 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = energy.OutputRequiredToCoolingSP * coolLoadRatio;
4367 8 : moisture.SequencedOutputRequired(equipNum) = moisture.TotalOutputRequired * coolLoadRatio;
4368 8 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = moisture.OutputRequiredToHumidifyingSP * coolLoadRatio;
4369 8 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = moisture.OutputRequiredToDehumidifyingSP * coolLoadRatio;
4370 : } else {
4371 4 : energy.SequencedOutputRequired(equipNum) = 0.0;
4372 4 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = 0.0;
4373 4 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = 0.0;
4374 4 : moisture.SequencedOutputRequired(equipNum) = 0.0;
4375 4 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = 0.0;
4376 4 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = 0.0;
4377 : }
4378 : }
4379 : }
4380 8 : break;
4381 4 : case DataZoneEquipment::LoadDist::UniformPLR:
4382 : // Distribute load at uniform PLR across all active equipment
4383 4 : if (energy.TotalOutputRequired >= 0.0) {
4384 8 : for (int equipNum = 1.0; equipNum <= thisZEqList.NumOfEquipTypes; ++equipNum) {
4385 6 : if (thisZEqList.HeatingPriority(equipNum) > 0) availCap += thisZEqList.HeatingCapacity(equipNum);
4386 : }
4387 2 : if (availCap > 0.0) {
4388 2 : plr = energy.TotalOutputRequired / availCap;
4389 : } else {
4390 0 : plr = 0.0;
4391 : }
4392 : } else {
4393 8 : for (int equipNum = 1.0; equipNum <= thisZEqList.NumOfEquipTypes; ++equipNum) {
4394 6 : if (thisZEqList.CoolingPriority(equipNum) > 0) availCap += thisZEqList.CoolingCapacity(equipNum);
4395 : }
4396 2 : if (availCap < 0.0) {
4397 2 : plr = energy.TotalOutputRequired / availCap;
4398 : } else {
4399 0 : plr = 0.0;
4400 : }
4401 : }
4402 4 : if (plr <= 0.0) break; // Don't change anything
4403 16 : for (int equipNum = 1.0; equipNum <= thisZEqList.NumOfEquipTypes; ++equipNum) {
4404 12 : if (energy.TotalOutputRequired >= 0.0) {
4405 6 : if (thisZEqList.HeatingPriority(equipNum) > 0) {
4406 6 : energy.SequencedOutputRequired(equipNum) = thisZEqList.HeatingCapacity(equipNum) * plr;
4407 6 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = thisZEqList.HeatingCapacity(equipNum) * plr;
4408 6 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = thisZEqList.HeatingCapacity(equipNum) * plr;
4409 6 : if (energy.OutputRequiredToHeatingSP != 0.0) {
4410 12 : moisture.SequencedOutputRequired(equipNum) =
4411 6 : moisture.TotalOutputRequired * (thisZEqList.HeatingCapacity(equipNum) * plr) / energy.OutputRequiredToHeatingSP;
4412 6 : moisture.SequencedOutputRequiredToHumidSP(equipNum) =
4413 6 : moisture.OutputRequiredToHumidifyingSP * (thisZEqList.HeatingCapacity(equipNum) * plr) / energy.OutputRequiredToHeatingSP;
4414 : } else {
4415 0 : moisture.SequencedOutputRequired(equipNum) = moisture.TotalOutputRequired * plr;
4416 0 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = moisture.OutputRequiredToHumidifyingSP * plr;
4417 : }
4418 6 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = 0.0;
4419 : } else {
4420 0 : energy.SequencedOutputRequired(equipNum) = 0.0;
4421 0 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = 0.0;
4422 0 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = 0.0;
4423 0 : moisture.SequencedOutputRequired(equipNum) = 0.0;
4424 0 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = 0.0;
4425 0 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = 0.0;
4426 : }
4427 : } else {
4428 6 : if (thisZEqList.CoolingPriority(equipNum) > 0) {
4429 4 : energy.SequencedOutputRequired(equipNum) = thisZEqList.CoolingCapacity(equipNum) * plr;
4430 4 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = thisZEqList.CoolingCapacity(equipNum) * plr;
4431 4 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = thisZEqList.CoolingCapacity(equipNum) * plr;
4432 4 : if (energy.OutputRequiredToCoolingSP != 0.0) {
4433 8 : moisture.SequencedOutputRequired(equipNum) =
4434 4 : moisture.TotalOutputRequired * (thisZEqList.CoolingCapacity(equipNum) * plr) / energy.OutputRequiredToCoolingSP;
4435 4 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = moisture.OutputRequiredToDehumidifyingSP *
4436 4 : (thisZEqList.CoolingCapacity(equipNum) * plr) /
4437 4 : energy.OutputRequiredToCoolingSP;
4438 : } else {
4439 0 : moisture.SequencedOutputRequired(equipNum) = moisture.TotalOutputRequired * plr;
4440 0 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = moisture.OutputRequiredToDehumidifyingSP * plr;
4441 : }
4442 4 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = 0.0;
4443 : } else {
4444 2 : energy.SequencedOutputRequired(equipNum) = 0.0;
4445 2 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = 0.0;
4446 2 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = 0.0;
4447 2 : moisture.SequencedOutputRequired(equipNum) = 0.0;
4448 2 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = 0.0;
4449 2 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = 0.0;
4450 : }
4451 : }
4452 : }
4453 4 : break;
4454 12 : case DataZoneEquipment::LoadDist::SequentialUniformPLR:
4455 : // Determine how many pieces of equipment are required to meet the current load,
4456 : // then distribute load at uniform PLR across all active equipment
4457 12 : if (energy.TotalOutputRequired >= 0.0) {
4458 : // For heating capacities and TotalOutputRequired are positive
4459 24 : for (int equipNum = 1.0; equipNum <= thisZEqList.NumOfEquipTypes; ++equipNum) {
4460 18 : if ((thisZEqList.HeatingCapacity(equipNum) > 0.0) && (availCap < energy.TotalOutputRequired)) {
4461 12 : if (thisZEqList.HeatingPriority(equipNum) > 0) availCap += thisZEqList.HeatingCapacity(equipNum);
4462 12 : ++numOperating;
4463 : }
4464 : }
4465 6 : if (availCap > 0.0) {
4466 6 : plr = energy.TotalOutputRequired / availCap;
4467 : } else {
4468 0 : plr = 0.0;
4469 0 : numOperating = 0;
4470 : }
4471 : } else {
4472 24 : for (int equipNum = 1.0; equipNum <= thisZEqList.NumOfEquipTypes; ++equipNum) {
4473 : // For cooling capacities and TotalOutputRequired are negative
4474 18 : if ((thisZEqList.CoolingCapacity(equipNum) < 0.0) && (availCap > energy.TotalOutputRequired)) {
4475 12 : if (thisZEqList.CoolingPriority(equipNum) > 0) availCap += thisZEqList.CoolingCapacity(equipNum);
4476 12 : ++numOperating;
4477 : }
4478 : }
4479 6 : if (availCap < 0.0) {
4480 6 : plr = energy.TotalOutputRequired / availCap;
4481 : } else {
4482 0 : plr = 0.0;
4483 0 : numOperating = 0;
4484 : }
4485 : }
4486 12 : if (plr <= 0.0) break; // Don't change anything
4487 : // Set loads for operating equipment
4488 36 : for (int equipNum = 1.0; equipNum <= numOperating; ++equipNum) {
4489 24 : if (energy.TotalOutputRequired >= 0.0) {
4490 12 : if (thisZEqList.HeatingPriority(equipNum) > 0) {
4491 12 : energy.SequencedOutputRequired(equipNum) = thisZEqList.HeatingCapacity(equipNum) * plr;
4492 12 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = thisZEqList.HeatingCapacity(equipNum) * plr;
4493 12 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = thisZEqList.HeatingCapacity(equipNum) * plr;
4494 12 : if (energy.OutputRequiredToHeatingSP != 0.0) {
4495 24 : moisture.SequencedOutputRequired(equipNum) =
4496 12 : moisture.TotalOutputRequired * (thisZEqList.HeatingCapacity(equipNum) * plr) / energy.OutputRequiredToHeatingSP;
4497 12 : moisture.SequencedOutputRequiredToHumidSP(equipNum) =
4498 12 : moisture.OutputRequiredToHumidifyingSP * (thisZEqList.HeatingCapacity(equipNum) * plr) / energy.OutputRequiredToHeatingSP;
4499 : } else {
4500 0 : moisture.SequencedOutputRequired(equipNum) = moisture.TotalOutputRequired * plr;
4501 0 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = moisture.OutputRequiredToHumidifyingSP * plr;
4502 : }
4503 12 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = 0.0;
4504 : } else {
4505 0 : energy.SequencedOutputRequired(equipNum) = 0.0;
4506 0 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = 0.0;
4507 0 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = 0.0;
4508 0 : moisture.SequencedOutputRequired(equipNum) = 0.0;
4509 0 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = 0.0;
4510 0 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = 0.0;
4511 : }
4512 : } else {
4513 12 : if (thisZEqList.CoolingPriority(equipNum) > 0) {
4514 10 : energy.SequencedOutputRequired(equipNum) = thisZEqList.CoolingCapacity(equipNum) * plr;
4515 10 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = thisZEqList.CoolingCapacity(equipNum) * plr;
4516 10 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = thisZEqList.CoolingCapacity(equipNum) * plr;
4517 10 : if (energy.OutputRequiredToCoolingSP != 0.0) {
4518 20 : moisture.SequencedOutputRequired(equipNum) =
4519 10 : moisture.TotalOutputRequired * (thisZEqList.CoolingCapacity(equipNum) * plr) / energy.OutputRequiredToCoolingSP;
4520 10 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = moisture.OutputRequiredToDehumidifyingSP *
4521 10 : (thisZEqList.CoolingCapacity(equipNum) * plr) /
4522 10 : energy.OutputRequiredToCoolingSP;
4523 : } else {
4524 0 : moisture.SequencedOutputRequired(equipNum) = moisture.TotalOutputRequired * plr;
4525 0 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = moisture.OutputRequiredToDehumidifyingSP * plr;
4526 : }
4527 10 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = 0.0;
4528 : } else {
4529 2 : energy.SequencedOutputRequired(equipNum) = 0.0;
4530 2 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = 0.0;
4531 2 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = 0.0;
4532 2 : moisture.SequencedOutputRequired(equipNum) = 0.0;
4533 2 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = 0.0;
4534 2 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = 0.0;
4535 : }
4536 : }
4537 : }
4538 : // Set loads to zero for remaining equipment
4539 24 : for (int equipNum = numOperating + 1; equipNum <= thisZEqList.NumOfEquipTypes; ++equipNum) {
4540 12 : energy.SequencedOutputRequired(equipNum) = 0.0;
4541 12 : energy.SequencedOutputRequiredToHeatingSP(equipNum) = 0.0;
4542 12 : energy.SequencedOutputRequiredToCoolingSP(equipNum) = 0.0;
4543 12 : moisture.SequencedOutputRequired(equipNum) = 0.0;
4544 12 : moisture.SequencedOutputRequiredToHumidSP(equipNum) = 0.0;
4545 12 : moisture.SequencedOutputRequiredToDehumidSP(equipNum) = 0.0;
4546 : }
4547 12 : break;
4548 0 : default:
4549 0 : ShowFatalError(state, "DistributeSystemOutputRequired: Illegal load distribution scheme type.");
4550 0 : break;
4551 : }
4552 : // For every load distribution scheme except SequentialLoad
4553 : // set the remaining loads to the first equipment type's load to support equipment types that don't use the sequenced loads
4554 292163 : if (thisZEqList.LoadDistScheme != DataZoneEquipment::LoadDist::Sequential) {
4555 24 : energy.RemainingOutputRequired = energy.SequencedOutputRequired(1);
4556 24 : moisture.RemainingOutputRequired = moisture.SequencedOutputRequired(1);
4557 24 : energy.RemainingOutputReqToHeatSP = energy.SequencedOutputRequiredToHeatingSP(1);
4558 24 : moisture.RemainingOutputReqToHumidSP = moisture.SequencedOutputRequiredToHumidSP(1);
4559 24 : energy.RemainingOutputReqToCoolSP = energy.SequencedOutputRequiredToCoolingSP(1);
4560 24 : moisture.RemainingOutputReqToDehumidSP = moisture.SequencedOutputRequiredToDehumidSP(1);
4561 : }
4562 292163 : }
4563 :
4564 397944 : void updateSystemOutputRequired(EnergyPlusData &state,
4565 : int const ZoneNum,
4566 : Real64 const SysOutputProvided, // sensible output provided by zone equipment (W)
4567 : Real64 const LatOutputProvided, // latent output provided by zone equipment (kg/s)
4568 : DataZoneEnergyDemands::ZoneSystemSensibleDemand &energy,
4569 : DataZoneEnergyDemands::ZoneSystemMoistureDemand &moisture,
4570 : int const EquipPriorityNum // optional index in PrioritySimOrder for this update
4571 : )
4572 : {
4573 :
4574 : // SUBROUTINE INFORMATION:
4575 : // AUTHOR Russ Taylor
4576 : // MODIFIED B. Griffith Sept 2011, add storage of requirements by sequence
4577 :
4578 : // If zone is uncontrolled use original method for remaining output
4579 397944 : if (!state.dataHeatBal->Zone(ZoneNum).IsControlled) {
4580 : // SequentialLoading, use original method for remaining output
4581 10 : energy.UnadjRemainingOutputRequired -= SysOutputProvided;
4582 10 : energy.RemainingOutputRequired = energy.UnadjRemainingOutputRequired;
4583 10 : energy.UnadjRemainingOutputReqToHeatSP -= SysOutputProvided;
4584 10 : energy.RemainingOutputReqToHeatSP = energy.UnadjRemainingOutputReqToHeatSP;
4585 10 : energy.UnadjRemainingOutputReqToCoolSP -= SysOutputProvided;
4586 10 : energy.RemainingOutputReqToCoolSP = energy.UnadjRemainingOutputReqToCoolSP;
4587 : // Latent output updates
4588 10 : moisture.UnadjRemainingOutputRequired -= LatOutputProvided;
4589 10 : moisture.RemainingOutputRequired = moisture.UnadjRemainingOutputRequired;
4590 10 : moisture.UnadjRemainingOutputReqToHumidSP -= LatOutputProvided;
4591 10 : moisture.RemainingOutputReqToHumidSP = moisture.UnadjRemainingOutputReqToHumidSP;
4592 10 : moisture.UnadjRemainingOutputReqToDehumidSP -= LatOutputProvided;
4593 10 : moisture.RemainingOutputReqToDehumidSP = moisture.UnadjRemainingOutputReqToDehumidSP;
4594 :
4595 : // re-evaluate if loads are now such that in dead band or set back
4596 10 : switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
4597 0 : case HVAC::SetptType::Uncontrolled: {
4598 : // uncontrolled zone; shouldn't ever get here, but who knows
4599 0 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) = false;
4600 0 : } break;
4601 :
4602 0 : case HVAC::SetptType::SingleHeat: {
4603 0 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) = ((energy.RemainingOutputRequired - 1.0) < 0.0);
4604 0 : } break;
4605 :
4606 0 : case HVAC::SetptType::SingleCool: {
4607 0 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) = ((energy.RemainingOutputRequired + 1.0) > 0.0);
4608 0 : } break;
4609 :
4610 0 : case HVAC::SetptType::SingleHeatCool: {
4611 0 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) =
4612 0 : (energy.RemainingOutputReqToHeatSP < 0.0 && energy.RemainingOutputReqToCoolSP > 0.0);
4613 0 : } break;
4614 :
4615 10 : case HVAC::SetptType::DualHeatCool: {
4616 10 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) =
4617 10 : (energy.RemainingOutputReqToHeatSP < 0.0 && energy.RemainingOutputReqToCoolSP > 0.0);
4618 10 : } break;
4619 :
4620 0 : default: {
4621 0 : } break;
4622 : } // swtich
4623 :
4624 10 : if (EquipPriorityNum > -1) {
4625 : // now store remaining load at the by sequence level
4626 0 : if (EquipPriorityNum + 1 <= energy.NumZoneEquipment) {
4627 0 : energy.SequencedOutputRequired(EquipPriorityNum + 1) = energy.RemainingOutputRequired;
4628 0 : moisture.SequencedOutputRequired(EquipPriorityNum + 1) = moisture.RemainingOutputRequired;
4629 : }
4630 :
4631 0 : if (state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).HeatingPriority + 1 <= energy.NumZoneEquipment) {
4632 0 : energy.SequencedOutputRequiredToHeatingSP(state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).HeatingPriority + 1) =
4633 0 : energy.RemainingOutputReqToHeatSP;
4634 0 : moisture.SequencedOutputRequiredToHumidSP(state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).HeatingPriority + 1) =
4635 0 : moisture.RemainingOutputReqToHumidSP;
4636 : }
4637 0 : if (state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).CoolingPriority + 1 <= energy.NumZoneEquipment) {
4638 0 : energy.SequencedOutputRequiredToCoolingSP(state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).CoolingPriority + 1) =
4639 0 : energy.RemainingOutputReqToCoolSP;
4640 0 : moisture.SequencedOutputRequiredToDehumidSP(state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).CoolingPriority + 1) =
4641 0 : moisture.RemainingOutputReqToDehumidSP;
4642 : }
4643 : }
4644 10 : return;
4645 : }
4646 :
4647 : // Sensible output updates
4648 397934 : auto &thisZEqList(state.dataZoneEquip->ZoneEquipList(ZoneNum));
4649 397934 : switch (thisZEqList.LoadDistScheme) {
4650 397934 : case DataZoneEquipment::LoadDist::Sequential: {
4651 : // Subtract the system output from the unadjusted loads required
4652 397934 : energy.UnadjRemainingOutputRequired -= SysOutputProvided;
4653 397934 : energy.UnadjRemainingOutputReqToHeatSP -= SysOutputProvided;
4654 397934 : energy.UnadjRemainingOutputReqToCoolSP -= SysOutputProvided;
4655 397934 : moisture.UnadjRemainingOutputRequired -= LatOutputProvided;
4656 397934 : moisture.UnadjRemainingOutputReqToHumidSP -= LatOutputProvided;
4657 397934 : moisture.UnadjRemainingOutputReqToDehumidSP -= LatOutputProvided;
4658 :
4659 397934 : if ((EquipPriorityNum > -1) && (EquipPriorityNum < thisZEqList.NumOfEquipTypes)) {
4660 :
4661 : // Look up the next system in priority order
4662 62255 : int nextEquipPriorityNum = EquipPriorityNum + 1;
4663 62255 : const int &nextSystem = state.dataZoneEquipmentManager->PrioritySimOrder(nextEquipPriorityNum).EquipPtr;
4664 :
4665 : // Determine the load ratio based on whether we're heating or cooling
4666 62255 : const Real64 loadRatio = (energy.TotalOutputRequired >= 0.0) ? thisZEqList.SequentialHeatingFraction(state, nextSystem)
4667 28588 : : thisZEqList.SequentialCoolingFraction(state, nextSystem);
4668 :
4669 : // Update the zone energy demands
4670 62255 : energy.RemainingOutputRequired = loadRatio * energy.UnadjRemainingOutputRequired;
4671 62255 : energy.RemainingOutputReqToHeatSP = loadRatio * energy.UnadjRemainingOutputReqToHeatSP;
4672 62255 : energy.RemainingOutputReqToCoolSP = loadRatio * energy.UnadjRemainingOutputReqToCoolSP;
4673 62255 : moisture.RemainingOutputRequired = loadRatio * moisture.UnadjRemainingOutputRequired;
4674 62255 : moisture.RemainingOutputReqToHumidSP = loadRatio * moisture.UnadjRemainingOutputReqToHumidSP;
4675 62255 : moisture.RemainingOutputReqToDehumidSP = loadRatio * moisture.UnadjRemainingOutputReqToDehumidSP;
4676 :
4677 : // now store remaining load at the sequence level
4678 62255 : energy.SequencedOutputRequired(nextEquipPriorityNum) = energy.RemainingOutputRequired;
4679 62255 : energy.SequencedOutputRequiredToHeatingSP(nextEquipPriorityNum) = energy.RemainingOutputReqToHeatSP;
4680 62255 : energy.SequencedOutputRequiredToCoolingSP(nextEquipPriorityNum) = energy.RemainingOutputReqToCoolSP;
4681 62255 : moisture.SequencedOutputRequired(nextEquipPriorityNum) = moisture.RemainingOutputRequired;
4682 62255 : moisture.SequencedOutputRequiredToHumidSP(nextEquipPriorityNum) = moisture.RemainingOutputReqToHumidSP;
4683 62255 : moisture.SequencedOutputRequiredToDehumidSP(nextEquipPriorityNum) = moisture.RemainingOutputReqToDehumidSP;
4684 62255 : } else {
4685 : // SequentialLoading, use original method for remaining output
4686 335679 : energy.RemainingOutputRequired = energy.UnadjRemainingOutputRequired;
4687 335679 : energy.RemainingOutputReqToHeatSP = energy.UnadjRemainingOutputReqToHeatSP;
4688 335679 : energy.RemainingOutputReqToCoolSP = energy.UnadjRemainingOutputReqToCoolSP;
4689 : // Latent output updates
4690 335679 : moisture.RemainingOutputRequired = moisture.UnadjRemainingOutputRequired;
4691 335679 : moisture.RemainingOutputReqToHumidSP = moisture.UnadjRemainingOutputReqToHumidSP;
4692 335679 : moisture.RemainingOutputReqToDehumidSP = moisture.UnadjRemainingOutputReqToDehumidSP;
4693 : }
4694 :
4695 : // re-evaluate if loads are now such that in dead band or set back
4696 397934 : switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
4697 2 : case HVAC::SetptType::Uncontrolled: {
4698 : // uncontrolled zone; shouldn't ever get here, but who knows
4699 2 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) = false;
4700 2 : } break;
4701 :
4702 24688 : case HVAC::SetptType::SingleHeat: {
4703 24688 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) = ((energy.RemainingOutputRequired - 1.0) < 0.0);
4704 24688 : } break;
4705 :
4706 24092 : case HVAC::SetptType::SingleCool: {
4707 24092 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) = ((energy.RemainingOutputRequired + 1.0) > 0.0);
4708 24092 : } break;
4709 :
4710 0 : case HVAC::SetptType::SingleHeatCool: {
4711 0 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) =
4712 0 : (energy.RemainingOutputReqToHeatSP < 0.0 && energy.RemainingOutputReqToCoolSP > 0.0);
4713 0 : } break;
4714 :
4715 349152 : case HVAC::SetptType::DualHeatCool: {
4716 349152 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) =
4717 349152 : (energy.RemainingOutputReqToHeatSP < 0.0 && energy.RemainingOutputReqToCoolSP > 0.0);
4718 349152 : } break;
4719 :
4720 0 : default: {
4721 0 : } break;
4722 :
4723 : } // switch
4724 :
4725 397934 : } break;
4726 0 : case DataZoneEquipment::LoadDist::Uniform:
4727 : case DataZoneEquipment::LoadDist::UniformPLR:
4728 : case DataZoneEquipment::LoadDist::SequentialUniformPLR:
4729 : // For every load distribution scheme except SequentialLoad, do not touch the sequenced loads,
4730 : // but set the remaining loads to the next equipment type's load to support equipment types that don't use the sequenced loads
4731 0 : if (EquipPriorityNum > -1) {
4732 0 : if (EquipPriorityNum + 1 <= energy.NumZoneEquipment) {
4733 0 : energy.RemainingOutputRequired = energy.SequencedOutputRequired(EquipPriorityNum + 1);
4734 0 : moisture.RemainingOutputRequired = moisture.SequencedOutputRequired(EquipPriorityNum + 1);
4735 : }
4736 :
4737 0 : if (state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).HeatingPriority + 1 <= energy.NumZoneEquipment) {
4738 0 : energy.RemainingOutputReqToHeatSP =
4739 0 : energy.SequencedOutputRequiredToHeatingSP(state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).HeatingPriority + 1);
4740 0 : moisture.RemainingOutputReqToHumidSP =
4741 0 : moisture.SequencedOutputRequiredToHumidSP(state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).HeatingPriority + 1);
4742 : }
4743 0 : if (state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).CoolingPriority + 1 <= energy.NumZoneEquipment) {
4744 0 : energy.RemainingOutputReqToCoolSP =
4745 0 : energy.SequencedOutputRequiredToCoolingSP(state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).CoolingPriority + 1);
4746 0 : moisture.RemainingOutputReqToDehumidSP = moisture.SequencedOutputRequiredToDehumidSP(
4747 0 : state.dataZoneEquipmentManager->PrioritySimOrder(EquipPriorityNum).CoolingPriority + 1);
4748 : }
4749 : }
4750 0 : break;
4751 0 : default:
4752 0 : ShowFatalError(state, "UpdateSystemOutputRequired: Illegal load distribution scheme type.");
4753 0 : break;
4754 : }
4755 : }
4756 :
4757 2 : void adjustSystemOutputRequired(Real64 const sensibleRatio, // sensible load adjustment
4758 : Real64 const latentRatio, // latent load adjustment
4759 : DataZoneEnergyDemands::ZoneSystemSensibleDemand &energy,
4760 : DataZoneEnergyDemands::ZoneSystemMoistureDemand &moisture,
4761 : int const equipPriorityNum // index in PrioritySimOrder
4762 : )
4763 : {
4764 : // Adjust the zone energy demands for space thermostat control
4765 2 : energy.RemainingOutputRequired *= sensibleRatio;
4766 2 : energy.RemainingOutputReqToHeatSP *= sensibleRatio;
4767 2 : energy.RemainingOutputReqToCoolSP *= sensibleRatio;
4768 2 : moisture.RemainingOutputRequired *= latentRatio;
4769 2 : moisture.RemainingOutputReqToHumidSP *= latentRatio;
4770 2 : moisture.RemainingOutputReqToDehumidSP *= latentRatio;
4771 :
4772 2 : energy.SequencedOutputRequired(equipPriorityNum) *= sensibleRatio;
4773 2 : energy.SequencedOutputRequiredToHeatingSP(equipPriorityNum) *= sensibleRatio;
4774 2 : energy.SequencedOutputRequiredToCoolingSP(equipPriorityNum) *= sensibleRatio;
4775 2 : moisture.SequencedOutputRequired(equipPriorityNum) *= latentRatio;
4776 2 : moisture.SequencedOutputRequiredToHumidSP(equipPriorityNum) *= latentRatio;
4777 2 : moisture.SequencedOutputRequiredToDehumidSP(equipPriorityNum) *= latentRatio;
4778 2 : }
4779 :
4780 513293 : void CalcZoneMassBalance(EnergyPlusData &state, bool const FirstHVACIteration)
4781 : {
4782 :
4783 : // SUBROUTINE INFORMATION:
4784 : // AUTHOR Russ Taylor
4785 : // DATE WRITTEN May 1997
4786 :
4787 : // PURPOSE OF THIS SUBROUTINE:
4788 : // Perform zone mass balance to get outlet air flow conditions.
4789 :
4790 : // METHODOLOGY EMPLOYED:
4791 : // Mass continuity equation.
4792 :
4793 513293 : int constexpr IterMax(25);
4794 513293 : Real64 constexpr ConvergenceTolerance(0.000010);
4795 :
4796 513293 : state.dataHVACGlobal->ZoneMassBalanceHVACReSim = false;
4797 513293 : int Iteration = 0;
4798 513293 : Real64 BuildingZoneMixingFlow = 0.0;
4799 513293 : Real64 BuildingZoneMixingFlowOld = 0.0;
4800 513293 : Real64 BuildingZoneReturnFlow = 0.0;
4801 513293 : Real64 BuildingZoneReturnFlowOld = 0.0;
4802 :
4803 513293 : auto &Node(state.dataLoopNodes->Node);
4804 :
4805 : // Total loop supply and recirc flows (these have been zeroed earlier in InitZoneEquipment
4806 633625 : for (int airDistUnit = 1; airDistUnit <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++airDistUnit) {
4807 120332 : auto &airDisUnit = state.dataDefineEquipment->AirDistUnit(airDistUnit);
4808 120332 : if (airDisUnit.AirLoopNum > 0) {
4809 120255 : auto &airLoopFlow = state.dataAirLoop->AirLoopFlow(airDisUnit.AirLoopNum);
4810 120255 : airLoopFlow.SupFlow += airDisUnit.MassFlowRateSup;
4811 120255 : airLoopFlow.RecircFlow += airDisUnit.MassFlowRatePlenInd;
4812 120255 : airLoopFlow.LeakFlow += airDisUnit.MassFlowRateDnStrLk + airDisUnit.MassFlowRateUpStrLk;
4813 : }
4814 : }
4815 :
4816 : // Set max OA flow and frac for systems which are all OA (no OASys)
4817 589129 : for (int airLoop = 1; airLoop <= state.dataHVACGlobal->NumPrimaryAirSys; ++airLoop) {
4818 75836 : if (state.dataAirSystemsData->PrimaryAirSystems(airLoop).isAllOA) {
4819 0 : auto &airLoopFlow = state.dataAirLoop->AirLoopFlow(airLoop);
4820 0 : airLoopFlow.MaxOutAir = airLoopFlow.SupFlow;
4821 0 : airLoopFlow.OAFlow = airLoopFlow.SupFlow;
4822 0 : airLoopFlow.OAFrac = 1.0;
4823 : }
4824 : }
4825 :
4826 : do {
4827 513311 : if (state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) {
4828 : // These are also reset in ZoneEquipmentManager::InitZoneEquipment, reset again here for each zone mass balance iteration
4829 76 : for (int airLoop = 1; airLoop <= state.dataHVACGlobal->NumPrimaryAirSys; ++airLoop) {
4830 44 : auto &airLoopFlow = state.dataAirLoop->AirLoopFlow(airLoop);
4831 44 : airLoopFlow.ZoneRetFlow = 0.0;
4832 44 : airLoopFlow.SysRetFlow = 0.0;
4833 44 : airLoopFlow.ExcessZoneExhFlow = 0.0;
4834 : }
4835 98 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
4836 66 : if (!state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) continue;
4837 66 : state.dataHeatBalFanSys->ZoneInfiltrationFlag(ZoneNum) = false;
4838 66 : state.dataHeatBal->MassConservation(ZoneNum).IncludeInfilToZoneMassBal = 0.0;
4839 66 : state.dataHeatBal->MassConservation(ZoneNum).RetMassFlowRate = 0.0;
4840 66 : state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ExcessZoneExh = 0.0;
4841 66 : if (state.dataHeatBal->doSpaceHeatBalance) {
4842 0 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
4843 0 : if (!state.dataZoneEquip->spaceEquipConfig(spaceNum).IsControlled) continue;
4844 0 : state.dataZoneEquip->spaceEquipConfig(spaceNum).ExcessZoneExh = 0.0;
4845 : }
4846 : }
4847 : }
4848 : }
4849 513311 : BuildingZoneMixingFlowOld = BuildingZoneMixingFlow;
4850 513311 : BuildingZoneMixingFlow = 0.0;
4851 :
4852 513311 : BuildingZoneReturnFlowOld = BuildingZoneReturnFlow;
4853 513311 : BuildingZoneReturnFlow = 0.0;
4854 :
4855 1215538 : for (int ZoneNum1 = 1; ZoneNum1 <= state.dataGlobal->NumOfZones; ++ZoneNum1) {
4856 702227 : int ZoneNum = ZoneNum1;
4857 702227 : if (state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) ZoneNum = state.dataHeatBalFanSys->ZoneReOrder(ZoneNum1);
4858 702227 : if (!state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) continue;
4859 277049 : auto &massConservation = state.dataHeatBal->MassConservation(ZoneNum);
4860 277049 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(ZoneNum);
4861 277049 : Real64 TotExhaustAirMassFlowRate = 0.0;
4862 :
4863 277049 : zoneEquipConfig.TotExhaustAirMassFlowRate = 0.0;
4864 :
4865 277049 : Real64 ZoneMixingAirMassFlowRate = 0.0;
4866 277049 : Real64 ZoneMixingNetAirMassFlowRate = 0.0;
4867 277049 : Real64 ZoneReturnAirMassFlowRate = 0.0;
4868 :
4869 : // SpaceHVAC TODO: For now, ZoneMassBalance happens at the zone level, not space
4870 277049 : zoneEquipConfig.setTotalInletFlows(state);
4871 277049 : Real64 TotInletAirMassFlowRate = zoneEquipConfig.TotInletAirMassFlowRate;
4872 277049 : if (state.dataHeatBal->doSpaceHeatBalance) {
4873 59344 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
4874 44508 : auto &spaceEquipConfig = state.dataZoneEquip->spaceEquipConfig(spaceNum);
4875 44508 : if (spaceEquipConfig.IsControlled) {
4876 0 : spaceEquipConfig.setTotalInletFlows(state);
4877 : } else {
4878 : // If space is not controlled, allocate zone-level airflow by volume
4879 44508 : auto &thisSpace = state.dataHeatBal->space(spaceNum);
4880 44508 : Real64 spaceFrac = thisSpace.fracZoneVolume;
4881 44508 : DataZoneEquipment::scaleInletFlows(state, zoneEquipConfig.ZoneNode, thisSpace.SystemZoneNodeNumber, spaceFrac);
4882 : }
4883 : }
4884 : }
4885 :
4886 461853 : for (int NodeNum = 1; NodeNum <= zoneEquipConfig.NumExhaustNodes; ++NodeNum) {
4887 :
4888 184804 : if (state.afn->AirflowNetworkNumOfExhFan == 0) {
4889 156728 : zoneEquipConfig.TotExhaustAirMassFlowRate += Node(zoneEquipConfig.ExhaustNode(NodeNum)).MassFlowRate;
4890 : }
4891 : }
4892 277049 : TotExhaustAirMassFlowRate = zoneEquipConfig.TotExhaustAirMassFlowRate;
4893 :
4894 : // Include zone mixing mass flow rate
4895 277049 : if (state.dataHeatBalFanSys->ZoneMassBalanceFlag(ZoneNum)) {
4896 65 : int NumRetNodes = zoneEquipConfig.NumReturnNodes;
4897 130 : for (int NodeNumHere = 1; NodeNumHere <= NumRetNodes; ++NodeNumHere) {
4898 65 : int RetNode = zoneEquipConfig.ReturnNode(NodeNumHere);
4899 65 : if (RetNode > 0) {
4900 65 : ZoneReturnAirMassFlowRate += Node(RetNode).MassFlowRate;
4901 : }
4902 : }
4903 : // Set zone mixing incoming mass flow rate
4904 94 : if ((Iteration == 0) || state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment == DataHeatBalance::AdjustmentType::AdjustReturnOnly ||
4905 29 : state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment == DataHeatBalance::AdjustmentType::AdjustReturnThenMixing) {
4906 42 : ZoneMixingAirMassFlowRate = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MixingMassFlowZone;
4907 : } else {
4908 23 : ZoneMixingAirMassFlowRate = max(0.0,
4909 23 : ZoneReturnAirMassFlowRate + TotExhaustAirMassFlowRate - TotInletAirMassFlowRate +
4910 23 : massConservation.MixingSourceMassFlowRate);
4911 : }
4912 65 : CalcZoneMixingFlowRateOfReceivingZone(state, ZoneNum, ZoneMixingAirMassFlowRate);
4913 65 : ZoneMixingNetAirMassFlowRate = massConservation.MixingMassFlowRate - massConservation.MixingSourceMassFlowRate;
4914 : }
4915 :
4916 : // Calculate standard return air flow rate using default method of inlets minus exhausts adjusted for "balanced" exhaust flow
4917 277049 : Real64 StdTotalReturnMassFlow =
4918 277049 : TotInletAirMassFlowRate + ZoneMixingNetAirMassFlowRate - (TotExhaustAirMassFlowRate - zoneEquipConfig.ZoneExhBalanced);
4919 :
4920 277049 : if (!state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) {
4921 276983 : if (StdTotalReturnMassFlow < 0.0) {
4922 412 : zoneEquipConfig.ExcessZoneExh = -StdTotalReturnMassFlow;
4923 412 : StdTotalReturnMassFlow = 0.0;
4924 : } else {
4925 276571 : zoneEquipConfig.ExcessZoneExh = 0.0;
4926 : }
4927 : } else {
4928 66 : zoneEquipConfig.ExcessZoneExh = 0.0;
4929 66 : StdTotalReturnMassFlow = max(0.0, StdTotalReturnMassFlow);
4930 : }
4931 :
4932 277049 : Real64 FinalTotalReturnMassFlow = 0;
4933 277049 : zoneEquipConfig.calcReturnFlows(state, StdTotalReturnMassFlow, FinalTotalReturnMassFlow);
4934 277049 : if (state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) {
4935 : // set mass conservation variables
4936 66 : massConservation.InMassFlowRate = TotInletAirMassFlowRate;
4937 66 : massConservation.ExhMassFlowRate = TotExhaustAirMassFlowRate;
4938 :
4939 110 : if (state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment == DataHeatBalance::AdjustmentType::AdjustMixingOnly ||
4940 44 : state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment == DataHeatBalance::AdjustmentType::AdjustMixingThenReturn) {
4941 38 : massConservation.RetMassFlowRate = FinalTotalReturnMassFlow;
4942 38 : ZoneReturnAirMassFlowRate = FinalTotalReturnMassFlow;
4943 38 : if (state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment == DataHeatBalance::AdjustmentType::AdjustMixingThenReturn) {
4944 :
4945 : // Calculate return air flow rate using mass conservation equation
4946 : Real64 AdjustedTotalReturnMassFlow =
4947 16 : max(0.0, TotInletAirMassFlowRate - TotExhaustAirMassFlowRate + ZoneMixingNetAirMassFlowRate);
4948 16 : if (!state.dataGlobal->DoingSizing) {
4949 16 : AdjustedTotalReturnMassFlow = min(AdjustedTotalReturnMassFlow, zoneEquipConfig.AirLoopDesSupply);
4950 : }
4951 : // add adjust zone return node air flow calc
4952 16 : zoneEquipConfig.calcReturnFlows(state, AdjustedTotalReturnMassFlow, FinalTotalReturnMassFlow);
4953 16 : massConservation.RetMassFlowRate = FinalTotalReturnMassFlow;
4954 16 : ZoneReturnAirMassFlowRate = FinalTotalReturnMassFlow;
4955 : }
4956 : // Set zone infiltration air flow rate
4957 38 : CalcZoneInfiltrationFlows(state, ZoneNum, ZoneReturnAirMassFlowRate);
4958 :
4959 44 : } else if (state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment == DataHeatBalance::AdjustmentType::AdjustReturnOnly ||
4960 16 : state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment == DataHeatBalance::AdjustmentType::AdjustReturnThenMixing) {
4961 :
4962 : // Calculate return air flow rate using mass conservation equation
4963 24 : Real64 AdjustedTotalReturnMassFlow = max(0.0, TotInletAirMassFlowRate - TotExhaustAirMassFlowRate + ZoneMixingNetAirMassFlowRate);
4964 24 : if (!state.dataGlobal->DoingSizing) {
4965 24 : AdjustedTotalReturnMassFlow = min(AdjustedTotalReturnMassFlow, zoneEquipConfig.AirLoopDesSupply);
4966 : }
4967 :
4968 : // add adjust zone return node air flow calculation
4969 24 : zoneEquipConfig.calcReturnFlows(state, AdjustedTotalReturnMassFlow, FinalTotalReturnMassFlow);
4970 24 : massConservation.RetMassFlowRate = FinalTotalReturnMassFlow;
4971 24 : ZoneReturnAirMassFlowRate = FinalTotalReturnMassFlow;
4972 :
4973 24 : if (state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment == DataHeatBalance::AdjustmentType::AdjustReturnThenMixing) {
4974 24 : ZoneMixingAirMassFlowRate = max(0.0,
4975 12 : ZoneReturnAirMassFlowRate + TotExhaustAirMassFlowRate - TotInletAirMassFlowRate +
4976 12 : massConservation.MixingSourceMassFlowRate);
4977 12 : CalcZoneMixingFlowRateOfReceivingZone(state, ZoneNum, ZoneMixingAirMassFlowRate);
4978 12 : ZoneMixingNetAirMassFlowRate = massConservation.MixingMassFlowRate - massConservation.MixingSourceMassFlowRate;
4979 :
4980 : // Calculate return air flow rate using mass conservation equation
4981 12 : AdjustedTotalReturnMassFlow = max(0.0, TotInletAirMassFlowRate - TotExhaustAirMassFlowRate + ZoneMixingNetAirMassFlowRate);
4982 12 : if (!state.dataGlobal->DoingSizing) {
4983 12 : AdjustedTotalReturnMassFlow = min(AdjustedTotalReturnMassFlow, zoneEquipConfig.AirLoopDesSupply);
4984 : }
4985 :
4986 : // add adjust zone return node air flow calc
4987 12 : zoneEquipConfig.calcReturnFlows(state, AdjustedTotalReturnMassFlow, FinalTotalReturnMassFlow);
4988 12 : massConservation.RetMassFlowRate = FinalTotalReturnMassFlow;
4989 12 : ZoneReturnAirMassFlowRate = FinalTotalReturnMassFlow;
4990 : }
4991 :
4992 : // Set zone infiltration air flow rate
4993 24 : CalcZoneInfiltrationFlows(state, ZoneNum, ZoneReturnAirMassFlowRate);
4994 : } else {
4995 : // if infiltration treatment method is not None
4996 : // Set zone infiltration air flow rate
4997 4 : CalcZoneInfiltrationFlows(state, ZoneNum, ZoneReturnAirMassFlowRate);
4998 : }
4999 : }
5000 :
5001 277049 : BuildingZoneMixingFlow += massConservation.MixingMassFlowRate;
5002 277049 : BuildingZoneReturnFlow += massConservation.RetMassFlowRate;
5003 :
5004 : // Accumulate airloop total return flows and allocate excess exhaust flows
5005 545617 : for (int returnNum = 1; returnNum <= zoneEquipConfig.NumReturnNodes; ++returnNum) {
5006 268568 : int retNode = zoneEquipConfig.ReturnNode(returnNum);
5007 268568 : int airLoop = zoneEquipConfig.ReturnNodeAirLoopNum(returnNum);
5008 268568 : if (airLoop > 0) {
5009 120327 : state.dataAirLoop->AirLoopFlow(airLoop).ZoneRetFlow += Node(retNode).MassFlowRate;
5010 120327 : if (zoneEquipConfig.TotAvailAirLoopOA > 0.0) {
5011 105571 : state.dataAirLoop->AirLoopFlow(airLoop).ExcessZoneExhFlow +=
5012 105571 : zoneEquipConfig.ExcessZoneExh * state.dataAirLoop->AirLoopFlow(airLoop).MaxOutAir / zoneEquipConfig.TotAvailAirLoopOA;
5013 : }
5014 : }
5015 : }
5016 : }
5017 :
5018 : // adjust the zone return air flow rates to match any excess zone exhaust flows
5019 589171 : for (int airLoopNum = 1; airLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++airLoopNum) {
5020 75860 : auto &thisAirLoopFlow(state.dataAirLoop->AirLoopFlow(airLoopNum));
5021 75860 : Real64 adjZoneRetFlow = max(0.0, thisAirLoopFlow.ZoneRetFlow - thisAirLoopFlow.ExcessZoneExhFlow);
5022 75860 : if (thisAirLoopFlow.ZoneRetFlow > 0.0) {
5023 64899 : thisAirLoopFlow.ZoneRetFlowRatio = adjZoneRetFlow / thisAirLoopFlow.ZoneRetFlow;
5024 : } else {
5025 10961 : thisAirLoopFlow.ZoneRetFlowRatio = 1.0;
5026 : }
5027 75860 : thisAirLoopFlow.ZoneRetFlow = 0.0; // reset to zero and re-accumulate below
5028 : }
5029 :
5030 1215538 : for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
5031 702227 : auto &thisZoneEquip(state.dataZoneEquip->ZoneEquipConfig(zoneNum));
5032 702227 : auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
5033 702227 : if (!thisZoneEquip.IsControlled) continue;
5034 277049 : int numRetNodes = thisZoneEquip.NumReturnNodes;
5035 277049 : Real64 totalZoneReturnMassFlow = 0.0;
5036 545617 : for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) {
5037 268568 : int retNode = thisZoneEquip.ReturnNode(returnNum);
5038 268568 : int airLoopNum = thisZoneEquip.ReturnNodeAirLoopNum(returnNum);
5039 268568 : if (retNode > 0) {
5040 268568 : if (airLoopNum > 0) {
5041 120327 : auto &thisAirLoopFlow(state.dataAirLoop->AirLoopFlow(airLoopNum));
5042 120327 : Node(retNode).MassFlowRate *= thisAirLoopFlow.ZoneRetFlowRatio;
5043 120327 : thisAirLoopFlow.ZoneRetFlow += Node(retNode).MassFlowRate;
5044 : }
5045 268568 : totalZoneReturnMassFlow += Node(retNode).MassFlowRate;
5046 : }
5047 : }
5048 : // Check zone flow balance but not when zone air mass balance is active
5049 554032 : if (!state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance && !state.dataGlobal->DoingSizing &&
5050 554032 : !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->WarmupFlag && !FirstHVACIteration) {
5051 11338 : if (!thisZoneEquip.FlowError) {
5052 : // Net system flows first (sum leaving flows, less entering flows)
5053 11338 : Real64 sysUnbalExhaust = (thisZoneEquip.TotExhaustAirMassFlowRate - thisZoneEquip.ZoneExhBalanced);
5054 11338 : Real64 sysUnbalancedFlow = sysUnbalExhaust + totalZoneReturnMassFlow - thisZoneEquip.TotInletAirMassFlowRate;
5055 11338 : if (sysUnbalancedFlow > HVAC::SmallMassFlow) {
5056 : // Now include infiltration, ventilation, and mixing flows (these are all entering the zone, so subtract them)
5057 1 : Real64 incomingFlow = thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.MixingMassFlowZone;
5058 1 : Real64 unbalancedFlow = max(0.0, sysUnbalancedFlow - incomingFlow);
5059 1 : if (unbalancedFlow > HVAC::SmallMassFlow) {
5060 : // Re-check on volume basis - use current zone density for incoming, standard density for HVAC sys
5061 1 : Real64 zoneTemp = Node(thisZoneEquip.ZoneNode).Temp;
5062 1 : Real64 zoneHumRat = Node(thisZoneEquip.ZoneNode).HumRat;
5063 1 : Real64 rhoZone = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, zoneTemp, zoneHumRat, "CalcZoneMassBalance");
5064 1 : Real64 incomingVolFlow = incomingFlow / rhoZone;
5065 1 : Real64 sysUnbalancedVolFlow = sysUnbalancedFlow / state.dataEnvrn->StdRhoAir;
5066 1 : Real64 unbalancedVolFlow = max(0.0, sysUnbalancedVolFlow - incomingVolFlow);
5067 1 : if (unbalancedVolFlow > HVAC::SmallAirVolFlow) {
5068 2 : ShowWarningError(state,
5069 2 : format("In zone {} there is unbalanced air flow. Load due to induced outdoor air is neglected.",
5070 1 : thisZoneEquip.ZoneName));
5071 2 : ShowContinueErrorTimeStamp(state, "");
5072 2 : ShowContinueError(state,
5073 2 : format(" Flows [m3/s]: Inlets: {:.6R} Unbalanced exhausts: {:.6R} Returns: {:.6R}",
5074 1 : thisZoneEquip.TotInletAirMassFlowRate / state.dataEnvrn->StdRhoAir,
5075 1 : sysUnbalExhaust / state.dataEnvrn->StdRhoAir,
5076 1 : totalZoneReturnMassFlow / state.dataEnvrn->StdRhoAir));
5077 2 : ShowContinueError(state,
5078 2 : format(" Infiltration: {:.6R} Zone Ventilation: {:.6R} Mixing (incoming): {:.6R}",
5079 0 : thisZoneHB.OAMFL / rhoZone,
5080 0 : thisZoneHB.VAMFL / rhoZone,
5081 1 : thisZoneHB.MixingMassFlowZone / rhoZone));
5082 2 : ShowContinueError(
5083 : state,
5084 2 : format(" Imbalance (excess outflow): {:.6R} Total system OA flow (for all airloops serving this zone): {:.6R}",
5085 : unbalancedVolFlow,
5086 1 : thisZoneEquip.TotAvailAirLoopOA / state.dataEnvrn->StdRhoAir));
5087 2 : ShowContinueError(state, " This error will only be reported once per zone.");
5088 1 : thisZoneEquip.FlowError = true;
5089 : }
5090 : }
5091 : }
5092 : }
5093 : }
5094 : }
5095 :
5096 : // update the
5097 513311 : if (Iteration > 0) {
5098 18 : Real64 totalResidual = 0.0;
5099 18 : totalResidual =
5100 18 : std::abs(BuildingZoneMixingFlow - BuildingZoneMixingFlowOld) + std::abs(BuildingZoneReturnFlow - BuildingZoneReturnFlowOld);
5101 18 : if (totalResidual < ConvergenceTolerance) {
5102 14 : state.dataHVACGlobal->ZoneMassBalanceHVACReSim = false;
5103 14 : break;
5104 : } else {
5105 4 : state.dataHVACGlobal->ZoneMassBalanceHVACReSim = true;
5106 : }
5107 : }
5108 513297 : if (!state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) break;
5109 18 : Iteration += 1;
5110 :
5111 18 : } while (Iteration < IterMax);
5112 : // Set system return flows
5113 589129 : for (int AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
5114 75836 : auto &thisAirLoopFlow(state.dataAirLoop->AirLoopFlow(AirLoopNum));
5115 75836 : thisAirLoopFlow.SysRetFlow = thisAirLoopFlow.ZoneRetFlow - thisAirLoopFlow.RecircFlow + thisAirLoopFlow.LeakFlow;
5116 : }
5117 513293 : }
5118 :
5119 66 : void CalcZoneInfiltrationFlows(EnergyPlusData &state,
5120 : int const ZoneNum, // current zone index
5121 : Real64 const &ZoneReturnAirMassFlowRate // zone total zone return air mass flow rate
5122 : )
5123 : {
5124 66 : Real64 constexpr ConvergenceTolerance(0.000010);
5125 66 : Real64 ZoneInfiltrationMassFlowRate = 0.0;
5126 66 : auto &massConservation = state.dataHeatBal->MassConservation(ZoneNum);
5127 :
5128 : // Set zone infiltration flow rate
5129 66 : if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment != DataHeatBalance::InfiltrationFlow::No) {
5130 66 : if (massConservation.InfiltrationPtr > 0) {
5131 92 : if (massConservation.IsOnlySourceZone ||
5132 30 : (state.dataHeatBal->ZoneAirMassFlow.InfiltrationForZones == DataHeatBalance::InfiltrationZoneType::AllZones)) {
5133 186 : ZoneInfiltrationMassFlowRate = massConservation.MixingSourceMassFlowRate - massConservation.MixingMassFlowRate +
5134 62 : state.dataZoneEquip->ZoneEquipConfig(ZoneNum).TotExhaustAirMassFlowRate + ZoneReturnAirMassFlowRate -
5135 62 : state.dataZoneEquip->ZoneEquipConfig(ZoneNum).TotInletAirMassFlowRate;
5136 62 : if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Adjust) {
5137 62 : if (std::abs(ZoneInfiltrationMassFlowRate) > ConvergenceTolerance) {
5138 19 : state.dataHeatBalFanSys->ZoneInfiltrationFlag(ZoneNum) = true;
5139 19 : massConservation.InfiltrationMassFlowRate = ZoneInfiltrationMassFlowRate;
5140 19 : massConservation.IncludeInfilToZoneMassBal = 1;
5141 19 : state.dataHeatBal->Infiltration(massConservation.InfiltrationPtr).MassFlowRate = ZoneInfiltrationMassFlowRate;
5142 19 : state.dataHeatBal->Infiltration(massConservation.InfiltrationPtr).MassFlowRate =
5143 19 : max(0.0, state.dataHeatBal->Infiltration(massConservation.InfiltrationPtr).MassFlowRate);
5144 : } else {
5145 43 : massConservation.InfiltrationMassFlowRate = 0.0;
5146 43 : state.dataHeatBal->Infiltration(massConservation.InfiltrationPtr).MassFlowRate = 0.0;
5147 : }
5148 0 : } else if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Add) {
5149 0 : if (ZoneInfiltrationMassFlowRate > ConvergenceTolerance) {
5150 0 : state.dataHeatBalFanSys->ZoneInfiltrationFlag(ZoneNum) = true;
5151 0 : massConservation.InfiltrationMassFlowRate = ZoneInfiltrationMassFlowRate;
5152 0 : massConservation.IncludeInfilToZoneMassBal = 1;
5153 0 : state.dataHeatBal->Infiltration(massConservation.InfiltrationPtr).MassFlowRate += ZoneInfiltrationMassFlowRate;
5154 : } else {
5155 0 : massConservation.InfiltrationMassFlowRate = 0.0;
5156 : }
5157 0 : } else if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::No) {
5158 0 : massConservation.InfiltrationMassFlowRate = 0.0;
5159 : }
5160 : } else {
5161 0 : if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Adjust) {
5162 0 : massConservation.InfiltrationMassFlowRate = state.dataHeatBal->Infiltration(massConservation.InfiltrationPtr).MassFlowRate;
5163 0 : } else if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Add) {
5164 0 : massConservation.InfiltrationMassFlowRate = 0.0;
5165 0 : } else if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::No) {
5166 0 : massConservation.InfiltrationMassFlowRate = 0.0;
5167 : }
5168 : }
5169 : } else {
5170 : // Zone has no infiltration objects
5171 4 : massConservation.InfiltrationMassFlowRate = 0.0;
5172 : }
5173 : }
5174 66 : }
5175 :
5176 513275 : void CalcZoneLeavingConditions(EnergyPlusData &state, bool const FirstHVACIteration)
5177 : {
5178 :
5179 : // SUBROUTINE INFORMATION:
5180 : // AUTHOR Richard Liesen
5181 : // DATE WRITTEN January 2001
5182 : // MODIFIED June 2003, FCW: add heat from airflow window to return air
5183 :
5184 : // PURPOSE OF THIS SUBROUTINE:
5185 : // Perform zone upate of the leaving conditions.
5186 :
5187 : // METHODOLOGY EMPLOYED:
5188 : // Energy Balance.
5189 :
5190 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5191 : Real64 TempRetAir; // Return air temperature [C]
5192 : Real64 TempZoneAir; // Zone air temperature [C]
5193 : Real64 SumRetAirLatentGainRate;
5194 :
5195 : // If SpaceHVAC is active calculate SpaceHVAC:ReturnMixer inlet and outlet conditions before setting zone return conditions
5196 513275 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation && !state.dataGlobal->DoingSizing) {
5197 36872 : for (auto &thisSpaceHVACMixer : state.dataZoneEquip->zoneReturnMixer) {
5198 0 : thisSpaceHVACMixer.setInletFlows(state);
5199 0 : thisSpaceHVACMixer.setInletConditions(state);
5200 0 : thisSpaceHVACMixer.setOutletConditions(state);
5201 : }
5202 : }
5203 :
5204 1215432 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
5205 702157 : if (!state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) continue;
5206 : // A return air system may not exist for certain systems; Therefore when no return node exists
5207 : // there is no update. Of course if there is no return air system then you cannot update
5208 : // the energy for the return air heat gain from the lights statements.
5209 276979 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes == 0) continue;
5210 268498 : int ZoneNode = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ZoneNode;
5211 268498 : int ZoneMult = state.dataHeatBal->Zone(ZoneNum).Multiplier * state.dataHeatBal->Zone(ZoneNum).ListMultiplier;
5212 268498 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
5213 536997 : for (int nodeCount = 1; nodeCount <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes; ++nodeCount) {
5214 268499 : int ReturnNode = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ReturnNode(nodeCount);
5215 268499 : int ReturnNodeExhaustNum = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ReturnNodeExhaustNodeNum(nodeCount);
5216 :
5217 : // RETURN AIR HEAT GAIN from the Lights statement; this heat gain is stored in
5218 : // Add sensible heat gain from refrigerated cases with under case returns
5219 268499 : Real64 QRetAir = InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, ZoneNum, ReturnNode);
5220 :
5221 : // Need to add the energy to the return air from lights and from airflow windows. Where the heat
5222 : // is added depends on if there is system flow or not. If there is system flow the heat is added
5223 : // to the Zone Return Node. If there is no system flow then the heat is added back to the zone in the
5224 : // Correct step through the SysDepZoneLoads variable.
5225 :
5226 268499 : Real64 MassFlowRA = state.dataLoopNodes->Node(ReturnNode).MassFlowRate / ZoneMult;
5227 268499 : if (ReturnNodeExhaustNum > 0 && state.dataLoopNodes->Node(ReturnNodeExhaustNum).MassFlowRate > 0.0) {
5228 5 : MassFlowRA += state.dataLoopNodes->Node(ReturnNodeExhaustNum).MassFlowRate;
5229 : }
5230 :
5231 : // user defined room air model may feed temp that differs from zone node
5232 :
5233 268499 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation && !state.dataGlobal->DoingSizing &&
5234 0 : (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).returnNodeSpaceMixerIndex(nodeCount) > -1)) {
5235 : // If a SpaceHVAC:ZoneReturnMixer feeds this node, use the node conditions which was set above in
5236 : // thisSpaceHVACMixer.setOutletConditions
5237 0 : TempZoneAir = state.dataLoopNodes->Node(ReturnNode).Temp;
5238 0 : TempRetAir = TempZoneAir;
5239 268499 : } else if (allocated(state.dataRoomAir->AirPatternZoneInfo)) {
5240 0 : if ((state.dataRoomAir->AirPatternZoneInfo(ZoneNum).IsUsed) && (!state.dataGlobal->BeginEnvrnFlag)) {
5241 0 : TempZoneAir = state.dataRoomAir->AirPatternZoneInfo(ZoneNum).Tleaving;
5242 0 : TempRetAir = TempZoneAir;
5243 : } else {
5244 0 : TempZoneAir = state.dataLoopNodes->Node(ZoneNode).Temp;
5245 0 : TempRetAir = TempZoneAir;
5246 : }
5247 : } else {
5248 268499 : TempZoneAir = state.dataLoopNodes->Node(ZoneNode).Temp;
5249 268499 : TempRetAir = TempZoneAir;
5250 : }
5251 :
5252 268499 : Real64 WinGapFlowToRA = 0.0; // Mass flow to return air from all airflow windows in zone [kg/s]
5253 268499 : Real64 WinGapTtoRA = 0.0; // Temp of outlet flow mixture to return air from all airflow windows in zone [C]
5254 268499 : Real64 WinGapFlowTtoRA = 0.0; // Sum of mass flow times outlet temp for all airflow windows in zone [(kg/s)-C]
5255 :
5256 268499 : if (state.dataHeatBal->Zone(ZoneNum).HasAirFlowWindowReturn) {
5257 0 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
5258 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
5259 0 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
5260 0 : if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0 &&
5261 0 : state.dataSurface->SurfWinAirflowDestination(SurfNum) == DataSurfaces::WindowAirFlowDestination::Return) {
5262 0 : Real64 FlowThisTS = PsyRhoAirFnPbTdbW(state,
5263 0 : state.dataEnvrn->OutBaroPress,
5264 0 : state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum),
5265 0 : state.dataLoopNodes->Node(ZoneNode).HumRat) *
5266 0 : state.dataSurface->SurfWinAirflowThisTS(SurfNum) * state.dataSurface->Surface(SurfNum).Width;
5267 0 : WinGapFlowToRA += FlowThisTS;
5268 0 : WinGapFlowTtoRA += FlowThisTS * state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum);
5269 : }
5270 : }
5271 : }
5272 : }
5273 268499 : if (WinGapFlowToRA > 0.0) WinGapTtoRA = WinGapFlowTtoRA / WinGapFlowToRA;
5274 : // the flag NoHeatToReturnAir is TRUE if the system is zonal only or is central with on/off air flow. In these
5275 : // cases the heat to return air is treated as a zone heat gain and dealt with in CalcZoneSums in
5276 : // MODULE ZoneTempPredictorCorrector.
5277 268499 : if (!state.dataHeatBal->Zone(ZoneNum).NoHeatToReturnAir) {
5278 229941 : Real64 CpAir = PsyCpAirFnW(state.dataLoopNodes->Node(ZoneNode).HumRat);
5279 229941 : if (MassFlowRA > 0.0) {
5280 201632 : if (WinGapFlowToRA > 0.0) {
5281 : // Add heat-to-return from window gap airflow
5282 0 : if (MassFlowRA >= WinGapFlowToRA) {
5283 0 : TempRetAir = (WinGapFlowTtoRA + (MassFlowRA - WinGapFlowToRA) * TempZoneAir) / MassFlowRA;
5284 : } else {
5285 : // All of return air comes from flow through airflow windows
5286 0 : TempRetAir = WinGapTtoRA;
5287 : // Put heat from window airflow that exceeds return air flow into zone air
5288 0 : thisZoneHB.SysDepZoneLoads += (WinGapFlowToRA - MassFlowRA) * CpAir * (WinGapTtoRA - TempZoneAir);
5289 : }
5290 : }
5291 : // Add heat-to-return from lights
5292 201632 : TempRetAir += QRetAir / (MassFlowRA * CpAir);
5293 201632 : if (TempRetAir > HVAC::RetTempMax) {
5294 41 : state.dataLoopNodes->Node(ReturnNode).Temp = HVAC::RetTempMax;
5295 41 : if (!state.dataGlobal->ZoneSizingCalc) {
5296 0 : thisZoneHB.SysDepZoneLoads += CpAir * MassFlowRA * (TempRetAir - HVAC::RetTempMax);
5297 : }
5298 201591 : } else if (TempRetAir < HVAC::RetTempMin) {
5299 0 : state.dataLoopNodes->Node(ReturnNode).Temp = HVAC::RetTempMin;
5300 0 : if (!state.dataGlobal->ZoneSizingCalc) {
5301 0 : thisZoneHB.SysDepZoneLoads += CpAir * MassFlowRA * (TempRetAir - HVAC::RetTempMin);
5302 : }
5303 : } else {
5304 201591 : state.dataLoopNodes->Node(ReturnNode).Temp = TempRetAir;
5305 : }
5306 201632 : if (ReturnNodeExhaustNum > 0 && state.dataLoopNodes->Node(ReturnNodeExhaustNum).MassFlowRate > 0.0 && QRetAir > 0.0) {
5307 5 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).SharedExhaustNode(nodeCount) != LightReturnExhaustConfig::Shared) {
5308 4 : state.dataLoopNodes->Node(ReturnNodeExhaustNum).Temp = TempRetAir;
5309 : } else {
5310 1 : state.dataLoopNodes->Node(ReturnNodeExhaustNum).Temp += QRetAir / (MassFlowRA * CpAir);
5311 : }
5312 : }
5313 : } else { // No return air flow
5314 : // Assign all heat-to-return from window gap airflow to zone air
5315 28309 : if (WinGapFlowToRA > 0.0) thisZoneHB.SysDepZoneLoads += WinGapFlowToRA * CpAir * (WinGapTtoRA - TempZoneAir);
5316 : // Assign all heat-to-return from lights to zone air
5317 28309 : if (QRetAir > 0.0) thisZoneHB.SysDepZoneLoads += QRetAir;
5318 28309 : state.dataLoopNodes->Node(ReturnNode).Temp = state.dataLoopNodes->Node(ZoneNode).Temp;
5319 : }
5320 : } else {
5321 : // update the return air node for zonal and central on/off systems
5322 38558 : state.dataLoopNodes->Node(ReturnNode).Temp = state.dataLoopNodes->Node(ZoneNode).Temp;
5323 : }
5324 :
5325 : // Update the rest of the Return Air Node conditions, if the return air system exists!
5326 268499 : state.dataLoopNodes->Node(ReturnNode).Press = state.dataLoopNodes->Node(ZoneNode).Press;
5327 :
5328 : // Include impact of under case returns for refrigerated display case when updating the return air node humidity
5329 268499 : if (!state.dataHeatBal->Zone(ZoneNum).NoHeatToReturnAir) {
5330 229941 : if (MassFlowRA > 0) {
5331 201632 : SumRetAirLatentGainRate = InternalHeatGains::SumAllReturnAirLatentGains(state, ZoneNum, ReturnNode);
5332 201632 : Real64 H2OHtOfVap = PsyHgAirFnWTdb(state.dataLoopNodes->Node(ZoneNode).HumRat, state.dataLoopNodes->Node(ReturnNode).Temp);
5333 201632 : state.dataLoopNodes->Node(ReturnNode).HumRat =
5334 201632 : state.dataLoopNodes->Node(ZoneNode).HumRat + (SumRetAirLatentGainRate / (H2OHtOfVap * MassFlowRA));
5335 : } else {
5336 : // If no mass flow rate exists, include the latent HVAC case credit with the latent Zone case credit
5337 28309 : state.dataLoopNodes->Node(ReturnNode).HumRat = state.dataLoopNodes->Node(ZoneNode).HumRat;
5338 28309 : state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToZone +=
5339 28309 : state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToHVAC;
5340 : // shouldn't the HVAC term be zeroed out then?
5341 28309 : SumRetAirLatentGainRate = InternalHeatGains::SumAllReturnAirLatentGains(state, ZoneNum, ReturnNode);
5342 28309 : thisZoneHB.latentGain += SumRetAirLatentGainRate;
5343 : }
5344 : } else {
5345 38558 : state.dataLoopNodes->Node(ReturnNode).HumRat = state.dataLoopNodes->Node(ZoneNode).HumRat;
5346 38558 : state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToZone += state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToHVAC;
5347 : // shouldn't the HVAC term be zeroed out then?
5348 38558 : SumRetAirLatentGainRate = InternalHeatGains::SumAllReturnAirLatentGains(state, ZoneNum, ReturnNode);
5349 38558 : thisZoneHB.latentGain += SumRetAirLatentGainRate;
5350 : }
5351 :
5352 268499 : state.dataLoopNodes->Node(ReturnNode).Enthalpy =
5353 268499 : PsyHFnTdbW(state.dataLoopNodes->Node(ReturnNode).Temp, state.dataLoopNodes->Node(ReturnNode).HumRat);
5354 :
5355 268499 : if (state.dataContaminantBalance->Contaminant.CO2Simulation)
5356 0 : state.dataLoopNodes->Node(ReturnNode).CO2 = state.dataLoopNodes->Node(ZoneNode).CO2;
5357 268499 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation)
5358 0 : state.dataLoopNodes->Node(ReturnNode).GenContam = state.dataLoopNodes->Node(ZoneNode).GenContam;
5359 :
5360 : } // End of check for a return air node, which implies a return air system.
5361 :
5362 : // Reset current deadband flags, remaining output required, so no impact beyond zone equipment
5363 268498 : InitSystemOutputRequired(state, ZoneNum, FirstHVACIteration, true);
5364 : }
5365 513275 : }
5366 :
5367 513264 : void UpdateZoneEquipment(EnergyPlusData &state, bool &SimAir)
5368 : {
5369 : // SUBROUTINE INFORMATION:
5370 : // AUTHOR Russ Taylor
5371 : // DATE WRITTEN Nov 1997
5372 :
5373 : // PURPOSE OF THIS SUBROUTINE:
5374 : // This subroutine performs the update for Zone Equipment Management.
5375 : // Specifically, it transfers the conditions from the zone equipment return air nodes across
5376 : // to the air loop side, allowing for multiple return air nodes
5377 :
5378 : // Transfer the conditions from the zone equipment return air nodes across
5379 : // to the air loop side, allowing for multiple return air nodes
5380 589077 : for (int ZoneGroupNum = 1; ZoneGroupNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++ZoneGroupNum) {
5381 151626 : for (int RetAirPathNum = 1; RetAirPathNum <= state.dataAirLoop->AirToZoneNodeInfo(ZoneGroupNum).NumReturnNodes; ++RetAirPathNum) {
5382 151626 : HVACInterfaceManager::UpdateHVACInterface(state,
5383 : ZoneGroupNum,
5384 : DataConvergParams::CalledFrom::AirSystemDemandSide,
5385 75813 : state.dataAirLoop->AirToZoneNodeInfo(ZoneGroupNum).ZoneEquipReturnNodeNum(RetAirPathNum),
5386 75813 : state.dataAirLoop->AirToZoneNodeInfo(ZoneGroupNum).AirLoopReturnNodeNum(RetAirPathNum),
5387 : SimAir);
5388 : }
5389 : }
5390 513264 : }
5391 :
5392 297290 : void CalcAirFlowSimple(EnergyPlusData &state,
5393 : int const SysTimestepLoop, // System time step index
5394 : bool const AdjustZoneMixingFlowFlag, // holds zone mixing air flow calc status
5395 : bool const AdjustZoneInfiltrationFlowFlag // holds zone mixing air flow calc status
5396 : )
5397 : {
5398 : // SUBROUTINE INFORMATION:
5399 : // AUTHOR Legacy Code
5400 : // MODIFIED Shirey, Jan 2008 (MIXING objects, use avg. conditions for Cp, Air Density and Hfg)
5401 : // MODIFIED L. Lawrie and L. GU, Jan. 2008 (Allow multiple infiltration and ventilation objects)
5402 : // B. Griffith. Jan 2009 add infiltration, residential basic/sherman-grimsrud and enhanced/AIM2
5403 : // L. Lawrie - March 2009 - move ventilation electric calculation to this routine (for
5404 : // Electricity Net.
5405 : // L. Gu - Dec. 2009 - Added a new ventilation object to calculate flow rate based on wind and stack
5406 : // effect through an opening.
5407 : // MODIFIED Stovall - Aug 2011 (add refrigerator door mixing)
5408 :
5409 : // PURPOSE OF THIS SUBROUTINE:
5410 : // This subroutine calculates the air component of the heat balance.
5411 :
5412 297290 : constexpr Real64 StdGravity(9.80665); // The acceleration of gravity at the sea level (m/s2)
5413 : static constexpr std::string_view RoutineNameVentilation("CalcAirFlowSimple:Ventilation");
5414 : static constexpr std::string_view RoutineNameMixing("CalcAirFlowSimple:Mixing");
5415 : static constexpr std::string_view RoutineNameCrossMixing("CalcAirFlowSimple:CrossMixing");
5416 : static constexpr std::string_view RoutineNameRefrigerationDoorMixing("CalcAirFlowSimple:RefrigerationDoorMixing");
5417 : static constexpr std::string_view RoutineNameInfiltration("CalcAirFlowSimple:Infiltration");
5418 : static constexpr std::string_view RoutineNameZoneAirBalance("CalcAirFlowSimple:ZoneAirBalance");
5419 :
5420 715680 : for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
5421 418390 : thisZoneHB.MCPM = 0.0;
5422 418390 : thisZoneHB.MCPTM = 0.0;
5423 418390 : thisZoneHB.MCPTI = 0.0;
5424 418390 : thisZoneHB.MCPI = 0.0;
5425 418390 : thisZoneHB.OAMFL = 0.0;
5426 418390 : thisZoneHB.MCPTV = 0.0;
5427 418390 : thisZoneHB.MCPV = 0.0;
5428 418390 : thisZoneHB.VAMFL = 0.0;
5429 418390 : thisZoneHB.MDotCPOA = 0.0;
5430 418390 : thisZoneHB.MDotOA = 0.0;
5431 418390 : thisZoneHB.MCPThermChim = 0.0;
5432 418390 : thisZoneHB.ThermChimAMFL = 0.0;
5433 418390 : thisZoneHB.MCPTThermChim = 0.0;
5434 418390 : thisZoneHB.MixingMassFlowZone = 0.0;
5435 418390 : thisZoneHB.MixingMassFlowXHumRat = 0.0;
5436 : }
5437 297290 : if (state.dataHeatBal->doSpaceHeatBalance) {
5438 59316 : for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
5439 44487 : thisSpaceHB.MCPM = 0.0;
5440 44487 : thisSpaceHB.MCPTM = 0.0;
5441 44487 : thisSpaceHB.MCPTI = 0.0;
5442 44487 : thisSpaceHB.MCPI = 0.0;
5443 44487 : thisSpaceHB.OAMFL = 0.0;
5444 44487 : thisSpaceHB.MCPTV = 0.0;
5445 44487 : thisSpaceHB.MCPV = 0.0;
5446 44487 : thisSpaceHB.VAMFL = 0.0;
5447 44487 : thisSpaceHB.MDotCPOA = 0.0;
5448 44487 : thisSpaceHB.MDotOA = 0.0;
5449 44487 : thisSpaceHB.MCPThermChim = 0.0;
5450 44487 : thisSpaceHB.ThermChimAMFL = 0.0;
5451 44487 : thisSpaceHB.MCPTThermChim = 0.0;
5452 44487 : thisSpaceHB.MixingMassFlowZone = 0.0;
5453 44487 : thisSpaceHB.MixingMassFlowXHumRat = 0.0;
5454 : }
5455 : }
5456 297291 : if (state.dataContaminantBalance->Contaminant.CO2Simulation &&
5457 1 : state.dataHeatBal->TotMixing + state.dataHeatBal->TotCrossMixing + state.dataHeatBal->TotRefDoorMixing > 0)
5458 1 : state.dataContaminantBalance->MixingMassFlowCO2 = 0.0;
5459 297291 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation &&
5460 1 : state.dataHeatBal->TotMixing + state.dataHeatBal->TotCrossMixing + state.dataHeatBal->TotRefDoorMixing > 0)
5461 1 : state.dataContaminantBalance->MixingMassFlowGC = 0.0;
5462 :
5463 297290 : if (!state.dataHeatBal->AirFlowFlag) return;
5464 : // AirflowNetwork Multizone field /= SIMPLE
5465 302974 : if (!(state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution ||
5466 5684 : state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation)) {
5467 5684 : return;
5468 : }
5469 :
5470 291606 : EarthTube::ManageEarthTube(state);
5471 291606 : CoolTower::ManageCoolTower(state);
5472 291606 : ThermalChimney::ManageThermalChimney(state);
5473 :
5474 : // Assign zone air temperature
5475 692944 : for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
5476 401338 : thisZoneHB.MixingMAT = thisZoneHB.MAT;
5477 401338 : thisZoneHB.MixingHumRat = thisZoneHB.airHumRat;
5478 : // This is only temporary fix for CR8867. (L. Gu 8/12)
5479 401338 : if (SysTimestepLoop == 1) {
5480 15757 : thisZoneHB.MixingMAT = thisZoneHB.XMPT;
5481 15757 : thisZoneHB.MixingHumRat = thisZoneHB.WTimeMinusP;
5482 : }
5483 : }
5484 291606 : if (state.dataHeatBal->doSpaceHeatBalance) {
5485 59316 : for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
5486 44487 : thisSpaceHB.MixingMAT = thisSpaceHB.MAT;
5487 44487 : thisSpaceHB.MixingHumRat = thisSpaceHB.airHumRat;
5488 : // This is only temporary fix for CR8867. (L. Gu 8/12)
5489 44487 : if (SysTimestepLoop == 1) {
5490 369 : thisSpaceHB.MixingMAT = thisSpaceHB.XMPT;
5491 369 : thisSpaceHB.MixingHumRat = thisSpaceHB.WTimeMinusP;
5492 : }
5493 : }
5494 : }
5495 :
5496 : // Initialization of ZoneAirBalance
5497 291606 : if (state.dataHeatBal->TotZoneAirBalance > 0) {
5498 0 : for (auto &e : state.dataHeatBal->ZoneAirBalance) {
5499 0 : e.BalMassFlowRate = 0.0;
5500 0 : e.InfMassFlowRate = 0.0;
5501 0 : e.NatMassFlowRate = 0.0;
5502 0 : e.ExhMassFlowRate = 0.0;
5503 0 : e.IntMassFlowRate = 0.0;
5504 0 : e.ERVMassFlowRate = 0.0;
5505 : }
5506 : }
5507 :
5508 291606 : if (state.dataHeatBal->TotVentilation > 0) {
5509 12 : for (auto &e : state.dataHeatBal->ZnAirRpt) {
5510 0 : e.VentilFanElec = 0.0;
5511 : }
5512 : }
5513 :
5514 : // Process the scheduled Ventilation for air heat balance
5515 291618 : for (int j = 1; j <= state.dataHeatBal->TotVentilation; ++j) {
5516 12 : auto &thisVentilation = state.dataHeatBal->Ventilation(j);
5517 12 : int zoneNum = thisVentilation.ZonePtr;
5518 12 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
5519 12 : Real64 thisMixingMAT = 0.0;
5520 12 : if (state.dataHeatBal->doSpaceHeatBalance) {
5521 0 : thisMixingMAT = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisVentilation.spaceIndex).MixingMAT;
5522 : } else {
5523 12 : thisMixingMAT = thisZoneHB.MixingMAT;
5524 : }
5525 12 : thisVentilation.FanPower = 0.0;
5526 12 : thisVentilation.MCP = 0.0;
5527 :
5528 12 : Real64 TempExt = state.dataHeatBal->Zone(zoneNum).OutDryBulbTemp;
5529 12 : Real64 WindSpeedExt = state.dataHeatBal->Zone(zoneNum).WindSpeed;
5530 12 : Real64 WindDirExt = state.dataHeatBal->Zone(zoneNum).WindDir;
5531 12 : Real64 thisMCPV = 0.0;
5532 12 : Real64 thisVAMFL = 0.0;
5533 12 : Real64 thisMCPTV = 0.0;
5534 :
5535 : // Use air node information linked to the zone if defined
5536 12 : Real64 HumRatExt = 0.0;
5537 12 : Real64 EnthalpyExt = 0.0;
5538 12 : if (state.dataHeatBal->Zone(zoneNum).LinkedOutAirNode > 0) {
5539 0 : HumRatExt = state.dataLoopNodes->Node(state.dataHeatBal->Zone(zoneNum).LinkedOutAirNode).HumRat;
5540 0 : EnthalpyExt = state.dataLoopNodes->Node(state.dataHeatBal->Zone(zoneNum).LinkedOutAirNode).Enthalpy;
5541 : } else {
5542 12 : HumRatExt = state.dataEnvrn->OutHumRat;
5543 12 : EnthalpyExt = state.dataEnvrn->OutEnthalpy;
5544 : }
5545 :
5546 12 : Real64 AirDensity = 0.0; // Density of air for converting from volume flow to mass flow (kg/m^3)
5547 12 : switch (thisVentilation.densityBasis) {
5548 0 : case DataHeatBalance::InfVentDensityBasis::Standard: {
5549 0 : AirDensity = state.dataEnvrn->StdRhoAir;
5550 0 : } break;
5551 0 : case DataHeatBalance::InfVentDensityBasis::Indoor: {
5552 0 : if (state.dataHeatBal->doSpaceHeatBalance) {
5553 0 : auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisVentilation.spaceIndex);
5554 0 : AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(
5555 0 : state, state.dataEnvrn->OutBaroPress, thisMixingMAT, thisSpaceHB.MixingHumRat, RoutineNameInfiltration);
5556 : } else {
5557 0 : AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(
5558 0 : state, state.dataEnvrn->OutBaroPress, thisMixingMAT, thisZoneHB.MixingHumRat, RoutineNameInfiltration);
5559 : }
5560 0 : } break;
5561 12 : default:
5562 12 : AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, HumRatExt, RoutineNameInfiltration);
5563 12 : break;
5564 : }
5565 :
5566 12 : Real64 CpAir = PsyCpAirFnW(HumRatExt);
5567 :
5568 : // Hybrid ventilation global control
5569 12 : int I = 0;
5570 12 : if (thisVentilation.HybridControlType == DataHeatBalance::HybridCtrlType::Global && thisVentilation.HybridControlMasterNum > 0) {
5571 0 : I = thisVentilation.HybridControlMasterNum;
5572 0 : if (j == I) {
5573 0 : thisVentilation.HybridControlMasterStatus = false;
5574 : }
5575 : } else {
5576 12 : I = j;
5577 : }
5578 12 : auto &hybridControlVentilation = state.dataHeatBal->Ventilation(I);
5579 : // Hybrid controlled zone MAT
5580 12 : Real64 hybridControlZoneMAT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(hybridControlVentilation.ZonePtr).MixingMAT;
5581 :
5582 : // Check scheduled temperatures
5583 12 : if (hybridControlVentilation.minIndoorTempSched != nullptr) {
5584 0 : hybridControlVentilation.MinIndoorTemperature = hybridControlVentilation.minIndoorTempSched->getCurrentVal();
5585 : }
5586 12 : if (hybridControlVentilation.maxIndoorTempSched != nullptr) {
5587 0 : hybridControlVentilation.MaxIndoorTemperature = hybridControlVentilation.maxIndoorTempSched->getCurrentVal();
5588 : }
5589 : // Ensure the minimum indoor temperature <= the maximum indoor temperature
5590 12 : if (hybridControlVentilation.minIndoorTempSched != nullptr || hybridControlVentilation.maxIndoorTempSched != nullptr) {
5591 0 : if (hybridControlVentilation.MinIndoorTemperature > hybridControlVentilation.MaxIndoorTemperature) {
5592 0 : ++hybridControlVentilation.IndoorTempErrCount;
5593 0 : if (hybridControlVentilation.IndoorTempErrCount < 2) {
5594 0 : ShowWarningError(state,
5595 0 : format("Ventilation indoor temperature control: The minimum indoor temperature is above the maximum indoor "
5596 : "temperature in {}",
5597 0 : hybridControlVentilation.Name));
5598 0 : ShowContinueError(state, "The minimum indoor temperature is set to the maximum indoor temperature. Simulation continues.");
5599 0 : ShowContinueErrorTimeStamp(state, " Occurrence info:");
5600 : } else {
5601 0 : ShowRecurringWarningErrorAtEnd(state,
5602 : "The minimum indoor temperature is still above the maximum indoor temperature",
5603 0 : hybridControlVentilation.IndoorTempErrIndex,
5604 0 : hybridControlVentilation.MinIndoorTemperature,
5605 0 : hybridControlVentilation.MinIndoorTemperature);
5606 : }
5607 0 : hybridControlVentilation.MinIndoorTemperature = hybridControlVentilation.MaxIndoorTemperature;
5608 : }
5609 : }
5610 12 : if (hybridControlVentilation.minOutdoorTempSched != nullptr) {
5611 0 : hybridControlVentilation.MinOutdoorTemperature = hybridControlVentilation.minOutdoorTempSched->getCurrentVal();
5612 : }
5613 12 : if (hybridControlVentilation.maxOutdoorTempSched != nullptr) {
5614 0 : hybridControlVentilation.MaxOutdoorTemperature = hybridControlVentilation.maxOutdoorTempSched->getCurrentVal();
5615 : }
5616 : // Ensure the minimum outdoor temperature <= the maximum outdoor temperature
5617 12 : if (hybridControlVentilation.minOutdoorTempSched != nullptr || hybridControlVentilation.maxOutdoorTempSched != nullptr) {
5618 0 : if (hybridControlVentilation.MinOutdoorTemperature > hybridControlVentilation.MaxOutdoorTemperature) {
5619 0 : ++hybridControlVentilation.OutdoorTempErrCount;
5620 0 : if (hybridControlVentilation.OutdoorTempErrCount < 2) {
5621 0 : ShowWarningError(state,
5622 0 : format("Ventilation outdoor temperature control: The minimum outdoor temperature is above the maximum "
5623 : "outdoor temperature in {}",
5624 0 : hybridControlVentilation.Name));
5625 0 : ShowContinueError(state, "The minimum outdoor temperature is set to the maximum outdoor temperature. Simulation continues.");
5626 0 : ShowContinueErrorTimeStamp(state, " Occurrence info:");
5627 : } else {
5628 0 : ShowRecurringWarningErrorAtEnd(state,
5629 : "The minimum outdoor temperature is still above the maximum outdoor temperature",
5630 0 : hybridControlVentilation.OutdoorTempErrIndex,
5631 0 : hybridControlVentilation.MinOutdoorTemperature,
5632 0 : hybridControlVentilation.MinOutdoorTemperature);
5633 : }
5634 0 : hybridControlVentilation.MinIndoorTemperature = hybridControlVentilation.MaxIndoorTemperature;
5635 : }
5636 : }
5637 12 : if (hybridControlVentilation.deltaTempSched != nullptr) {
5638 0 : hybridControlVentilation.DelTemperature = hybridControlVentilation.deltaTempSched->getCurrentVal();
5639 : }
5640 : // Skip this if the zone is below the minimum indoor temperature limit
5641 12 : if ((hybridControlZoneMAT < hybridControlVentilation.MinIndoorTemperature) && (!thisVentilation.EMSSimpleVentOn)) continue;
5642 : // Skip this if the zone is above the maximum indoor temperature limit
5643 12 : if ((hybridControlZoneMAT > hybridControlVentilation.MaxIndoorTemperature) && (!thisVentilation.EMSSimpleVentOn)) continue;
5644 : // Skip if below the temperature difference limit (3/12/03 Negative DelTemperature allowed now)
5645 12 : if (((hybridControlZoneMAT - TempExt) < hybridControlVentilation.DelTemperature) && (!thisVentilation.EMSSimpleVentOn)) continue;
5646 : // Skip this if the outdoor temperature is below the minimum outdoor temperature limit
5647 12 : if ((TempExt < hybridControlVentilation.MinOutdoorTemperature) && (!thisVentilation.EMSSimpleVentOn)) continue;
5648 : // Skip this if the outdoor temperature is above the maximum outdoor temperature limit
5649 12 : if ((TempExt > hybridControlVentilation.MaxOutdoorTemperature) && (!thisVentilation.EMSSimpleVentOn)) continue;
5650 : // Skip this if the outdoor wind speed is above the maximum windspeed limit
5651 12 : if ((WindSpeedExt > hybridControlVentilation.MaxWindSpeed) && (!thisVentilation.EMSSimpleVentOn)) continue;
5652 :
5653 : // Hybrid ventilation controls
5654 12 : if ((thisVentilation.HybridControlType == DataHeatBalance::HybridCtrlType::Close) && (!thisVentilation.EMSSimpleVentOn)) continue;
5655 12 : if (thisVentilation.HybridControlType == DataHeatBalance::HybridCtrlType::Global && thisVentilation.HybridControlMasterNum > 0) {
5656 0 : if (j == I) thisVentilation.HybridControlMasterStatus = true;
5657 : }
5658 :
5659 12 : if (thisVentilation.ModelType == DataHeatBalance::VentilationModelType::DesignFlowRate) {
5660 : // CR6845 if calculated < 0, don't propagate.
5661 0 : Real64 VVF = thisVentilation.DesignLevel * thisVentilation.availSched->getCurrentVal(); // VENTILATION FLOW RATE (M**3/SEC)
5662 :
5663 0 : if (thisVentilation.EMSSimpleVentOn) VVF = thisVentilation.EMSimpleVentFlowRate;
5664 :
5665 0 : if (VVF < 0.0) VVF = 0.0;
5666 0 : thisVentilation.MCP = VVF * AirDensity * CpAir *
5667 0 : (thisVentilation.ConstantTermCoef + std::abs(TempExt - thisMixingMAT) * thisVentilation.TemperatureTermCoef +
5668 0 : WindSpeedExt * (thisVentilation.VelocityTermCoef + WindSpeedExt * thisVentilation.VelocitySQTermCoef));
5669 0 : if (thisVentilation.MCP < 0.0) thisVentilation.MCP = 0.0;
5670 0 : Real64 VAMFL_temp = thisVentilation.MCP / CpAir;
5671 0 : if (state.dataHeatBal->Zone(zoneNum).zoneOAQuadratureSum) {
5672 0 : auto &thisZoneAirBalance = state.dataHeatBal->ZoneAirBalance(state.dataHeatBal->Zone(zoneNum).zoneOABalanceIndex);
5673 0 : switch (thisVentilation.FanType) {
5674 : // ventilation type based calculation
5675 0 : case DataHeatBalance::VentilationType::Exhaust: {
5676 0 : thisZoneAirBalance.ExhMassFlowRate += VAMFL_temp;
5677 0 : } break;
5678 0 : case DataHeatBalance::VentilationType::Intake: {
5679 0 : thisZoneAirBalance.IntMassFlowRate += VAMFL_temp;
5680 0 : } break;
5681 0 : case DataHeatBalance::VentilationType::Natural: {
5682 0 : thisZoneAirBalance.NatMassFlowRate += VAMFL_temp;
5683 0 : } break;
5684 0 : case DataHeatBalance::VentilationType::Balanced: {
5685 0 : thisZoneAirBalance.BalMassFlowRate += VAMFL_temp;
5686 0 : } break;
5687 0 : default:
5688 0 : break;
5689 : }
5690 : } else {
5691 0 : thisMCPV = thisVentilation.MCP;
5692 0 : thisVAMFL = VAMFL_temp;
5693 : }
5694 0 : if (thisVentilation.FanEfficiency > 0.0) {
5695 0 : thisVentilation.FanPower = VAMFL_temp * thisVentilation.FanPressure / (thisVentilation.FanEfficiency * AirDensity);
5696 0 : if (thisVentilation.FanType == DataHeatBalance::VentilationType::Balanced) thisVentilation.FanPower *= 2.0;
5697 : // calc electric
5698 0 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation) {
5699 : // CR7608 IF (.not. TurnFansOn .or. .not. AirflowNetworkZoneFlag(zoneNum)) &
5700 0 : if (!state.dataGlobal->KickOffSimulation) {
5701 0 : if (!(state.dataZoneEquip->ZoneEquipAvail(zoneNum) == Avail::Status::CycleOn ||
5702 0 : state.dataZoneEquip->ZoneEquipAvail(zoneNum) == Avail::Status::CycleOnZoneFansOnly) ||
5703 0 : !state.afn->AirflowNetworkZoneFlag(zoneNum))
5704 0 : state.dataHeatBal->ZnAirRpt(zoneNum).VentilFanElec += thisVentilation.FanPower * state.dataHVACGlobal->TimeStepSysSec;
5705 0 : } else if (!state.afn->AirflowNetworkZoneFlag(zoneNum)) {
5706 0 : state.dataHeatBal->ZnAirRpt(zoneNum).VentilFanElec += thisVentilation.FanPower * state.dataHVACGlobal->TimeStepSysSec;
5707 : }
5708 : } else {
5709 0 : state.dataHeatBal->ZnAirRpt(zoneNum).VentilFanElec += thisVentilation.FanPower * state.dataHVACGlobal->TimeStepSysSec;
5710 : }
5711 : }
5712 : // Intake fans will add some heat to the air, raising the temperature for an intake fan...
5713 0 : if (thisVentilation.FanType == DataHeatBalance::VentilationType::Intake ||
5714 0 : thisVentilation.FanType == DataHeatBalance::VentilationType::Balanced) {
5715 0 : Real64 OutletAirEnthalpy = 0.0;
5716 0 : if (VAMFL_temp == 0.0) {
5717 0 : OutletAirEnthalpy = EnthalpyExt;
5718 : } else {
5719 0 : if (thisVentilation.FanPower > 0.0) {
5720 0 : if (thisVentilation.FanType == DataHeatBalance::VentilationType::Balanced) {
5721 0 : OutletAirEnthalpy = EnthalpyExt + thisVentilation.FanPower / VAMFL_temp / 2.0; // Half fan power to calculate inlet T
5722 : } else {
5723 0 : OutletAirEnthalpy = EnthalpyExt + thisVentilation.FanPower / VAMFL_temp;
5724 : }
5725 : } else {
5726 0 : OutletAirEnthalpy = EnthalpyExt;
5727 : }
5728 : }
5729 0 : thisVentilation.AirTemp = Psychrometrics::PsyTdbFnHW(OutletAirEnthalpy, HumRatExt);
5730 0 : } else {
5731 0 : thisVentilation.AirTemp = TempExt;
5732 : }
5733 0 : if (!state.dataHeatBal->Zone(zoneNum).zoneOAQuadratureSum) thisMCPTV = thisVentilation.MCP * thisVentilation.AirTemp;
5734 12 : } else if (thisVentilation.ModelType == DataHeatBalance::VentilationModelType::WindAndStack) {
5735 12 : Real64 Cw = 0.0; // Opening effectivenss
5736 12 : Real64 Cd = 0.0; // Discharge coefficent
5737 12 : Real64 angle = 0.0; // Angle between wind direction and effective angle
5738 12 : Real64 Qw = 0.0; // Volumetric flow driven by wind
5739 12 : Real64 Qst = 0.0; // Volumetric flow driven by stack effect
5740 12 : if (thisVentilation.OpenEff != Constant::AutoCalculate) {
5741 0 : Cw = thisVentilation.OpenEff;
5742 : } else {
5743 : // Wind Dir (β1) 90°, min effectiveness
5744 : // ▲ (ϕ3) . ▲
5745 : // . ϕ │ Opening Normal (α) │ . Angle (ϕ1)
5746 : // . ┌──┼─┐ x . (β4) Wind │
5747 : // .▼ │ ▼x . <=> Blowing │
5748 : // . │ x . Opposite │ . (ϕ4)
5749 : // . │x Side │
5750 : // ─────────┼─────────► North = 0° (ϕ2).─────────┴─────────► Opening Normal = 0°, max effectiveness
5751 : // .│.
5752 : // . │ .
5753 : // . │ .
5754 : // (β2) . │ . (β3)
5755 : //
5756 : // This is the absolute angle between opening normal and the wind direction, in the [0, 180] range:
5757 : // * 0 means that it's blowing directly towards the opening (what ASHRAE HoF calls "Perpendicular winds"), so maximum
5758 : // effectiveness
5759 : // │ │
5760 : // ▼ ▼
5761 : // ┌──====──┐
5762 : // │ │
5763 : // └────────┘
5764 : //
5765 : // * 90 means that the wind direction is perpendicular to the normal (the wind is blowing parallel to the opening's plane), so
5766 : // effectiveness is very small
5767 : // ~~~~►
5768 : // ~~~~►
5769 : // ┌──====──┐
5770 : // │ │
5771 : // └────────┘
5772 : //
5773 : // * Anything >90 means the wind is blowing in the opposite direction (on the other side), so effectiveness is nil
5774 : // ┌──====──┐
5775 : // │ │
5776 : // └────────┘
5777 : // ▲ ▲
5778 : // │ │
5779 :
5780 12 : angle = 180.0 - std::abs(std::abs(WindDirExt - thisVentilation.EffAngle) - 180);
5781 12 : if (angle > 90.0) {
5782 4 : Cw = 0.0; // blowing on the opposite side of the opening
5783 : } else {
5784 : // Linear interpolation between effective angle and wind direction
5785 : // ASHRAE HoF 2009 (Ch 16.14, Equation 37), Q = Cw*A*U, and it describes Cw as :
5786 : // > Cw = effectiness of openings (Cw is assumed to be 0.5 to 0.6 for perpendicular winds and 0.25 to 0.35 for diagonal winds)
5787 : //
5788 : // | ASHRAE description | min | max | mean | Angle* |
5789 : // |---------------------|------|------|------|--------|
5790 : // | Perpendicular winds | 0.5 | 0.6 | 0.55 | 0 |
5791 : // | Diagonal winds | 0.25 | 0.35 | 0.3 | 45 |
5792 : //
5793 : // * Angle is using our convention described above
5794 8 : constexpr Real64 slope = (0.3 - 0.55) / (45 - 0.0);
5795 8 : constexpr Real64 intercept = 0.55;
5796 8 : Cw = intercept + angle * slope;
5797 : }
5798 : }
5799 12 : if (thisVentilation.DiscCoef != Constant::AutoCalculate) {
5800 12 : Cd = thisVentilation.DiscCoef;
5801 : } else {
5802 0 : Cd = 0.40 + 0.0045 * std::abs(TempExt - thisMixingMAT);
5803 : }
5804 12 : Qw = Cw * thisVentilation.OpenArea * thisVentilation.openAreaFracSched->getCurrentVal() * WindSpeedExt;
5805 12 : Qst = Cd * thisVentilation.OpenArea * thisVentilation.openAreaFracSched->getCurrentVal() *
5806 12 : std::sqrt(2.0 * 9.81 * thisVentilation.DH * std::abs(TempExt - thisMixingMAT) / (thisMixingMAT + 273.15));
5807 12 : Real64 VVF = std::sqrt(Qw * Qw + Qst * Qst); // VENTILATION FLOW RATE (M**3/SEC)
5808 12 : if (thisVentilation.EMSSimpleVentOn) VVF = thisVentilation.EMSimpleVentFlowRate;
5809 12 : if (VVF < 0.0) VVF = 0.0;
5810 12 : thisVentilation.MCP = VVF * AirDensity * CpAir;
5811 12 : if (thisVentilation.MCP < 0.0) thisVentilation.MCP = 0.0;
5812 12 : if (state.dataHeatBal->Zone(zoneNum).zoneOAQuadratureSum) {
5813 0 : state.dataHeatBal->ZoneAirBalance(state.dataHeatBal->Zone(zoneNum).zoneOABalanceIndex).NatMassFlowRate += thisVentilation.MCP / CpAir;
5814 : } else {
5815 12 : thisMCPV = thisVentilation.MCP;
5816 12 : thisVAMFL = thisVentilation.MCP / CpAir;
5817 12 : thisVentilation.AirTemp = TempExt;
5818 12 : thisMCPTV = thisVentilation.MCP * thisVentilation.AirTemp;
5819 : }
5820 : }
5821 : // Accumulate for zone and space
5822 12 : thisZoneHB.MCPV += thisMCPV;
5823 12 : thisZoneHB.VAMFL += thisVAMFL;
5824 12 : thisZoneHB.MCPTV += thisMCPTV;
5825 12 : if (state.dataHeatBal->doSpaceHeatBalance) {
5826 0 : auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisVentilation.spaceIndex);
5827 0 : thisSpaceHB.MCPV += thisMCPV;
5828 0 : thisSpaceHB.VAMFL += thisVAMFL;
5829 0 : thisSpaceHB.MCPTV += thisMCPTV;
5830 : }
5831 : }
5832 :
5833 : // Process Mixing
5834 383801 : for (int j = 1; j <= state.dataHeatBal->TotMixing; ++j) {
5835 92195 : auto &thisMixing = state.dataHeatBal->Mixing(j);
5836 92195 : int thisZoneNum = thisMixing.ZonePtr;
5837 92195 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisZoneNum);
5838 92195 : int fromZoneNum = thisMixing.FromZone;
5839 92195 : Real64 TD = thisMixing.DeltaTemperature; // Delta Temp limit
5840 92195 : thisMixing.ReportFlag = false;
5841 :
5842 : // Get scheduled delta temperature
5843 92195 : if (thisMixing.deltaTempSched != nullptr) {
5844 0 : TD = thisMixing.deltaTempSched->getCurrentVal();
5845 : }
5846 92195 : Real64 TZN = 0.0; // Temperature of this Zone/Space
5847 92195 : Real64 TZM = 0.0; // Temperature of From Zone/Space
5848 92195 : Real64 HumRatZN = 0.0; // HumRat of this Zone/Space
5849 92195 : Real64 HumRatZM = 0.0; // HumRat of From Zone/Space
5850 92195 : if (state.dataHeatBal->doSpaceHeatBalance) {
5851 0 : auto const &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisMixing.spaceIndex);
5852 0 : TZN = thisSpaceHB.MixingMAT; // Temperature of this Space
5853 0 : HumRatZN = thisSpaceHB.MixingHumRat; // HumRat of this Space
5854 0 : if (thisMixing.fromSpaceIndex == 0) {
5855 0 : auto const &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(fromZoneNum);
5856 0 : TZM = fromZoneHB.MixingMAT; // Temperature of From Zone
5857 0 : HumRatZM = fromZoneHB.MixingHumRat; // HumRat of From Zone
5858 : } else {
5859 0 : auto const &fromSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisMixing.fromSpaceIndex);
5860 0 : TZM = fromSpaceHB.MixingMAT; // Temperature of From Space
5861 0 : HumRatZM = fromSpaceHB.MixingHumRat; // HumRat of From Space
5862 : }
5863 : } else {
5864 92195 : auto const &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(fromZoneNum);
5865 92195 : TZN = thisZoneHB.MixingMAT; // Temperature of this zone
5866 92195 : TZM = fromZoneHB.MixingMAT; // Temperature of From Zone
5867 92195 : HumRatZN = thisZoneHB.MixingHumRat; // HumRat of this zone
5868 92195 : HumRatZM = fromZoneHB.MixingHumRat; // HumRat of From Zone
5869 : }
5870 92195 : Real64 thisMCPM = 0.0;
5871 92195 : Real64 thisMCPTM = 0.0;
5872 92195 : Real64 thisMixingMassFlow = 0.0;
5873 92195 : Real64 thisMixingMassFlowXHumRat = 0.0;
5874 :
5875 : // Hybrid ventilation controls
5876 92195 : if (thisMixing.HybridControlType == DataHeatBalance::HybridCtrlType::Close) continue;
5877 : // Check temperature limit
5878 92195 : bool MixingLimitFlag = false;
5879 :
5880 : // Hybrid ventilation global control
5881 92195 : if (thisMixing.HybridControlType == DataHeatBalance::HybridCtrlType::Global && thisMixing.HybridControlMasterNum > 0) {
5882 0 : int I = thisMixing.HybridControlMasterNum;
5883 0 : if (!state.dataHeatBal->Ventilation(I).HybridControlMasterStatus) continue;
5884 0 : } else {
5885 : // Ensure the minimum indoor temperature <= the maximum indoor temperature
5886 92195 : Real64 MixingTmin = 0.0;
5887 92195 : Real64 MixingTmax = 0.0;
5888 92195 : if (thisMixing.minIndoorTempSched != nullptr) MixingTmin = thisMixing.minIndoorTempSched->getCurrentVal();
5889 92195 : if (thisMixing.maxIndoorTempSched != nullptr) MixingTmax = thisMixing.maxIndoorTempSched->getCurrentVal();
5890 92195 : if (thisMixing.minIndoorTempSched != nullptr && thisMixing.maxIndoorTempSched != nullptr) {
5891 0 : if (MixingTmin > MixingTmax) {
5892 0 : ++thisMixing.IndoorTempErrCount;
5893 0 : if (thisMixing.IndoorTempErrCount < 2) {
5894 0 : ShowWarningError(
5895 : state,
5896 0 : format("Mixing zone temperature control: The minimum zone temperature is above the maximum zone temperature in {}",
5897 0 : thisMixing.Name));
5898 0 : ShowContinueError(state, "The minimum zone temperature is set to the maximum zone temperature. Simulation continues.");
5899 0 : ShowContinueErrorTimeStamp(state, " Occurrence info:");
5900 : } else {
5901 0 : ShowRecurringWarningErrorAtEnd(state,
5902 : "The minimum zone temperature is still above the maximum zone temperature",
5903 0 : thisMixing.IndoorTempErrIndex,
5904 : MixingTmin,
5905 : MixingTmin);
5906 : }
5907 0 : MixingTmin = MixingTmax;
5908 : }
5909 : }
5910 92195 : if (thisMixing.minIndoorTempSched != nullptr) {
5911 0 : if (TZN < MixingTmin) MixingLimitFlag = true;
5912 : }
5913 92195 : if (thisMixing.maxIndoorTempSched != nullptr) {
5914 0 : if (TZN > MixingTmax) MixingLimitFlag = true;
5915 : }
5916 : // Ensure the minimum source temperature <= the maximum source temperature
5917 92195 : if (thisMixing.minSourceTempSched != nullptr) MixingTmin = thisMixing.minSourceTempSched->getCurrentVal();
5918 92195 : if (thisMixing.maxSourceTempSched != nullptr) MixingTmax = thisMixing.maxSourceTempSched->getCurrentVal();
5919 92195 : if (thisMixing.minSourceTempSched != nullptr && thisMixing.maxSourceTempSched != nullptr) {
5920 0 : if (MixingTmin > MixingTmax) {
5921 0 : ++thisMixing.SourceTempErrCount;
5922 0 : if (thisMixing.SourceTempErrCount < 2) {
5923 0 : ShowWarningError(
5924 : state,
5925 0 : format("Mixing source temperature control: The minimum source temperature is above the maximum source temperature in {}",
5926 0 : thisMixing.Name));
5927 0 : ShowContinueError(state, "The minimum source temperature is set to the maximum source temperature. Simulation continues.");
5928 0 : ShowContinueErrorTimeStamp(state, " Occurrence info:");
5929 : } else {
5930 0 : ShowRecurringWarningErrorAtEnd(state,
5931 : "The minimum source temperature is still above the maximum source temperature",
5932 0 : thisMixing.SourceTempErrIndex,
5933 : MixingTmin,
5934 : MixingTmin);
5935 : }
5936 0 : MixingTmin = MixingTmax;
5937 : }
5938 : }
5939 92195 : if (thisMixing.minSourceTempSched != nullptr) {
5940 0 : if (TZM < MixingTmin) MixingLimitFlag = true;
5941 : }
5942 92195 : if (thisMixing.maxSourceTempSched != nullptr) {
5943 0 : if (TZM > MixingTmax) MixingLimitFlag = true;
5944 : }
5945 : // Ensure the minimum outdoor temperature <= the maximum outdoor temperature
5946 92195 : Real64 TempExt = state.dataHeatBal->Zone(thisZoneNum).OutDryBulbTemp;
5947 92195 : if (thisMixing.minOutdoorTempSched != nullptr) MixingTmin = thisMixing.minOutdoorTempSched->getCurrentVal();
5948 92195 : if (thisMixing.maxOutdoorTempSched != nullptr) MixingTmax = thisMixing.maxOutdoorTempSched->getCurrentVal();
5949 92195 : if (thisMixing.minOutdoorTempSched != nullptr && thisMixing.maxOutdoorTempSched != nullptr) {
5950 0 : if (MixingTmin > MixingTmax) {
5951 0 : ++thisMixing.OutdoorTempErrCount;
5952 0 : if (thisMixing.OutdoorTempErrCount < 2) {
5953 0 : ShowWarningError(state,
5954 0 : format("Mixing outdoor temperature control: The minimum outdoor temperature is above the maximum "
5955 : "outdoor temperature in {}",
5956 0 : thisMixing.Name));
5957 0 : ShowContinueError(state, "The minimum outdoor temperature is set to the maximum source temperature. Simulation continues.");
5958 0 : ShowContinueErrorTimeStamp(state, " Occurrence info:");
5959 : } else {
5960 0 : ShowRecurringWarningErrorAtEnd(state,
5961 : "The minimum outdoor temperature is still above the maximum outdoor temperature",
5962 0 : thisMixing.OutdoorTempErrIndex,
5963 : MixingTmin,
5964 : MixingTmin);
5965 : }
5966 0 : MixingTmin = MixingTmax;
5967 : }
5968 : }
5969 92195 : if (thisMixing.minOutdoorTempSched != nullptr) {
5970 0 : if (TempExt < MixingTmin) MixingLimitFlag = true;
5971 : }
5972 92195 : if (thisMixing.maxOutdoorTempSched != nullptr) {
5973 0 : if (TempExt > MixingTmax) MixingLimitFlag = true;
5974 : }
5975 : }
5976 :
5977 92195 : if (thisMixing.HybridControlType != DataHeatBalance::HybridCtrlType::Global && MixingLimitFlag) continue;
5978 92195 : if (thisMixing.HybridControlType == DataHeatBalance::HybridCtrlType::Global) TD = 0.0;
5979 :
5980 : // Per Jan 17, 2008 conference call, agreed to use average conditions for Rho, Cp and Hfg
5981 92195 : Real64 AirDensity = PsyRhoAirFnPbTdbW(
5982 92195 : state, state.dataEnvrn->OutBaroPress, (TZN + TZM) / 2.0, (HumRatZN + HumRatZM) / 2.0, RoutineNameMixing); // Density of air (kg/m^3)
5983 92195 : Real64 CpAir = PsyCpAirFnW((HumRatZN + HumRatZM) / 2.0); // Use average conditions
5984 :
5985 : // If TD equals zero (default) set coefficients for full mixing otherwise test
5986 : // for mixing conditions if user input delta temp > 0, then from zone temp (TZM)
5987 : // must be td degrees warmer than zone temp (TZN). If user input delta temp < 0,
5988 : // then from zone temp (TZM) must be TD degrees cooler than zone temp (TZN).
5989 92195 : if (TD < 0.0) {
5990 0 : if (TZM < TZN + TD) {
5991 :
5992 0 : thisMixing.DesiredAirFlowRate = thisMixing.DesiredAirFlowRateSaved;
5993 0 : if (state.dataHeatBalFanSys->ZoneMassBalanceFlag(thisZoneNum) && AdjustZoneMixingFlowFlag) {
5994 0 : if (thisMixing.MixingMassFlowRate > 0.0) {
5995 0 : thisMixing.DesiredAirFlowRate = thisMixing.MixingMassFlowRate / AirDensity;
5996 : }
5997 : }
5998 0 : thisMixing.MixingMassFlowRate = thisMixing.DesiredAirFlowRate * AirDensity;
5999 :
6000 0 : thisMCPM = thisMixing.MixingMassFlowRate * CpAir;
6001 0 : thisMCPTM = thisMCPM * TZN;
6002 :
6003 : // Now to determine the moisture conditions
6004 0 : thisMixingMassFlow = thisMixing.DesiredAirFlowRate * AirDensity;
6005 0 : thisMixingMassFlowXHumRat = thisMixing.DesiredAirFlowRate * AirDensity * HumRatZM;
6006 0 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
6007 0 : state.dataContaminantBalance->MixingMassFlowCO2(thisZoneNum) +=
6008 0 : thisMixing.DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirCO2(fromZoneNum);
6009 : }
6010 0 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
6011 0 : state.dataContaminantBalance->MixingMassFlowGC(thisZoneNum) +=
6012 0 : thisMixing.DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirGC(fromZoneNum);
6013 : }
6014 0 : thisMixing.ReportFlag = true;
6015 : }
6016 92195 : } else if (TD > 0.0) {
6017 0 : if (TZM > TZN + TD) {
6018 0 : thisMixing.DesiredAirFlowRate = thisMixing.DesiredAirFlowRateSaved;
6019 0 : if (state.dataHeatBalFanSys->ZoneMassBalanceFlag(thisZoneNum) && AdjustZoneMixingFlowFlag) {
6020 0 : if (thisMixing.MixingMassFlowRate > 0.0) {
6021 0 : thisMixing.DesiredAirFlowRate = thisMixing.MixingMassFlowRate / AirDensity;
6022 : }
6023 : }
6024 0 : thisMixing.MixingMassFlowRate = thisMixing.DesiredAirFlowRate * AirDensity;
6025 :
6026 0 : thisMCPM = thisMixing.MixingMassFlowRate * CpAir;
6027 0 : thisMCPTM = thisMCPM * TZM;
6028 : // Now to determine the moisture conditions
6029 0 : thisMixingMassFlow = thisMixing.MixingMassFlowRate;
6030 0 : thisMixingMassFlowXHumRat = thisMixing.MixingMassFlowRate * HumRatZM;
6031 0 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
6032 0 : state.dataContaminantBalance->MixingMassFlowCO2(thisZoneNum) +=
6033 0 : thisMixing.MixingMassFlowRate * state.dataContaminantBalance->ZoneAirCO2(fromZoneNum);
6034 : }
6035 0 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
6036 0 : state.dataContaminantBalance->MixingMassFlowGC(thisZoneNum) +=
6037 0 : thisMixing.MixingMassFlowRate * state.dataContaminantBalance->ZoneAirGC(fromZoneNum);
6038 : }
6039 0 : thisMixing.ReportFlag = true;
6040 : }
6041 92195 : } else if (TD == 0.0) {
6042 92195 : thisMixing.DesiredAirFlowRate = thisMixing.DesiredAirFlowRateSaved;
6043 92195 : if (state.dataHeatBalFanSys->ZoneMassBalanceFlag(thisZoneNum) && AdjustZoneMixingFlowFlag) {
6044 6 : if (thisMixing.MixingMassFlowRate > 0.0) {
6045 6 : thisMixing.DesiredAirFlowRate = thisMixing.MixingMassFlowRate / AirDensity;
6046 : }
6047 : }
6048 92195 : thisMixing.MixingMassFlowRate = thisMixing.DesiredAirFlowRate * AirDensity;
6049 :
6050 92195 : thisMCPM = thisMixing.MixingMassFlowRate * CpAir;
6051 92195 : thisMCPTM = thisMCPM * TZM;
6052 : // Now to determine the moisture conditions
6053 92195 : thisMixingMassFlow = thisMixing.MixingMassFlowRate;
6054 92195 : thisMixingMassFlowXHumRat = thisMixing.MixingMassFlowRate * HumRatZM;
6055 92195 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
6056 0 : state.dataContaminantBalance->MixingMassFlowCO2(thisZoneNum) +=
6057 0 : thisMixing.MixingMassFlowRate * state.dataContaminantBalance->ZoneAirCO2(fromZoneNum);
6058 : }
6059 92195 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
6060 0 : state.dataContaminantBalance->MixingMassFlowGC(thisZoneNum) +=
6061 0 : thisMixing.MixingMassFlowRate * state.dataContaminantBalance->ZoneAirGC(fromZoneNum);
6062 : }
6063 92195 : thisMixing.ReportFlag = true;
6064 : }
6065 : // Accumulate for zone and space
6066 92195 : thisZoneHB.MCPM += thisMCPM;
6067 92195 : thisZoneHB.MCPTM += thisMCPTM;
6068 92195 : thisZoneHB.MixingMassFlowZone += thisMixingMassFlow;
6069 92195 : thisZoneHB.MixingMassFlowXHumRat += thisMixingMassFlowXHumRat;
6070 92195 : if (state.dataHeatBal->doSpaceHeatBalance) {
6071 0 : auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisMixing.spaceIndex);
6072 0 : thisSpaceHB.MCPM += thisMCPM;
6073 0 : thisSpaceHB.MCPTM += thisMCPTM;
6074 0 : thisSpaceHB.MixingMassFlowZone += thisMixingMassFlow;
6075 0 : thisSpaceHB.MixingMassFlowXHumRat += thisMixingMassFlowXHumRat;
6076 : }
6077 : }
6078 :
6079 : // COMPUTE CROSS ZONE
6080 : // AIR MIXING
6081 383786 : for (int j = 1; j <= state.dataHeatBal->TotCrossMixing; ++j) {
6082 92180 : auto &thisCrossMixing = state.dataHeatBal->CrossMixing(j);
6083 92180 : int thisZoneNum = thisCrossMixing.ZonePtr;
6084 92180 : thisCrossMixing.ReportFlag = false;
6085 92180 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisZoneNum);
6086 92180 : int fromZoneNum = thisCrossMixing.FromZone;
6087 92180 : auto &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(fromZoneNum);
6088 92180 : Real64 TD = thisCrossMixing.DeltaTemperature; // Delta Temp limit
6089 : // Get scheduled delta temperature
6090 92180 : if (thisCrossMixing.deltaTempSched != nullptr) {
6091 0 : TD = thisCrossMixing.deltaTempSched->getCurrentVal();
6092 : }
6093 92180 : Real64 thisMCPxM = 0.0;
6094 92180 : Real64 thisMCPTxM = 0.0;
6095 92180 : Real64 thisXMixingMassFlow = 0.0;
6096 92180 : Real64 thisXMixingMassFlowXHumRat = 0.0;
6097 92180 : Real64 fromMCPxM = 0.0;
6098 92180 : Real64 fromMCPTxM = 0.0;
6099 92180 : Real64 fromXMixingMassFlowXHumRat = 0.0;
6100 :
6101 92180 : if (TD >= 0.0) {
6102 92180 : Real64 TZN = 0.0; // Temperature of this Zone/Space
6103 92180 : Real64 TZM = 0.0; // Temperature of From Zone/Space
6104 92180 : Real64 HumRatZN = 0.0; // HumRat of this Zone/Space
6105 92180 : Real64 HumRatZM = 0.0; // HumRat of From Zone/Space
6106 92180 : if (state.dataHeatBal->doSpaceHeatBalance) {
6107 0 : auto const &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisCrossMixing.spaceIndex);
6108 0 : TZN = thisSpaceHB.MixingMAT; // Temperature of this Space
6109 0 : HumRatZN = thisSpaceHB.MixingHumRat; // HumRat of this Space
6110 0 : if (thisCrossMixing.fromSpaceIndex == 0) {
6111 0 : TZM = fromZoneHB.MixingMAT; // Temperature of From Zone
6112 0 : HumRatZM = fromZoneHB.MixingHumRat; // HumRat of From Zone
6113 : } else {
6114 0 : auto const &fromSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisCrossMixing.fromSpaceIndex);
6115 0 : TZM = fromSpaceHB.MixingMAT; // Temperature of From Space
6116 0 : HumRatZM = fromSpaceHB.MixingHumRat; // HumRat of From Space
6117 : }
6118 : } else {
6119 92180 : TZN = thisZoneHB.MixingMAT; // Temperature of this zone
6120 92180 : TZM = fromZoneHB.MixingMAT; // Temperature of From Zone
6121 92180 : HumRatZN = thisZoneHB.MixingHumRat; // HumRat of this zone
6122 92180 : HumRatZM = fromZoneHB.MixingHumRat; // HumRat of From Zone
6123 : }
6124 : // Check temperature limit
6125 92180 : bool MixingLimitFlag = false;
6126 : // Ensure the minimum indoor temperature <= the maximum indoor temperature
6127 92180 : Real64 MixingTmin = 0.0;
6128 92180 : Real64 MixingTmax = 0.0;
6129 92180 : if (thisCrossMixing.minIndoorTempSched != nullptr) MixingTmin = thisCrossMixing.minIndoorTempSched->getCurrentVal();
6130 92180 : if (thisCrossMixing.maxIndoorTempSched != nullptr) MixingTmax = thisCrossMixing.maxIndoorTempSched->getCurrentVal();
6131 92180 : if (thisCrossMixing.minIndoorTempSched != nullptr && thisCrossMixing.maxIndoorTempSched != nullptr) {
6132 5 : if (MixingTmin > MixingTmax) {
6133 0 : ++thisCrossMixing.IndoorTempErrCount;
6134 0 : if (thisCrossMixing.IndoorTempErrCount < 2) {
6135 0 : ShowWarningError(
6136 : state,
6137 0 : format("CrossMixing zone temperature control: The minimum zone temperature is above the maximum zone temperature in {}",
6138 0 : thisCrossMixing.Name));
6139 0 : ShowContinueError(state, "The minimum zone temperature is set to the maximum zone temperature. Simulation continues.");
6140 0 : ShowContinueErrorTimeStamp(state, " Occurrence info:");
6141 : } else {
6142 0 : ShowRecurringWarningErrorAtEnd(state,
6143 : "The minimum zone temperature is still above the maximum zone temperature",
6144 0 : thisCrossMixing.IndoorTempErrIndex,
6145 : MixingTmin,
6146 : MixingTmin);
6147 : }
6148 0 : MixingTmin = MixingTmax;
6149 : }
6150 : }
6151 92180 : if (thisCrossMixing.minIndoorTempSched != nullptr) {
6152 5 : if (TZN < MixingTmin) MixingLimitFlag = true;
6153 : }
6154 92180 : if (thisCrossMixing.maxIndoorTempSched != nullptr) {
6155 5 : if (TZN > MixingTmax) MixingLimitFlag = true;
6156 : }
6157 : // Ensure the minimum source temperature <= the maximum source temperature
6158 92180 : if (thisCrossMixing.minSourceTempSched != nullptr) MixingTmin = thisCrossMixing.minSourceTempSched->getCurrentVal();
6159 92180 : if (thisCrossMixing.maxSourceTempSched != nullptr) MixingTmax = thisCrossMixing.maxSourceTempSched->getCurrentVal();
6160 92180 : if (thisCrossMixing.minSourceTempSched != nullptr && thisCrossMixing.maxSourceTempSched != nullptr) {
6161 5 : if (MixingTmin > MixingTmax) {
6162 0 : ++thisCrossMixing.SourceTempErrCount;
6163 0 : if (thisCrossMixing.SourceTempErrCount < 2) {
6164 0 : ShowWarningError(state,
6165 0 : format("CrossMixing source temperature control: The minimum source temperature is above the maximum source "
6166 : "temperature in {}",
6167 0 : thisCrossMixing.Name));
6168 0 : ShowContinueError(state, "The minimum source temperature is set to the maximum source temperature. Simulation continues.");
6169 0 : ShowContinueErrorTimeStamp(state, " Occurrence info:");
6170 : } else {
6171 0 : ShowRecurringWarningErrorAtEnd(state,
6172 : "The minimum source temperature is still above the maximum source temperature",
6173 0 : thisCrossMixing.SourceTempErrIndex,
6174 : MixingTmin,
6175 : MixingTmin);
6176 : }
6177 0 : MixingTmin = MixingTmax;
6178 : }
6179 : }
6180 92180 : if (thisCrossMixing.minSourceTempSched != nullptr) {
6181 5 : if (TZM < MixingTmin) MixingLimitFlag = true;
6182 : }
6183 92180 : if (thisCrossMixing.maxSourceTempSched != nullptr) {
6184 5 : if (TZM > MixingTmax) MixingLimitFlag = true;
6185 : }
6186 : // Ensure the minimum outdoor temperature <= the maximum outdoor temperature
6187 92180 : Real64 TempExt = state.dataHeatBal->Zone(thisZoneNum).OutDryBulbTemp;
6188 92180 : if (thisCrossMixing.minOutdoorTempSched != nullptr) MixingTmin = thisCrossMixing.minOutdoorTempSched->getCurrentVal();
6189 92180 : if (thisCrossMixing.maxOutdoorTempSched != nullptr) MixingTmax = thisCrossMixing.maxOutdoorTempSched->getCurrentVal();
6190 92180 : if (thisCrossMixing.minOutdoorTempSched != nullptr && thisCrossMixing.maxOutdoorTempSched != nullptr) {
6191 5 : if (MixingTmin > MixingTmax) {
6192 0 : ++thisCrossMixing.OutdoorTempErrCount;
6193 0 : if (thisCrossMixing.OutdoorTempErrCount < 2) {
6194 0 : ShowWarningError(state,
6195 0 : format("CrossMixing outdoor temperature control: The minimum outdoor temperature is above the maximum "
6196 : "outdoor temperature in {}",
6197 0 : state.dataHeatBal->Mixing(j).Name));
6198 0 : ShowContinueError(state, "The minimum outdoor temperature is set to the maximum source temperature. Simulation continues.");
6199 0 : ShowContinueErrorTimeStamp(state, " Occurrence info:");
6200 : } else {
6201 0 : ShowRecurringWarningErrorAtEnd(state,
6202 : "The minimum outdoor temperature is still above the maximum outdoor temperature",
6203 0 : thisCrossMixing.OutdoorTempErrIndex,
6204 : MixingTmin,
6205 : MixingTmin);
6206 : }
6207 0 : MixingTmin = MixingTmax;
6208 : }
6209 : }
6210 92180 : if (thisCrossMixing.minOutdoorTempSched != nullptr) {
6211 5 : if (TempExt < MixingTmin) MixingLimitFlag = true;
6212 : }
6213 92180 : if (thisCrossMixing.maxOutdoorTempSched != nullptr) {
6214 5 : if (TempExt > MixingTmax) MixingLimitFlag = true;
6215 : }
6216 92180 : if (MixingLimitFlag) continue;
6217 :
6218 92180 : if ((TD == 0.0 || (TD > 0.0 && (TZM - TZN) >= TD))) {
6219 92179 : thisCrossMixing.ReportFlag = true;
6220 : }
6221 :
6222 92180 : if ((TD <= 0.0) || (TZM - TZN >= TD)) {
6223 : // SET COEFFICIENTS .
6224 92179 : Real64 Tavg = (TZN + TZM) / 2.0;
6225 92179 : Real64 Wavg = (HumRatZN + HumRatZM) / 2.0;
6226 92179 : Real64 AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, Tavg, Wavg, RoutineNameCrossMixing);
6227 92179 : Real64 CpAir = PsyCpAirFnW(Wavg);
6228 92179 : thisXMixingMassFlow = thisCrossMixing.DesiredAirFlowRate * AirDensity;
6229 92179 : thisMCPxM = thisXMixingMassFlow * CpAir;
6230 :
6231 92179 : fromMCPxM = thisMCPxM;
6232 92179 : thisMCPTxM = thisMCPxM * TZM;
6233 92179 : fromMCPTxM = fromMCPxM * TZN;
6234 :
6235 : // Now to determine the moisture conditions
6236 92179 : fromXMixingMassFlowXHumRat = thisXMixingMassFlow * HumRatZN;
6237 92179 : thisXMixingMassFlowXHumRat = thisXMixingMassFlow * HumRatZM;
6238 :
6239 92179 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
6240 0 : state.dataContaminantBalance->MixingMassFlowCO2(fromZoneNum) +=
6241 0 : thisXMixingMassFlow * state.dataContaminantBalance->ZoneAirCO2(thisZoneNum);
6242 0 : state.dataContaminantBalance->MixingMassFlowCO2(thisZoneNum) +=
6243 0 : thisXMixingMassFlow * state.dataContaminantBalance->ZoneAirCO2(fromZoneNum);
6244 : }
6245 92179 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
6246 0 : state.dataContaminantBalance->MixingMassFlowGC(fromZoneNum) +=
6247 0 : thisXMixingMassFlow * state.dataContaminantBalance->ZoneAirGC(thisZoneNum);
6248 0 : state.dataContaminantBalance->MixingMassFlowGC(thisZoneNum) +=
6249 0 : thisXMixingMassFlow * state.dataContaminantBalance->ZoneAirGC(fromZoneNum);
6250 : }
6251 : }
6252 : }
6253 : // Accumulate for zone and space
6254 92180 : thisZoneHB.MCPM += thisMCPxM;
6255 92180 : thisZoneHB.MCPTM += thisMCPTxM;
6256 92180 : thisZoneHB.MixingMassFlowZone += thisXMixingMassFlow;
6257 92180 : thisZoneHB.MixingMassFlowXHumRat += thisXMixingMassFlowXHumRat;
6258 92180 : fromZoneHB.MCPM += fromMCPxM;
6259 92180 : fromZoneHB.MCPTM += fromMCPTxM;
6260 92180 : fromZoneHB.MixingMassFlowZone += thisXMixingMassFlow;
6261 92180 : fromZoneHB.MixingMassFlowXHumRat += fromXMixingMassFlowXHumRat;
6262 92180 : if (state.dataHeatBal->doSpaceHeatBalance) {
6263 0 : auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisCrossMixing.spaceIndex);
6264 0 : thisSpaceHB.MCPM += thisMCPxM;
6265 0 : thisSpaceHB.MCPTM += thisMCPTxM;
6266 0 : thisSpaceHB.MixingMassFlowZone += thisXMixingMassFlow;
6267 0 : thisSpaceHB.MixingMassFlowXHumRat += thisXMixingMassFlowXHumRat;
6268 0 : if (thisCrossMixing.fromSpaceIndex > 0) {
6269 0 : auto &fromSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisCrossMixing.fromSpaceIndex);
6270 0 : fromSpaceHB.MCPM += fromMCPxM;
6271 0 : fromSpaceHB.MCPTM += fromMCPTxM;
6272 0 : fromSpaceHB.MixingMassFlowZone += thisXMixingMassFlow;
6273 0 : fromSpaceHB.MixingMassFlowXHumRat += fromXMixingMassFlowXHumRat;
6274 : } else {
6275 : // Allocate mixing flows by space volume fraction of zone volume
6276 0 : for (int spaceNum : state.dataHeatBal->Zone(fromZoneNum).spaceIndexes) {
6277 0 : Real64 spaceFrac = state.dataHeatBal->space(spaceNum).fracZoneVolume;
6278 0 : auto &fromSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum);
6279 0 : fromSpaceHB.MCPM += fromMCPxM * spaceFrac;
6280 0 : fromSpaceHB.MCPTM += fromMCPTxM * spaceFrac;
6281 0 : fromSpaceHB.MixingMassFlowZone += thisXMixingMassFlow * spaceFrac;
6282 0 : fromSpaceHB.MixingMassFlowXHumRat += fromXMixingMassFlowXHumRat * spaceFrac;
6283 : }
6284 : }
6285 : }
6286 : }
6287 :
6288 : // COMPUTE REFRIGERATION DOOR
6289 : // AIR MIXING
6290 291606 : if (state.dataHeatBal->TotRefDoorMixing > 0) {
6291 : // Zone loops structured in getinput so only do each pair of zones bounding door once, even if multiple doors in one zone
6292 2 : for (int ZoneA = 1; ZoneA <= (state.dataGlobal->NumOfZones - 1); ++ZoneA) {
6293 1 : if (!state.dataHeatBal->RefDoorMixing(ZoneA).RefDoorMixFlag) continue;
6294 1 : auto &thisRefDoorMixing = state.dataHeatBal->RefDoorMixing(ZoneA);
6295 1 : auto &zoneAHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneA);
6296 1 : Real64 TZoneA = zoneAHB.MixingMAT;
6297 1 : Real64 HumRatZoneA = zoneAHB.MixingHumRat;
6298 1 : if ((state.dataHeatBal->doSpaceHeatBalance) && (thisRefDoorMixing.spaceIndex > 0)) {
6299 0 : auto const &spaceAHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.spaceIndex);
6300 0 : TZoneA = spaceAHB.MixingMAT;
6301 0 : HumRatZoneA = spaceAHB.MixingHumRat;
6302 : }
6303 1 : Real64 AirDensityZoneA = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TZoneA, HumRatZoneA, RoutineNameRefrigerationDoorMixing);
6304 1 : Real64 CpAirZoneA = PsyCpAirFnW(HumRatZoneA);
6305 2 : for (int j = 1; j <= state.dataHeatBal->RefDoorMixing(ZoneA).NumRefDoorConnections; ++j) {
6306 1 : int ZoneB = state.dataHeatBal->RefDoorMixing(ZoneA).MateZonePtr(j);
6307 1 : auto &zoneBHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneB);
6308 1 : Real64 TZoneB = zoneBHB.MixingMAT;
6309 1 : Real64 HumRatZoneB = zoneBHB.MixingHumRat;
6310 1 : Real64 CpAirZoneB = PsyCpAirFnW(HumRatZoneB);
6311 1 : if ((state.dataHeatBal->doSpaceHeatBalance) && (thisRefDoorMixing.fromSpaceIndex > 0)) {
6312 0 : auto const &spaceBHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.fromSpaceIndex);
6313 0 : TZoneB = spaceBHB.MixingMAT;
6314 0 : HumRatZoneB = spaceBHB.MixingHumRat;
6315 : }
6316 1 : Real64 Tavg = (TZoneA + TZoneB) / 2.0;
6317 1 : Real64 Wavg = (HumRatZoneA + HumRatZoneB) / 2.0;
6318 1 : Real64 AirDensityAvg = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, Tavg, Wavg, RoutineNameRefrigerationDoorMixing);
6319 : // following variables used for refrigeration door mixing and all defined in EngRef
6320 1 : Real64 MassFlowDryAir = 0.0;
6321 1 : Real64 FDens = 0.0;
6322 1 : Real64 Fb = 0.0;
6323 :
6324 1 : if (state.dataHeatBal->RefDoorMixing(ZoneA).EMSRefDoorMixingOn(j)) {
6325 1 : MassFlowDryAir = state.dataHeatBal->RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * AirDensityAvg;
6326 : } else {
6327 : Real64 AirDensityZoneB =
6328 0 : PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TZoneB, HumRatZoneB, RoutineNameRefrigerationDoorMixing);
6329 0 : Real64 SchedDoorOpen = state.dataHeatBal->RefDoorMixing(ZoneA).openScheds(j)->getCurrentVal();
6330 0 : if (SchedDoorOpen == 0.0) continue;
6331 0 : Real64 DoorHeight = state.dataHeatBal->RefDoorMixing(ZoneA).DoorHeight(j);
6332 0 : Real64 DoorArea = state.dataHeatBal->RefDoorMixing(ZoneA).DoorArea(j);
6333 0 : Real64 DoorProt = state.dataHeatBal->RefDoorMixing(ZoneA).Protection(j);
6334 0 : if (AirDensityZoneA >= AirDensityZoneB) {
6335 : // Mass of dry air flow between zones is equal,
6336 : // but have to calc directionally to avoid sqrt(neg number)
6337 0 : FDens = std::pow(2.0 / (1.0 + std::pow(AirDensityZoneA / AirDensityZoneB, 1.0 / 3.0)), 1.5);
6338 0 : Fb = 0.221 * DoorArea * AirDensityZoneA * FDens *
6339 0 : std::sqrt((1.0 - AirDensityZoneB / AirDensityZoneA) * StdGravity * DoorHeight);
6340 : } else { // ZoneADens < ZoneBDens
6341 0 : FDens = std::pow(2.0 / (1.0 + std::pow(AirDensityZoneB / AirDensityZoneA, 1.0 / 3.0)), 1.5);
6342 0 : Fb = 0.221 * DoorArea * AirDensityZoneB * FDens *
6343 0 : std::sqrt((1.0 - AirDensityZoneA / AirDensityZoneB) * StdGravity * DoorHeight);
6344 : } // ZoneADens .GE. ZoneBDens
6345 : // FFlow = Doorway flow factor, is determined by temperature difference
6346 0 : Real64 FFlow = 1.1;
6347 0 : if (std::abs(TZoneA - TZoneB) > 11.0) FFlow = 0.8;
6348 0 : MassFlowDryAir = Fb * SchedDoorOpen * FFlow * (1.0 - DoorProt);
6349 0 : state.dataHeatBal->RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) = MassFlowDryAir / AirDensityAvg;
6350 : // Note - VolRefDoorFlowRate is used ONLY for reporting purposes, where it is
6351 : // used with the avg density to generate a reported mass flow
6352 : // Considering the small values typical for HumRat, this is not far off.
6353 : } // EMSRefDoorMixingOn
6354 :
6355 1 : Real64 MassFlowToA = MassFlowDryAir * (1.0 + HumRatZoneB);
6356 1 : Real64 MassFlowToB = MassFlowDryAir * (1.0 + HumRatZoneA);
6357 1 : Real64 MassFlowXCpToA = MassFlowToA * CpAirZoneB;
6358 1 : Real64 MassFlowXCpToB = MassFlowToB * CpAirZoneA;
6359 1 : Real64 MassFlowXCpXTempToA = MassFlowXCpToA * TZoneB;
6360 1 : Real64 MassFlowXCpXTempToB = MassFlowXCpToB * TZoneA;
6361 1 : Real64 MassFlowXHumRatToA = MassFlowToA * HumRatZoneB;
6362 1 : Real64 MassFlowXHumRatToB = MassFlowToB * HumRatZoneA;
6363 :
6364 1 : zoneAHB.MCPM += MassFlowXCpToA;
6365 1 : zoneBHB.MCPM += MassFlowXCpToB;
6366 1 : zoneAHB.MCPTM += MassFlowXCpXTempToA;
6367 1 : zoneBHB.MCPTM += MassFlowXCpXTempToB;
6368 1 : zoneAHB.MixingMassFlowZone += MassFlowToA;
6369 1 : zoneBHB.MixingMassFlowZone += MassFlowToB;
6370 1 : zoneAHB.MixingMassFlowXHumRat += MassFlowXHumRatToA;
6371 1 : zoneBHB.MixingMassFlowXHumRat += MassFlowXHumRatToB;
6372 1 : if (state.dataHeatBal->doSpaceHeatBalance) {
6373 0 : if (thisRefDoorMixing.spaceIndex > 0) {
6374 0 : auto &spaceAHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.spaceIndex);
6375 0 : spaceAHB.MCPM += MassFlowXCpToA;
6376 0 : spaceAHB.MCPTM += MassFlowXCpXTempToA;
6377 0 : spaceAHB.MixingMassFlowZone += MassFlowToA;
6378 0 : spaceAHB.MixingMassFlowXHumRat += MassFlowXHumRatToA;
6379 : } else {
6380 : // Allocate mixing flows by space volume fraction of zone volume
6381 0 : for (int spaceNum : state.dataHeatBal->Zone(ZoneA).spaceIndexes) {
6382 0 : Real64 spaceFrac = state.dataHeatBal->space(spaceNum).fracZoneVolume;
6383 0 : auto &spaceAHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum);
6384 0 : spaceAHB.MCPM += MassFlowXCpToA * spaceFrac;
6385 0 : spaceAHB.MCPTM += MassFlowXCpXTempToA * spaceFrac;
6386 0 : spaceAHB.MixingMassFlowZone += MassFlowToA * spaceFrac;
6387 0 : spaceAHB.MixingMassFlowXHumRat += MassFlowXHumRatToA * spaceFrac;
6388 : }
6389 : }
6390 0 : if (thisRefDoorMixing.spaceIndex > 0) {
6391 0 : auto &spaceBHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisRefDoorMixing.fromSpaceIndex);
6392 0 : spaceBHB.MCPM += MassFlowXCpToB;
6393 0 : spaceBHB.MCPTM += MassFlowXCpXTempToB;
6394 0 : spaceBHB.MixingMassFlowZone += MassFlowToB;
6395 0 : spaceBHB.MixingMassFlowXHumRat += MassFlowXHumRatToB;
6396 : } else {
6397 : // Allocate mixing flows by space volume fraction of zone volume
6398 0 : for (int spaceNum : state.dataHeatBal->Zone(ZoneB).spaceIndexes) {
6399 0 : Real64 spaceFrac = state.dataHeatBal->space(spaceNum).fracZoneVolume;
6400 0 : auto &spaceBHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum);
6401 0 : spaceBHB.MCPM += MassFlowXCpToB * spaceFrac;
6402 0 : spaceBHB.MCPTM += MassFlowXCpXTempToB * spaceFrac;
6403 0 : spaceBHB.MixingMassFlowZone += MassFlowToB * spaceFrac;
6404 0 : spaceBHB.MixingMassFlowXHumRat += MassFlowXHumRatToB * spaceFrac;
6405 : }
6406 : }
6407 : }
6408 :
6409 : // Now to determine the CO2 and generic contaminant conditions
6410 1 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
6411 1 : state.dataContaminantBalance->MixingMassFlowCO2(ZoneA) += MassFlowToA * state.dataContaminantBalance->ZoneAirCO2(ZoneB);
6412 1 : state.dataContaminantBalance->MixingMassFlowCO2(ZoneB) += MassFlowToB * state.dataContaminantBalance->ZoneAirCO2(ZoneA);
6413 : }
6414 1 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
6415 1 : state.dataContaminantBalance->MixingMassFlowGC(ZoneA) += MassFlowToA * state.dataContaminantBalance->ZoneAirGC(ZoneB);
6416 1 : state.dataContaminantBalance->MixingMassFlowGC(ZoneB) += MassFlowToB * state.dataContaminantBalance->ZoneAirGC(ZoneA);
6417 : }
6418 :
6419 : } // J=1,RefDoorMixing(ZoneA)%NumRefDoorConnections
6420 : } // ZoneA=1,(NumOfZones - 1)
6421 : } //(TotRefrigerationDoorMixing > 0) THEN
6422 :
6423 : // Process the scheduled Infiltration for air heat balance depending on model type
6424 355877 : for (int j = 1; j <= state.dataHeatBal->TotInfiltration; ++j) {
6425 :
6426 64271 : auto &thisInfiltration = state.dataHeatBal->Infiltration(j);
6427 64271 : int NZ = state.dataHeatBal->Infiltration(j).ZonePtr;
6428 64271 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ);
6429 64271 : Real64 tempInt = 0.0;
6430 64271 : if (state.dataHeatBal->doSpaceHeatBalance) {
6431 0 : tempInt = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisInfiltration.spaceIndex).MixingMAT;
6432 : } else {
6433 64271 : tempInt = thisZoneHB.MixingMAT;
6434 : }
6435 :
6436 64271 : Real64 TempExt = state.dataHeatBal->Zone(NZ).OutDryBulbTemp;
6437 64271 : Real64 WindSpeedExt = state.dataHeatBal->Zone(NZ).WindSpeed;
6438 :
6439 : // Use air node information linked to the zone if defined
6440 64271 : Real64 HumRatExt = 0.0;
6441 64271 : if (state.dataHeatBal->Zone(NZ).LinkedOutAirNode > 0) {
6442 0 : HumRatExt = state.dataLoopNodes->Node(state.dataHeatBal->Zone(NZ).LinkedOutAirNode).HumRat;
6443 : } else {
6444 64271 : HumRatExt = state.dataEnvrn->OutHumRat;
6445 : }
6446 :
6447 64271 : Real64 AirDensity = 0.0; // Density of air for converting from volume flow to mass flow (kg/m^3)
6448 64271 : switch (thisInfiltration.densityBasis) {
6449 1 : case DataHeatBalance::InfVentDensityBasis::Standard: {
6450 1 : AirDensity = state.dataEnvrn->StdRhoAir;
6451 1 : } break;
6452 0 : case DataHeatBalance::InfVentDensityBasis::Indoor: {
6453 0 : if (state.dataHeatBal->doSpaceHeatBalance) {
6454 0 : auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisInfiltration.spaceIndex);
6455 0 : AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(
6456 0 : state, state.dataEnvrn->OutBaroPress, tempInt, thisSpaceHB.MixingHumRat, RoutineNameInfiltration);
6457 : } else {
6458 0 : AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(
6459 0 : state, state.dataEnvrn->OutBaroPress, tempInt, thisZoneHB.MixingHumRat, RoutineNameInfiltration);
6460 : }
6461 0 : } break;
6462 64270 : default:
6463 64270 : AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, HumRatExt, RoutineNameInfiltration);
6464 64270 : break;
6465 : }
6466 :
6467 64271 : Real64 CpAir = PsyCpAirFnW(HumRatExt);
6468 64271 : Real64 MCpI_temp = 0.0;
6469 64271 : Real64 scheduleFrac = thisInfiltration.sched->getCurrentVal();
6470 64271 : if (scheduleFrac > 0.0) {
6471 : // CR7751 should maybe use code below, indoor conditions instead of outdoor conditions
6472 : // AirDensity = PsyRhoAirFnPbTdbW(state, OutBaroPress, MixingMAT(NZ), MixingHumRat(NZ))
6473 : // CpAir = PsyCpAirFnW(MixingHumRat(NZ),MixingMAT(NZ))
6474 64271 : switch (thisInfiltration.ModelType) {
6475 64269 : case DataHeatBalance::InfiltrationModelType::DesignFlowRate: {
6476 64269 : Real64 IVF = thisInfiltration.DesignLevel * scheduleFrac; // INFILTRATION FLOW RATE (M**3/SEC)
6477 : // CR6845 if calculated < 0.0, don't propagate
6478 64269 : if (IVF < 0.0) IVF = 0.0;
6479 128538 : MCpI_temp = IVF * AirDensity * CpAir *
6480 64269 : (thisInfiltration.ConstantTermCoef + std::abs(TempExt - tempInt) * thisInfiltration.TemperatureTermCoef +
6481 64269 : WindSpeedExt * (thisInfiltration.VelocityTermCoef + WindSpeedExt * thisInfiltration.VelocitySQTermCoef));
6482 :
6483 64269 : if (MCpI_temp < 0.0) MCpI_temp = 0.0;
6484 64269 : thisInfiltration.VolumeFlowRate = MCpI_temp / AirDensity / CpAir;
6485 64269 : } break;
6486 1 : case DataHeatBalance::InfiltrationModelType::ShermanGrimsrud: {
6487 : // Sherman Grimsrud model as formulated in ASHRAE HoF
6488 1 : WindSpeedExt = state.dataEnvrn->WindSpeed; // formulated to use wind at Meterological Station rather than local
6489 1 : Real64 IVF = scheduleFrac * thisInfiltration.LeakageArea / 1000.0 *
6490 1 : std::sqrt(thisInfiltration.BasicStackCoefficient * std::abs(TempExt - tempInt) +
6491 1 : thisInfiltration.BasicWindCoefficient * pow_2(WindSpeedExt));
6492 1 : if (IVF < 0.0) IVF = 0.0;
6493 1 : MCpI_temp = IVF * AirDensity * CpAir;
6494 1 : if (MCpI_temp < 0.0) MCpI_temp = 0.0;
6495 1 : thisInfiltration.VolumeFlowRate = MCpI_temp / AirDensity / CpAir;
6496 1 : } break;
6497 1 : case DataHeatBalance::InfiltrationModelType::AIM2: {
6498 : // Walker Wilson model as formulated in ASHRAE HoF
6499 : Real64 IVF =
6500 3 : scheduleFrac * std::sqrt(pow_2(thisInfiltration.FlowCoefficient * thisInfiltration.AIM2StackCoefficient *
6501 1 : std::pow(std::abs(TempExt - tempInt), thisInfiltration.PressureExponent)) +
6502 1 : pow_2(thisInfiltration.FlowCoefficient * thisInfiltration.AIM2WindCoefficient *
6503 1 : std::pow(thisInfiltration.ShelterFactor * WindSpeedExt, 2.0 * thisInfiltration.PressureExponent)));
6504 1 : if (IVF < 0.0) IVF = 0.0;
6505 1 : MCpI_temp = IVF * AirDensity * CpAir;
6506 1 : if (MCpI_temp < 0.0) MCpI_temp = 0.0;
6507 1 : thisInfiltration.VolumeFlowRate = MCpI_temp / AirDensity / CpAir;
6508 1 : } break;
6509 0 : default:
6510 0 : break;
6511 : }
6512 : } else {
6513 0 : thisInfiltration.VolumeFlowRate = 0.0;
6514 0 : MCpI_temp = 0.0;
6515 : }
6516 :
6517 64271 : if (AdjustZoneInfiltrationFlowFlag && state.dataHeatBalFanSys->ZoneInfiltrationFlag(NZ)) {
6518 2 : if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Adjust) {
6519 2 : if (thisInfiltration.MassFlowRate > 0.0 || thisInfiltration.ModelType == DataHeatBalance::InfiltrationModelType::DesignFlowRate) {
6520 : // For DesignFlowRate, allow exfiltraion
6521 2 : thisInfiltration.VolumeFlowRate = thisInfiltration.MassFlowRate / AirDensity;
6522 2 : MCpI_temp = thisInfiltration.VolumeFlowRate * AirDensity * CpAir;
6523 : }
6524 : }
6525 2 : if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Add) {
6526 0 : thisInfiltration.VolumeFlowRate =
6527 0 : thisInfiltration.VolumeFlowRate + state.dataHeatBal->MassConservation(NZ).InfiltrationMassFlowRate / AirDensity;
6528 0 : MCpI_temp = thisInfiltration.VolumeFlowRate * AirDensity * CpAir;
6529 : }
6530 : }
6531 64271 : thisInfiltration.MassFlowRate = thisInfiltration.VolumeFlowRate * AirDensity;
6532 :
6533 64271 : if (thisInfiltration.EMSOverrideOn) {
6534 0 : Real64 IVF = thisInfiltration.EMSAirFlowRateValue; // INFILTRATION FLOW RATE (M**3/SEC)
6535 0 : if (IVF < 0.0) IVF = 0.0;
6536 0 : MCpI_temp = IVF * AirDensity * CpAir;
6537 0 : if (MCpI_temp < 0.0) MCpI_temp = 0.0;
6538 : }
6539 :
6540 64271 : if (state.dataHeatBal->Zone(NZ).zoneOAQuadratureSum) {
6541 0 : state.dataHeatBal->ZoneAirBalance(state.dataHeatBal->Zone(NZ).zoneOABalanceIndex).InfMassFlowRate += MCpI_temp / CpAir;
6542 : } else {
6543 64271 : thisInfiltration.MCpI_temp = MCpI_temp;
6544 64271 : thisZoneHB.MCPI += MCpI_temp;
6545 64271 : thisZoneHB.OAMFL += MCpI_temp / CpAir;
6546 64271 : thisZoneHB.MCPTI += MCpI_temp * TempExt;
6547 64271 : if (state.dataHeatBal->doSpaceHeatBalance) {
6548 0 : auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisInfiltration.spaceIndex);
6549 0 : thisSpaceHB.MCPI += MCpI_temp;
6550 0 : thisSpaceHB.OAMFL += MCpI_temp / CpAir;
6551 0 : thisSpaceHB.MCPTI += MCpI_temp * TempExt;
6552 : }
6553 : }
6554 : }
6555 :
6556 : // Add infiltration rate enhanced by the existence of thermal chimney
6557 692944 : for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
6558 401338 : thisZoneHB.MCPI += thisZoneHB.MCPThermChim;
6559 401338 : thisZoneHB.OAMFL += thisZoneHB.ThermChimAMFL;
6560 401338 : thisZoneHB.MCPTI += thisZoneHB.MCPTThermChim;
6561 : }
6562 291606 : if (state.dataHeatBal->doSpaceHeatBalance) {
6563 59316 : for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
6564 44487 : thisSpaceHB.MCPI += thisSpaceHB.MCPThermChim;
6565 44487 : thisSpaceHB.OAMFL += thisSpaceHB.ThermChimAMFL;
6566 44487 : thisSpaceHB.MCPTI += thisSpaceHB.MCPTThermChim;
6567 : }
6568 : }
6569 :
6570 : // Calculate combined outdoor air flows
6571 291606 : for (auto &thisZoneAirBalance : state.dataHeatBal->ZoneAirBalance) {
6572 0 : if (thisZoneAirBalance.BalanceMethod == DataHeatBalance::AirBalance::Quadrature) {
6573 0 : if (!thisZoneAirBalance.OneTimeFlag) GetStandAloneERVNodes(state, thisZoneAirBalance);
6574 0 : if (thisZoneAirBalance.NumOfERVs > 0) {
6575 0 : for (int I = 1; I <= thisZoneAirBalance.NumOfERVs; ++I) {
6576 0 : Real64 MassFlowDiff = state.dataLoopNodes->Node(thisZoneAirBalance.ERVExhaustNode(I)).MassFlowRate -
6577 0 : state.dataLoopNodes->Node(thisZoneAirBalance.ERVInletNode(I)).MassFlowRate;
6578 0 : if (MassFlowDiff > 0.0) {
6579 0 : thisZoneAirBalance.ERVMassFlowRate += MassFlowDiff;
6580 : }
6581 : }
6582 : }
6583 0 : int NZ = thisZoneAirBalance.ZonePtr;
6584 0 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ);
6585 : // Use air node information linked to the zone if defined
6586 0 : Real64 HumRatExt = 0.0;
6587 0 : if (state.dataHeatBal->Zone(NZ).LinkedOutAirNode > 0) {
6588 0 : HumRatExt = state.dataLoopNodes->Node(state.dataHeatBal->Zone(NZ).LinkedOutAirNode).HumRat;
6589 : } else {
6590 0 : HumRatExt = state.dataEnvrn->OutHumRat;
6591 : }
6592 0 : Real64 AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(
6593 0 : state, state.dataEnvrn->OutBaroPress, state.dataHeatBal->Zone(NZ).OutDryBulbTemp, HumRatExt, RoutineNameZoneAirBalance);
6594 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(HumRatExt);
6595 0 : thisZoneAirBalance.ERVMassFlowRate *= AirDensity;
6596 0 : thisZoneHB.MDotOA =
6597 0 : std::sqrt(pow_2(thisZoneAirBalance.NatMassFlowRate) + pow_2(thisZoneAirBalance.IntMassFlowRate) +
6598 0 : pow_2(thisZoneAirBalance.ExhMassFlowRate) + pow_2(thisZoneAirBalance.ERVMassFlowRate) +
6599 0 : pow_2(thisZoneAirBalance.InfMassFlowRate) +
6600 0 : pow_2(AirDensity * thisZoneAirBalance.InducedAirRate * thisZoneAirBalance.inducedAirSched->getCurrentVal())) +
6601 0 : thisZoneAirBalance.BalMassFlowRate;
6602 0 : thisZoneHB.MDotCPOA = thisZoneHB.MDotOA * CpAir;
6603 : }
6604 : }
6605 : }
6606 :
6607 0 : void GetStandAloneERVNodes(EnergyPlusData &state, DataHeatBalance::ZoneAirBalanceData &thisZoneAirBalance)
6608 : {
6609 :
6610 : // SUBROUTINE INFORMATION:
6611 : // AUTHOR Lixing Gu
6612 : // DATE WRITTEN July 2010
6613 :
6614 : // PURPOSE OF THIS SUBROUTINE:
6615 : // This subroutine gets node numbers of stand alone ERVs to calculate combined outdoor air flows.
6616 :
6617 : // METHODOLOGY EMPLOYED:
6618 : // Uses program data structures ZoneEquipInfo
6619 :
6620 0 : if (allocated(state.dataZoneEquip->ZoneEquipList)) {
6621 0 : int ZoneNum = thisZoneAirBalance.ZonePtr;
6622 0 : thisZoneAirBalance.OneTimeFlag = true;
6623 0 : if (state.dataZoneEquip->ZoneEquipList(ZoneNum).NumOfEquipTypes > 0) {
6624 0 : for (int I = 1; I <= state.dataZoneEquip->ZoneEquipList(ZoneNum).NumOfEquipTypes; ++I) {
6625 0 : if (state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipType(I) == DataZoneEquipment::ZoneEquipType::EnergyRecoveryVentilator) {
6626 0 : ++thisZoneAirBalance.NumOfERVs;
6627 : }
6628 : }
6629 0 : if (thisZoneAirBalance.NumOfERVs > 0) {
6630 0 : thisZoneAirBalance.ERVInletNode.allocate(thisZoneAirBalance.NumOfERVs);
6631 0 : thisZoneAirBalance.ERVExhaustNode.allocate(thisZoneAirBalance.NumOfERVs);
6632 0 : int j = 1;
6633 0 : for (int I = 1; I <= state.dataZoneEquip->ZoneEquipList(ZoneNum).NumOfEquipTypes; ++I) {
6634 0 : if (state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipType(I) == DataZoneEquipment::ZoneEquipType::EnergyRecoveryVentilator) {
6635 0 : thisZoneAirBalance.ERVInletNode(j) =
6636 0 : HVACStandAloneERV::GetStandAloneERVOutAirNode(state, state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipIndex(I));
6637 0 : thisZoneAirBalance.ERVExhaustNode(j) =
6638 0 : HVACStandAloneERV::GetStandAloneERVReturnAirNode(state, state.dataZoneEquip->ZoneEquipList(ZoneNum).EquipIndex(I));
6639 0 : ++j;
6640 : }
6641 : }
6642 : }
6643 : }
6644 : }
6645 0 : }
6646 :
6647 77 : void CalcZoneMixingFlowRateOfReceivingZone(EnergyPlusData &state, int const ZoneNum, Real64 &ZoneMixingMassFlowRate)
6648 : {
6649 :
6650 : // SUBROUTINE INFORMATION:
6651 : // AUTHOR Bereket Nigusse
6652 : // DATE WRITTEN February 2014
6653 :
6654 : // PURPOSE OF THIS SUBROUTINE:
6655 : // This subroutine updates the receiving zone mixing flow rate to ensures the zone air mass balance.
6656 :
6657 77 : auto &massConservation = state.dataHeatBal->MassConservation(ZoneNum);
6658 :
6659 77 : Real64 MixingMassFlowRate = 0.0; // current zone mixing mass flow rate, [kg/s]
6660 77 : int NumOfReceivingZoneMixingObjects = massConservation.NumReceivingZonesMixingObject;
6661 77 : if (NumOfReceivingZoneMixingObjects > 0) {
6662 : // distribute the total zone mixing flow rate to the source zones
6663 76 : for (int Loop = 1; Loop <= NumOfReceivingZoneMixingObjects; ++Loop) {
6664 38 : int MixingNum = massConservation.ZoneMixingReceivingPtr(Loop);
6665 38 : state.dataHeatBal->Mixing(MixingNum).MixingMassFlowRate = massConservation.ZoneMixingReceivingFr(Loop) * ZoneMixingMassFlowRate;
6666 38 : MixingMassFlowRate += state.dataHeatBal->Mixing(MixingNum).MixingMassFlowRate;
6667 38 : CalcZoneMixingFlowRateOfSourceZone(state, state.dataHeatBal->Mixing(MixingNum).FromZone);
6668 : }
6669 : }
6670 77 : massConservation.MixingMassFlowRate = MixingMassFlowRate;
6671 77 : ZoneMixingMassFlowRate = MixingMassFlowRate;
6672 77 : }
6673 :
6674 38 : void CalcZoneMixingFlowRateOfSourceZone(EnergyPlusData &state, int const ZoneNum)
6675 : {
6676 :
6677 : // SUBROUTINE INFORMATION:
6678 : // AUTHOR Bereket Nigusse
6679 : // DATE WRITTEN February 2014
6680 :
6681 : // PURPOSE OF THIS SUBROUTINE:
6682 : // This subroutine calculates the zone mixing flow rate such that it ensures the zone air mass balance.
6683 :
6684 38 : auto &massConservation = state.dataHeatBal->MassConservation(ZoneNum);
6685 :
6686 38 : Real64 ZoneSourceMassFlowRate = 0.0; // current zone as a source mass flow rate for zone mixing in other zones, [kg/s]
6687 38 : int NumOfSourceZoneMixingObjects = massConservation.NumSourceZonesMixingObject;
6688 38 : if (NumOfSourceZoneMixingObjects > 0) {
6689 76 : for (int ZoneMixingNum = 1; ZoneMixingNum <= NumOfSourceZoneMixingObjects; ++ZoneMixingNum) {
6690 38 : int MixingNum = massConservation.ZoneMixingSourcesPtr(ZoneMixingNum);
6691 80 : for (int Loop = 1; Loop <= state.dataHeatBal->TotMixing; ++Loop) {
6692 42 : if (Loop == MixingNum) {
6693 38 : ZoneSourceMassFlowRate += state.dataHeatBal->Mixing(Loop).MixingMassFlowRate;
6694 : }
6695 : }
6696 : }
6697 : }
6698 38 : massConservation.MixingSourceMassFlowRate = ZoneSourceMassFlowRate;
6699 38 : }
6700 :
6701 66 : void AutoCalcDOASControlStrategy(EnergyPlusData &state)
6702 : {
6703 : // SUBROUTINE INFORMATION:
6704 : // AUTHOR Fred Buhl
6705 : // DATE WRITTEN March 2016
6706 :
6707 : // PURPOSE OF THIS Function:
6708 : // This subroutine does the autosizing calculations for the Sizing:Zone DOAS input.
6709 :
6710 : // REFERENCES:
6711 : // See IO Ref for suggested values
6712 :
6713 66 : bool headerAlreadyPrinted = false;
6714 66 : bool ErrorsFound = false;
6715 164 : for (int ZoneSizIndex = 1; ZoneSizIndex <= state.dataSize->NumZoneSizingInput; ++ZoneSizIndex) {
6716 98 : if (state.dataSize->ZoneSizingInput(ZoneSizIndex).AccountForDOAS) {
6717 20 : auto &zoneSizingInput = state.dataSize->ZoneSizingInput(ZoneSizIndex);
6718 20 : if (zoneSizingInput.DOASControlStrategy == DOASControl::NeutralSup) {
6719 7 : if (zoneSizingInput.DOASLowSetpoint == AutoSize && zoneSizingInput.DOASHighSetpoint == AutoSize) {
6720 4 : zoneSizingInput.DOASLowSetpoint = 21.1;
6721 4 : zoneSizingInput.DOASHighSetpoint = 23.9;
6722 3 : } else if (zoneSizingInput.DOASLowSetpoint == AutoSize && zoneSizingInput.DOASHighSetpoint > 0.0) {
6723 1 : zoneSizingInput.DOASLowSetpoint = zoneSizingInput.DOASHighSetpoint - 2.8;
6724 2 : } else if (zoneSizingInput.DOASLowSetpoint > 0.0 && zoneSizingInput.DOASHighSetpoint == AutoSize) {
6725 1 : zoneSizingInput.DOASHighSetpoint = zoneSizingInput.DOASLowSetpoint + 2.8;
6726 : }
6727 28 : ReportZoneSizingDOASInputs(state,
6728 7 : zoneSizingInput.ZoneName,
6729 : "NeutralSupplyAir",
6730 : zoneSizingInput.DOASLowSetpoint,
6731 : zoneSizingInput.DOASHighSetpoint,
6732 : headerAlreadyPrinted);
6733 13 : } else if (zoneSizingInput.DOASControlStrategy == DataSizing::DOASControl::NeutralDehumSup) {
6734 4 : if (zoneSizingInput.DOASLowSetpoint == AutoSize && zoneSizingInput.DOASHighSetpoint == AutoSize) {
6735 1 : zoneSizingInput.DOASLowSetpoint = 14.4;
6736 1 : zoneSizingInput.DOASHighSetpoint = 22.2;
6737 3 : } else if (zoneSizingInput.DOASLowSetpoint == AutoSize && zoneSizingInput.DOASHighSetpoint > 0.0) {
6738 1 : zoneSizingInput.DOASLowSetpoint = 14.4;
6739 2 : } else if (zoneSizingInput.DOASLowSetpoint > 0.0 && zoneSizingInput.DOASHighSetpoint == AutoSize) {
6740 1 : zoneSizingInput.DOASHighSetpoint = 22.2;
6741 : }
6742 16 : ReportZoneSizingDOASInputs(state,
6743 4 : zoneSizingInput.ZoneName,
6744 : "NeutralDehumidifiedSupplyAir",
6745 : zoneSizingInput.DOASLowSetpoint,
6746 : zoneSizingInput.DOASHighSetpoint,
6747 : headerAlreadyPrinted);
6748 9 : } else if (zoneSizingInput.DOASControlStrategy == DOASControl::CoolSup) {
6749 9 : if (zoneSizingInput.DOASLowSetpoint == AutoSize && zoneSizingInput.DOASHighSetpoint == AutoSize) {
6750 1 : zoneSizingInput.DOASLowSetpoint = 12.2;
6751 1 : zoneSizingInput.DOASHighSetpoint = 14.4;
6752 8 : } else if (zoneSizingInput.DOASLowSetpoint == AutoSize && zoneSizingInput.DOASHighSetpoint > 0.0) {
6753 1 : zoneSizingInput.DOASLowSetpoint = zoneSizingInput.DOASHighSetpoint - 2.2;
6754 7 : } else if (zoneSizingInput.DOASLowSetpoint > 0.0 && zoneSizingInput.DOASHighSetpoint == AutoSize) {
6755 1 : zoneSizingInput.DOASHighSetpoint = zoneSizingInput.DOASLowSetpoint + 2.2;
6756 : }
6757 36 : ReportZoneSizingDOASInputs(state,
6758 9 : zoneSizingInput.ZoneName,
6759 : "ColdSupplyAir",
6760 : zoneSizingInput.DOASLowSetpoint,
6761 : zoneSizingInput.DOASHighSetpoint,
6762 : headerAlreadyPrinted);
6763 : }
6764 20 : if (zoneSizingInput.DOASLowSetpoint > zoneSizingInput.DOASHighSetpoint) {
6765 0 : ShowSevereError(state, format("For Sizing:Zone = {}", zoneSizingInput.ZoneName));
6766 0 : ShowContinueError(state, "... Dedicated Outside Air Low Setpoint for Design must be less than the High Setpoint");
6767 0 : ErrorsFound = true;
6768 : }
6769 : }
6770 : }
6771 66 : if (ErrorsFound) {
6772 0 : ShowFatalError(state, "Errors found in DOAS sizing input. Program terminates.");
6773 : }
6774 66 : }
6775 :
6776 20 : void ReportZoneSizingDOASInputs(EnergyPlusData &state,
6777 : std::string const &ZoneName, // the name of the zone
6778 : std::string const &DOASCtrlStrategy, // DOAS control strategy
6779 : Real64 const DOASLowTemp, // DOAS design low setpoint temperature [C]
6780 : Real64 const DOASHighTemp, // DOAS design high setpoint temperature [C]
6781 : bool &headerAlreadyPrinted)
6782 : {
6783 :
6784 : // SUBROUTINE INFORMATION:
6785 : // AUTHOR Fred Buhl
6786 : // DATE WRITTEN March 2016
6787 :
6788 : // PURPOSE OF THIS SUBROUTINE:
6789 : // This subroutine writes the DOAS Sizing:Zone input for 1 zone to the eio file
6790 :
6791 : // Formats
6792 : static constexpr std::string_view Format_990(
6793 : "! <Zone Sizing DOAS Inputs>, Zone Name, DOAS Design Control Strategy, DOAS Design Low Setpoint Temperature "
6794 : "{C}, DOAS Design High Setpoint Temperature {C} ");
6795 :
6796 20 : if (!headerAlreadyPrinted) {
6797 16 : print(state.files.eio, "{}\n", Format_990);
6798 16 : headerAlreadyPrinted = true;
6799 : }
6800 :
6801 : static constexpr std::string_view Format_991(" Zone Sizing DOAS Inputs, {}, {}, {:.3R}, {:.3R}\n");
6802 20 : print(state.files.eio, Format_991, ZoneName, DOASCtrlStrategy, DOASLowTemp, DOASHighTemp);
6803 :
6804 : // BSLLC Start
6805 : // if ( sqlite ) {
6806 : // state.dataSQLiteProcedures->sqlite->addSQLiteZoneSizingRecord( ZoneName, LoadType, CalcDesLoad, UserDesLoad, CalcDesFlow,
6807 : // UserDesFlow, DesDayName, PeakHrMin,
6808 : // PeakTemp, PeakHumRat, MinOAVolFlow, DOASHeatAddRate );
6809 : // }
6810 : // BSLLC Finish
6811 20 : }
6812 :
6813 : } // namespace EnergyPlus::ZoneEquipmentManager
|