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