Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, 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 <memory>
52 :
53 : // ObjexxFCL Headers
54 : #include <ObjexxFCL/Array.functions.hh>
55 : #include <ObjexxFCL/Array1D.hh>
56 : #include <ObjexxFCL/Fmath.hh>
57 : #include <ObjexxFCL/string.functions.hh>
58 :
59 : // EnergyPlus Headers
60 : #include <AirflowNetwork/Solver.hpp>
61 : #include <EnergyPlus/AirLoopHVACDOAS.hh>
62 : #include <EnergyPlus/Autosizing/Base.hh>
63 : #include <EnergyPlus/BranchInputManager.hh>
64 : #include <EnergyPlus/Data/EnergyPlusData.hh>
65 : #include <EnergyPlus/DataAirLoop.hh>
66 : #include <EnergyPlus/DataAirSystems.hh>
67 : #include <EnergyPlus/DataContaminantBalance.hh>
68 : #include <EnergyPlus/DataConvergParams.hh>
69 : #include <EnergyPlus/DataDefineEquip.hh>
70 : #include <EnergyPlus/DataEnvironment.hh>
71 : #include <EnergyPlus/DataGlobalConstants.hh>
72 : #include <EnergyPlus/DataHVACGlobals.hh>
73 : #include <EnergyPlus/DataHeatBalance.hh>
74 : #include <EnergyPlus/DataLoopNode.hh>
75 : #include <EnergyPlus/DataPrecisionGlobals.hh>
76 : #include <EnergyPlus/DataSizing.hh>
77 : #include <EnergyPlus/DataSystemVariables.hh>
78 : #include <EnergyPlus/DataZoneEquipment.hh>
79 : #include <EnergyPlus/DesiccantDehumidifiers.hh>
80 : #include <EnergyPlus/EMSManager.hh>
81 : #include <EnergyPlus/EvaporativeCoolers.hh>
82 : #include <EnergyPlus/Fans.hh>
83 : #include <EnergyPlus/Furnaces.hh>
84 : #include <EnergyPlus/General.hh>
85 : #include <EnergyPlus/GeneralRoutines.hh>
86 : #include <EnergyPlus/HVACControllers.hh>
87 : #include <EnergyPlus/HVACDXHeatPumpSystem.hh>
88 : #include <EnergyPlus/HVACDuct.hh>
89 : #include <EnergyPlus/HVACFan.hh>
90 : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
91 : #include <EnergyPlus/HVACInterfaceManager.hh>
92 : #include <EnergyPlus/HVACMultiSpeedHeatPump.hh>
93 : #include <EnergyPlus/HVACUnitaryBypassVAV.hh>
94 : #include <EnergyPlus/HVACVariableRefrigerantFlow.hh>
95 : #include <EnergyPlus/HeatRecovery.hh>
96 : #include <EnergyPlus/HeatingCoils.hh>
97 : #include <EnergyPlus/Humidifiers.hh>
98 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
99 : #include <EnergyPlus/MixedAir.hh>
100 : #include <EnergyPlus/MixerComponent.hh>
101 : #include <EnergyPlus/NodeInputManager.hh>
102 : #include <EnergyPlus/OutAirNodeManager.hh>
103 : #include <EnergyPlus/OutputProcessor.hh>
104 : #include <EnergyPlus/OutputReportPredefined.hh>
105 : #include <EnergyPlus/Psychrometrics.hh>
106 : #include <EnergyPlus/SimAirServingZones.hh>
107 : #include <EnergyPlus/SizingManager.hh>
108 : #include <EnergyPlus/SplitterComponent.hh>
109 : #include <EnergyPlus/SteamCoils.hh>
110 : #include <EnergyPlus/SystemAvailabilityManager.hh>
111 : #include <EnergyPlus/UnitarySystem.hh>
112 : #include <EnergyPlus/UserDefinedComponents.hh>
113 : #include <EnergyPlus/UtilityRoutines.hh>
114 : #include <EnergyPlus/WaterCoils.hh>
115 : #include <EnergyPlus/ZonePlenum.hh>
116 :
117 : namespace EnergyPlus::SimAirServingZones {
118 :
119 : // MODULE INFORMATION
120 : // AUTHOR: Russ Taylor, Dan Fisher, Fred Buhl
121 : // DATE WRITTEN: Oct 1997
122 : // MODIFIED: Dec 1997 Fred Buhl; Richard Liesen Apr 1998,
123 : // Dec 1999 Fred Buhl
124 : // 22Aug2010 Craig Wray - added Fan:ComponentModel
125 : // RE-ENGINEERED: This is new code, not reengineered
126 :
127 : // PURPOSE OF THIS MODULE:
128 : // Contains the data and code for simulating the HVAC forced
129 : // air systems.
130 :
131 : // METHODOLOGY EMPLOYED:
132 : // Successive iteration forward from the return air inlet
133 : // to the supply air outlets.
134 :
135 : using namespace DataLoopNode;
136 : using namespace DataAirLoop;
137 : using namespace DataHVACGlobals;
138 : using namespace DataSizing;
139 : using namespace DataZoneEquipment;
140 : using namespace DataAirSystems;
141 :
142 6484926 : void ManageAirLoops(EnergyPlusData &state,
143 : bool const FirstHVACIteration, // TRUE if first full HVAC iteration in an HVAC timestep
144 : bool &SimAir, // TRUE means air loops must be (re)simulated
145 : bool &SimZoneEquipment // TRUE means zone equipment must be (re) simulated
146 : )
147 : {
148 :
149 : // SUBROUTINE INFORMATION
150 : // AUTHOR: Russ Taylor, Dan Fisher, Fred Buhl
151 : // DATE WRITTEN: Oct 1997
152 : // MODIFIED: Dec 1997 Fred Buhl
153 : // RE-ENGINEERED: This is new code, not reengineered
154 :
155 : // PURPOSE OF THIS SUBROUTINE:
156 : // This is the manager subroutine for the air loop simulation.
157 : // Called from SimSelectedEquipment, which is called from SimHVAC,
158 : // which is called from ManageHVAC, the top level system/plant driver.
159 : // The subroutine performs the usual manager functions: it calls the
160 : // Get, Init, Sim, Update, and Report routines.
161 :
162 6484926 : auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo);
163 :
164 : using MixedAir::ManageOutsideAirSystem;
165 :
166 6484926 : if (state.dataSimAirServingZones->GetAirLoopInputFlag) { // First time subroutine has been entered
167 770 : GetAirPathData(state); // Get air loop descriptions from input file
168 770 : state.dataSimAirServingZones->GetAirLoopInputFlag = false;
169 : }
170 :
171 : // Initialize air loop related parameters
172 6484926 : InitAirLoops(state, FirstHVACIteration);
173 :
174 : // Call the AirLoop Simulation
175 6484925 : if (state.dataGlobal->SysSizingCalc) {
176 329 : SizeAirLoops(state);
177 6484596 : } else if (!state.dataGlobal->SysSizingCalc) {
178 6484596 : SimAirLoops(state, FirstHVACIteration, SimZoneEquipment);
179 : }
180 :
181 : // This flag could be used to resimulate only the air loops that needed additional iterations.
182 : // This flag would have to be moved inside SimAirLoops to gain this flexibility.
183 6484925 : SimAir = std::any_of(
184 24972786 : AirLoopControlInfo.begin(), AirLoopControlInfo.end(), [](DataAirLoop::AirLoopControlData const &e) { return e.ResimAirLoopFlag; });
185 6484925 : }
186 :
187 : // Get Input Section of the Module
188 : //******************************************************************************
189 :
190 770 : void GetAirPathData(EnergyPlusData &state)
191 : {
192 :
193 : // SUBROUTINE INFORMATION
194 : // AUTHOR: Fred Buhl
195 : // DATE WRITTEN: Jan 1998
196 : // MODIFIED: Richard Liesen April 1998, Fred Buhl Dec 1999
197 : // RE-ENGINEERED: This is new code, not reengineered
198 :
199 : // PURPOSE OF THIS SUBROUTINE:
200 : // Input all the data needed to simulate the air loops in the problem.
201 :
202 : // METHODOLOGY EMPLOYED:
203 : // Use the various "Get" routines from the InputProcessor module to
204 : // obtain input data and store it in the data structures defined in MODULE SimAirServingZones
205 :
206 : // REFERENCES: This gets the following object:
207 : // AirLoopHVAC,
208 : // \min-fields 10
209 : // \memo Defines a central forced air system
210 : // A1, \field Name
211 : // \required-field
212 : // \type alpha
213 : // \reference AirPrimaryLoops
214 : // A2, \field Controller List Name
215 : // \note Enter the name of an AirLoopHVAC:ControllerList object.
216 : // \type object-list
217 : // \object-list ControllerLists
218 : // A3, \field Availability Manager List Name
219 : // \note Enter the name of an AvailabilityManagerAssignmentList object.
220 : // \type object-list
221 : // \object-list SystemAvailabilityManagerLists
222 : // N1, \field Design Primary Air Flow Rate
223 : // \default 0
224 : // \units m3/s
225 : // \autosizable
226 : // A4, \field BranchList Name
227 : // \note Name of a BranchList containing all the branches in this air loop
228 : // \required-field
229 : // \type object-list
230 : // \object-list BranchLists
231 : // A5, \field ConnectorList Name
232 : // \note Name of a Connector List containing all the splitters and mixers in the loop
233 : // \type object-list
234 : // \object-list ConnectorLists
235 : // A6, \field Supply Side Inlet Node Name
236 : // \note Name of inlet node where return air enters the supply side of the air loop
237 : // \required-field
238 : // A7, \field Demand Side Outlet Node Name
239 : // \note Name of outlet node where return air leaves the demand side and enters the supply side.
240 : // \required-field
241 : // A8, \field Demand Side Inlet Node Names
242 : // \note Name of a Node or NodeList containing the inlet node(s) supplying air to zone equipment.
243 : // \required-field
244 : // A9; \field Supply Side Outlet Node Names
245 : // \note Name of a Node or NodeList containing the outlet node(s) supplying air to the demand side.
246 : // \required-field
247 :
248 : // Using/Aliasing
249 : using BranchInputManager::GetBranchData;
250 : using BranchInputManager::GetBranchList;
251 : using BranchInputManager::GetLoopMixer;
252 : using BranchInputManager::GetLoopSplitter;
253 : using BranchInputManager::GetNumSplitterMixerInConntrList;
254 : using BranchInputManager::NumBranchesInBranchList;
255 : using BranchInputManager::NumCompsInBranch;
256 : using HVACControllers::CheckCoilWaterInletNode;
257 : using HVACControllers::GetControllerActuatorNodeNum;
258 : using MixedAir::FindOAMixerMatchForOASystem;
259 : using MixedAir::GetNumOASystems;
260 : using MixedAir::GetOACompListNumber;
261 : using MixedAir::GetOACompName;
262 : using MixedAir::GetOACompType;
263 : using MixedAir::GetOACompTypeNum;
264 : using MixedAir::GetOAMixerInletNodeNumber;
265 : using MixedAir::GetOASysControllerListIndex;
266 : using MixedAir::GetOASysNumCoolingCoils;
267 : using MixedAir::GetOASysNumHeatingCoils;
268 : using MixedAir::GetOASysNumHXs;
269 : using MixedAir::GetOASysNumSimpControllers;
270 : using MixedAir::GetOASystemNumber;
271 : using NodeInputManager::GetNodeNums;
272 : using NodeInputManager::GetOnlySingleNode;
273 : using SystemAvailabilityManager::GetAirLoopAvailabilityManager;
274 : using WaterCoils::GetCoilWaterInletNode;
275 :
276 : // SUBROUTINE PARAMETER DEFINITIONS:
277 770 : constexpr const char *RoutineName("GetAirPathData: ");
278 :
279 770 : auto &OutsideAirSys(state.dataAirLoop->OutsideAirSys);
280 770 : auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo);
281 :
282 : // SUBROUTINE LOCAL VARIABLE DEFINITIONS
283 : int NumNumbers; // number of numbers returned by GetObjectItem
284 1294 : Array1D<Real64> Numbers; // numbers (REAL(r64)s) returned by GetObjectItem
285 1294 : Array1D_string cNumericFields; // Numeric field names
286 1294 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
287 : int NumAlphas; // number of strings returned by GetObjectItem
288 : int NumParams;
289 : int MaxNumbers;
290 : int MaxAlphas;
291 1294 : Array1D_string Alphas; // alpha strings returned by GetObjectItem
292 1294 : Array1D_string cAlphaFields; // Alpha field names
293 1294 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
294 1294 : std::string CurrentModuleObject; // Object type for getting and error messages
295 : int NumNodes; // number of nodes returned by GetNodeNums
296 1294 : Array1D_int NodeNums; // node numbers returned by GetNodeNums
297 : int NodeNum; // a node number
298 : int AirSysNum; // an air system (air loop) number
299 : int OANum; // outside air system index
300 : int NumInList;
301 : int OAMixNum; // outside air mixer index
302 : int IOStat; // status number returned by GetObjectItem
303 : int NumControllers; // number of controllers
304 : int ControllerListNum; // Controller List index
305 : int ControllerNum; // Controller index
306 : int I; // do loop index
307 : int BranchNum; // branch index
308 : int CompNum; // component index
309 : int NumCompsOnBranch; // Number of components on a branch
310 : int OutBranchNum; // outlet branch index
311 : int InBranchNum; // inlet branch index
312 1294 : std::string ControllerName; // controller name
313 1294 : std::string ControllerType; // controller type
314 1294 : std::string BranchListName; // Name of a Branch List object
315 1294 : std::string ControllerListName; // Name of a controller list object
316 1294 : std::string AvailManagerListName; // Name of an availability manager list object
317 1294 : std::string ConnectorListName; // Name of a connector list object
318 1294 : Array1D_string BranchNames; // Branch names from GetBranchList call
319 1294 : Array1D_string CompTypes; // Component types from GetBranchList call
320 1294 : Array1D_string CompNames; // Component names from GetBranchList call
321 1294 : Array1D_string InletNodeNames; // Component inlet node names from GetBranchData call
322 1294 : Array1D_string OutletNodeNames; // Component outlet node names from GetBranchData call
323 1294 : Array1D_string NodeNames; // Outlet node names from GetLoopSplitter call
324 1294 : Array1D_int NodeNumbers; // Outlet node numbers from GetLoopSplitter call
325 1294 : Array1D_int InletNodeNumbers; // Component inlet node numbers from GetBranchData call
326 1294 : Array1D_int OutletNodeNumbers; // Component outlet node numbers from GetBranchData call
327 : DataBranchAirLoopPlant::PressureCurveType PressCurveType;
328 : int PressCurveIndex;
329 770 : bool ErrorsFound(false); // TRUE if errors detected in input
330 1294 : Array1D_bool PackagedUnit;
331 : int test;
332 : int count;
333 : bool ErrInList;
334 770 : int ConListNum(0); // index of a Connector List object in the input
335 770 : bool SplitterExists(false); // TRUE if there is a slitter in a primary air system
336 770 : bool MixerExists(false); // TRUE if there is a mixer in a primary air system
337 : bool errFlag;
338 : bool IsNotOK;
339 : /////////// hoisted into namespace
340 : // static int TestUniqueNodesNum( 0 );
341 : ///////////////////////////
342 : int NumOASysSimpControllers; // number of simple controllers in the OA Sys of an air primary system
343 : int NumOASysControllers; // total number of controllers in the OA Sys
344 : int OASysContListNum; // index of the controller list of the OA Sys
345 : int OASysControllerNum; // index of OA Sys simple controller in the air primary system controller lists
346 : bool NodeNotFound; // true if matching actuator node not found
347 : CompType CompType_Num; // numeric equivalent for component type
348 1294 : std::string CompType; // component type
349 : int WaterCoilNodeNum; // numeric equivalent for water coil node number
350 : int ActuatorNodeNum; // numeric equivalent for controller actuator node number
351 1294 : Array1D_string MatchNodeName(3);
352 :
353 10186 : struct AirUniqueNodes
354 : {
355 : // Members
356 : std::string NodeName;
357 : std::string AirLoopName;
358 : std::string FieldName;
359 : bool NodeNameUsed;
360 :
361 : // Default Constructor
362 770 : AirUniqueNodes() : NodeNameUsed(false)
363 : {
364 770 : }
365 : };
366 :
367 : // Object Data
368 1294 : Array1D<AirUniqueNodes> TestUniqueNodes;
369 :
370 770 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "AirLoopHVAC", NumParams, MaxAlphas, MaxNumbers);
371 770 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "ConnectorList", NumParams, NumAlphas, NumNumbers);
372 770 : MaxAlphas = max(MaxAlphas, NumAlphas);
373 770 : MaxNumbers = max(MaxNumbers, NumNumbers);
374 770 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "AirLoopHVAC:ControllerList", NumParams, NumAlphas, NumNumbers);
375 770 : MaxAlphas = max(MaxAlphas, NumAlphas);
376 770 : MaxNumbers = max(MaxNumbers, NumNumbers);
377 :
378 770 : Numbers.allocate(MaxNumbers);
379 770 : cNumericFields.allocate(MaxNumbers);
380 770 : lNumericBlanks.allocate(MaxNumbers);
381 770 : Alphas.allocate(MaxAlphas);
382 770 : cAlphaFields.allocate(MaxAlphas);
383 770 : lAlphaBlanks.allocate(MaxAlphas);
384 :
385 : // Initialize some local arrays
386 770 : Numbers = 0.0;
387 770 : cNumericFields = "";
388 770 : lNumericBlanks = true;
389 770 : Alphas = "";
390 770 : cAlphaFields = "";
391 770 : lAlphaBlanks = true;
392 :
393 770 : state.dataSimAirServingZones->NumOfTimeStepInDay = state.dataGlobal->NumOfTimeStepInHour * 24;
394 :
395 770 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "NodeList", NumParams, NumAlphas, NumNumbers);
396 770 : NodeNums.dimension(NumParams, 0);
397 :
398 770 : auto &NumPrimaryAirSys = state.dataHVACGlobal->NumPrimaryAirSys;
399 :
400 : // Find number of primary air systems
401 770 : NumPrimaryAirSys = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC");
402 770 : TestUniqueNodes.allocate(NumPrimaryAirSys * 4); // used to look at specific nodes that must be unique, fields A6-A9
403 :
404 770 : state.dataAirSystemsData->PrimaryAirSystems.allocate(NumPrimaryAirSys); // allocate the primary air sys data array
405 770 : state.dataAirLoop->AirToZoneNodeInfo.allocate(NumPrimaryAirSys); // allocate the array that stores the air sys / zone equp connection data
406 770 : state.dataAirLoop->AirLoopZoneInfo.allocate(NumPrimaryAirSys); // allocate array that has cleaner list of zones attached to air loop
407 770 : state.dataAirLoop->AirToOANodeInfo.allocate(NumPrimaryAirSys); // allocate the array that stores the OA node connections (reporting)
408 770 : PackagedUnit.allocate(NumPrimaryAirSys);
409 770 : AirLoopControlInfo.allocate(NumPrimaryAirSys);
410 770 : state.dataAirLoop->AirLoopFlow.allocate(NumPrimaryAirSys);
411 770 : state.dataConvergeParams->AirLoopConvergence.allocate(NumPrimaryAirSys);
412 770 : state.dataSize->UnitarySysEqSizing.allocate(NumPrimaryAirSys);
413 770 : if (state.afn->distribution_simulated) {
414 23 : state.dataAirLoop->AirLoopAFNInfo.allocate(NumPrimaryAirSys);
415 : }
416 :
417 770 : state.dataHVACGlobal->GetAirPathDataDone = true; // used by UnitarySystem::getUnitarySystemInputData to determine if airloops are setup yet
418 770 : if (NumPrimaryAirSys <= 0) {
419 246 : TestUniqueNodes.deallocate();
420 246 : NodeNums.deallocate();
421 246 : return;
422 : }
423 :
424 : // Loop through the primary air systems and obtain the data for each system
425 1701 : for (AirSysNum = 1; AirSysNum <= NumPrimaryAirSys; ++AirSysNum) {
426 1177 : auto &primaryAirSystems = state.dataAirSystemsData->PrimaryAirSystems(AirSysNum);
427 1177 : auto &airLoopZoneInfo = state.dataAirLoop->AirToZoneNodeInfo(AirSysNum);
428 1177 : NumOASysControllers = 0;
429 1177 : NumOASysSimpControllers = 0;
430 1177 : OASysContListNum = 0;
431 1177 : PackagedUnit(AirSysNum) = false;
432 1177 : primaryAirSystems.OASysExists = false; // init Outside Air system connection data to none
433 1177 : primaryAirSystems.isAllOA = false;
434 1177 : primaryAirSystems.OASysInletNodeNum = 0;
435 1177 : primaryAirSystems.OASysOutletNodeNum = 0;
436 1177 : primaryAirSystems.NumOAHeatCoils = 0;
437 1177 : primaryAirSystems.NumOACoolCoils = 0;
438 1177 : AirLoopControlInfo(AirSysNum).FanOpMode = DataHVACGlobals::ContFanCycCoil; // initialize to constant fan mode for all air loops
439 1177 : state.dataAirLoop->AirLoopFlow(AirSysNum).FanPLR = 1.0; // initialize to 1 for all air loops
440 :
441 1177 : CurrentModuleObject = "AirLoopHVAC";
442 :
443 1177 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
444 : CurrentModuleObject,
445 : AirSysNum,
446 : Alphas,
447 : NumAlphas,
448 : Numbers,
449 : NumNumbers,
450 : IOStat,
451 : lNumericBlanks,
452 : lAlphaBlanks,
453 : cAlphaFields,
454 : cNumericFields); // get all the input data for the air system
455 :
456 : // Assign the air system data to the simulation variables.
457 : // Data needed to simulate the system goes into PrimaryAirSystem.
458 : // Data connecting the air system to the zone equipment goes into AirToZoneNodeInfo (in DataLoopNode).
459 1177 : UtilityRoutines::IsNameEmpty(state, Alphas(1), CurrentModuleObject, ErrorsFound);
460 1177 : primaryAirSystems.Name = Alphas(1);
461 1177 : airLoopZoneInfo.AirLoopName = Alphas(1);
462 1177 : if (NumAlphas < 9) {
463 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", insufficient information.");
464 0 : ShowContinueError(state, "...Have supplied less than 9 alpha fields.");
465 0 : ErrorsFound = true;
466 0 : continue;
467 : }
468 1177 : if (NumNumbers < 1) {
469 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", insufficient information.");
470 0 : ShowContinueError(state, "...Have supplied less than 1 numeric field.");
471 0 : ErrorsFound = true;
472 0 : continue;
473 : }
474 1177 : primaryAirSystems.DesignVolFlowRate = Numbers(1);
475 1177 : if (!lNumericBlanks(2)) {
476 1 : primaryAirSystems.DesignReturnFlowFraction = Numbers(2);
477 : }
478 : // Only allow one return air node (at the loop level)
479 1177 : airLoopZoneInfo.NumReturnNodes = 1;
480 : // Allocate the return air node arrays
481 1177 : airLoopZoneInfo.AirLoopReturnNodeNum.allocate(airLoopZoneInfo.NumReturnNodes);
482 1177 : airLoopZoneInfo.ZoneEquipReturnNodeNum.allocate(airLoopZoneInfo.NumReturnNodes);
483 : // fill the return air node arrays with node numbers
484 1177 : airLoopZoneInfo.AirLoopReturnNodeNum(1) = GetOnlySingleNode(state,
485 1177 : Alphas(6),
486 : ErrorsFound,
487 : DataLoopNode::ConnectionObjectType::AirLoopHVAC,
488 1177 : Alphas(1),
489 : DataLoopNode::NodeFluidType::Air,
490 : DataLoopNode::ConnectionType::Inlet,
491 : NodeInputManager::CompFluidStream::Primary,
492 1177 : ObjectIsParent);
493 1177 : if (!lAlphaBlanks(7)) {
494 1173 : airLoopZoneInfo.ZoneEquipReturnNodeNum(1) = GetOnlySingleNode(state,
495 1173 : Alphas(7),
496 : ErrorsFound,
497 : DataLoopNode::ConnectionObjectType::AirLoopHVAC,
498 1173 : Alphas(1),
499 : DataLoopNode::NodeFluidType::Air,
500 : DataLoopNode::ConnectionType::Outlet,
501 : NodeInputManager::CompFluidStream::Primary,
502 1173 : ObjectIsParent);
503 : } else {
504 : // If no return path, set this to zero to trigger special handling when calling UpdateHVACInterface
505 4 : airLoopZoneInfo.ZoneEquipReturnNodeNum(1) = 0;
506 : }
507 :
508 : // work on unique nodes
509 1177 : test =
510 1177 : UtilityRoutines::FindItemInList(Alphas(6), TestUniqueNodes, &AirUniqueNodes::NodeName, state.dataSimAirServingZones->TestUniqueNodesNum);
511 1177 : if (test == 0) {
512 1177 : ++state.dataSimAirServingZones->TestUniqueNodesNum;
513 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).NodeName = Alphas(6);
514 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).AirLoopName = Alphas(1);
515 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).FieldName = cAlphaFields(6);
516 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).NodeNameUsed = true;
517 : } else {
518 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", duplicate node name.");
519 0 : ShowContinueError(state, "...used for " + cAlphaFields(6) + "=\"" + Alphas(6) + "\"");
520 0 : ShowContinueError(state,
521 0 : "...first used in " + CurrentModuleObject + "=\"" + TestUniqueNodes(test).AirLoopName + "\" for " +
522 0 : TestUniqueNodes(test).FieldName);
523 0 : ErrorsFound = true;
524 : }
525 1177 : if (!lAlphaBlanks(7)) {
526 2346 : test = UtilityRoutines::FindItemInList(
527 2346 : Alphas(7), TestUniqueNodes, &AirUniqueNodes::NodeName, state.dataSimAirServingZones->TestUniqueNodesNum);
528 1173 : if (test == 0) {
529 1173 : ++state.dataSimAirServingZones->TestUniqueNodesNum;
530 1173 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).NodeName = Alphas(7);
531 1173 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).AirLoopName = Alphas(1);
532 1173 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).FieldName = cAlphaFields(7);
533 1173 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).NodeNameUsed = true;
534 : } else {
535 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", duplicate node name.");
536 0 : ShowContinueError(state, "...used for " + cAlphaFields(7) + "=\"" + Alphas(7) + "\"");
537 0 : ShowContinueError(state,
538 0 : "...first used in " + CurrentModuleObject + "=\"" + TestUniqueNodes(test).AirLoopName + "\" for " +
539 0 : TestUniqueNodes(test).FieldName);
540 0 : ErrorsFound = true;
541 : }
542 : }
543 1177 : test =
544 1177 : UtilityRoutines::FindItemInList(Alphas(8), TestUniqueNodes, &AirUniqueNodes::NodeName, state.dataSimAirServingZones->TestUniqueNodesNum);
545 1177 : if (test == 0) {
546 1177 : ++state.dataSimAirServingZones->TestUniqueNodesNum;
547 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).NodeName = Alphas(8);
548 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).AirLoopName = Alphas(1);
549 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).FieldName = cAlphaFields(8);
550 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).NodeNameUsed = true;
551 : } else {
552 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", duplicate node name/list.");
553 0 : ShowContinueError(state, "...used for " + cAlphaFields(8) + "=\"" + Alphas(8) + "\"");
554 0 : ShowContinueError(state,
555 0 : "...first used in " + CurrentModuleObject + "=\"" + TestUniqueNodes(test).AirLoopName + "\" for " +
556 0 : TestUniqueNodes(test).FieldName);
557 0 : ErrorsFound = true;
558 : }
559 1177 : test =
560 1177 : UtilityRoutines::FindItemInList(Alphas(9), TestUniqueNodes, &AirUniqueNodes::NodeName, state.dataSimAirServingZones->TestUniqueNodesNum);
561 1177 : if (test == 0) {
562 1177 : ++state.dataSimAirServingZones->TestUniqueNodesNum;
563 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).NodeName = Alphas(9);
564 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).AirLoopName = Alphas(1);
565 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).FieldName = cAlphaFields(9);
566 1177 : TestUniqueNodes(state.dataSimAirServingZones->TestUniqueNodesNum).NodeNameUsed = true;
567 : } else {
568 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", duplicate node name/list.");
569 0 : ShowContinueError(state, "...used for " + cAlphaFields(9) + "=\"" + Alphas(9) + "\"");
570 0 : ShowContinueError(state,
571 0 : "...first used in " + CurrentModuleObject + "=\"" + TestUniqueNodes(test).AirLoopName + "\" for " +
572 0 : TestUniqueNodes(test).FieldName);
573 0 : ErrorsFound = true;
574 : }
575 : // this test depends on the controlled zone input having been "gotten"
576 1177 : test = 0;
577 6469 : for (count = 1; count <= state.dataZoneEquip->NumReturnAirPaths; ++count) {
578 6456 : if (state.dataZoneEquip->ReturnAirPath(count).OutletNodeNum == airLoopZoneInfo.ZoneEquipReturnNodeNum(1)) {
579 1164 : test = state.dataZoneEquip->ReturnAirPath(count).OutletNodeNum;
580 1164 : break;
581 : }
582 : }
583 1177 : if ((test == 0) && (airLoopZoneInfo.NumReturnNodes > 0)) { // there, see if it's in the controlled zone info
584 53 : for (count = 1; count <= state.dataGlobal->NumOfZones; ++count) {
585 85 : for (int retNode = 1; retNode <= state.dataZoneEquip->ZoneEquipConfig(count).NumReturnNodes; ++retNode) {
586 45 : if (state.dataZoneEquip->ZoneEquipConfig(count).ReturnNode(retNode) != airLoopZoneInfo.ZoneEquipReturnNodeNum(1)) continue;
587 9 : test = count;
588 9 : break;
589 : }
590 49 : if (test == count) break;
591 : }
592 : }
593 1177 : if ((test == 0) && (airLoopZoneInfo.NumReturnNodes > 0) && !lAlphaBlanks(7)) {
594 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", invalid.");
595 0 : ShowContinueError(state, cAlphaFields(7) + " (Return Air Path or ZoneHVAC:EquipmentConnections) not valid = \"" + Alphas(7) + "\".");
596 0 : ErrorsFound = true;
597 : }
598 : // Get the supply nodes
599 1177 : ErrInList = false;
600 2354 : GetNodeNums(state,
601 1177 : Alphas(8),
602 : NumNodes,
603 : NodeNums,
604 : ErrInList,
605 : DataLoopNode::NodeFluidType::Air,
606 : DataLoopNode::ConnectionObjectType::AirLoopHVAC,
607 : primaryAirSystems.Name,
608 : DataLoopNode::ConnectionType::Inlet,
609 : NodeInputManager::CompFluidStream::Primary,
610 : ObjectIsParent,
611 : false,
612 1177 : cAlphaFields(8));
613 1177 : if (ErrInList) {
614 0 : ErrorsFound = true;
615 : }
616 : // Allow at most 3 supply nodes (for a 3 deck system)
617 1177 : if (NumNodes > 3) {
618 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name + "\", too many nodes.");
619 0 : ShowContinueError(state, "Only 1st 3 Nodes will be used from " + cAlphaFields(8) + "=\"" + Alphas(8) + "\".");
620 0 : ErrorsFound = true;
621 : }
622 1177 : if (NumNodes == 0) {
623 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name + "\", too few nodes.");
624 0 : ShowContinueError(state, "There must be at least 1 supply node in the system.");
625 0 : ErrorsFound = true;
626 : }
627 1177 : airLoopZoneInfo.NumSupplyNodes = NumNodes;
628 : // Allocate the supply node arrays in AirToZoneNodeInfo
629 1177 : airLoopZoneInfo.ZoneEquipSupplyNodeNum.allocate(airLoopZoneInfo.NumSupplyNodes);
630 1177 : airLoopZoneInfo.AirLoopSupplyNodeNum.allocate(airLoopZoneInfo.NumSupplyNodes);
631 1177 : airLoopZoneInfo.SupplyDuctType.allocate(airLoopZoneInfo.NumSupplyNodes);
632 : // Fill the supply node arrays with node numbers
633 2362 : for (I = 1; I <= airLoopZoneInfo.NumSupplyNodes; ++I) {
634 1185 : airLoopZoneInfo.ZoneEquipSupplyNodeNum(I) = NodeNums(I);
635 1185 : airLoopZoneInfo.SupplyDuctType(I) = DataHVACGlobals::AirDuctType::Invalid;
636 : }
637 1177 : ErrInList = false;
638 2354 : GetNodeNums(state,
639 1177 : Alphas(9),
640 : NumNodes,
641 : NodeNums,
642 : ErrInList,
643 : DataLoopNode::NodeFluidType::Air,
644 : DataLoopNode::ConnectionObjectType::AirLoopHVAC,
645 : primaryAirSystems.Name,
646 : DataLoopNode::ConnectionType::Outlet,
647 : NodeInputManager::CompFluidStream::Primary,
648 : ObjectIsParent,
649 : false,
650 1177 : cAlphaFields(9));
651 1177 : if (ErrInList) {
652 0 : ErrorsFound = true;
653 : }
654 1177 : if (NumNodes != airLoopZoneInfo.NumSupplyNodes) {
655 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", node mismatch.");
656 0 : ShowContinueError(state,
657 0 : format("...number of air system exit nodes [{}] must match number of zone equip inlet nodes [{}].",
658 : NumNodes,
659 0 : airLoopZoneInfo.NumSupplyNodes));
660 0 : ErrorsFound = true;
661 : }
662 2362 : for (I = 1; I <= airLoopZoneInfo.NumSupplyNodes; ++I) {
663 1185 : airLoopZoneInfo.AirLoopSupplyNodeNum(I) = NodeNums(I);
664 : }
665 1177 : airLoopZoneInfo.NumZonesCooled = 0;
666 1177 : airLoopZoneInfo.NumZonesHeated = 0;
667 : // Branch, Controller, Availability Manager and Connector List Names to access later
668 1177 : ControllerListName = Alphas(2);
669 1177 : BranchListName = Alphas(4);
670 1177 : AvailManagerListName = Alphas(3);
671 1177 : ConnectorListName = Alphas(5);
672 1177 : primaryAirSystems.NumBranches = NumBranchesInBranchList(state, BranchListName);
673 1177 : if (primaryAirSystems.NumBranches == 0) {
674 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name + "\", insufficient information.");
675 0 : ShowContinueError(state, "...there must be at least 1 branch specified.");
676 0 : ErrorsFound = true;
677 : }
678 1177 : BranchNames.allocate(primaryAirSystems.NumBranches);
679 1177 : BranchNames = "";
680 : // get the branch lists
681 1177 : GetBranchList(state, primaryAirSystems.Name, BranchListName, primaryAirSystems.NumBranches, BranchNames, "Air");
682 1177 : primaryAirSystems.Branch.allocate(primaryAirSystems.NumBranches);
683 : // Cycle through all of the branches and set up the branch data
684 2373 : for (BranchNum = 1; BranchNum <= primaryAirSystems.NumBranches; ++BranchNum) {
685 1196 : primaryAirSystems.Branch(BranchNum).Name = BranchNames(BranchNum);
686 1196 : NumCompsOnBranch = NumCompsInBranch(state, BranchNames(BranchNum));
687 1196 : if (NumCompsOnBranch <= 0) {
688 0 : ShowSevereError(state,
689 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name + "\", insufficient information.");
690 0 : ShowContinueError(state, "...Branch=\"" + BranchNames(BranchNum) + "\", no components on branch.");
691 0 : ErrorsFound = true;
692 0 : continue;
693 : }
694 1196 : CompTypes.allocate(NumCompsOnBranch);
695 1196 : CompNames.allocate(NumCompsOnBranch);
696 1196 : InletNodeNames.allocate(NumCompsOnBranch);
697 1196 : InletNodeNumbers.dimension(NumCompsOnBranch, 0);
698 1196 : OutletNodeNames.allocate(NumCompsOnBranch);
699 1196 : OutletNodeNumbers.dimension(NumCompsOnBranch, 0);
700 :
701 1196 : GetBranchData(state,
702 : primaryAirSystems.Name,
703 1196 : BranchNames(BranchNum),
704 : PressCurveType,
705 : PressCurveIndex,
706 : NumCompsOnBranch,
707 : CompTypes,
708 : CompNames,
709 : InletNodeNames,
710 : InletNodeNumbers,
711 : OutletNodeNames,
712 : OutletNodeNumbers,
713 : ErrorsFound); // Placeholders for plant branch pressure data (not used in air loops)
714 1196 : primaryAirSystems.Branch(BranchNum).Comp.allocate(NumCompsOnBranch);
715 1196 : primaryAirSystems.Branch(BranchNum).TotalComponents = NumCompsOnBranch;
716 :
717 1196 : primaryAirSystems.Branch(BranchNum).TotalNodes = NumCompsOnBranch + 1;
718 1196 : primaryAirSystems.Branch(BranchNum).NodeNum.allocate(NumCompsOnBranch + 1);
719 1196 : primaryAirSystems.Branch(BranchNum).NodeNum(1) = InletNodeNumbers(1);
720 1196 : primaryAirSystems.Branch(BranchNum).DuctType = DataHVACGlobals::AirDuctType::Main;
721 :
722 : // If first node is an outdoor air node, then consider this to have a simple OA system (many places check for this)
723 1196 : if (OutAirNodeManager::CheckOutAirNodeNumber(state, InletNodeNumbers(1))) {
724 4 : primaryAirSystems.OASysExists = true;
725 4 : primaryAirSystems.isAllOA = true;
726 4 : primaryAirSystems.OASysInletNodeNum = InletNodeNumbers(1);
727 4 : primaryAirSystems.OASysOutletNodeNum = InletNodeNumbers(1);
728 4 : primaryAirSystems.OAMixOAInNodeNum = InletNodeNumbers(1);
729 4 : state.dataAirLoop->AirToOANodeInfo(AirSysNum).OASysExists = true;
730 4 : state.dataAirLoop->AirToOANodeInfo(AirSysNum).OASysInletNodeNum = InletNodeNumbers(1);
731 4 : state.dataAirLoop->AirToOANodeInfo(AirSysNum).OASysOutletNodeNum = InletNodeNumbers(1);
732 : }
733 4822 : for (CompNum = 1; CompNum <= primaryAirSystems.Branch(BranchNum).TotalComponents; ++CompNum) {
734 :
735 3626 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).TypeOf = CompTypes(CompNum);
736 3626 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name = CompNames(CompNum);
737 3626 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompIndex = 0;
738 3626 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).NodeNameIn = InletNodeNames(CompNum);
739 3626 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).NodeNumIn = InletNodeNumbers(CompNum);
740 3626 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).NodeNameOut = OutletNodeNames(CompNum);
741 3626 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).NodeNumOut = OutletNodeNumbers(CompNum);
742 3626 : primaryAirSystems.Branch(BranchNum).NodeNum(CompNum + 1) = OutletNodeNumbers(CompNum);
743 :
744 : // Check for Outside Air system; if there, store its connection node numbers to primary air system
745 3626 : if (UtilityRoutines::SameString(CompTypes(CompNum), "AirLoopHVAC:OutdoorAirSystem")) {
746 1026 : if (primaryAirSystems.OASysExists) {
747 0 : ShowSevereError(state,
748 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name +
749 : "\", too many outdoor air systems.");
750 0 : ShowContinueError(state, "Only one AirLoopHVAC:OutdoorAirSystem allowed.");
751 0 : ErrorsFound = true;
752 0 : continue;
753 : }
754 1026 : primaryAirSystems.OASysExists = true;
755 1026 : primaryAirSystems.OASysInletNodeNum = InletNodeNumbers(CompNum);
756 1026 : primaryAirSystems.OASysOutletNodeNum = OutletNodeNumbers(CompNum);
757 1026 : state.dataAirLoop->AirToOANodeInfo(AirSysNum).OASysExists = true;
758 1026 : state.dataAirLoop->AirToOANodeInfo(AirSysNum).OASysInletNodeNum = InletNodeNumbers(CompNum);
759 1026 : state.dataAirLoop->AirToOANodeInfo(AirSysNum).OASysOutletNodeNum = OutletNodeNumbers(CompNum);
760 1026 : OANum = GetOASystemNumber(state, CompNames(CompNum));
761 1026 : if (OANum > 0) {
762 1026 : NumOASysSimpControllers = GetOASysNumSimpControllers(state, OANum);
763 1026 : primaryAirSystems.NumOAHeatCoils = GetOASysNumHeatingCoils(state, OANum);
764 1026 : primaryAirSystems.NumOACoolCoils = GetOASysNumCoolingCoils(state, OANum);
765 1026 : primaryAirSystems.NumOAHXs = GetOASysNumHXs(state, OANum);
766 1026 : OASysContListNum = GetOASysControllerListIndex(state, OANum);
767 1026 : OAMixNum = FindOAMixerMatchForOASystem(state, OANum);
768 1026 : if (OAMixNum > 0) {
769 1026 : primaryAirSystems.OAMixOAInNodeNum = GetOAMixerInletNodeNumber(state, OAMixNum);
770 : } else {
771 0 : ShowSevereError(state,
772 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name + "\", item not found.");
773 0 : ShowContinueError(state, "OutdoorAir:Mixer for AirLoopHVAC:OutdoorAirSystem=\"" + CompNames(CompNum) + "\" not found.");
774 0 : ErrorsFound = true;
775 : }
776 : } else {
777 0 : ShowSevereError(state,
778 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name + "\", item not found.");
779 0 : ShowContinueError(state, "AirLoopHVAC:OutdoorAirSystem=\"" + CompNames(CompNum) + "\" not found.");
780 0 : ShowContinueError(state, " referenced in Branch=\"" + primaryAirSystems.Branch(BranchNum).Name + "\".");
781 0 : ErrorsFound = true;
782 : }
783 : }
784 : {
785 7252 : auto const componentType(uppercased(CompTypes(CompNum)));
786 3626 : if (componentType == "COILSYSTEM:COOLING:DX") {
787 283 : PackagedUnit(AirSysNum) = true;
788 3343 : } else if (componentType == "COILSYSTEM:HEATING:DX") {
789 2 : PackagedUnit(AirSysNum) = true;
790 3341 : } else if (componentType == "COILSYSTEM:COOLING:WATER") {
791 2 : PackagedUnit(AirSysNum) = true;
792 3339 : } else if (componentType == "AIRLOOPHVAC:UNITARYSYSTEM") {
793 104 : PackagedUnit(AirSysNum) = true;
794 3235 : } else if (componentType == "AIRLOOPHVAC:UNITARY:FURNACE:HEATONLY") {
795 3 : PackagedUnit(AirSysNum) = true;
796 3232 : } else if (componentType == "AIRLOOPHVAC:UNITARY:FURNACE:HEATCOOL") {
797 108 : PackagedUnit(AirSysNum) = true;
798 3124 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATONLY") {
799 1 : PackagedUnit(AirSysNum) = true;
800 3123 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATCOOL") {
801 73 : PackagedUnit(AirSysNum) = true;
802 3050 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATPUMP:AIRTOAIR") {
803 32 : PackagedUnit(AirSysNum) = true;
804 3018 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATPUMP:WATERTOAIR") {
805 139 : PackagedUnit(AirSysNum) = true;
806 2879 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATCOOL:VAVCHANGEOVERBYPASS") {
807 4 : PackagedUnit(AirSysNum) = true;
808 2875 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATPUMP:AIRTOAIR:MULTISPEED") {
809 11 : PackagedUnit(AirSysNum) = true;
810 : }
811 : }
812 :
813 : } // end of component loop
814 :
815 1196 : primaryAirSystems.Branch(BranchNum).ControlType = "";
816 1196 : primaryAirSystems.Branch(BranchNum).NodeNumIn = InletNodeNumbers(1);
817 1196 : primaryAirSystems.Branch(BranchNum).NodeNumOut = OutletNodeNumbers(NumCompsOnBranch);
818 :
819 1196 : CompTypes.deallocate();
820 1196 : CompNames.deallocate();
821 1196 : InletNodeNames.deallocate();
822 1196 : InletNodeNumbers.deallocate();
823 1196 : OutletNodeNames.deallocate();
824 1196 : OutletNodeNumbers.deallocate();
825 :
826 : } // end of branch loop
827 :
828 1177 : BranchNames.deallocate();
829 :
830 : // find and store the primary air system outlet branch reference numbers
831 1177 : primaryAirSystems.NumOutletBranches = airLoopZoneInfo.NumSupplyNodes;
832 2362 : for (OutBranchNum = 1; OutBranchNum <= 3; ++OutBranchNum) {
833 2362 : primaryAirSystems.OutletBranchNum[OutBranchNum - 1] = 0;
834 2362 : if (OutBranchNum > primaryAirSystems.NumOutletBranches) break;
835 1185 : MatchNodeName(OutBranchNum) = state.dataLoopNodes->NodeID(airLoopZoneInfo.AirLoopSupplyNodeNum(OutBranchNum));
836 2405 : for (BranchNum = 1; BranchNum <= primaryAirSystems.NumBranches; ++BranchNum) {
837 1220 : if (airLoopZoneInfo.AirLoopSupplyNodeNum(OutBranchNum) == primaryAirSystems.Branch(BranchNum).NodeNumOut) {
838 1185 : primaryAirSystems.OutletBranchNum[OutBranchNum - 1] = BranchNum;
839 : }
840 : }
841 : }
842 : // Check for errors
843 2362 : for (OutBranchNum = 1; OutBranchNum <= primaryAirSystems.NumOutletBranches; ++OutBranchNum) {
844 1185 : if (primaryAirSystems.OutletBranchNum[OutBranchNum - 1] != 0) continue;
845 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name + "\", branch in error.");
846 0 : ShowContinueError(state, "Probable missing or misspelled node referenced in the branch(es):");
847 0 : for (BranchNum = 1; BranchNum <= primaryAirSystems.NumBranches; ++BranchNum) {
848 0 : ShowContinueError(state, "Possible Error in Branch Object=\"" + primaryAirSystems.Branch(BranchNum).Name + "\".");
849 : }
850 0 : ShowContinueError(state, "...looking to match to Node=\"" + MatchNodeName(OutBranchNum) + "\".");
851 0 : ErrorsFound = true;
852 : }
853 :
854 : // find and store the primary air system inlet branch numbers
855 1177 : primaryAirSystems.NumInletBranches = airLoopZoneInfo.NumReturnNodes;
856 2354 : for (InBranchNum = 1; InBranchNum <= primaryAirSystems.NumInletBranches; ++InBranchNum) {
857 1177 : primaryAirSystems.InletBranchNum[InBranchNum - 1] = 0;
858 2373 : for (BranchNum = 1; BranchNum <= primaryAirSystems.NumBranches; ++BranchNum) {
859 1196 : if (airLoopZoneInfo.AirLoopReturnNodeNum(InBranchNum) == primaryAirSystems.Branch(BranchNum).NodeNumIn) {
860 1177 : primaryAirSystems.InletBranchNum[InBranchNum - 1] = BranchNum;
861 : }
862 : }
863 1177 : if (primaryAirSystems.InletBranchNum[InBranchNum - 1] == 0) {
864 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name + "\", connection to zone.");
865 0 : ShowContinueError(state, "No Connection found for Return Air from Zone");
866 0 : ShowContinueError(state,
867 0 : "Expected node name =\"" + state.dataLoopNodes->NodeID(airLoopZoneInfo.AirLoopReturnNodeNum(InBranchNum)) + "\".");
868 0 : ErrorsFound = true;
869 : }
870 : }
871 :
872 : // Check to see if a spliter and/or mixer exist
873 1177 : SplitterExists = false;
874 1177 : MixerExists = false;
875 :
876 1177 : if (ConnectorListName != std::string()) {
877 9 : ConListNum = state.dataInputProcessing->inputProcessor->getObjectItemNum(state, "ConnectorList", ConnectorListName);
878 9 : if (ConListNum > 0) {
879 18 : state.dataInputProcessing->inputProcessor->getObjectItem(
880 9 : state, "ConnectorList", ConListNum, Alphas, NumAlphas, Numbers, NumNumbers, IOStat);
881 18 : if ((UtilityRoutines::SameString(Alphas(2), "Connector:Splitter")) ||
882 9 : (UtilityRoutines::SameString(Alphas(4), "Connector:Splitter"))) {
883 9 : SplitterExists = true;
884 : }
885 9 : if ((UtilityRoutines::SameString(Alphas(2), "Connector:Mixer")) || (UtilityRoutines::SameString(Alphas(4), "Connector:Mixer"))) {
886 1 : MixerExists = true;
887 : }
888 : } else {
889 0 : ShowSevereError(state,
890 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name + "\", connector list object.");
891 0 : ShowContinueError(state, "ConnectorList object=\"" + ConnectorListName + "\" not found in input.");
892 : }
893 9 : errFlag = false;
894 18 : GetNumSplitterMixerInConntrList(
895 18 : state, "AirLoop", ConnectorListName, state.dataLoopNodes->NumofSplitters, state.dataLoopNodes->NumofMixers, errFlag);
896 9 : if (errFlag) {
897 : }
898 : }
899 :
900 : // If there is a SPLITTER, get its data
901 1177 : if (SplitterExists) {
902 9 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Connector:Splitter", NumParams, NumAlphas, NumNodes);
903 9 : NodeNames.allocate(NumAlphas);
904 9 : NodeNumbers.allocate(NumAlphas);
905 9 : GetLoopSplitter(state,
906 : primaryAirSystems.Name,
907 : ConnectorListName,
908 : primaryAirSystems.Splitter.Name,
909 : primaryAirSystems.Splitter.Exists,
910 : primaryAirSystems.Splitter.NodeNameIn,
911 : primaryAirSystems.Splitter.NodeNumIn,
912 : primaryAirSystems.Splitter.TotalOutletNodes,
913 : NodeNames,
914 : NodeNumbers,
915 : ErrorsFound);
916 :
917 9 : primaryAirSystems.Splitter.NodeNameOut.allocate(primaryAirSystems.Splitter.TotalOutletNodes);
918 9 : primaryAirSystems.Splitter.NodeNumOut.allocate(primaryAirSystems.Splitter.TotalOutletNodes);
919 9 : primaryAirSystems.Splitter.BranchNumOut.allocate(primaryAirSystems.Splitter.TotalOutletNodes);
920 :
921 27 : for (NodeNum = 1; NodeNum <= primaryAirSystems.Splitter.TotalOutletNodes; ++NodeNum) {
922 :
923 18 : primaryAirSystems.Splitter.NodeNameOut(NodeNum) = NodeNames(NodeNum);
924 18 : primaryAirSystems.Splitter.NodeNumOut(NodeNum) = NodeNumbers(NodeNum);
925 :
926 18 : primaryAirSystems.Splitter.BranchNumOut(NodeNum) = 0;
927 45 : for (BranchNum = 1; BranchNum <= primaryAirSystems.NumBranches; ++BranchNum) {
928 :
929 45 : if (primaryAirSystems.Branch(BranchNum).NodeNumIn == primaryAirSystems.Splitter.NodeNumOut(NodeNum)) {
930 18 : primaryAirSystems.Splitter.BranchNumOut(NodeNum) = BranchNum;
931 18 : break;
932 : }
933 : }
934 : }
935 :
936 9 : primaryAirSystems.Splitter.BranchNumIn = 0;
937 9 : for (BranchNum = 1; BranchNum <= primaryAirSystems.NumBranches; ++BranchNum) {
938 :
939 9 : if (primaryAirSystems.Branch(BranchNum).NodeNumOut == primaryAirSystems.Splitter.NodeNumIn) {
940 9 : primaryAirSystems.Splitter.BranchNumIn = BranchNum;
941 9 : break;
942 : }
943 : }
944 :
945 9 : if (allocated(NodeNames)) {
946 9 : NodeNames.deallocate();
947 9 : NodeNumbers.deallocate();
948 : }
949 :
950 : } else {
951 1168 : primaryAirSystems.Splitter.Exists = false;
952 1168 : primaryAirSystems.Splitter.NodeNumIn = 0;
953 1168 : primaryAirSystems.Splitter.BranchNumIn = 0;
954 1168 : primaryAirSystems.Splitter.NodeNameIn = "";
955 1168 : primaryAirSystems.Splitter.TotalOutletNodes = 0;
956 1168 : primaryAirSystems.Splitter.NodeNumOut.allocate(0);
957 1168 : primaryAirSystems.Splitter.BranchNumOut.allocate(0);
958 1168 : primaryAirSystems.Splitter.NodeNameOut.allocate(0);
959 : }
960 :
961 : // If there is a MIXER, get its data
962 1177 : if (MixerExists) {
963 1 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Connector:Mixer", NumParams, NumAlphas, NumNodes);
964 1 : NodeNames.allocate(NumAlphas);
965 1 : NodeNumbers.allocate(NumAlphas);
966 1 : GetLoopMixer(state,
967 : primaryAirSystems.Name,
968 : ConnectorListName,
969 : primaryAirSystems.Mixer.Name,
970 : primaryAirSystems.Mixer.Exists,
971 : primaryAirSystems.Mixer.NodeNameOut,
972 : primaryAirSystems.Mixer.NodeNumOut,
973 : primaryAirSystems.Mixer.TotalInletNodes,
974 : NodeNames,
975 : NodeNumbers,
976 : ErrorsFound);
977 :
978 1 : primaryAirSystems.Mixer.NodeNameIn.allocate(primaryAirSystems.Mixer.TotalInletNodes);
979 1 : primaryAirSystems.Mixer.NodeNumIn.allocate(primaryAirSystems.Mixer.TotalInletNodes);
980 1 : primaryAirSystems.Mixer.BranchNumIn.allocate(primaryAirSystems.Mixer.TotalInletNodes);
981 :
982 3 : for (NodeNum = 1; NodeNum <= primaryAirSystems.Mixer.TotalInletNodes; ++NodeNum) {
983 :
984 2 : primaryAirSystems.Mixer.NodeNameIn(NodeNum) = NodeNames(NodeNum);
985 2 : primaryAirSystems.Mixer.NodeNumIn(NodeNum) = NodeNumbers(NodeNum);
986 :
987 2 : primaryAirSystems.Mixer.BranchNumIn(NodeNum) = 0;
988 10 : for (BranchNum = 1; BranchNum <= primaryAirSystems.NumBranches; ++BranchNum) {
989 :
990 8 : if (primaryAirSystems.Branch(BranchNum).NodeNumIn == primaryAirSystems.Mixer.NodeNumIn(NodeNum)) {
991 0 : primaryAirSystems.Mixer.BranchNumIn(NodeNum) = BranchNum;
992 0 : break;
993 : }
994 : }
995 : }
996 :
997 1 : primaryAirSystems.Mixer.BranchNumOut = 0;
998 4 : for (BranchNum = 1; BranchNum <= primaryAirSystems.NumBranches; ++BranchNum) {
999 :
1000 4 : if (primaryAirSystems.Branch(BranchNum).NodeNumIn == primaryAirSystems.Mixer.NodeNumOut) {
1001 1 : primaryAirSystems.Mixer.BranchNumOut = BranchNum;
1002 1 : break;
1003 : }
1004 : }
1005 :
1006 1 : if (allocated(NodeNames)) {
1007 1 : NodeNames.deallocate();
1008 1 : NodeNumbers.deallocate();
1009 : }
1010 :
1011 : } else {
1012 1176 : primaryAirSystems.Mixer.Exists = false;
1013 1176 : primaryAirSystems.Mixer.NodeNumOut = 0;
1014 1176 : primaryAirSystems.Mixer.BranchNumOut = 0;
1015 1176 : primaryAirSystems.Mixer.NodeNameOut = "";
1016 1176 : primaryAirSystems.Mixer.TotalInletNodes = 0;
1017 1176 : primaryAirSystems.Mixer.NodeNumIn.allocate(0);
1018 1176 : primaryAirSystems.Mixer.BranchNumIn.allocate(0);
1019 1176 : primaryAirSystems.Mixer.NodeNameIn.allocate(0);
1020 : }
1021 :
1022 1177 : NumControllers = 0;
1023 1177 : if (ControllerListName != std::string()) { // If not blank, then must be there and valid
1024 : // Loop through the controller lists until you find the one attached to this primary air system
1025 415 : ControllerListNum = state.dataInputProcessing->inputProcessor->getObjectItemNum(state, "AirLoopHVAC:ControllerList", ControllerListName);
1026 415 : if (ControllerListNum > 0) {
1027 830 : state.dataInputProcessing->inputProcessor->getObjectItem(
1028 415 : state, "AirLoopHVAC:ControllerList", ControllerListNum, Alphas, NumAlphas, Numbers, NumNumbers, IOStat);
1029 : // Check the current controller list and if it matches input names
1030 415 : NumControllers = (NumAlphas - 1) / 2; // Subtract off the controller list name first
1031 : // store all the controller data
1032 415 : primaryAirSystems.NumControllers = NumControllers + NumOASysSimpControllers;
1033 415 : primaryAirSystems.ControllerName.allocate(NumControllers + NumOASysSimpControllers);
1034 415 : primaryAirSystems.ControllerType.allocate(NumControllers + NumOASysSimpControllers);
1035 415 : primaryAirSystems.ControllerIndex.allocate(NumControllers + NumOASysSimpControllers);
1036 415 : primaryAirSystems.ControllerIndex = 0;
1037 415 : primaryAirSystems.ControlConverged.allocate(NumControllers + NumOASysSimpControllers);
1038 415 : primaryAirSystems.CanBeLockedOutByEcono.allocate(NumControllers + NumOASysSimpControllers);
1039 1183 : for (ControllerNum = NumOASysSimpControllers + 1; ControllerNum <= NumOASysSimpControllers + NumControllers; ++ControllerNum) {
1040 768 : ControllerName = Alphas((ControllerNum - NumOASysSimpControllers) * 2 + 1);
1041 768 : ControllerType = Alphas((ControllerNum - NumOASysSimpControllers) * 2);
1042 768 : primaryAirSystems.ControllerName(ControllerNum) = ControllerName;
1043 768 : primaryAirSystems.ControllerType(ControllerNum) = ControllerType;
1044 768 : IsNotOK = false;
1045 768 : ValidateComponent(state, ControllerType, ControllerName, IsNotOK, CurrentModuleObject);
1046 768 : if (IsNotOK) {
1047 0 : ShowContinueError(state,
1048 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name +
1049 0 : "\", for ControllerList=\"" + ControllerListName + "\".");
1050 0 : ErrorsFound = true;
1051 : }
1052 768 : primaryAirSystems.ControlConverged(ControllerNum) = false;
1053 768 : primaryAirSystems.CanBeLockedOutByEcono(ControllerNum) = false;
1054 : } // End of ControllerListNum Loop
1055 : } else {
1056 0 : ShowSevereError(state,
1057 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name + "\", controller list object.");
1058 0 : ShowContinueError(state, "ControllerList object=\"" + ControllerListName + "\" not found in input.");
1059 0 : ErrorsFound = true;
1060 : }
1061 : }
1062 1177 : if (NumOASysSimpControllers > 0) {
1063 54 : state.dataInputProcessing->inputProcessor->getObjectItem(
1064 27 : state, "AirLoopHVAC:ControllerList", OASysContListNum, Alphas, NumAlphas, Numbers, NumNumbers, IOStat);
1065 : // allocate air primary system controller lists if not already done
1066 27 : if (NumControllers == 0) {
1067 2 : primaryAirSystems.NumControllers = NumOASysSimpControllers;
1068 2 : primaryAirSystems.ControllerName.allocate(NumOASysSimpControllers);
1069 2 : primaryAirSystems.ControllerType.allocate(NumOASysSimpControllers);
1070 2 : primaryAirSystems.ControllerIndex.allocate(NumOASysSimpControllers);
1071 2 : primaryAirSystems.ControllerIndex = 0;
1072 2 : primaryAirSystems.ControlConverged.allocate(NumOASysSimpControllers);
1073 2 : primaryAirSystems.CanBeLockedOutByEcono.allocate(NumOASysSimpControllers);
1074 2 : primaryAirSystems.ControlConverged = false;
1075 2 : primaryAirSystems.CanBeLockedOutByEcono = false;
1076 : }
1077 : // loop over the OA Sys controllers and move them up to the primary air system controller lists
1078 27 : OASysControllerNum = 0;
1079 27 : NumOASysControllers = (NumAlphas - 1) / 2;
1080 106 : for (ControllerNum = 1; ControllerNum <= NumOASysControllers; ++ControllerNum) {
1081 79 : ControllerName = Alphas(ControllerNum * 2 + 1);
1082 79 : ControllerType = Alphas(ControllerNum * 2);
1083 79 : if (!UtilityRoutines::SameString(ControllerType, "Controller:OutdoorAir")) {
1084 52 : ++OASysControllerNum;
1085 52 : primaryAirSystems.ControllerName(OASysControllerNum) = ControllerName;
1086 52 : primaryAirSystems.ControllerType(OASysControllerNum) = ControllerType;
1087 52 : primaryAirSystems.ControlConverged(OASysControllerNum) = false;
1088 52 : primaryAirSystems.CanBeLockedOutByEcono(OASysControllerNum) = true;
1089 52 : GetControllerActuatorNodeNum(state, ControllerName, ActuatorNodeNum, errFlag);
1090 :
1091 52 : bool nonLockoutCoilFound = false;
1092 52 : WaterCoilNodeNum = -1;
1093 : // added to fix bug issue #5695, if HW coil on outdoor air system, don't lock out during economizing
1094 52 : if (OANum > 0) {
1095 54 : for (int OACompNum = 1; OACompNum <= OutsideAirSys(OANum).NumComponents; ++OACompNum) {
1096 54 : CompType = OutsideAirSys(OANum).ComponentType(OACompNum);
1097 54 : if (UtilityRoutines::SameString(CompType, "Coil:Heating:Water")) {
1098 52 : WaterCoilNodeNum = GetCoilWaterInletNode(state, CompType, OutsideAirSys(OANum).ComponentName(OACompNum), ErrorsFound);
1099 52 : if (WaterCoilNodeNum == ActuatorNodeNum) nonLockoutCoilFound = true;
1100 52 : break;
1101 : }
1102 : }
1103 : }
1104 52 : if (!nonLockoutCoilFound) {
1105 : // Coil controllers can be entered either in the air loop controller list or the
1106 : // OA system controller list. The CanBeLockedOutByEcono should only be set for OA coils
1107 : // First get the OA controller actuator node and then compare to the air loop coil water inlet node
1108 : // If these node numbers match, the coil is in the main air loop and the lockout flag should be reset to FALSE
1109 50 : for (BranchNum = 1; BranchNum <= primaryAirSystems.NumBranches; ++BranchNum) {
1110 125 : for (CompNum = 1; CompNum <= primaryAirSystems.Branch(BranchNum).TotalComponents; ++CompNum) {
1111 100 : if (UtilityRoutines::SameString(primaryAirSystems.Branch(BranchNum).Comp(CompNum).TypeOf,
1112 100 : "AirloopHVAC:OutdoorAirSystem"))
1113 25 : continue;
1114 75 : CompType = primaryAirSystems.Branch(BranchNum).Comp(CompNum).TypeOf;
1115 225 : if (UtilityRoutines::SameString(CompType, "Coil:Cooling:Water:DetailedGeometry") ||
1116 200 : UtilityRoutines::SameString(CompType, "Coil:Heating:Water") ||
1117 125 : UtilityRoutines::SameString(CompType, "Coil:Cooling:Water")) {
1118 50 : WaterCoilNodeNum =
1119 50 : GetCoilWaterInletNode(state, CompType, primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name, ErrorsFound);
1120 50 : if (WaterCoilNodeNum == ActuatorNodeNum) {
1121 0 : nonLockoutCoilFound = true;
1122 0 : break;
1123 : }
1124 : }
1125 : }
1126 : }
1127 : }
1128 52 : if (nonLockoutCoilFound) {
1129 27 : primaryAirSystems.CanBeLockedOutByEcono(OASysControllerNum) = false;
1130 : }
1131 : }
1132 : }
1133 : }
1134 1177 : if (NumControllers + NumOASysSimpControllers == 0) {
1135 760 : if (!PackagedUnit(AirSysNum)) {
1136 25 : ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + primaryAirSystems.Name + "\" has no Controllers.");
1137 : }
1138 760 : primaryAirSystems.NumControllers = 0;
1139 760 : primaryAirSystems.ControllerName.allocate(0);
1140 760 : primaryAirSystems.ControllerType.allocate(0);
1141 760 : primaryAirSystems.ControlConverged.allocate(0);
1142 760 : primaryAirSystems.CanBeLockedOutByEcono.allocate(0);
1143 : }
1144 :
1145 1177 : errFlag = false;
1146 1177 : GetAirLoopAvailabilityManager(state, AvailManagerListName, AirSysNum, NumPrimaryAirSys, errFlag);
1147 :
1148 1177 : if (errFlag) {
1149 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + primaryAirSystems.Name);
1150 0 : ErrorsFound = true;
1151 : }
1152 :
1153 : } // End Air Loop
1154 :
1155 524 : Numbers.deallocate();
1156 524 : cNumericFields.deallocate();
1157 524 : lNumericBlanks.deallocate();
1158 524 : Alphas.deallocate();
1159 524 : cAlphaFields.deallocate();
1160 524 : lAlphaBlanks.deallocate();
1161 :
1162 524 : TestUniqueNodes.deallocate();
1163 1701 : for (AirSysNum = 1; AirSysNum <= NumPrimaryAirSys; ++AirSysNum) {
1164 1177 : auto &primaryAirSystems = state.dataAirSystemsData->PrimaryAirSystems(AirSysNum);
1165 2373 : for (BranchNum = 1; BranchNum <= primaryAirSystems.NumBranches; ++BranchNum) {
1166 4822 : for (CompNum = 1; CompNum <= primaryAirSystems.Branch(BranchNum).TotalComponents; ++CompNum) {
1167 :
1168 : {
1169 7252 : auto const componentType(uppercased(primaryAirSystems.Branch(BranchNum).Comp(CompNum).TypeOf));
1170 :
1171 3626 : if (componentType == "AIRLOOPHVAC:OUTDOORAIRSYSTEM") {
1172 1026 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::OAMixer_Num;
1173 :
1174 : // Fan Types for the air sys simulation
1175 2600 : } else if (componentType == "FAN:CONSTANTVOLUME") {
1176 333 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Fan_Simple_CV;
1177 :
1178 2267 : } else if (componentType == "FAN:VARIABLEVOLUME") {
1179 366 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Fan_Simple_VAV;
1180 :
1181 1901 : } else if (componentType == "FAN:SYSTEMMODEL") {
1182 9 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Fan_System_Object;
1183 : // Construct fan object
1184 9 : if (HVACFan::getFanObjectVectorIndex(state, primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name, false) < 0) {
1185 18 : state.dataHVACFan->fanObjs.emplace_back(
1186 18 : new HVACFan::FanSystem(state, primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name));
1187 : }
1188 9 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompIndex =
1189 9 : HVACFan::getFanObjectVectorIndex(state, primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name) +
1190 : 1; // + 1 for shift from zero-based vector to 1-based compIndex
1191 9 : state.dataHVACFan->fanObjs[HVACFan::getFanObjectVectorIndex(state, primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name)]
1192 9 : ->AirPathFlag = true;
1193 1892 : } else if (componentType == "FAN:COMPONENTMODEL") {
1194 1 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Fan_ComponentModel;
1195 :
1196 : // Coil Types for the air sys simulation
1197 : // HX Assisted coils are not allowed on a branch at this time
1198 : // CASE('COILSYSTEM:COOLING:DX:HEATEXCHANGERASSISTED')
1199 : // PrimaryAirSystem(AirSysNum)%Branch(BranchNum)%Comp(CompNum)%CompType_Num=DXCoil_CoolingHXAsst
1200 1891 : } else if (componentType == "COILSYSTEM:COOLING:WATER:HEATEXCHANGERASSISTED") {
1201 5 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::WaterCoil_CoolingHXAsst;
1202 1886 : } else if (componentType == "COIL:HEATING:WATER") {
1203 358 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::WaterCoil_SimpleHeat;
1204 1528 : } else if (componentType == "COIL:HEATING:STEAM") {
1205 2 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::SteamCoil_AirHeat;
1206 1526 : } else if (componentType == "COIL:COOLING:WATER:DETAILEDGEOMETRY") {
1207 138 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::WaterCoil_DetailedCool;
1208 1388 : } else if (componentType == "COIL:COOLING:WATER") {
1209 267 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::WaterCoil_Cooling;
1210 1121 : } else if (componentType == "COIL:HEATING:ELECTRIC") {
1211 30 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Coil_ElectricHeat;
1212 1091 : } else if (componentType == "COIL:HEATING:FUEL") {
1213 246 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Coil_GasHeat;
1214 :
1215 : // Heat reclaim
1216 845 : } else if (componentType == "COIL:HEATING:DESUPERHEATER") {
1217 0 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Coil_DeSuperHeat;
1218 :
1219 845 : } else if (componentType == "COILSYSTEM:COOLING:DX") {
1220 283 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::DXSystem;
1221 562 : } else if (componentType == "COILSYSTEM:HEATING:DX") {
1222 2 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::DXHeatPumpSystem;
1223 560 : } else if (componentType == "COIL:USERDEFINED") {
1224 4 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::CoilUserDefined;
1225 556 : } else if (componentType == "AIRLOOPHVAC:UNITARYSYSTEM") {
1226 104 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::UnitarySystemModel;
1227 208 : UnitarySystems::UnitarySys thisSys;
1228 104 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).compPointer = thisSys.factory(
1229 104 : state, DataHVACGlobals::UnitarySys_AnyCoilType, primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name, false, 0);
1230 452 : } else if (componentType == "COILSYSTEM:COOLING:WATER") {
1231 2 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::CoilSystemWater;
1232 4 : UnitarySystems::UnitarySys thisSys;
1233 2 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).compPointer = thisSys.factory(
1234 2 : state, DataHVACGlobals::UnitarySys_AnyCoilType, primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name, false, 0);
1235 450 : } else if (componentType == "AIRLOOPHVAC:UNITARY:FURNACE:HEATONLY") {
1236 3 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Furnace_UnitarySys_HeatOnly;
1237 447 : } else if (componentType == "AIRLOOPHVAC:UNITARY:FURNACE:HEATCOOL") {
1238 108 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Furnace_UnitarySys_HeatCool;
1239 339 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATONLY") {
1240 1 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Furnace_UnitarySys_HeatOnly;
1241 338 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATCOOL") {
1242 73 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Furnace_UnitarySys_HeatCool;
1243 265 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATPUMP:AIRTOAIR") {
1244 32 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Furnace_UnitarySys_HeatCool;
1245 233 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATPUMP:WATERTOAIR") {
1246 139 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Furnace_UnitarySys_HeatCool;
1247 :
1248 94 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATCOOL:VAVCHANGEOVERBYPASS") {
1249 4 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::UnitarySystem_BypassVAVSys;
1250 :
1251 : // Humidifier Types for the air system simulation
1252 90 : } else if (componentType == "HUMIDIFIER:STEAM:ELECTRIC") {
1253 34 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Humidifier;
1254 :
1255 56 : } else if (componentType == "HUMIDIFIER:STEAM:GAS") {
1256 1 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Humidifier;
1257 :
1258 : // Evap Cooler Types for the air system simulation
1259 55 : } else if (componentType == "EVAPORATIVECOOLER:DIRECT:CELDEKPAD") {
1260 7 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::EvapCooler;
1261 48 : } else if (componentType == "EVAPORATIVECOOLER:INDIRECT:CELDEKPAD") {
1262 1 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::EvapCooler;
1263 47 : } else if (componentType == "EVAPORATIVECOOLER:INDIRECT:WETCOIL") {
1264 1 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::EvapCooler;
1265 46 : } else if (componentType == "EVAPORATIVECOOLER:INDIRECT:RESEARCHSPECIAL") {
1266 24 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::EvapCooler;
1267 22 : } else if (componentType == "EVAPORATIVECOOLER:DIRECT:RESEARCHSPECIAL") {
1268 4 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::EvapCooler;
1269 :
1270 : // Desiccant Dehumidifier Types for the air system simulation
1271 18 : } else if (componentType == "DEHUMIDIFIER:DESICCANT:NOFANS") {
1272 0 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Desiccant;
1273 18 : } else if (componentType == "DEHUMIDIFIER:DESICCANT:SYSTEM") {
1274 2 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Desiccant;
1275 :
1276 : // Heat recovery
1277 16 : } else if (componentType == "HEATEXCHANGER:AIRTOAIR:FLATPLATE") {
1278 0 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::HeatXchngr;
1279 :
1280 16 : } else if (componentType == "HEATEXCHANGER:AIRTOAIR:SENSIBLEANDLATENT") {
1281 1 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::HeatXchngr;
1282 :
1283 15 : } else if (componentType == "HEATEXCHANGER:DESICCANT:BALANCEDFLOW") {
1284 0 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::HeatXchngr;
1285 :
1286 : // Ducts
1287 15 : } else if (componentType == "DUCT") {
1288 3 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::Duct;
1289 :
1290 12 : } else if (componentType == "AIRLOOPHVAC:UNITARYHEATPUMP:AIRTOAIR:MULTISPEED") {
1291 11 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::UnitarySystem_MSHeatPump;
1292 :
1293 1 : } else if (componentType == "ZONEHVAC:TERMINALUNIT:VARIABLEREFRIGERANTFLOW") {
1294 1 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num = CompType::ZoneVRFasAirLoopEquip;
1295 :
1296 0 : } else if (componentType == "FAN:ONOFF" || componentType == "COIL:COOLING:DX:SINGLESPEED" ||
1297 0 : componentType == "COIL:HEATING:DX:SINGLESPEED" || componentType == "COIL:COOLING:DX:TWOSTAGEWITHHUMIDITYCONTROLMODE" ||
1298 0 : componentType == "COIL:COOLING:DX:MULTISPEED" || componentType == "COIL:HEATING:DX:MULTISPEED") {
1299 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + " = \"" + primaryAirSystems.Name + "\".");
1300 0 : ShowContinueError(
1301 0 : state, "..Invalid Air Loop Component Type = \"" + primaryAirSystems.Branch(BranchNum).Comp(CompNum).TypeOf + "\".");
1302 0 : ShowContinueError(state, "..Air Loop Component Name = \"" + primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name + "\".");
1303 0 : ShowContinueError(state, "..reference Branch = \"" + primaryAirSystems.Branch(BranchNum).Name + "\".");
1304 0 : ShowContinueError(state,
1305 : "...This component may only be referenced by a parent component such as "
1306 : "AirLoopHVAC:Unitary:Furnace:HeatCool or similar.");
1307 0 : ErrorsFound = true;
1308 :
1309 : } else {
1310 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + " = \"" + primaryAirSystems.Name + "\".");
1311 0 : ShowContinueError(
1312 0 : state, "..Invalid Air Loop Component Type = \"" + primaryAirSystems.Branch(BranchNum).Comp(CompNum).TypeOf + "\".");
1313 0 : ShowContinueError(state, "..Air Loop Component Name = \"" + primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name + "\".");
1314 0 : ShowContinueError(state, "..reference Branch = \"" + primaryAirSystems.Branch(BranchNum).Name + "\".");
1315 0 : ErrorsFound = true;
1316 : }
1317 : }
1318 : }
1319 : }
1320 : }
1321 :
1322 : // check that actuator nodes are matched by a water coil inlet node
1323 :
1324 1701 : for (AirSysNum = 1; AirSysNum <= NumPrimaryAirSys; ++AirSysNum) {
1325 1177 : auto &primaryAirSystems = state.dataAirSystemsData->PrimaryAirSystems(AirSysNum);
1326 2373 : for (BranchNum = 1; BranchNum <= primaryAirSystems.NumBranches; ++BranchNum) {
1327 4822 : for (CompNum = 1; CompNum <= primaryAirSystems.Branch(BranchNum).TotalComponents; ++CompNum) {
1328 3626 : CompType_Num = primaryAirSystems.Branch(BranchNum).Comp(CompNum).CompType_Num;
1329 3626 : if (CompType_Num == CompType::WaterCoil_DetailedCool || CompType_Num == CompType::WaterCoil_SimpleHeat ||
1330 : CompType_Num == CompType::WaterCoil_Cooling) {
1331 1526 : WaterCoilNodeNum = GetCoilWaterInletNode(state,
1332 763 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).TypeOf,
1333 763 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name,
1334 : ErrorsFound);
1335 763 : CheckCoilWaterInletNode(state, WaterCoilNodeNum, NodeNotFound);
1336 763 : if (NodeNotFound) {
1337 0 : ErrorsFound = true;
1338 0 : ShowSevereError(state,
1339 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" +
1340 0 : primaryAirSystems.Branch(BranchNum).Comp(CompNum).Name + "\", invalid actuator.");
1341 0 : ShowContinueError(state,
1342 : "...this coil requires a water coil controller and the inlet node of a water coil must also be an "
1343 : "actuator node of a water coil controller.");
1344 : }
1345 : }
1346 : }
1347 : }
1348 : }
1349 :
1350 524 : OANum = GetNumOASystems(state);
1351 1551 : for (int OASysNum = 1; OASysNum <= OANum; ++OASysNum) {
1352 1027 : NumInList = GetOACompListNumber(state, OASysNum);
1353 2176 : for (int OACompNum = 1; OACompNum <= NumInList; ++OACompNum) {
1354 1149 : CompType_Num = GetOACompTypeNum(state, OASysNum, OACompNum);
1355 1149 : if (CompType_Num == CompType::WaterCoil_DetailedCool || CompType_Num == CompType::WaterCoil_SimpleHeat ||
1356 : CompType_Num == CompType::WaterCoil_Cooling) {
1357 55 : WaterCoilNodeNum =
1358 110 : GetCoilWaterInletNode(state, GetOACompType(state, OASysNum, OACompNum), GetOACompName(state, OASysNum, OACompNum), ErrorsFound);
1359 55 : CheckCoilWaterInletNode(state, WaterCoilNodeNum, NodeNotFound);
1360 55 : UnitarySystems::isWaterCoilHeatRecoveryType(state, WaterCoilNodeNum, NodeNotFound);
1361 55 : if (NodeNotFound) {
1362 0 : ErrorsFound = true;
1363 0 : ShowSevereError(state,
1364 0 : std::string{RoutineName} + CurrentModuleObject + "=\"" + GetOACompName(state, OASysNum, OACompNum) +
1365 : "\", invalid actuator.");
1366 0 : ShowContinueError(state,
1367 : "...this coil requires a water coil controller and the inlet node of a water coil must also be an actuator "
1368 : "node of a water coil controller.");
1369 : }
1370 : }
1371 : }
1372 : }
1373 :
1374 524 : if (ErrorsFound) {
1375 0 : ShowFatalError(state, format("{}Errors found retrieving input for {}.", RoutineName, CurrentModuleObject));
1376 : }
1377 :
1378 1701 : for (AirSysNum = 1; AirSysNum <= NumPrimaryAirSys; ++AirSysNum) {
1379 4708 : SetupOutputVariable(state,
1380 : "Air System Simulation Cycle On Off Status",
1381 : OutputProcessor::Unit::None,
1382 1177 : state.dataAirLoop->PriAirSysAvailMgr(AirSysNum).AvailStatus,
1383 : OutputProcessor::SOVTimeStepType::HVAC,
1384 : OutputProcessor::SOVStoreType::Average,
1385 2354 : state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Name);
1386 : }
1387 :
1388 524 : if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:DedicatedOutdoorAirSystem") > 0) {
1389 1 : if (state.dataAirLoopHVACDOAS->GetInputOnceFlag) {
1390 1 : AirLoopHVACDOAS::getAirLoopHVACDOASInput(state);
1391 1 : state.dataAirLoopHVACDOAS->GetInputOnceFlag = false;
1392 : }
1393 : }
1394 : }
1395 :
1396 : // End of Get Input subroutines for the Module
1397 : //******************************************************************************
1398 :
1399 : // Beginning Initialization Section of the Module
1400 : //******************************************************************************
1401 :
1402 6484926 : void InitAirLoops(EnergyPlusData &state, bool const FirstHVACIteration) // TRUE if first full HVAC iteration in an HVAC timestep
1403 : {
1404 :
1405 : // SUBROUTINE INFORMATION:
1406 : // AUTHOR Richard J. Liesen
1407 : // DATE WRITTEN April 1998
1408 : // MODIFIED Dec 1999 Fred Buhl
1409 :
1410 : // PURPOSE OF THIS SUBROUTINE:
1411 : // Initializes the primary air system simulation
1412 :
1413 : // METHODOLOGY EMPLOYED:
1414 : // (1) For the first simulation in an HVAC timestep, the air system is initialized to
1415 : // design air flow rates.
1416 : // (2) For subsequent simulations, air flow data is set by the zone equipment inlet
1417 : // nodes and the return air node.
1418 : // (3) Other air system node data such as temperatures and humidity ratios are only
1419 : // initialized at the start of an environment (run period or design day).
1420 :
1421 6484926 : int const numPrimaryAirSys = state.dataHVACGlobal->NumPrimaryAirSys;
1422 :
1423 6484926 : bool ErrorsFound = false;
1424 6484926 : state.dataHVACGlobal->AirLoopInit = true;
1425 :
1426 : // Do the one time initializations
1427 6484926 : if (state.dataSimAirServingZones->InitAirLoopsOneTimeFlag) {
1428 :
1429 : // Figure out what zones are served by each primary air system (air loop) and
1430 : // store the results in AirToZoneNodeInfo()%CoolCtrlZoneNums and AirToZoneNodeInfo()%HeatCtrlZoneNums
1431 :
1432 : // Temporary air loop zone data
1433 9640 : struct AirloopZone
1434 : {
1435 : int ctrlZoneNum = 0; // Controlled zone num
1436 : int zoneInletNode = 0; // Zone supply inlet node
1437 : int termUnitInletNode = 0; // Terminal unit inlet node
1438 : int termUnitSizingIndex = 0; // Terminal unit sizing index
1439 : };
1440 :
1441 1540 : EPVector<AirloopZone> cooledZone;
1442 1540 : EPVector<AirloopZone> heatedZone;
1443 770 : size_t atuArraySize = max(static_cast<size_t>(state.dataGlobal->NumOfZones), state.dataDefineEquipment->AirDistUnit.size());
1444 770 : cooledZone.allocate(atuArraySize);
1445 770 : heatedZone.allocate(atuArraySize);
1446 :
1447 770 : state.dataSimAirServingZones->MassFlowSetToler = DataConvergParams::HVACFlowRateToler * 0.00001;
1448 :
1449 1951 : for (int SupAirPath = 1; SupAirPath <= state.dataZoneEquip->NumSupplyAirPaths; ++SupAirPath) {
1450 :
1451 1181 : int NumAllSupAirPathNodes = 0;
1452 1181 : int SupAirPathNodeNum = 0;
1453 1181 : int SupAirPathOutNodeNum = 0;
1454 1181 : int NumSupAirPathOutNodes = 0;
1455 1181 : int NumSupAirPathNodes = 0;
1456 1181 : int NumSupAirPathIntNodes = 0;
1457 :
1458 : // each supply air path may have up to one splitter and one plenum. Check for all combinations count
1459 : // all nodes (including duplicates)
1460 2369 : for (int CompNum = 1; CompNum <= state.dataZoneEquip->SupplyAirPath(SupAirPath).NumOfComponents; ++CompNum) {
1461 1188 : if (UtilityRoutines::SameString(state.dataZoneEquip->SupplyAirPath(SupAirPath).ComponentType(CompNum), "AirLoopHVAC:ZoneSplitter")) {
1462 1180 : int SplitterNum = UtilityRoutines::FindItemInList(state.dataZoneEquip->SupplyAirPath(SupAirPath).ComponentName(CompNum),
1463 1180 : state.dataSplitterComponent->SplitterCond,
1464 1180 : &SplitterComponent::SplitterConditions::SplitterName);
1465 1180 : if (SplitterNum == 0) {
1466 0 : ShowSevereError(
1467 0 : state, "AirLoopHVAC:ZoneSplitter not found=" + state.dataZoneEquip->SupplyAirPath(SupAirPath).ComponentName(CompNum));
1468 0 : ShowContinueError(state, "Occurs in AirLoopHVAC:SupplyPath=" + state.dataZoneEquip->SupplyAirPath(SupAirPath).Name);
1469 0 : ErrorsFound = true;
1470 : }
1471 1180 : state.dataZoneEquip->SupplyAirPath(SupAirPath).SplitterIndex(CompNum) = SplitterNum;
1472 1180 : NumAllSupAirPathNodes += state.dataSplitterComponent->SplitterCond(SplitterNum).NumOutletNodes + 1;
1473 8 : } else if (UtilityRoutines::SameString(state.dataZoneEquip->SupplyAirPath(SupAirPath).ComponentType(CompNum),
1474 8 : "AirLoopHVAC:SupplyPlenum")) {
1475 8 : int PlenumNum = UtilityRoutines::FindItemInList(state.dataZoneEquip->SupplyAirPath(SupAirPath).ComponentName(CompNum),
1476 8 : state.dataZonePlenum->ZoneSupPlenCond,
1477 8 : &ZonePlenum::ZoneSupplyPlenumConditions::ZonePlenumName);
1478 8 : if (PlenumNum == 0) {
1479 0 : ShowSevereError(
1480 0 : state, "AirLoopHVAC:SupplyPlenum not found=" + state.dataZoneEquip->SupplyAirPath(SupAirPath).ComponentName(CompNum));
1481 0 : ShowContinueError(state, "Occurs in AirLoopHVAC:SupplyPath=" + state.dataZoneEquip->SupplyAirPath(SupAirPath).Name);
1482 0 : ErrorsFound = true;
1483 : }
1484 8 : state.dataZoneEquip->SupplyAirPath(SupAirPath).PlenumIndex(CompNum) = PlenumNum;
1485 8 : NumAllSupAirPathNodes += state.dataZonePlenum->ZoneSupPlenCond(PlenumNum).NumOutletNodes + 1;
1486 : }
1487 : }
1488 2362 : EPVector<int> supNode;
1489 2362 : EPVector<DataZoneEquipment::AirNodeType> supNodeType;
1490 1181 : supNode.allocate(NumAllSupAirPathNodes);
1491 1181 : supNodeType.allocate(NumAllSupAirPathNodes);
1492 :
1493 : // figure out the order of the splitter and plenum in the path, by flagging the first node of the component
1494 : // as either a 'pathinlet' or a 'compinlet'
1495 2369 : for (int CompNum = 1; CompNum <= state.dataZoneEquip->SupplyAirPath(SupAirPath).NumOfComponents; ++CompNum) {
1496 1188 : int SplitterNum = state.dataZoneEquip->SupplyAirPath(SupAirPath).SplitterIndex(CompNum);
1497 1188 : int PlenumNum = state.dataZoneEquip->SupplyAirPath(SupAirPath).PlenumIndex(CompNum);
1498 1188 : if (SplitterNum > 0) {
1499 1180 : ++SupAirPathNodeNum;
1500 1180 : supNode(SupAirPathNodeNum) = state.dataSplitterComponent->SplitterCond(SplitterNum).InletNode;
1501 1180 : if (CompNum == 1) {
1502 1173 : supNodeType(SupAirPathNodeNum) = DataZoneEquipment::AirNodeType::PathInlet;
1503 : } else {
1504 7 : supNodeType(SupAirPathNodeNum) = DataZoneEquipment::AirNodeType::CompInlet;
1505 : }
1506 4660 : for (int SplitterOutNum = 1; SplitterOutNum <= state.dataSplitterComponent->SplitterCond(SplitterNum).NumOutletNodes;
1507 : ++SplitterOutNum) {
1508 3480 : ++SupAirPathNodeNum;
1509 3480 : supNode(SupAirPathNodeNum) = state.dataSplitterComponent->SplitterCond(SplitterNum).OutletNode(SplitterOutNum);
1510 3480 : supNodeType(SupAirPathNodeNum) = DataZoneEquipment::AirNodeType::Invalid;
1511 : }
1512 8 : } else if (PlenumNum > 0) {
1513 8 : ++SupAirPathNodeNum;
1514 8 : supNode(SupAirPathNodeNum) = state.dataZonePlenum->ZoneSupPlenCond(PlenumNum).InletNode;
1515 8 : if (CompNum == 1) {
1516 8 : supNodeType(SupAirPathNodeNum) = DataZoneEquipment::AirNodeType::PathInlet;
1517 : } else {
1518 0 : supNodeType(SupAirPathNodeNum) = DataZoneEquipment::AirNodeType::CompInlet;
1519 : }
1520 20 : for (int PlenumOutNum = 1; PlenumOutNum <= state.dataZonePlenum->ZoneSupPlenCond(PlenumNum).NumOutletNodes; ++PlenumOutNum) {
1521 12 : ++SupAirPathNodeNum;
1522 12 : supNode(SupAirPathNodeNum) = state.dataZonePlenum->ZoneSupPlenCond(PlenumNum).OutletNode(PlenumOutNum);
1523 12 : supNodeType(SupAirPathNodeNum) = DataZoneEquipment::AirNodeType::Invalid;
1524 : }
1525 : }
1526 : }
1527 :
1528 : // find the nodes that connect a splitter and a plenum
1529 5861 : for (int SupNodeIndex = 1; SupNodeIndex <= NumAllSupAirPathNodes; ++SupNodeIndex) {
1530 4680 : if (supNodeType(SupNodeIndex) == DataZoneEquipment::AirNodeType::Invalid) {
1531 17640 : for (int SupNodeIndex2 = SupNodeIndex + 1; SupNodeIndex2 <= NumAllSupAirPathNodes; ++SupNodeIndex2) {
1532 14162 : if ((supNode(SupNodeIndex) == supNode(SupNodeIndex2)) &&
1533 7 : (supNodeType(SupNodeIndex2) == DataZoneEquipment::AirNodeType::CompInlet)) {
1534 7 : supNodeType(SupNodeIndex) = DataZoneEquipment::AirNodeType::Intermediate;
1535 7 : break;
1536 : }
1537 : }
1538 : }
1539 : }
1540 :
1541 : // the rest of the nodes are outlet nodes and count the duplicated intermediate nodes
1542 5861 : for (int SupNodeIndex = 1; SupNodeIndex <= NumAllSupAirPathNodes; ++SupNodeIndex) {
1543 4680 : if (supNodeType(SupNodeIndex) == DataZoneEquipment::AirNodeType::Invalid) {
1544 3485 : ++NumSupAirPathOutNodes;
1545 3485 : supNodeType(SupNodeIndex) = DataZoneEquipment::AirNodeType::Outlet;
1546 1195 : } else if (supNodeType(SupNodeIndex) == DataZoneEquipment::AirNodeType::Intermediate) {
1547 7 : ++NumSupAirPathIntNodes;
1548 : }
1549 : }
1550 :
1551 : // eliminate the duplicates to find the number of nodes in the supply air path
1552 1181 : NumSupAirPathNodes = NumAllSupAirPathNodes - NumSupAirPathIntNodes;
1553 1181 : SupAirPathNodeNum = 0;
1554 1181 : state.dataZoneEquip->SupplyAirPath(SupAirPath).OutletNode.allocate(NumSupAirPathOutNodes);
1555 1181 : state.dataZoneEquip->SupplyAirPath(SupAirPath).Node.allocate(NumSupAirPathNodes);
1556 1181 : state.dataZoneEquip->SupplyAirPath(SupAirPath).NodeType.allocate(NumSupAirPathNodes);
1557 1181 : state.dataZoneEquip->SupplyAirPath(SupAirPath).NumNodes = NumSupAirPathNodes;
1558 1181 : state.dataZoneEquip->SupplyAirPath(SupAirPath).NumOutletNodes = NumSupAirPathOutNodes;
1559 :
1560 : // transfer data from the local SupNode array to the SupplyAirPath data structure
1561 5861 : for (int SupNodeIndex = 1; SupNodeIndex <= NumAllSupAirPathNodes; ++SupNodeIndex) {
1562 12859 : if (supNodeType(SupNodeIndex) == DataZoneEquipment::AirNodeType::PathInlet ||
1563 8172 : supNodeType(SupNodeIndex) == DataZoneEquipment::AirNodeType::Intermediate ||
1564 3492 : supNodeType(SupNodeIndex) == DataZoneEquipment::AirNodeType::Outlet) {
1565 4673 : ++SupAirPathNodeNum;
1566 : // map the local node numbers to the HVAC (global) node numbers
1567 4673 : state.dataZoneEquip->SupplyAirPath(SupAirPath).Node(SupAirPathNodeNum) = supNode(SupNodeIndex);
1568 4673 : state.dataZoneEquip->SupplyAirPath(SupAirPath).NodeType(SupAirPathNodeNum) = supNodeType(SupNodeIndex);
1569 : }
1570 4680 : if (supNodeType(SupNodeIndex) == DataZoneEquipment::AirNodeType::Outlet) {
1571 3485 : ++SupAirPathOutNodeNum;
1572 : // map the outlet node number to the HVAC (global) node number
1573 3485 : state.dataZoneEquip->SupplyAirPath(SupAirPath).OutletNode(SupAirPathOutNodeNum) = supNode(SupNodeIndex);
1574 : }
1575 : }
1576 : }
1577 :
1578 : // Now loop over the air loops
1579 1947 : for (int AirLoopNum = 1; AirLoopNum <= numPrimaryAirSys; ++AirLoopNum) {
1580 1177 : auto &thisPrimaryAirSys = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
1581 1177 : auto &thisAirLoopControlInfo = state.dataAirLoop->AirLoopControlInfo(AirLoopNum);
1582 23667 : for (size_t num = 1; num <= atuArraySize; ++num) {
1583 22490 : cooledZone(num).ctrlZoneNum = 0;
1584 22490 : heatedZone(num).ctrlZoneNum = 0;
1585 22490 : cooledZone(num).zoneInletNode = 0;
1586 22490 : heatedZone(num).zoneInletNode = 0;
1587 22490 : cooledZone(num).termUnitInletNode = 0;
1588 22490 : heatedZone(num).termUnitInletNode = 0;
1589 22490 : cooledZone(num).termUnitSizingIndex = 0;
1590 22490 : heatedZone(num).termUnitSizingIndex = 0;
1591 : }
1592 1177 : int NumZonesCool = 0;
1593 1177 : int NumZonesHeat = 0;
1594 1177 : int NumComponentsInSys = 0;
1595 :
1596 : // count the number of components in this primary air system
1597 2373 : for (int BranchNum = 1; BranchNum <= thisPrimaryAirSys.NumBranches; ++BranchNum) {
1598 1196 : NumComponentsInSys += thisPrimaryAirSys.Branch(BranchNum).TotalComponents;
1599 : }
1600 : // set the Simple flag
1601 1177 : if (thisPrimaryAirSys.NumBranches == 1 && NumComponentsInSys == 1) {
1602 60 : thisAirLoopControlInfo.Simple = true;
1603 : }
1604 :
1605 1177 : auto &thisAirToZoneNodeInfo = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum);
1606 : // loop over the air loop's output nodes
1607 2362 : for (int OutNum = 1; OutNum <= thisAirToZoneNodeInfo.NumSupplyNodes; ++OutNum) {
1608 1185 : int ZoneSideNodeNum = thisAirToZoneNodeInfo.ZoneEquipSupplyNodeNum(OutNum);
1609 : // find the corresponding branch number
1610 1185 : int OutBranchNum = thisPrimaryAirSys.OutletBranchNum[OutNum - 1];
1611 : // find the supply air path corresponding to each air loop outlet node
1612 1185 : int SupAirPathNum = 0;
1613 : // loop over the air loop's output nodes
1614 6496 : for (int SupAirPath = 1; SupAirPath <= state.dataZoneEquip->NumSupplyAirPaths; ++SupAirPath) {
1615 6492 : if (ZoneSideNodeNum == state.dataZoneEquip->SupplyAirPath(SupAirPath).InletNodeNum) {
1616 1181 : SupAirPathNum = SupAirPath;
1617 1181 : break;
1618 : }
1619 : }
1620 1185 : int NumSupAirPathOutNodes = 0;
1621 1185 : if (SupAirPathNum > 0) {
1622 1181 : NumSupAirPathOutNodes = state.dataZoneEquip->SupplyAirPath(SupAirPathNum).NumOutletNodes;
1623 : }
1624 :
1625 : // Now Loop over the Supply Air Path outlet nodes and find out which zone and which air terminal
1626 : // unit on that zone is connected to that supply air path.
1627 :
1628 4670 : for (int SupAirPathOutNodeNum = 1; SupAirPathOutNodeNum <= NumSupAirPathOutNodes; ++SupAirPathOutNodeNum) {
1629 3485 : int FoundSupPathZoneConnect = false;
1630 : // loop over all controlled zones.
1631 53729 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
1632 53724 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
1633 : // Loop over the air distribution unit inlets for each controlled zone.
1634 : // Look for a match between the zone splitter outlet node and the air distribution unit inlet node.
1635 : // When match found save the controlled zone number in CtrlZoneNumsCool or CtrlZoneNumsHeat
1636 101674 : for (int ZoneInNum = 1; ZoneInNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumInletNodes; ++ZoneInNum) {
1637 :
1638 : // BEGIN COOLING: Check for a match between the cooling air distribution unit inlet
1639 : // and the supply air path outlet
1640 108938 : if (state.dataZoneEquip->SupplyAirPath(SupAirPathNum).OutletNode(SupAirPathOutNodeNum) ==
1641 54469 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitCool(ZoneInNum).InNode) {
1642 3451 : ++NumZonesCool;
1643 : // Set Duct Type for branch for dual duct
1644 3451 : if (NumZonesCool == 1 && OutBranchNum > 1) {
1645 9 : thisPrimaryAirSys.Branch(OutBranchNum).DuctType = DataHVACGlobals::AirDuctType::Cooling;
1646 : }
1647 3451 : if (NumZonesCool == 1) {
1648 1168 : thisAirToZoneNodeInfo.SupplyDuctType(OutNum) = DataHVACGlobals::AirDuctType::Cooling;
1649 : }
1650 3451 : cooledZone(NumZonesCool).ctrlZoneNum = CtrlZoneNum;
1651 3451 : cooledZone(NumZonesCool).zoneInletNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNode(ZoneInNum);
1652 3451 : cooledZone(NumZonesCool).termUnitInletNode =
1653 3451 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitCool(ZoneInNum).InNode;
1654 3451 : cooledZone(NumZonesCool).termUnitSizingIndex =
1655 3451 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitCool(ZoneInNum).TermUnitSizingIndex;
1656 3451 : if (AirLoopNum > 0) {
1657 3451 : if (thisPrimaryAirSys.OASysExists) {
1658 3105 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).ZoneHasAirLoopWithOASys = true;
1659 : }
1660 : }
1661 3451 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNodeAirLoopNum(ZoneInNum) = AirLoopNum;
1662 3451 : FoundSupPathZoneConnect = true;
1663 :
1664 : // set the supply air path
1665 3451 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitCool(ZoneInNum).SupplyAirPathExists = true;
1666 :
1667 : // Once a match is found between a supply air path outlet node and an air distribution inlet
1668 : // node, we go on to the next supply air path outlet. Therefore, *both* the air distribution
1669 : // unit loop and the controlled zone loop may be exited.
1670 3451 : goto ControlledZoneLoop_exit;
1671 : } // end check for cooling air distribution units
1672 :
1673 : // END COOLING: end check for match between supply air path outlet and cooling air
1674 : // distribution inlet
1675 :
1676 : // BEGIN HEATING: If we don't get a match, check for a heating match
1677 102036 : if (state.dataZoneEquip->SupplyAirPath(SupAirPathNum).OutletNode(SupAirPathOutNodeNum) ==
1678 51018 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitHeat(ZoneInNum).InNode) {
1679 29 : ++NumZonesHeat;
1680 : // Set Duct Type for branch for dual duct
1681 29 : if (NumZonesHeat == 1 && OutBranchNum > 1) {
1682 8 : thisPrimaryAirSys.Branch(OutBranchNum).DuctType = DataHVACGlobals::AirDuctType::Heating;
1683 : }
1684 29 : if (NumZonesHeat == 1) {
1685 8 : thisAirToZoneNodeInfo.SupplyDuctType(OutNum) = DataHVACGlobals::AirDuctType::Heating;
1686 : }
1687 29 : heatedZone(NumZonesHeat).ctrlZoneNum = CtrlZoneNum;
1688 29 : heatedZone(NumZonesHeat).zoneInletNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNode(ZoneInNum);
1689 29 : heatedZone(NumZonesHeat).termUnitInletNode =
1690 29 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitHeat(ZoneInNum).InNode;
1691 29 : heatedZone(NumZonesHeat).termUnitSizingIndex =
1692 29 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitHeat(ZoneInNum).TermUnitSizingIndex;
1693 29 : if (state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNodeAirLoopNum(ZoneInNum) == 0)
1694 29 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNodeAirLoopNum(ZoneInNum) = AirLoopNum;
1695 29 : FoundSupPathZoneConnect = true;
1696 :
1697 : // Set the supply air path flag
1698 29 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitHeat(ZoneInNum).SupplyAirPathExists = true;
1699 :
1700 : // Once a match is found between a supply air path outlet node and an air distribution inlet
1701 : // node, we go on to the next supply air path outlet. Therefore, *both* the air distribution
1702 : // unit loop and the controlled zone loop may be exited.
1703 29 : goto ControlledZoneLoop_exit;
1704 : } // end check for heatingair distribution units
1705 : }
1706 : }
1707 5 : ControlledZoneLoop_exit:;
1708 :
1709 : // If the supply air path is not connected to either a heating or a cooling air distribution
1710 : // unit...we have a problem!
1711 3485 : if (!FoundSupPathZoneConnect) {
1712 15 : ShowSevereError(
1713 : state,
1714 10 : "Node " +
1715 15 : state.dataLoopNodes->NodeID(state.dataZoneEquip->SupplyAirPath(SupAirPathNum).OutletNode(SupAirPathOutNodeNum)) +
1716 : " connects to no component");
1717 5 : ShowContinueError(state, "Occurs in Supply Air Path=" + state.dataZoneEquip->SupplyAirPath(SupAirPathNum).Name);
1718 5 : ShowContinueError(state, "Check the connection to a ZoneHVAC:EquipmentConnections object");
1719 5 : ShowContinueError(state, "Check if this component is missing from the Supply Air Path");
1720 5 : ErrorsFound = true;
1721 : }
1722 : }
1723 :
1724 : // What if there is no supply air path & the air loop outlet is just hooked directly to
1725 : // an air distribution unit of a single zone? In this case look for a match between
1726 : // ZoneSideNodeNum and a zone's air distribution unit inlets.
1727 1185 : if (SupAirPathNum == 0) {
1728 :
1729 10 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
1730 10 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
1731 : // Loop over the air distribution unit inlets for each controlled zone.
1732 : // Look for a match between the zone equip inlet node and the air distribution unit inlet node.
1733 : // When match found save the controlled zone number in CtrlZoneNumsCool or CtrlZoneNumsHeat
1734 16 : for (int ZoneInNum = 1; ZoneInNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumInletNodes; ++ZoneInNum) {
1735 :
1736 : // set supply air path flag
1737 10 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitCool(ZoneInNum).SupplyAirPathExists = false;
1738 :
1739 10 : if (ZoneSideNodeNum == state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitCool(ZoneInNum).InNode) {
1740 4 : ++NumZonesCool;
1741 : // Set Duct Type for branch for dual duct
1742 4 : if (NumZonesCool == 1 && OutBranchNum > 1) {
1743 0 : thisPrimaryAirSys.Branch(OutBranchNum).DuctType = DataHVACGlobals::AirDuctType::Cooling;
1744 : }
1745 4 : cooledZone(NumZonesCool).ctrlZoneNum = CtrlZoneNum;
1746 4 : cooledZone(NumZonesCool).zoneInletNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNode(ZoneInNum);
1747 4 : cooledZone(NumZonesCool).termUnitInletNode =
1748 4 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitCool(ZoneInNum).InNode;
1749 4 : cooledZone(NumZonesCool).termUnitSizingIndex =
1750 4 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitCool(ZoneInNum).TermUnitSizingIndex;
1751 4 : if (state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNodeAirLoopNum(ZoneInNum) == 0)
1752 4 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNodeAirLoopNum(ZoneInNum) = AirLoopNum;
1753 4 : goto ControlledZoneLoop2_exit;
1754 : }
1755 :
1756 6 : if (ZoneSideNodeNum == state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitHeat(ZoneInNum).InNode) {
1757 0 : ++NumZonesHeat;
1758 : // Set Duct Type for branch for dual duct
1759 0 : if (NumZonesHeat == 1 && OutBranchNum > 1) {
1760 0 : thisPrimaryAirSys.Branch(OutBranchNum).DuctType = DataHVACGlobals::AirDuctType::Heating;
1761 : }
1762 0 : heatedZone(NumZonesHeat).ctrlZoneNum = CtrlZoneNum;
1763 0 : heatedZone(NumZonesHeat).zoneInletNode = state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNode(ZoneInNum);
1764 0 : heatedZone(NumZonesHeat).termUnitInletNode =
1765 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitHeat(ZoneInNum).InNode;
1766 0 : heatedZone(NumZonesHeat).termUnitSizingIndex =
1767 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitHeat(ZoneInNum).TermUnitSizingIndex;
1768 0 : if (state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNodeAirLoopNum(ZoneInNum) == 0)
1769 0 : state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).InletNodeAirLoopNum(ZoneInNum) = AirLoopNum;
1770 0 : goto ControlledZoneLoop2_exit;
1771 : }
1772 : }
1773 : }
1774 0 : ControlledZoneLoop2_exit:;
1775 : } // End of no supply air path case
1776 1185 : if ((NumZonesCool + NumZonesHeat) == 0) {
1777 5 : ShowSevereError(state, "An outlet node in AirLoopHVAC=\"" + thisPrimaryAirSys.Name + "\" is not connected to any zone");
1778 15 : ShowContinueError(state,
1779 10 : "Could not match ZoneEquipGroup Inlet Node=\"" + state.dataLoopNodes->NodeID(ZoneSideNodeNum) +
1780 : "\" to any Supply Air Path or controlled zone");
1781 5 : ErrorsFound = true;
1782 : }
1783 : }
1784 :
1785 : // we now know the number of heated and cooled zones served by this primary air system.
1786 : // Allocate the subarrays in AirToZoneNodeInfo
1787 1177 : thisAirToZoneNodeInfo.CoolCtrlZoneNums.allocate(NumZonesCool);
1788 1177 : thisAirToZoneNodeInfo.HeatCtrlZoneNums.allocate(NumZonesHeat);
1789 1177 : thisAirToZoneNodeInfo.CoolZoneInletNodes.allocate(NumZonesCool);
1790 1177 : thisAirToZoneNodeInfo.HeatZoneInletNodes.allocate(NumZonesHeat);
1791 1177 : thisAirToZoneNodeInfo.TermUnitCoolInletNodes.allocate(NumZonesCool);
1792 1177 : thisAirToZoneNodeInfo.TermUnitHeatInletNodes.allocate(NumZonesHeat);
1793 1177 : thisAirToZoneNodeInfo.TermUnitCoolSizingIndex.allocate(NumZonesCool);
1794 1177 : thisAirToZoneNodeInfo.TermUnitHeatSizingIndex.allocate(NumZonesHeat);
1795 : // Move the controlled zone numbers from the scratch arrays into AirToZoneNodeInfo
1796 4632 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumZonesCool; ++ZoneInSysIndex) {
1797 3455 : thisAirToZoneNodeInfo.CoolCtrlZoneNums(ZoneInSysIndex) = cooledZone(ZoneInSysIndex).ctrlZoneNum;
1798 3455 : thisAirToZoneNodeInfo.CoolZoneInletNodes(ZoneInSysIndex) = cooledZone(ZoneInSysIndex).zoneInletNode;
1799 3455 : thisAirToZoneNodeInfo.TermUnitCoolInletNodes(ZoneInSysIndex) = cooledZone(ZoneInSysIndex).termUnitInletNode;
1800 3455 : thisAirToZoneNodeInfo.TermUnitCoolSizingIndex(ZoneInSysIndex) = cooledZone(ZoneInSysIndex).termUnitSizingIndex;
1801 : }
1802 :
1803 1206 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumZonesHeat; ++ZoneInSysIndex) {
1804 29 : thisAirToZoneNodeInfo.HeatCtrlZoneNums(ZoneInSysIndex) = heatedZone(ZoneInSysIndex).ctrlZoneNum;
1805 29 : thisAirToZoneNodeInfo.HeatZoneInletNodes(ZoneInSysIndex) = heatedZone(ZoneInSysIndex).zoneInletNode;
1806 29 : thisAirToZoneNodeInfo.TermUnitHeatInletNodes(ZoneInSysIndex) = heatedZone(ZoneInSysIndex).termUnitInletNode;
1807 29 : thisAirToZoneNodeInfo.TermUnitHeatSizingIndex(ZoneInSysIndex) = heatedZone(ZoneInSysIndex).termUnitSizingIndex;
1808 : }
1809 :
1810 1177 : thisAirToZoneNodeInfo.NumZonesCooled = NumZonesCool;
1811 1177 : thisAirToZoneNodeInfo.NumZonesHeated = NumZonesHeat;
1812 :
1813 : // now fill the return air bypass information needed by the RAB setpoint manager
1814 1177 : if (thisPrimaryAirSys.Splitter.Exists && thisPrimaryAirSys.Mixer.Exists) {
1815 1 : thisPrimaryAirSys.RABExists = true;
1816 5 : for (int BranchNum = 1; BranchNum <= thisPrimaryAirSys.NumBranches; ++BranchNum) {
1817 : // find the RAB branch; its inlet is a splitter outlet and it outlet is a mixer inlet
1818 11 : if ((thisPrimaryAirSys.Branch(BranchNum).NodeNumIn == thisPrimaryAirSys.Splitter.NodeNumOut(1) ||
1819 5 : thisPrimaryAirSys.Branch(BranchNum).NodeNumIn == thisPrimaryAirSys.Splitter.NodeNumOut(2)) &&
1820 3 : (thisPrimaryAirSys.Branch(BranchNum).NodeNumOut == thisPrimaryAirSys.Mixer.NodeNumIn(1) ||
1821 3 : thisPrimaryAirSys.Branch(BranchNum).NodeNumOut == thisPrimaryAirSys.Mixer.NodeNumIn(2)) &&
1822 7 : (thisPrimaryAirSys.Branch(BranchNum).TotalComponents == 1) &&
1823 5 : (UtilityRoutines::SameString(thisPrimaryAirSys.Branch(BranchNum).Comp(1).TypeOf, "Duct"))) {
1824 : // set the RAB splitter outlet node and the RAB mixer inlet node
1825 1 : thisPrimaryAirSys.RABSplitOutNode = thisPrimaryAirSys.Branch(BranchNum).NodeNumIn;
1826 1 : thisPrimaryAirSys.RABMixInNode = thisPrimaryAirSys.Branch(BranchNum).NodeNumOut;
1827 : // set the other nodes
1828 1 : if (thisPrimaryAirSys.Splitter.NodeNumOut(1) == thisPrimaryAirSys.RABSplitOutNode) {
1829 1 : thisPrimaryAirSys.OtherSplitOutNode = thisPrimaryAirSys.Splitter.NodeNumOut(2);
1830 : } else {
1831 0 : thisPrimaryAirSys.OtherSplitOutNode = thisPrimaryAirSys.Splitter.NodeNumOut(1);
1832 : }
1833 1 : if (thisPrimaryAirSys.Mixer.NodeNumIn(1) == thisPrimaryAirSys.RABMixInNode) {
1834 0 : thisPrimaryAirSys.SupMixInNode = thisPrimaryAirSys.Mixer.NodeNumIn(2);
1835 : } else {
1836 1 : thisPrimaryAirSys.SupMixInNode = thisPrimaryAirSys.Mixer.NodeNumIn(1);
1837 : }
1838 : // set the duct type
1839 1 : thisPrimaryAirSys.Branch(BranchNum).DuctType = DataHVACGlobals::AirDuctType::RAB;
1840 : }
1841 : }
1842 1 : thisPrimaryAirSys.MixOutNode = thisPrimaryAirSys.Mixer.NodeNumOut;
1843 : }
1844 : }
1845 :
1846 : // now fill out AirLoopZoneInfo for cleaner struct of zones attached to air loop, moved from MixedAir to here for use with Std. 62.1
1847 770 : int MaxNumAirLoopZones = 0;
1848 1947 : for (int AirLoopNum = 1; AirLoopNum <= numPrimaryAirSys; ++AirLoopNum) {
1849 1177 : auto &thisAirToZoneNodeInfo = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum);
1850 1177 : int NumAirLoopZones = thisAirToZoneNodeInfo.NumZonesCooled + thisAirToZoneNodeInfo.NumZonesHeated;
1851 : // NumZonesCooled + NumZonesHeated must be > 0 or Fatal error is issued in SimAirServingZones
1852 1177 : MaxNumAirLoopZones = max(MaxNumAirLoopZones, NumAirLoopZones); // Max number of zones on any air loop being simulated
1853 : }
1854 : // Find the zones attached to each air loop
1855 1947 : for (int AirLoopNum = 1; AirLoopNum <= numPrimaryAirSys; ++AirLoopNum) {
1856 1177 : auto &thisAirToZoneNodeInfo = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum);
1857 1177 : auto &thisAirLoopZoneInfo = state.dataAirLoop->AirLoopZoneInfo(AirLoopNum);
1858 1177 : thisAirLoopZoneInfo.Zone.allocate(MaxNumAirLoopZones);
1859 1177 : thisAirLoopZoneInfo.ActualZoneNumber.allocate(MaxNumAirLoopZones);
1860 1177 : int NumAirLoopCooledZones = thisAirToZoneNodeInfo.NumZonesCooled;
1861 1177 : int AirLoopZones = NumAirLoopCooledZones;
1862 1177 : int NumAirLoopHeatedZones = thisAirToZoneNodeInfo.NumZonesHeated;
1863 : // Store cooling zone numbers in AirLoopZoneInfo data structure
1864 4632 : for (int NumAirLoopCooledZonesTemp = 1; NumAirLoopCooledZonesTemp <= NumAirLoopCooledZones; ++NumAirLoopCooledZonesTemp) {
1865 3455 : thisAirLoopZoneInfo.Zone(NumAirLoopCooledZonesTemp) = thisAirToZoneNodeInfo.CoolCtrlZoneNums(NumAirLoopCooledZonesTemp);
1866 3455 : thisAirLoopZoneInfo.ActualZoneNumber(NumAirLoopCooledZonesTemp) = thisAirToZoneNodeInfo.CoolCtrlZoneNums(NumAirLoopCooledZonesTemp);
1867 : }
1868 : // Store heating zone numbers in AirLoopZoneInfo data structure
1869 : // Only store zone numbers that aren't already defined as cooling zones above
1870 1206 : for (int NumAirLoopHeatedZonesTemp = 1; NumAirLoopHeatedZonesTemp <= NumAirLoopHeatedZones; ++NumAirLoopHeatedZonesTemp) {
1871 29 : int ZoneNum = thisAirToZoneNodeInfo.HeatCtrlZoneNums(NumAirLoopHeatedZonesTemp);
1872 29 : bool CommonZone = false;
1873 144 : for (int NumAirLoopCooledZonesTemp = 1; NumAirLoopCooledZonesTemp <= NumAirLoopCooledZones; ++NumAirLoopCooledZonesTemp) {
1874 115 : if (ZoneNum != thisAirToZoneNodeInfo.CoolCtrlZoneNums(NumAirLoopCooledZonesTemp)) continue;
1875 29 : CommonZone = true;
1876 : }
1877 29 : if (!CommonZone) {
1878 0 : ++AirLoopZones;
1879 0 : thisAirLoopZoneInfo.Zone(AirLoopZones) = ZoneNum;
1880 0 : thisAirLoopZoneInfo.ActualZoneNumber(AirLoopZones) = ZoneNum;
1881 : }
1882 : }
1883 1177 : thisAirLoopZoneInfo.NumZones = AirLoopZones;
1884 : }
1885 :
1886 : // now register zone inlet nodes as critical demand nodes in the convergence tracking
1887 770 : state.dataConvergeParams->ZoneInletConvergence.allocate(state.dataGlobal->NumOfZones);
1888 5578 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
1889 4808 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumInletNodes > 0) {
1890 4017 : state.dataConvergeParams->ZoneInletConvergence(ZoneNum).NumInletNodes = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumInletNodes;
1891 8034 : state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode.allocate(
1892 8034 : state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumInletNodes);
1893 8255 : for (int nodeLoop = 1; nodeLoop <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumInletNodes; ++nodeLoop) {
1894 4238 : state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(nodeLoop).NodeNum =
1895 4238 : state.dataZoneEquip->ZoneEquipConfig(ZoneNum).InletNode(nodeLoop);
1896 : }
1897 : }
1898 : }
1899 :
1900 : // now connect return nodes with airloops and corresponding inlet nodes
1901 770 : ConnectReturnNodes(state);
1902 :
1903 770 : state.dataSimAirServingZones->InitAirLoopsOneTimeFlag = false;
1904 :
1905 770 : if (ErrorsFound) {
1906 2 : ShowFatalError(state, "Preceding errors cause termination");
1907 : }
1908 :
1909 1941 : for (int AirLoopNum = 1; AirLoopNum <= numPrimaryAirSys; ++AirLoopNum) {
1910 1172 : auto &thisPrimaryAirSys = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
1911 :
1912 1172 : int SupFanIndex = 0;
1913 1172 : int RetFanIndex = 0;
1914 1172 : bool FoundOASys = false;
1915 1172 : thisPrimaryAirSys.FanDesCoolLoad = 0.0;
1916 1172 : FanModelType supFanModelType = FanModelType::Invalid;
1917 1172 : FanModelType retFanModelType = FanModelType::Invalid;
1918 :
1919 1172 : bool FoundCentralCoolCoil = false;
1920 1653 : for (int BranchNum = 1; BranchNum <= thisPrimaryAirSys.NumBranches; ++BranchNum) {
1921 :
1922 3885 : for (int CompNum = 1; CompNum <= thisPrimaryAirSys.Branch(BranchNum).TotalComponents; ++CompNum) {
1923 3404 : CompType compType = thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).CompType_Num;
1924 3404 : if (thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).CompType_Num == CompType::OAMixer_Num) {
1925 1021 : FoundOASys = true;
1926 : }
1927 3404 : if (compType == CompType::WaterCoil_Cooling || compType == CompType::WaterCoil_DetailedCool ||
1928 3088 : compType == CompType::WaterCoil_CoolingHXAsst || compType == CompType::DXSystem) {
1929 561 : FoundCentralCoolCoil = true;
1930 : }
1931 3404 : if (compType == CompType::Fan_Simple_CV || compType == CompType::Fan_Simple_VAV || compType == CompType::Fan_ComponentModel) {
1932 695 : if (thisPrimaryAirSys.OASysExists && !thisPrimaryAirSys.isAllOA) {
1933 609 : if (FoundOASys) {
1934 599 : if (thisPrimaryAirSys.Branch(BranchNum).DuctType != DataHVACGlobals::AirDuctType::Heating) {
1935 597 : Fans::GetFanIndex(state, thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).Name, SupFanIndex, ErrorsFound);
1936 597 : supFanModelType = StructArrayLegacyFanModels;
1937 597 : goto EndOfAirLoop;
1938 : }
1939 : } else {
1940 4 : Fans::GetFanIndex(state, thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).Name, RetFanIndex, ErrorsFound);
1941 4 : retFanModelType = StructArrayLegacyFanModels;
1942 : }
1943 : } else {
1944 92 : Fans::GetFanIndex(state, thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).Name, SupFanIndex, ErrorsFound);
1945 92 : supFanModelType = StructArrayLegacyFanModels;
1946 92 : goto EndOfAirLoop;
1947 : }
1948 : }
1949 2715 : if (compType == CompType::Fan_System_Object) {
1950 9 : if (thisPrimaryAirSys.OASysExists && !thisPrimaryAirSys.isAllOA) {
1951 9 : if (FoundOASys) {
1952 9 : if (thisPrimaryAirSys.Branch(BranchNum).DuctType != DataHVACGlobals::AirDuctType::Heating) {
1953 9 : SupFanIndex = HVACFan::getFanObjectVectorIndex(state, thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).Name);
1954 9 : supFanModelType = ObjectVectorOOFanSystemModel;
1955 9 : goto EndOfAirLoop;
1956 : }
1957 : } else {
1958 0 : RetFanIndex = HVACFan::getFanObjectVectorIndex(state, thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).Name);
1959 0 : retFanModelType = ObjectVectorOOFanSystemModel;
1960 : }
1961 : } else {
1962 0 : SupFanIndex = HVACFan::getFanObjectVectorIndex(state, thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).Name);
1963 0 : supFanModelType = ObjectVectorOOFanSystemModel;
1964 0 : goto EndOfAirLoop;
1965 : }
1966 : }
1967 :
1968 : } // end of component loop
1969 :
1970 : } // end of Branch loop
1971 474 : EndOfAirLoop:;
1972 :
1973 1172 : if (supFanModelType == StructArrayLegacyFanModels) {
1974 689 : thisPrimaryAirSys.SupFanNum = SupFanIndex;
1975 689 : thisPrimaryAirSys.supFanModelType = StructArrayLegacyFanModels;
1976 483 : } else if (supFanModelType == ObjectVectorOOFanSystemModel) {
1977 9 : thisPrimaryAirSys.supFanVecIndex = SupFanIndex;
1978 9 : thisPrimaryAirSys.supFanModelType = ObjectVectorOOFanSystemModel;
1979 : }
1980 1172 : if (FoundCentralCoolCoil) { // parent systems with fan will need to set the fan placement
1981 549 : thisPrimaryAirSys.supFanLocation = FanPlacement::DrawThru;
1982 : } else {
1983 623 : thisPrimaryAirSys.supFanLocation = FanPlacement::BlowThru;
1984 : }
1985 :
1986 1172 : if (retFanModelType == StructArrayLegacyFanModels) {
1987 4 : thisPrimaryAirSys.retFanModelType = StructArrayLegacyFanModels;
1988 4 : thisPrimaryAirSys.RetFanNum = RetFanIndex;
1989 1168 : } else if (retFanModelType == ObjectVectorOOFanSystemModel) {
1990 0 : thisPrimaryAirSys.retFanModelType = ObjectVectorOOFanSystemModel;
1991 0 : thisPrimaryAirSys.retFanVecIndex = RetFanIndex;
1992 : }
1993 : }
1994 : // Check whether there are Central Heating Coils in the Primary Air System
1995 1941 : for (int AirLoopNum = 1; AirLoopNum <= numPrimaryAirSys; ++AirLoopNum) {
1996 1172 : auto &thisPrimaryAirSys = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
1997 1172 : bool FoundCentralHeatCoil = false;
1998 1172 : bool unitaryCoolingCoilExists = false;
1999 1172 : bool unitaryHeatingCoilExists = false;
2000 2354 : for (int BranchNum = 1; !FoundCentralHeatCoil && BranchNum <= thisPrimaryAirSys.NumBranches; ++BranchNum) {
2001 4127 : for (int CompNum = 1; !FoundCentralHeatCoil && CompNum <= thisPrimaryAirSys.Branch(BranchNum).TotalComponents; ++CompNum) {
2002 2945 : std::string &CompName = thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).Name;
2003 2945 : CompType CompTypeNum = thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).CompType_Num;
2004 2945 : switch (CompTypeNum) {
2005 947 : case CompType::WaterCoil_SimpleHeat:
2006 : case CompType::Coil_ElectricHeat:
2007 : case CompType::Coil_GasHeat:
2008 : case CompType::SteamCoil_AirHeat:
2009 : case CompType::Coil_DeSuperHeat:
2010 : case CompType::DXHeatPumpSystem:
2011 : case CompType::Furnace_UnitarySys_HeatOnly:
2012 : case CompType::Furnace_UnitarySys_HeatCool:
2013 : case CompType::UnitarySystem_BypassVAVSys:
2014 : case CompType::UnitarySystem_MSHeatPump:
2015 : case CompType::CoilUserDefined:
2016 947 : FoundCentralHeatCoil = true;
2017 947 : break;
2018 104 : case CompType::UnitarySystemModel:
2019 : // mine HeatCoilExists from UnitarySystem
2020 104 : unitaryCoolingCoilExists = false;
2021 104 : unitaryHeatingCoilExists = false;
2022 104 : UnitarySystems::UnitarySys::getUnitarySysHeatCoolCoil(state, CompName, unitaryCoolingCoilExists, unitaryHeatingCoilExists, 0);
2023 104 : if (unitaryHeatingCoilExists) FoundCentralHeatCoil = true;
2024 104 : break;
2025 1894 : default:
2026 1894 : break;
2027 : }
2028 : } // end of component loop
2029 : } // end of Branch loop
2030 1172 : thisPrimaryAirSys.CentralHeatCoilExists = FoundCentralHeatCoil;
2031 : } // end of AirLoop loop
2032 :
2033 : // Check whether there are Central Cooling Coils in the Primary Air System
2034 1941 : for (int AirLoopNum = 1; AirLoopNum <= numPrimaryAirSys; ++AirLoopNum) {
2035 1172 : auto &thisPrimaryAirSys = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
2036 1172 : bool FoundCentralCoolCoil = false;
2037 1172 : bool unitaryCoolingCoilExists = false;
2038 1172 : bool unitaryHeatingCoilExists = false;
2039 2361 : for (int BranchNum = 1; !FoundCentralCoolCoil && BranchNum <= thisPrimaryAirSys.NumBranches; ++BranchNum) {
2040 3632 : for (int CompNum = 1; !FoundCentralCoolCoil && CompNum <= thisPrimaryAirSys.Branch(BranchNum).TotalComponents; ++CompNum) {
2041 2443 : CompType CompTypeNum = thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).CompType_Num;
2042 2443 : std::string &CompName = thisPrimaryAirSys.Branch(BranchNum).Comp(CompNum).Name;
2043 2443 : switch (CompTypeNum) {
2044 1040 : case CompType::WaterCoil_Cooling:
2045 : case CompType::WaterCoil_DetailedCool:
2046 : case CompType::WaterCoil_CoolingHXAsst:
2047 : case CompType::DXSystem:
2048 : case CompType::Furnace_UnitarySys_HeatCool:
2049 : case CompType::UnitarySystem_BypassVAVSys:
2050 : case CompType::UnitarySystem_MSHeatPump:
2051 : case CompType::CoilUserDefined:
2052 1040 : FoundCentralCoolCoil = true;
2053 1040 : break;
2054 103 : case CompType::UnitarySystemModel:
2055 : // mine CoolHeat coil exists from UnitarySys
2056 103 : unitaryCoolingCoilExists = false;
2057 103 : unitaryHeatingCoilExists = false;
2058 103 : UnitarySystems::UnitarySys::getUnitarySysHeatCoolCoil(state, CompName, unitaryCoolingCoilExists, unitaryHeatingCoilExists, 0);
2059 103 : if (unitaryCoolingCoilExists) FoundCentralCoolCoil = true;
2060 103 : break;
2061 1300 : default:
2062 1300 : break;
2063 : }
2064 : } // end of component loop
2065 : } // end of Branch loop
2066 1172 : thisPrimaryAirSys.CentralCoolCoilExists = FoundCentralCoolCoil;
2067 : } // end of AirLoop loop
2068 :
2069 : } // one time flag
2070 :
2071 : // Size the air loop branch air flows
2072 6484925 : if (!state.dataGlobal->SysSizingCalc && state.dataSimAirServingZones->InitAirLoopsBranchSizingFlag) {
2073 :
2074 1941 : for (int AirLoopNum = 1; AirLoopNum <= numPrimaryAirSys; ++AirLoopNum) {
2075 1172 : auto &thisPrimaryAirSys = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
2076 :
2077 2363 : for (int BranchNum = 1; BranchNum <= thisPrimaryAirSys.NumBranches; ++BranchNum) {
2078 1191 : SizeAirLoopBranches(state, AirLoopNum, BranchNum);
2079 : }
2080 : }
2081 :
2082 769 : state.dataSimAirServingZones->InitAirLoopsBranchSizingFlag = false;
2083 :
2084 : // calculate the ratio of air loop design flow to the sum of the zone design flows
2085 1941 : for (int AirLoopNum = 1; AirLoopNum <= numPrimaryAirSys; ++AirLoopNum) {
2086 1172 : auto &thisPrimaryAirSys = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
2087 1172 : auto &thisAirToZoneNodeInfo = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum);
2088 1172 : state.dataSimAirServingZones->SumZoneDesFlow = 0.0;
2089 1172 : state.dataAirLoop->AirLoopFlow(AirLoopNum).DesSupply = thisPrimaryAirSys.DesignVolFlowRate * state.dataEnvrn->StdRhoAir;
2090 1172 : state.dataAirLoop->AirLoopFlow(AirLoopNum).DesReturnFrac = thisPrimaryAirSys.DesignReturnFlowFraction;
2091 4627 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= thisAirToZoneNodeInfo.NumZonesCooled; ++ZoneInSysIndex) {
2092 3455 : state.dataSimAirServingZones->TUInNode = thisAirToZoneNodeInfo.TermUnitCoolInletNodes(ZoneInSysIndex);
2093 3455 : state.dataSimAirServingZones->SumZoneDesFlow += state.dataLoopNodes->Node(state.dataSimAirServingZones->TUInNode).MassFlowRateMax;
2094 : }
2095 1172 : if (state.dataSimAirServingZones->SumZoneDesFlow > VerySmallMassFlow) {
2096 1150 : state.dataAirLoop->AirLoopFlow(AirLoopNum).SysToZoneDesFlowRatio =
2097 1150 : state.dataAirLoop->AirLoopFlow(AirLoopNum).DesSupply / state.dataSimAirServingZones->SumZoneDesFlow;
2098 : } else {
2099 22 : state.dataAirLoop->AirLoopFlow(AirLoopNum).SysToZoneDesFlowRatio = 1.0;
2100 : }
2101 : }
2102 :
2103 5571 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
2104 4802 : if (!state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) continue;
2105 : // sets design supply air flow rate in the ZoneEquipConfig struct for use with zone air mass balance
2106 8192 : for (int returnNum = 1; returnNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes; ++returnNum) {
2107 4098 : int airLoop = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ReturnNodeAirLoopNum(returnNum);
2108 4098 : if (airLoop > 0) {
2109 3435 : state.dataZoneEquip->ZoneEquipConfig(ZoneNum).AirLoopDesSupply = state.dataAirLoop->AirLoopFlow(airLoop).DesSupply;
2110 : }
2111 : }
2112 : }
2113 : }
2114 :
2115 : // Do the Begin Environment initializations
2116 6484925 : if (state.dataGlobal->BeginEnvrnFlag && FirstHVACIteration && state.dataSimAirServingZones->MyEnvrnFlag) {
2117 :
2118 4495 : if (numPrimaryAirSys > 0) {
2119 10523 : for (auto &e : state.dataAirLoop->PriAirSysAvailMgr) {
2120 7372 : e.AvailStatus = NoAction;
2121 7372 : e.StartTime = 0;
2122 7372 : e.StopTime = 0;
2123 : }
2124 : }
2125 :
2126 11867 : for (int AirLoopNum = 1; AirLoopNum <= numPrimaryAirSys; ++AirLoopNum) { // Start looping through all of the air loops...
2127 7372 : auto &thisPrimaryAirSys = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
2128 :
2129 14870 : for (int BranchNum = 1; BranchNum <= thisPrimaryAirSys.NumBranches; ++BranchNum) { // loop over all branches in system
2130 37792 : for (int NodeIndex = 1; NodeIndex <= thisPrimaryAirSys.Branch(BranchNum).TotalNodes; ++NodeIndex) { // loop over alll nodes on branch
2131 :
2132 30294 : int NodeNum = thisPrimaryAirSys.Branch(BranchNum).NodeNum(NodeIndex);
2133 :
2134 : // Initialize the nodes to a standard set of initial conditions that will
2135 : // change after the first iteration to a system value
2136 30294 : state.dataLoopNodes->Node(NodeNum).Temp = 20.0;
2137 30294 : state.dataLoopNodes->Node(NodeNum).HumRat = state.dataEnvrn->OutHumRat;
2138 30294 : state.dataLoopNodes->Node(NodeNum).Enthalpy =
2139 30294 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(NodeNum).Temp, state.dataLoopNodes->Node(NodeNum).HumRat);
2140 : // set the node mass flow rates to the airloop max mass flow rate
2141 30294 : state.dataLoopNodes->Node(NodeNum).MassFlowRate = state.dataAirLoop->AirLoopFlow(AirLoopNum).DesSupply;
2142 30294 : state.dataLoopNodes->Node(NodeNum).MassFlowRateMax = state.dataAirLoop->AirLoopFlow(AirLoopNum).DesSupply;
2143 30294 : state.dataLoopNodes->Node(NodeNum).MassFlowRateMaxAvail = state.dataAirLoop->AirLoopFlow(AirLoopNum).DesSupply;
2144 30294 : state.dataLoopNodes->Node(NodeNum).MassFlowRateMin = 0.0;
2145 30294 : state.dataLoopNodes->Node(NodeNum).MassFlowRateSetPoint = 0.0;
2146 30294 : state.dataLoopNodes->Node(NodeNum).MassFlowRateMinAvail = 0.0;
2147 30294 : state.dataLoopNodes->Node(NodeNum).Press = state.dataEnvrn->StdBaroPress;
2148 30294 : state.dataLoopNodes->Node(NodeNum).Quality = 0.0;
2149 30294 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
2150 126 : state.dataLoopNodes->Node(NodeNum).CO2 = state.dataContaminantBalance->OutdoorCO2;
2151 : }
2152 30294 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
2153 45 : state.dataLoopNodes->Node(NodeNum).GenContam = state.dataContaminantBalance->OutdoorGC;
2154 : }
2155 :
2156 : } // end of loop over nodes on each branch
2157 :
2158 : } // end of loop through branches in system
2159 :
2160 : } // end of loop over primary air systems
2161 4495 : state.dataSimAirServingZones->MyEnvrnFlag = false;
2162 :
2163 : } // End the environment initializations
2164 :
2165 6484925 : if (!state.dataGlobal->BeginEnvrnFlag) {
2166 6460100 : state.dataSimAirServingZones->MyEnvrnFlag = true;
2167 : }
2168 :
2169 : // Do the Begin Day initializations
2170 6484925 : if (state.dataGlobal->BeginDayFlag) {
2171 : }
2172 :
2173 : // There are no hourly initializations done in the heat balance
2174 :
2175 : // Do the following initializations (every time step).
2176 :
2177 18559940 : for (int AirLoopNum = 1; AirLoopNum <= numPrimaryAirSys; ++AirLoopNum) {
2178 12075015 : auto &thisPrimaryAirSys = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
2179 12075015 : auto &thisAirToZoneNodeInfo = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum);
2180 12075015 : auto &thisAirLoopControlInfo = state.dataAirLoop->AirLoopControlInfo(AirLoopNum);
2181 : // zero all MassFlowRateSetPoints
2182 24272908 : for (int BranchNum = 1; BranchNum <= thisPrimaryAirSys.NumBranches; ++BranchNum) { // loop over all branches in system
2183 12197893 : if (thisPrimaryAirSys.Branch(BranchNum).DuctType == DataHVACGlobals::AirDuctType::RAB) continue;
2184 61437726 : for (int NodeIndex = 1; NodeIndex <= thisPrimaryAirSys.Branch(BranchNum).TotalNodes; ++NodeIndex) { // loop over alll nodes on branch
2185 49244207 : int NodeNum = thisPrimaryAirSys.Branch(BranchNum).NodeNum(NodeIndex);
2186 49244207 : state.dataLoopNodes->Node(NodeNum).MassFlowRateSetPoint = 0.0;
2187 : // Reset MassFlowRateMaxAvail at start of each HVAC simulation
2188 49244207 : if (FirstHVACIteration) {
2189 17854819 : state.dataLoopNodes->Node(NodeNum).MassFlowRateMaxAvail = state.dataLoopNodes->Node(NodeNum).MassFlowRateMax;
2190 17854819 : state.dataLoopNodes->Node(NodeNum).MassFlowRateMinAvail = state.dataLoopNodes->Node(NodeNum).MassFlowRateMin;
2191 : }
2192 : }
2193 : }
2194 :
2195 : // set the required flow (from zone equipment) at system outlet nodes
2196 24204908 : for (int OutNum = 1; OutNum <= thisPrimaryAirSys.NumOutletBranches; ++OutNum) {
2197 12129893 : int OutBranchNum = thisPrimaryAirSys.OutletBranchNum[OutNum - 1];
2198 12129893 : int NodeNumOut = thisPrimaryAirSys.Branch(OutBranchNum).NodeNumOut;
2199 12129893 : int ZoneSideNodeNum = thisAirToZoneNodeInfo.ZoneEquipSupplyNodeNum(OutNum);
2200 12129893 : Real64 MassFlowSet = 0.0;
2201 :
2202 12129893 : if (!FirstHVACIteration) {
2203 7883785 : MassFlowSet = state.dataLoopNodes->Node(ZoneSideNodeNum).MassFlowRate;
2204 : } else { // first time through in each HVAC timestep, use loop design mass flow rates for required mass flows
2205 4246108 : MassFlowSet = state.dataAirLoop->AirLoopFlow(AirLoopNum).DesSupply;
2206 : }
2207 : // Need to make sure that flows are greater than zero
2208 12129893 : if (MassFlowSet >= 0.0) {
2209 12129893 : state.dataLoopNodes->Node(NodeNumOut).MassFlowRateSetPoint = MassFlowSet;
2210 0 : } else if (MassFlowSet < 0.0) {
2211 0 : state.dataLoopNodes->Node(NodeNumOut).MassFlowRateSetPoint = 0.0;
2212 : }
2213 :
2214 12129893 : if (state.dataLoopNodes->Node(NodeNumOut).MassFlowRateSetPoint < state.dataSimAirServingZones->MassFlowSetToler) {
2215 1150539 : state.dataLoopNodes->Node(NodeNumOut).MassFlowRateSetPoint = 0.0;
2216 : }
2217 :
2218 : // Pass the required mass flow upstream to the start of each outlet branch
2219 49105392 : for (int BranchNodeIndex = thisPrimaryAirSys.Branch(OutBranchNum).TotalNodes - 1; BranchNodeIndex >= 1; --BranchNodeIndex) {
2220 36975499 : int NodeNum = thisPrimaryAirSys.Branch(OutBranchNum).NodeNum(BranchNodeIndex);
2221 36975499 : if (thisPrimaryAirSys.OASysExists && (NodeNum == thisPrimaryAirSys.OASysInletNodeNum)) {
2222 : // need to modify if OA relief and supply not balanced because of exhaust fans
2223 20966586 : state.dataSimAirServingZones->OAReliefDiff = state.dataLoopNodes->Node(thisPrimaryAirSys.OASysOutletNodeNum).MassFlowRate -
2224 10483293 : state.dataLoopNodes->Node(NodeNum).MassFlowRate;
2225 20966586 : if (state.dataSimAirServingZones->OAReliefDiff > 0.0) {
2226 3697792 : state.dataLoopNodes->Node(NodeNum).MassFlowRateSetPoint =
2227 3697792 : state.dataLoopNodes->Node(NodeNumOut).MassFlowRateSetPoint - state.dataSimAirServingZones->OAReliefDiff;
2228 : } else {
2229 6785501 : state.dataLoopNodes->Node(NodeNum).MassFlowRateSetPoint = state.dataLoopNodes->Node(NodeNumOut).MassFlowRateSetPoint;
2230 : }
2231 : } else {
2232 26492206 : state.dataLoopNodes->Node(NodeNum).MassFlowRateSetPoint = state.dataLoopNodes->Node(NodeNumOut).MassFlowRateSetPoint;
2233 : }
2234 : } // end loop over branch nodes
2235 :
2236 : } // end loop over outlet branches
2237 :
2238 : // [DC/LBNL] Initialize flag for current air loop
2239 12075015 : thisAirLoopControlInfo.NewFlowRateFlag = false;
2240 :
2241 : // start each HVAC simulation at design air flow rate
2242 12075015 : if (FirstHVACIteration) {
2243 : // At each new HVAC iteration reset air loop converged flag to avoid attempting a warm restart
2244 : // in SimAirLoop
2245 4222351 : thisAirLoopControlInfo.ConvergedFlag = false;
2246 :
2247 8444702 : for (int InNum = 1; InNum <= thisPrimaryAirSys.NumInletBranches; ++InNum) {
2248 4222351 : int InBranchNum = thisPrimaryAirSys.InletBranchNum[InNum - 1];
2249 4222351 : if (InBranchNum == 0) {
2250 0 : ShowFatalError(state, "Missing Inlet Branch on Primary Air System=" + thisPrimaryAirSys.Name);
2251 : }
2252 4222351 : int NodeNumIn = thisPrimaryAirSys.Branch(InBranchNum).NodeNumIn;
2253 :
2254 : // [DC/LBNL] Save previous mass flow rate
2255 4222351 : Real64 MassFlowSaved = state.dataLoopNodes->Node(NodeNumIn).MassFlowRate;
2256 :
2257 4222351 : state.dataLoopNodes->Node(NodeNumIn).MassFlowRate = state.dataAirLoop->AirLoopFlow(AirLoopNum).DesSupply;
2258 :
2259 : // [DC/LBNL] Detect if air mass flow rate has changed since last air loop simulation
2260 4222351 : if (state.dataLoopNodes->Node(NodeNumIn).MassFlowRate != MassFlowSaved) {
2261 3124062 : thisAirLoopControlInfo.NewFlowRateFlag = true;
2262 : }
2263 :
2264 : } // end loop over inlet branches
2265 4222351 : thisAirLoopControlInfo.EconoLockout = false;
2266 : }
2267 : // if a flow rate is specified for the loop use it here
2268 12075015 : if (thisAirLoopControlInfo.LoopFlowRateSet && !FirstHVACIteration) {
2269 15190 : for (int InNum = 1; InNum <= thisPrimaryAirSys.NumInletBranches; ++InNum) {
2270 7595 : int InBranchNum = thisPrimaryAirSys.InletBranchNum[InNum - 1];
2271 7595 : int NodeNumIn = thisPrimaryAirSys.Branch(InBranchNum).NodeNumIn;
2272 7595 : state.dataLoopNodes->Node(NodeNumIn).MassFlowRate =
2273 15190 : state.dataAirLoop->AirLoopFlow(AirLoopNum).DesSupply * state.dataAirLoop->AirLoopFlow(AirLoopNum).ReqSupplyFrac -
2274 7595 : (state.dataAirLoop->AirLoopFlow(AirLoopNum).SupFlow - state.dataAirLoop->AirLoopFlow(AirLoopNum).SysRetFlow);
2275 : }
2276 : }
2277 :
2278 : } // end loop over primary air systems
2279 6484925 : }
2280 :
2281 770 : void ConnectReturnNodes(EnergyPlusData &state)
2282 : {
2283 : // This initializes ZoneEquipConfig.ReturnNodeInletNum and ReturnNodeAirLoopNum
2284 : // Search all return paths to match return nodes with the airloop they are connected to and find the corresponding zone inlet node
2285 : // (same zone, same airloop)
2286 :
2287 770 : auto &AirToZoneNodeInfo(state.dataAirLoop->AirToZoneNodeInfo);
2288 770 : auto &NumPrimaryAirSys = state.dataHVACGlobal->NumPrimaryAirSys;
2289 :
2290 770 : if (!state.dataZoneEquip->ZoneEquipInputsFilled) return;
2291 :
2292 770 : bool returnPathFound = false;
2293 : // Loop over all controlled zones
2294 5578 : for (int ctrlZoneNum = 1; ctrlZoneNum <= state.dataGlobal->NumOfZones; ++ctrlZoneNum) {
2295 4808 : auto &thisZoneEquip(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum));
2296 4808 : if (!thisZoneEquip.IsControlled) continue;
2297 : // Loop over each return node for this zone
2298 8202 : for (int zoneOutNum = 1; zoneOutNum <= thisZoneEquip.NumReturnNodes; ++zoneOutNum) {
2299 4103 : returnPathFound = false;
2300 4103 : int airLoopNum = 0;
2301 4103 : int thisReturnNode = thisZoneEquip.ReturnNode(zoneOutNum);
2302 : // Loop over all return paths
2303 12865 : for (int retPathNum = 1; retPathNum <= state.dataZoneEquip->NumReturnAirPaths; ++retPathNum) {
2304 12193 : auto const &thisRetPath(state.dataZoneEquip->ReturnAirPath(retPathNum));
2305 : // Find which airloop this return path is on
2306 119830 : for (int sysNum = 1; sysNum <= NumPrimaryAirSys; ++sysNum) {
2307 119830 : if (AirToZoneNodeInfo(sysNum).NumReturnNodes > 0) {
2308 119830 : if (thisRetPath.OutletNodeNum == AirToZoneNodeInfo(sysNum).ZoneEquipReturnNodeNum(1)) {
2309 12193 : airLoopNum = sysNum;
2310 12193 : break;
2311 : }
2312 : }
2313 : }
2314 : // Loop over components in return path and each component's inlet nodes
2315 21577 : for (int compNum = 1; compNum <= thisRetPath.NumOfComponents; ++compNum) {
2316 12815 : DataZoneEquipment::AirLoopHVACZone compType = thisRetPath.ComponentTypeEnum(compNum);
2317 12815 : if (compType == DataZoneEquipment::AirLoopHVACZone::Mixer) {
2318 10845 : auto const &thisMixer(state.dataMixerComponent->MixerCond(thisRetPath.ComponentIndex(compNum)));
2319 54085 : for (int inNode = 1; inNode <= thisMixer.NumInletNodes; ++inNode) {
2320 45421 : if (thisReturnNode == thisMixer.InletNode(inNode)) {
2321 2181 : thisZoneEquip.ReturnNodeAirLoopNum(zoneOutNum) = airLoopNum; // set the return node airloop num
2322 2181 : returnPathFound = true;
2323 2181 : break; // leave component inlet node loop
2324 : }
2325 : }
2326 1970 : } else if (compType == DataZoneEquipment::AirLoopHVACZone::ReturnPlenum) {
2327 1970 : auto const &thisPlenum(state.dataZonePlenum->ZoneRetPlenCond(thisRetPath.ComponentIndex(compNum)));
2328 7628 : for (int inNode = 1; inNode <= thisPlenum.NumInletNodes; ++inNode) {
2329 6908 : if (thisReturnNode == thisPlenum.InletNode(inNode)) {
2330 1250 : thisZoneEquip.ReturnNodeAirLoopNum(zoneOutNum) = airLoopNum; // set the return node airloop num
2331 1250 : returnPathFound = true;
2332 1250 : break; // leave component inlet node loop
2333 : }
2334 : }
2335 : }
2336 12815 : if (returnPathFound) break; // leave return path component loop
2337 : }
2338 12193 : if (returnPathFound) break; // leave return path loop
2339 : }
2340 :
2341 4103 : if (airLoopNum > 0) {
2342 : // Find matching inlet node connected to the same air loop
2343 3821 : for (int inletNum = 1; inletNum <= thisZoneEquip.NumInletNodes; ++inletNum) {
2344 3648 : if (thisZoneEquip.InletNodeAirLoopNum(inletNum) == airLoopNum) {
2345 3426 : thisZoneEquip.ReturnNodeInletNum(zoneOutNum) = inletNum;
2346 3426 : break;
2347 : }
2348 : }
2349 : }
2350 : } // return nodes loop
2351 : } // controlled zones loop
2352 :
2353 : // Check for any air loops that may be connected directly to a zone return node
2354 1947 : for (int airLoopNum = 1; airLoopNum <= NumPrimaryAirSys; ++airLoopNum) {
2355 1177 : bool returnFound = false;
2356 1177 : if (AirToZoneNodeInfo(airLoopNum).NumReturnNodes > 0) {
2357 1177 : int zeqReturnNodeNum = AirToZoneNodeInfo(airLoopNum).ZoneEquipReturnNodeNum(1);
2358 1177 : if (zeqReturnNodeNum > 0) {
2359 23615 : for (int ctrlZoneNum = 1; ctrlZoneNum <= state.dataGlobal->NumOfZones; ++ctrlZoneNum) {
2360 22442 : auto &thisZoneEquip(state.dataZoneEquip->ZoneEquipConfig(ctrlZoneNum));
2361 22442 : if (!thisZoneEquip.IsControlled) continue;
2362 40241 : for (int zoneOutNum = 1; zoneOutNum <= thisZoneEquip.NumReturnNodes; ++zoneOutNum) {
2363 20148 : if (thisZoneEquip.ReturnNode(zoneOutNum) == zeqReturnNodeNum) {
2364 9 : thisZoneEquip.ReturnNodeAirLoopNum(zoneOutNum) = airLoopNum;
2365 9 : returnFound = true;
2366 : // Find matching inlet node connected to the same air loop
2367 9 : for (int inletNum = 1; inletNum <= thisZoneEquip.NumInletNodes; ++inletNum) {
2368 9 : if (thisZoneEquip.InletNodeAirLoopNum(inletNum) == airLoopNum) {
2369 9 : thisZoneEquip.ReturnNodeInletNum(zoneOutNum) = inletNum;
2370 9 : break;
2371 : }
2372 : }
2373 9 : break; // leave zone return node loop
2374 : }
2375 20139 : if (returnFound) break; // leave controlled zone loop
2376 : }
2377 : }
2378 : }
2379 : }
2380 : }
2381 : }
2382 :
2383 6484596 : void SimAirLoops(EnergyPlusData &state, bool const FirstHVACIteration, bool &SimZoneEquipment)
2384 : {
2385 :
2386 : // SUBROUTINE INFORMATION
2387 : // AUTHOR: Russ Taylor, Dan Fisher, Fred Buhl
2388 : // DATE WRITTEN: Oct 1997
2389 : // MODIFIED: Dec 1997 Fred Buhl
2390 : // MODIFIED: Apr 1998 Richard Liesen
2391 : // MODIFIED: Dec 1999 Fred Buhl
2392 : // MODIFIED: Feb 2006 Dimitri Curtil (LBNL)
2393 : // - Moved air loop simulation to SimAirLoop() routine.
2394 : // RE-ENGINEERED: This is new code, not reengineered
2395 :
2396 : // PURPOSE OF THIS SUBROUTINE:
2397 : // This is the driver subroutine for the air loop simulation. It simulates
2398 : // each primary air system in the problem and passes the outlet node conditions
2399 : // on to the attached Zone Equipment inlet nodes.
2400 :
2401 : // METHODOLOGY EMPLOYED:
2402 : // For each primary air system:
2403 : // (1) each component in the system is simulated in natural order, beginning at
2404 : // the return air inlet and progressing to the supply air outlets. Node data
2405 : // is passed in the same direction.
2406 : // (2) The controllers and their actions are simulated.
2407 : // (3) Steps 2 and 3 are repeated until the control criteria are satisfied.
2408 : // (4) A mass balance check is performed; if it fails, mass balance is imposed
2409 : // and steps 1, 2, and 3 are repeated. At the end we should have a correct,
2410 : // self consistent primary air system simulation.
2411 :
2412 : // REFERENCES: None
2413 :
2414 : // Using/Aliasing
2415 : using General::GetPreviousHVACTime;
2416 : using HVACInterfaceManager::UpdateHVACInterface;
2417 :
2418 : // Locals
2419 : // SUBROUTINE ARGUMENT DEFINITIONS:
2420 : // TRUE if first full HVAC iteration in an HVAC timestep
2421 : // TRUE if Zone Equipment needs to be resimulated.
2422 :
2423 : // SUBROUTINE LOCAL VARIABLE DEFINITIONS
2424 : Real64 rxTime;
2425 : // Primary Air Sys DO loop index
2426 : int AirLoopNum;
2427 : // Max number of iterations performed by controllers on each air loop
2428 : int AirLoopIterMax;
2429 : // Aggregated number of iterations across all controllers on each air loop
2430 : int AirLoopIterTot;
2431 : // Total number of times SimAirLoopComponents() has been invoked to simulate each air loop
2432 : int AirLoopNumCalls;
2433 : // Primary air system outlet DO loop index
2434 : int AirSysOutNum;
2435 : // DO loop index; there are 2 passes - the 2nd is done only if mass balance fails
2436 : int AirLoopPass;
2437 : // Flag set by ResolveSysFlow; if TRUE, mass balance failed and there must be a second pass
2438 : bool SysReSim;
2439 : DataConvergParams::CalledFrom CalledFrom;
2440 :
2441 6484596 : auto &AirToZoneNodeInfo(state.dataAirLoop->AirToZoneNodeInfo);
2442 6484596 : auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo);
2443 :
2444 : // Set up output variables
2445 6484596 : if (!state.dataSimAirServingZones->OutputSetupFlag) {
2446 2307 : SetupOutputVariable(state,
2447 : "Air System Simulation Maximum Iteration Count",
2448 : OutputProcessor::Unit::None,
2449 769 : state.dataSimAirServingZones->salIterMax,
2450 : OutputProcessor::SOVTimeStepType::HVAC,
2451 : OutputProcessor::SOVStoreType::Summed,
2452 1538 : "SimAir");
2453 2307 : SetupOutputVariable(state,
2454 : "Air System Simulation Iteration Count",
2455 : OutputProcessor::Unit::None,
2456 769 : state.dataSimAirServingZones->salIterTot,
2457 : OutputProcessor::SOVTimeStepType::HVAC,
2458 : OutputProcessor::SOVStoreType::Summed,
2459 1538 : "SimAir");
2460 2307 : SetupOutputVariable(state,
2461 : "Air System Component Model Simulation Calls",
2462 : OutputProcessor::Unit::None,
2463 769 : state.dataSimAirServingZones->NumCallsTot,
2464 : OutputProcessor::SOVTimeStepType::HVAC,
2465 : OutputProcessor::SOVStoreType::Summed,
2466 1538 : "SimAir");
2467 769 : state.dataSimAirServingZones->OutputSetupFlag = true;
2468 : }
2469 :
2470 : // BUG: IterMax should not be aggregated as a Sum output variable
2471 : // We need a new aggregation scheme to track the max value across HVAC steps
2472 : // instead of summing it up.
2473 6484596 : state.dataSimAirServingZones->salIterMax = 0;
2474 :
2475 : // Reset counters to capture statistics for the current zone time step
2476 : // Aggregate statistics over all HVAC time steps, even the rejected ones, to properly
2477 : // reflect the numerical work. The condition to detect a new HVAC time step is essentially
2478 : // based on the time stamp at the beginning of the current HVAC step (expressed in seconds).
2479 6484596 : if (FirstHVACIteration) {
2480 2638872 : rxTime = GetPreviousHVACTime(state);
2481 2638872 : if (state.dataSimAirServingZones->SavedPreviousHVACTime != rxTime) {
2482 2397118 : state.dataSimAirServingZones->SavedPreviousHVACTime = rxTime;
2483 2397118 : state.dataSimAirServingZones->salIterTot = 0;
2484 2397118 : state.dataSimAirServingZones->NumCallsTot = 0;
2485 : }
2486 : }
2487 :
2488 : // Loop over all the primary air loop; simulate their components (equipment)
2489 : // and controllers
2490 18558686 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) { // NumPrimaryAirSys is the number of primary air loops
2491 :
2492 : // Check to see if System Availability Managers are asking for fans to cycle on or shut off
2493 : // and set fan on/off flags accordingly.
2494 12074090 : state.dataHVACGlobal->TurnFansOn = false;
2495 12074090 : state.dataHVACGlobal->TurnFansOff = false;
2496 12074090 : state.dataHVACGlobal->NightVentOn = false;
2497 12074090 : if (state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).AvailStatus == CycleOn) {
2498 7395941 : state.dataHVACGlobal->TurnFansOn = true;
2499 : }
2500 12074090 : if (state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).AvailStatus == ForceOff) {
2501 673860 : state.dataHVACGlobal->TurnFansOff = true;
2502 : }
2503 12074090 : if (AirLoopControlInfo(AirLoopNum).NightVent) {
2504 0 : state.dataHVACGlobal->NightVentOn = true;
2505 : }
2506 :
2507 : // Set current system number for sizing routines
2508 12074090 : state.dataSize->CurSysNum = AirLoopNum;
2509 :
2510 : // 2 passes; 1 usually suffices; 2 is done if ResolveSysFlow detects a failure of mass balance
2511 19591810 : for (AirLoopPass = 1; AirLoopPass <= 2; ++AirLoopPass) {
2512 :
2513 15832950 : SysReSim = false;
2514 15832950 : AirLoopControlInfo(AirLoopNum).AirLoopPass = AirLoopPass; // save for use without passing as argument
2515 :
2516 : // Simulate controllers on air loop with current air mass flow rates
2517 15832950 : SimAirLoop(state, FirstHVACIteration, AirLoopNum, AirLoopPass, AirLoopIterMax, AirLoopIterTot, AirLoopNumCalls);
2518 :
2519 : // Update tracker for maximum number of iterations needed by any controller on all air loops
2520 15832950 : state.dataSimAirServingZones->salIterMax = max(state.dataSimAirServingZones->salIterMax, AirLoopIterMax);
2521 : // Update tracker for aggregated number of iterations needed by all controllers on all air loops
2522 15832950 : state.dataSimAirServingZones->salIterTot += AirLoopIterTot;
2523 : // Update tracker for total number of times SimAirLoopComponents() has been invoked across all air loops
2524 15832950 : state.dataSimAirServingZones->NumCallsTot += AirLoopNumCalls;
2525 :
2526 : // At the end of the first pass, check whether a second pass is needed or not
2527 15832950 : if (AirLoopPass == 1) {
2528 : // If simple system, skip second pass
2529 12074090 : if (AirLoopControlInfo(AirLoopNum).Simple) break;
2530 11036464 : ResolveSysFlow(state, AirLoopNum, SysReSim);
2531 : // If mass balance OK, skip second pass
2532 11036464 : if (!SysReSim) break;
2533 : }
2534 : }
2535 :
2536 : // Air system side has been simulated, now transfer conditions across to
2537 : // the zone equipment side, looping through all supply air paths for this
2538 : // air loop.
2539 24203055 : for (AirSysOutNum = 1; AirSysOutNum <= AirToZoneNodeInfo(AirLoopNum).NumSupplyNodes; ++AirSysOutNum) {
2540 12128965 : if (AirSysOutNum == 1) CalledFrom = DataConvergParams::CalledFrom::AirSystemSupplySideDeck1;
2541 12128965 : if (AirSysOutNum == 2) CalledFrom = DataConvergParams::CalledFrom::AirSystemSupplySideDeck2;
2542 24257930 : UpdateHVACInterface(state,
2543 : AirLoopNum,
2544 : CalledFrom,
2545 12128965 : AirToZoneNodeInfo(AirLoopNum).AirLoopSupplyNodeNum(AirSysOutNum),
2546 12128965 : AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(AirSysOutNum),
2547 : SimZoneEquipment);
2548 : } // ...end of DO loop over supply air paths for this air loop.
2549 :
2550 : } // End of Air Loop iteration
2551 :
2552 6484596 : if ((int)state.dataAirLoopHVACDOAS->airloopDOAS.size() > 0) {
2553 : int index;
2554 10882 : Real64 OAMassFLowrate = 0.0;
2555 21764 : for (std::size_t loop = 0; loop < state.dataAirLoopHVACDOAS->airloopDOAS.size(); ++loop) {
2556 10882 : auto &thisAirLoopDOASObjec = state.dataAirLoopHVACDOAS->airloopDOAS[loop]; // <- regular reference variable, not a pointer
2557 10882 : if (thisAirLoopDOASObjec.m_AirLoopDOASNum > -1) {
2558 10882 : index = thisAirLoopDOASObjec.m_AirLoopDOASNum;
2559 : } else {
2560 0 : index = -1;
2561 : }
2562 10882 : thisAirLoopDOASObjec.SimAirLoopHVACDOAS(state, FirstHVACIteration, index);
2563 10882 : OAMassFLowrate += thisAirLoopDOASObjec.SumMassFlowRate;
2564 : }
2565 :
2566 10882 : if (OAMassFLowrate > 0.0) {
2567 32148 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys;
2568 : ++AirLoopNum) { // NumPrimaryAirSys is the number of primary air loops
2569 26790 : state.dataHVACGlobal->TurnFansOn = false;
2570 26790 : state.dataHVACGlobal->TurnFansOff = false;
2571 26790 : state.dataHVACGlobal->NightVentOn = false;
2572 26790 : if (state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).AvailStatus == CycleOn) {
2573 0 : state.dataHVACGlobal->TurnFansOn = true;
2574 : }
2575 26790 : if (state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).AvailStatus == ForceOff) {
2576 0 : state.dataHVACGlobal->TurnFansOff = true;
2577 : }
2578 26790 : if (AirLoopControlInfo(AirLoopNum).NightVent) {
2579 0 : state.dataHVACGlobal->NightVentOn = true;
2580 : }
2581 :
2582 : // Set current system number for sizing routines
2583 26790 : state.dataSize->CurSysNum = AirLoopNum;
2584 :
2585 : // 2 passes; 1 usually suffices; 2 is done if ResolveSysFlow detects a failure of mass balance
2586 26790 : for (AirLoopPass = 1; AirLoopPass <= 2; ++AirLoopPass) {
2587 :
2588 26790 : SysReSim = false;
2589 26790 : AirLoopControlInfo(AirLoopNum).AirLoopPass = AirLoopPass; // save for use without passing as argument
2590 :
2591 : // Simulate controllers on air loop with current air mass flow rates
2592 26790 : SimAirLoop(state, FirstHVACIteration, AirLoopNum, AirLoopPass, AirLoopIterMax, AirLoopIterTot, AirLoopNumCalls);
2593 :
2594 : // Update tracker for maximum number of iterations needed by any controller on all air loops
2595 26790 : state.dataSimAirServingZones->salIterMax = max(state.dataSimAirServingZones->salIterMax, AirLoopIterMax);
2596 : // Update tracker for aggregated number of iterations needed by all controllers on all air loops
2597 26790 : state.dataSimAirServingZones->salIterTot += AirLoopIterTot;
2598 : // Update tracker for total number of times SimAirLoopComponents() has been invoked across all air loops
2599 26790 : state.dataSimAirServingZones->NumCallsTot += AirLoopNumCalls;
2600 :
2601 : // At the end of the first pass, check whether a second pass is needed or not
2602 26790 : if (AirLoopPass == 1) {
2603 : // If simple system, skip second pass
2604 26790 : if (AirLoopControlInfo(AirLoopNum).Simple) break;
2605 26790 : ResolveSysFlow(state, AirLoopNum, SysReSim);
2606 : // If mass balance OK, skip second pass
2607 26790 : if (!SysReSim) break;
2608 : }
2609 : }
2610 :
2611 : // Air system side has been simulated, now transfer conditions across to
2612 : // the zone equipment side, looping through all supply air paths for this
2613 : // air loop.
2614 53580 : for (AirSysOutNum = 1; AirSysOutNum <= AirToZoneNodeInfo(AirLoopNum).NumSupplyNodes; ++AirSysOutNum) {
2615 26790 : if (AirSysOutNum == 1) CalledFrom = DataConvergParams::CalledFrom::AirSystemSupplySideDeck1;
2616 26790 : if (AirSysOutNum == 2) CalledFrom = DataConvergParams::CalledFrom::AirSystemSupplySideDeck2;
2617 53580 : UpdateHVACInterface(state,
2618 : AirLoopNum,
2619 : CalledFrom,
2620 26790 : AirToZoneNodeInfo(AirLoopNum).AirLoopSupplyNodeNum(AirSysOutNum),
2621 26790 : AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(AirSysOutNum),
2622 : SimZoneEquipment);
2623 : } // ...end of DO loop over supply air paths for this air loop.
2624 :
2625 : } // End of Air Loop iteration
2626 : // check convergence at the mixer outlet or at the AirLoopDOAS outlet
2627 5358 : AirLoopHVACDOAS::CheckConvergence(state);
2628 : }
2629 : }
2630 : // Reset current system number for sizing routines
2631 6484596 : state.dataSize->CurSysNum = 0;
2632 6484596 : }
2633 :
2634 15859740 : void SimAirLoop(EnergyPlusData &state,
2635 : bool const FirstHVACIteration,
2636 : int const AirLoopNum,
2637 : int const AirLoopPass,
2638 : int &AirLoopIterMax,
2639 : int &AirLoopIterTot,
2640 : int &AirLoopNumCalls)
2641 : {
2642 :
2643 : // SUBROUTINE INFORMATION
2644 : // AUTHOR: Dimitri Curtil (LBNL)
2645 : // DATE WRITTEN: March 2006
2646 : // - Fine-tuned outer loop over controllers.
2647 : // - Added convergence tracing for air loop controllers.
2648 : // - Added mechanism for speculative warm restart after first iteration.
2649 : // RE-ENGINEERED: This is new code based on the code that used to be part
2650 : // of SimAirLoops().
2651 :
2652 : // PURPOSE OF THIS SUBROUTINE:
2653 : // This subroutine simulates the desired air loop by solving for all the
2654 : // controllers on the air loop in the order they are specified.
2655 :
2656 : // METHODOLOGY EMPLOYED:
2657 : // To speed up the simulation, we introduced the possiblity to perform the controller
2658 : // simulation on each air loop using a warm restart from the solution obtained
2659 : // at the previous HVAC step iteration. This is only attempted if the air mass flow
2660 : // rate(s) for the air system have not changed since the last iteration.
2661 : // Of course if the warm restart fails, then we perform a normal simulation from
2662 : // a cold start. We refer to this scheme as speculative warm restart.
2663 :
2664 : // REFERENCES: None
2665 :
2666 : // Using/Aliasing
2667 : using namespace DataHVACControllers;
2668 : using namespace DataSystemVariables;
2669 : using General::CreateSysTimeIntervalString;
2670 : using HVACControllers::TraceAirLoopControllers;
2671 : using HVACControllers::TrackAirLoopControllers;
2672 :
2673 : // Locals
2674 : // SUBROUTINE ARGUMENT DEFINITIONS:
2675 : // TRUE if first full HVAC iteration in an HVAC timestep
2676 : // Index of the air loop to simulate
2677 : // There are 2 passes - the 2nd is done only if mass balance fails
2678 : // Max number of iterations performed by controllers across this air loop
2679 : // Aggregated number of iterations across all controllers on this air loop
2680 : // Total number of times SimAirLoopComponents() has been invoked to simulate this air loop
2681 :
2682 : // SUBROUTINE LOCAL VARIABLE DEFINITIONS
2683 :
2684 15859740 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
2685 15859740 : auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo);
2686 :
2687 : // Reset air loop trackers to zero
2688 15859740 : AirLoopIterMax = 0;
2689 15859740 : AirLoopIterTot = 0;
2690 15859740 : AirLoopNumCalls = 0;
2691 :
2692 : // Perform air loop simulation to satisfy convergence for all controllers
2693 : // If first HVAC iteration or new air flow we force a cold restart.
2694 : // Otherwise we attempt a speculative warm restart.
2695 : // TODO: Improve detection of when air flow rate has changed since last air loop simulation
2696 : // TODO: Detect whether warm restart is supported on air loop on very first air loop
2697 : // simulation only instead of at each HVAC iteration as done now.
2698 : // Only enabled if there are controllers on the air loop
2699 : // Check that the speculative warm restart feature is allowed
2700 : // Never done at first HVAC iteration
2701 : // Never done during sizing
2702 : // Next condition is true whenever the final check for the air loop was converged
2703 : // at the previous SimAirLoop call
2704 : // Next conditions should detect when air mass flow rates have changed
2705 15859740 : state.dataSimAirServingZones->DoWarmRestartFlagSAL =
2706 23414448 : PrimaryAirSystems(AirLoopNum).NumControllers > 0 && AirLoopControlInfo(AirLoopNum).AllowWarmRestartFlag && !FirstHVACIteration &&
2707 23760218 : !state.dataGlobal->SysSizingCalc && AirLoopControlInfo(AirLoopNum).ConvergedFlag && !AirLoopControlInfo(AirLoopNum).LoopFlowRateSet &&
2708 2617032 : !AirLoopControlInfo(AirLoopNum).NewFlowRateFlag;
2709 :
2710 15859740 : if (!state.dataSimAirServingZones->DoWarmRestartFlagSAL) {
2711 : // Solve controllers with cold start using default initial values
2712 52970832 : SolveAirLoopControllers(state,
2713 : FirstHVACIteration,
2714 : AirLoopNum,
2715 13242708 : state.dataSimAirServingZones->AirLoopConvergedFlagSAL,
2716 13242708 : state.dataSimAirServingZones->IterMaxSAL2,
2717 13242708 : state.dataSimAirServingZones->IterTotSAL2,
2718 13242708 : state.dataSimAirServingZones->NumCallsSAL2);
2719 :
2720 : // Update air loop trackers
2721 13242708 : state.dataSimAirServingZones->WarmRestartStatusSAL = ControllerWarmRestart::None;
2722 13242708 : AirLoopNumCalls += state.dataSimAirServingZones->NumCallsSAL2;
2723 13242708 : AirLoopIterMax = max(AirLoopIterMax, state.dataSimAirServingZones->IterMaxSAL2);
2724 13242708 : AirLoopIterTot += state.dataSimAirServingZones->IterTotSAL2;
2725 : } else {
2726 : // First try with speculative warm restart using previous solution
2727 10468128 : ReSolveAirLoopControllers(state,
2728 : FirstHVACIteration,
2729 : AirLoopNum,
2730 2617032 : state.dataSimAirServingZones->AirLoopConvergedFlagSAL,
2731 2617032 : state.dataSimAirServingZones->IterMaxSAL2,
2732 2617032 : state.dataSimAirServingZones->IterTotSAL2,
2733 2617032 : state.dataSimAirServingZones->NumCallsSAL2);
2734 :
2735 : // Update air loop trackers
2736 2617032 : state.dataSimAirServingZones->WarmRestartStatusSAL = ControllerWarmRestart::Success;
2737 2617032 : AirLoopNumCalls += state.dataSimAirServingZones->NumCallsSAL2;
2738 2617032 : AirLoopIterMax = max(AirLoopIterMax, state.dataSimAirServingZones->IterMaxSAL2);
2739 2617032 : AirLoopIterTot += state.dataSimAirServingZones->IterTotSAL2;
2740 :
2741 : // Retry with cold start using default initial values if speculative warm restart did not work
2742 2617032 : if (!state.dataSimAirServingZones->AirLoopConvergedFlagSAL) {
2743 4719000 : SolveAirLoopControllers(state,
2744 : FirstHVACIteration,
2745 : AirLoopNum,
2746 1179750 : state.dataSimAirServingZones->AirLoopConvergedFlagSAL,
2747 1179750 : state.dataSimAirServingZones->IterMaxSAL2,
2748 1179750 : state.dataSimAirServingZones->IterTotSAL2,
2749 1179750 : state.dataSimAirServingZones->NumCallsSAL2);
2750 :
2751 : // Update air loop trackers
2752 1179750 : state.dataSimAirServingZones->WarmRestartStatusSAL = DataHVACControllers::ControllerWarmRestart::Fail;
2753 1179750 : AirLoopNumCalls += state.dataSimAirServingZones->NumCallsSAL2;
2754 1179750 : AirLoopIterMax = max(AirLoopIterMax, state.dataSimAirServingZones->IterMaxSAL2);
2755 1179750 : AirLoopIterTot += state.dataSimAirServingZones->IterTotSAL2;
2756 : }
2757 : }
2758 :
2759 : // Updates air loop statistics
2760 : // To enable runtime statistics tracking for each air loop, define the environment variable
2761 : // TRACK_AIRLOOP=YES or TRACK_AIRLOOP=Y
2762 15859740 : if (state.dataSysVars->TrackAirLoopEnvFlag) {
2763 0 : TrackAirLoopControllers(
2764 0 : state, AirLoopNum, state.dataSimAirServingZones->WarmRestartStatusSAL, AirLoopIterMax, AirLoopIterTot, AirLoopNumCalls);
2765 : }
2766 :
2767 : // Generate trace for all controllers on this air loop
2768 : // To enable generating a trace file with the converged solution for all controllers on each air loop,
2769 : // define the environment variable TRACE_AIRLOOP=YES or TRACE_AIRLOOP=Y.
2770 15859740 : if (state.dataSysVars->TraceAirLoopEnvFlag) {
2771 0 : TraceAirLoopControllers(
2772 0 : state, FirstHVACIteration, AirLoopNum, AirLoopPass, state.dataSimAirServingZones->AirLoopConvergedFlagSAL, AirLoopNumCalls);
2773 : }
2774 :
2775 : // When there is more than 1 controller on an air loop, each controller sensing
2776 : // different nodes with potentially different setpoints, it is likely that
2777 : // AirLoopConvergedFlag will be false as the individual setpoints will not
2778 : // be satisfied once all the controllers have been simulated. Typically, this could
2779 : // happen if
2780 : // If this is the case then we do not want to try a warm restart as it is very
2781 : // unlikely to succeed.
2782 15859740 : AirLoopControlInfo(AirLoopNum).ConvergedFlag = state.dataSimAirServingZones->AirLoopConvergedFlagSAL;
2783 15859740 : }
2784 :
2785 14422458 : void SolveAirLoopControllers(
2786 : EnergyPlusData &state, bool const FirstHVACIteration, int const AirLoopNum, bool &AirLoopConvergedFlag, int &IterMax, int &IterTot, int &NumCalls)
2787 : {
2788 :
2789 : // SUBROUTINE INFORMATION
2790 : // AUTHOR: Dimitri Curtil (LBNL)
2791 : // DATE WRITTEN: Feb 2006
2792 : // MODIFIED:
2793 : // RE-ENGINEERED: This is reengineered code that used to be in SimAirLoops()
2794 :
2795 : // PURPOSE OF THIS SUBROUTINE:
2796 : // This subroutine solves for the controllers on the specfied air loop assuming a cold start.
2797 :
2798 : // METHODOLOGY EMPLOYED:
2799 : // For the specified primary air system:
2800 : // (1) each component in the system is simulated in natural order, beginning at
2801 : // the return air inlet and progressing to the supply air outlets. Node data
2802 : // is passed in the same direction.
2803 : // (2) The controllers and their actions are simulated.
2804 : // (3) Steps 2 and 3 are repeated until the control criteria are satisfied.
2805 :
2806 : // REFERENCES: None
2807 :
2808 : // Using/Aliasing
2809 : using namespace DataHVACControllers;
2810 : using General::CreateSysTimeIntervalString;
2811 : using HVACControllers::ManageControllers;
2812 :
2813 : // Locals
2814 : // SUBROUTINE ARGUMENT DEFINITIONS:
2815 : // TRUE if first full HVAC iteration in an HVAC timestep
2816 : // DO loop index; there are 2 passes the 2nd is done only if mass balance fails
2817 : // Index of the air loop being simulated
2818 : // TRUE when primary air system & controllers simulation has converged;
2819 : // Max number of iterations performed by controllers across this air loop
2820 : // Aggregated number of iterations across all controllers on this air loop
2821 : // Total number of times SimAirLoopComponents() has been invoked
2822 :
2823 : // SUBROUTINE PARAMETER DEFINITIONS:
2824 : // Maximum iterations of an air system/controllers simulation sequence
2825 14422458 : int constexpr MaxIter(50);
2826 :
2827 : // INTERFACE BLOCK DEFINITIONS: None
2828 :
2829 : // DERIVED TYPE DEFINITIONS: None
2830 :
2831 : // SUBROUTINE LOCAL VARIABLE DEFINITIONS
2832 : // TRUE if controller supports speculative warm restart
2833 : bool AllowWarmRestartFlag;
2834 : // TRUE when controller has converged
2835 : bool ControllerConvergedFlag;
2836 : // TRUE when air loop has been evaluated with latest actuated variables
2837 : bool IsUpToDateFlag;
2838 :
2839 14422458 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
2840 14422458 : auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo);
2841 :
2842 : // To track number of calls to SimAirLoopComponents() for each air loop
2843 : // Represents the most computationally expensive operation in the iteration.
2844 : // Best metric to use to assess the runtime performance of air loop simulation
2845 14422458 : NumCalls = 0;
2846 14422458 : IterMax = 0;
2847 14422458 : IterTot = 0;
2848 :
2849 14422458 : AirLoopConvergedFlag = true;
2850 14422458 : state.dataSimAirServingZones->BypassOAControllerSALC = true; // don't simulate OA contollers at this time (see SolveWaterCoilController)
2851 14422458 : IsUpToDateFlag = false;
2852 14422458 : PrimaryAirSystems(AirLoopNum).ControlConverged = false;
2853 :
2854 14422458 : AllowWarmRestartFlag = true;
2855 14422458 : AirLoopControlInfo(AirLoopNum).AllowWarmRestartFlag = true;
2856 :
2857 14422458 : if (PrimaryAirSystems(AirLoopNum).SizeAirloopCoil) { // one time flag to initialize controller index and size coils if needed
2858 : // Loop through the controllers first to set the controller index in the PrimaryAirSystem array.
2859 : // Need to actaully simulate controller to get controller index.
2860 1992 : for (int AirLoopControlNum = 1; AirLoopControlNum <= PrimaryAirSystems(AirLoopNum).NumControllers; ++AirLoopControlNum) {
2861 820 : PrimaryAirSystems(AirLoopNum).ControllerIndex(AirLoopControlNum) =
2862 820 : HVACControllers::GetControllerIndex(state, PrimaryAirSystems(AirLoopNum).ControllerName(AirLoopControlNum));
2863 820 : state.dataHVACControllers->ControllerProps(PrimaryAirSystems(AirLoopNum).ControllerIndex(AirLoopControlNum)).AirLoopControllerIndex =
2864 : AirLoopControlNum;
2865 : }
2866 : // When using controllers, size air loop coils so ControllerProps (e.g., Min/Max Actuated) can be set
2867 1172 : if (PrimaryAirSystems(AirLoopNum).NumControllers > 0) SimAirLoopComponents(state, AirLoopNum, FirstHVACIteration);
2868 1172 : PrimaryAirSystems(AirLoopNum).SizeAirloopCoil = false;
2869 : }
2870 :
2871 : // This call to ManageControllers reinitializes the controllers actuated variables to zero
2872 : // E.g., actuator inlet water flow
2873 21988992 : for (int AirLoopControlNum = 1; AirLoopControlNum <= PrimaryAirSystems(AirLoopNum).NumControllers; ++AirLoopControlNum) {
2874 :
2875 : // BypassOAController is true here since we do not want to simulate the controller if it has already been simulated in the OA
2876 : // system ControllerConvergedFlag is returned true here for water coils in OA system
2877 30266136 : ManageControllers(state,
2878 7566534 : PrimaryAirSystems(AirLoopNum).ControllerName(AirLoopControlNum),
2879 7566534 : PrimaryAirSystems(AirLoopNum).ControllerIndex(AirLoopControlNum),
2880 : FirstHVACIteration,
2881 : AirLoopNum,
2882 : ControllerOperation::ColdStart,
2883 : ControllerConvergedFlag,
2884 : IsUpToDateFlag,
2885 7566534 : state.dataSimAirServingZones->BypassOAControllerSALC,
2886 : AllowWarmRestartFlag);
2887 : // Detect whether the speculative warm restart feature is supported by each controller
2888 : // on this air loop.
2889 7566534 : AirLoopControlInfo(AirLoopNum).AllowWarmRestartFlag = AirLoopControlInfo(AirLoopNum).AllowWarmRestartFlag && AllowWarmRestartFlag;
2890 : }
2891 :
2892 : // Evaluate air loop components with new actuated variables
2893 14422458 : ++NumCalls;
2894 14422458 : SimAirLoopComponents(state, AirLoopNum, FirstHVACIteration);
2895 14422458 : IsUpToDateFlag = true;
2896 :
2897 : // Loop over the air sys controllers until convergence or MaxIter iterations
2898 21988992 : for (int AirLoopControlNum = 1; AirLoopControlNum <= PrimaryAirSystems(AirLoopNum).NumControllers; ++AirLoopControlNum) {
2899 :
2900 7566534 : state.dataSimAirServingZones->IterSALC = 0;
2901 7566534 : ControllerConvergedFlag = false;
2902 : // if the controller can be locked out by the economizer operation and the economizer is active, leave the controller inactive
2903 7566534 : if (AirLoopControlInfo(AirLoopNum).EconoActive) {
2904 : // nesting this next if to try and speed this up. If economizer is not active, it doesn't matter if CanBeLockedOutByEcono =
2905 : // true
2906 2077535 : if (PrimaryAirSystems(AirLoopNum).CanBeLockedOutByEcono(AirLoopControlNum)) {
2907 0 : ControllerConvergedFlag = true;
2908 0 : continue;
2909 : }
2910 : }
2911 :
2912 : // For each controller in sequence, iterate until convergence
2913 41362760 : while (!ControllerConvergedFlag) {
2914 :
2915 16898143 : ++state.dataSimAirServingZones->IterSALC;
2916 :
2917 67592572 : ManageControllers(state,
2918 16898143 : PrimaryAirSystems(AirLoopNum).ControllerName(AirLoopControlNum),
2919 16898143 : PrimaryAirSystems(AirLoopNum).ControllerIndex(AirLoopControlNum),
2920 : FirstHVACIteration,
2921 : AirLoopNum,
2922 : ControllerOperation::Iterate,
2923 : ControllerConvergedFlag,
2924 : IsUpToDateFlag,
2925 16898143 : state.dataSimAirServingZones->BypassOAControllerSALC);
2926 :
2927 16898143 : PrimaryAirSystems(AirLoopNum).ControlConverged(AirLoopControlNum) = ControllerConvergedFlag;
2928 :
2929 16898143 : if (!ControllerConvergedFlag) {
2930 : // Only check abnormal termination if not yet converged
2931 : // The iteration counter has been exceeded.
2932 9331639 : if (state.dataSimAirServingZones->IterSALC > MaxIter) {
2933 : // Indicate that this air loop is not converged
2934 30 : AirLoopConvergedFlag = false;
2935 :
2936 : // The warning message will be suppressed during the warm up days.
2937 30 : if (!state.dataGlobal->WarmupFlag) {
2938 4 : ++state.dataSimAirServingZones->ErrCountSALC;
2939 4 : if (state.dataSimAirServingZones->ErrCountSALC < 15) {
2940 4 : state.dataSimAirServingZones->ErrEnvironmentName = state.dataEnvrn->EnvironmentName;
2941 8 : const auto CharErrOut = fmt::to_string(MaxIter);
2942 12 : ShowWarningError(state,
2943 8 : "SolveAirLoopControllers: Maximum iterations (" + CharErrOut + ") exceeded for " +
2944 12 : PrimaryAirSystems(AirLoopNum).Name + ", " +
2945 12 : PrimaryAirSystems(AirLoopNum).ControllerName(AirLoopControlNum) + ", at " +
2946 12 : state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
2947 8 : CreateSysTimeIntervalString(state));
2948 : } else {
2949 0 : if (state.dataEnvrn->EnvironmentName != state.dataSimAirServingZones->ErrEnvironmentName) {
2950 0 : state.dataSimAirServingZones->MaxErrCountSALC = 0;
2951 0 : state.dataSimAirServingZones->ErrEnvironmentName = state.dataEnvrn->EnvironmentName;
2952 : }
2953 0 : ShowRecurringWarningErrorAtEnd(state,
2954 0 : "SolveAirLoopControllers: Exceeding Maximum iterations for " +
2955 0 : PrimaryAirSystems(AirLoopNum).Name + " during " + state.dataEnvrn->EnvironmentName +
2956 : " continues",
2957 0 : state.dataSimAirServingZones->MaxErrCountSALC);
2958 : }
2959 : }
2960 :
2961 : // It is necessary to execute this statement anytime, even if the warning message is suppressed.
2962 : // To continue the simulation it must be able to goto the Exit statement
2963 30 : break; // It will not converge this time
2964 : }
2965 :
2966 : // Re-evaluate air loop components with new actuated variables
2967 9331609 : ++NumCalls;
2968 : // this call to SimAirLoopComponents will simulate the OA system and set the PrimaryAirSystem( AirLoopNum
2969 : // ).ControlConverged( AirLoopControlNum ) flag for controllers of water coils in the OA system for controllers not in the
2970 : // OA system, this flag is set above in this function
2971 9331609 : SimAirLoopComponents(state, AirLoopNum, FirstHVACIteration);
2972 : // pass convergence flag from OA system water coils (i.e., SolveWaterCoilController) back to this loop
2973 : // for future reference, the PrimaryAirSystem().ControlConverged flag is set while managing OA system water coils.
2974 : // If convergence is not achieved with OA system water coils, suspect how this flag is passed back here or why OA system
2975 : // coils do not converge
2976 9331609 : ControllerConvergedFlag = PrimaryAirSystems(AirLoopNum).ControlConverged(AirLoopControlNum);
2977 9331609 : IsUpToDateFlag = true;
2978 : }
2979 :
2980 : } // End of the Convergence Iteration
2981 :
2982 : // Update tracker for max iteration counter across all controllers on this air loops
2983 7566534 : IterMax = max(IterMax, state.dataSimAirServingZones->IterSALC);
2984 : // Update tracker for aggregated counter of air loop inner iterations across controllers
2985 : // on this air loop
2986 7566534 : IterTot += state.dataSimAirServingZones->IterSALC;
2987 :
2988 : } // End of controller loop
2989 :
2990 : // Once the controllers are converged then need to simulate the components once
2991 : // more to ensure that they are simulated with the latest values.
2992 14422458 : if (!IsUpToDateFlag || !AirLoopConvergedFlag) {
2993 76846 : ++NumCalls;
2994 76846 : SimAirLoopComponents(state, AirLoopNum, FirstHVACIteration);
2995 76846 : IsUpToDateFlag = true;
2996 : }
2997 :
2998 : // Check that all active controllers are still convergence
2999 21988992 : for (int AirLoopControlNum = 1; AirLoopControlNum <= PrimaryAirSystems(AirLoopNum).NumControllers; ++AirLoopControlNum) {
3000 :
3001 7566534 : ControllerConvergedFlag = false;
3002 :
3003 30266136 : ManageControllers(state,
3004 7566534 : PrimaryAirSystems(AirLoopNum).ControllerName(AirLoopControlNum),
3005 7566534 : PrimaryAirSystems(AirLoopNum).ControllerIndex(AirLoopControlNum),
3006 : FirstHVACIteration,
3007 : AirLoopNum,
3008 : ControllerOperation::End,
3009 : ControllerConvergedFlag,
3010 : IsUpToDateFlag,
3011 7566534 : state.dataSimAirServingZones->BypassOAControllerSALC);
3012 :
3013 7566534 : PrimaryAirSystems(AirLoopNum).ControlConverged(AirLoopControlNum) = ControllerConvergedFlag;
3014 :
3015 7566534 : AirLoopConvergedFlag = AirLoopConvergedFlag && ControllerConvergedFlag;
3016 : }
3017 14422458 : }
3018 :
3019 2544316 : void SolveWaterCoilController(EnergyPlusData &state,
3020 : bool const FirstHVACIteration,
3021 : int const AirLoopNum,
3022 : std::string const &CompName,
3023 : int &CompIndex,
3024 : std::string const &ControllerName,
3025 : int ControllerIndex,
3026 : bool const HXAssistedWaterCoil)
3027 : {
3028 :
3029 : // SUBROUTINE INFORMATION
3030 : // AUTHOR: Richard Raustad (FSEC)
3031 : // DATE WRITTEN: July 2017
3032 :
3033 : // PURPOSE OF THIS SUBROUTINE:
3034 : // This subroutine solves for the controllers in the specfied air loop OA system.
3035 :
3036 : // METHODOLOGY EMPLOYED:
3037 : // For the specified primary air system:
3038 : // (1) the specific component in the OA system is simulated
3039 : // (2) The controllers and their actions are simulated
3040 : // (3) Steps 2 and 3 are repeated until the control criteria are satisfied
3041 : // (4) convergence is passed back to SolveAirLoopControllers via PrimaryAirSystem( AirLoopNum ).ControlConverged( ControllerIndex )
3042 :
3043 : // REFERENCES: None
3044 :
3045 : // Using/Aliasing
3046 : using namespace DataHVACControllers;
3047 : using General::CreateSysTimeIntervalString;
3048 : using HVACControllers::ManageControllers;
3049 : using HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil;
3050 : using WaterCoils::SimulateWaterCoilComponents;
3051 :
3052 : // Locals
3053 : // SUBROUTINE ARGUMENT DEFINITIONS:
3054 : // TRUE if first full HVAC iteration in an HVAC timestep
3055 : // DO loop index; there are 2 passes the 2nd is done only if mass balance fails
3056 : // Index of the air loop being simulated
3057 : // TRUE when primary air system & controllers simulation has converged;
3058 : // Max number of iterations performed by controllers across this air loop
3059 : // Aggregated number of iterations across all controllers on this air loop
3060 : // Total number of times SimAirLoopComponents() has been invoked
3061 :
3062 : // SUBROUTINE PARAMETER DEFINITIONS:
3063 : // Maximum iterations of an air system/controllers simulation sequence
3064 2544316 : constexpr int MaxIter(50);
3065 :
3066 : // SUBROUTINE LOCAL VARIABLE DEFINITIONS
3067 : // TRUE if controller supports speculative warm restart
3068 : bool AllowWarmRestartFlag;
3069 : // TRUE when controller has converged
3070 : bool ControllerConvergedFlag;
3071 : // TRUE when air loop has been evaluated with latest actuated variables
3072 : bool IsUpToDateFlag;
3073 :
3074 : // A character string equivalent of ErrCount
3075 :
3076 2544316 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
3077 2544316 : auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo);
3078 :
3079 2544316 : bool AirLoopCheck = false;
3080 2544316 : if (AirLoopNum > 0) {
3081 2522552 : AirLoopCheck = true;
3082 : }
3083 2544316 : state.dataSimAirServingZones->BypassOAControllerSWCC = false; // simulate OA water coil controllers
3084 2544316 : if (AirLoopCheck) {
3085 2522552 : state.dataSimAirServingZones->AirLoopPassSWCC = AirLoopControlInfo(AirLoopNum).AirLoopPass;
3086 : }
3087 2544316 : IsUpToDateFlag = false;
3088 2544316 : if (AirLoopCheck) {
3089 2522552 : PrimaryAirSystems(AirLoopNum).ControlConverged = false;
3090 : }
3091 :
3092 2544316 : AllowWarmRestartFlag = true;
3093 2544316 : if (AirLoopCheck) {
3094 2522552 : AirLoopControlInfo(AirLoopNum).AllowWarmRestartFlag = true;
3095 : }
3096 :
3097 : // This call to ManageControllers reinitializes the controllers actuated variables to zero
3098 :
3099 : // BypassOAController is false here since we want to simulate the controller
3100 5088632 : ManageControllers(state,
3101 : ControllerName,
3102 : ControllerIndex,
3103 : FirstHVACIteration,
3104 : AirLoopNum,
3105 : ControllerOperation::ColdStart,
3106 : ControllerConvergedFlag,
3107 : IsUpToDateFlag,
3108 2544316 : state.dataSimAirServingZones->BypassOAControllerSWCC,
3109 : AllowWarmRestartFlag);
3110 :
3111 : // Detect whether the speculative warm restart feature is supported by each controller on this air loop.
3112 2544316 : if (AirLoopCheck) {
3113 2522552 : AirLoopControlInfo(AirLoopNum).AllowWarmRestartFlag = AirLoopControlInfo(AirLoopNum).AllowWarmRestartFlag && AllowWarmRestartFlag;
3114 : }
3115 :
3116 : // Evaluate water coils with new actuated variables
3117 2544316 : if (HXAssistedWaterCoil) {
3118 0 : SimHXAssistedCoolingCoil(state, CompName, FirstHVACIteration, CompressorOperation::On, 0.0, CompIndex, ContFanCycCoil);
3119 : } else {
3120 2544316 : SimulateWaterCoilComponents(state, CompName, FirstHVACIteration, CompIndex);
3121 : }
3122 2544316 : IsUpToDateFlag = true;
3123 :
3124 : // Loop over the air sys controllers until convergence or MaxIter iterations
3125 2544316 : state.dataSimAirServingZones->IterSWCC = 0;
3126 2544316 : ControllerConvergedFlag = false;
3127 : // if the controller can be locked out by the economizer operation and the economizer is active, leave the controller inactive
3128 2544316 : if (AirLoopCheck) {
3129 2522552 : if (AirLoopControlInfo(AirLoopNum).EconoActive) {
3130 0 : if (PrimaryAirSystems(AirLoopNum)
3131 0 : .CanBeLockedOutByEcono(state.dataHVACControllers->ControllerProps(ControllerIndex).AirLoopControllerIndex)) {
3132 0 : ControllerConvergedFlag = true;
3133 : }
3134 : }
3135 : }
3136 :
3137 : // For this controller, iterate until convergence
3138 10332890 : while (!ControllerConvergedFlag) {
3139 :
3140 3894287 : ++state.dataSimAirServingZones->IterSWCC;
3141 :
3142 7788574 : ManageControllers(state,
3143 : ControllerName,
3144 : ControllerIndex,
3145 : FirstHVACIteration,
3146 : AirLoopNum,
3147 : ControllerOperation::Iterate,
3148 : ControllerConvergedFlag,
3149 : IsUpToDateFlag,
3150 3894287 : state.dataSimAirServingZones->BypassOAControllerSWCC);
3151 :
3152 3894287 : if (AirLoopCheck) {
3153 3863525 : PrimaryAirSystems(AirLoopNum).ControlConverged(state.dataHVACControllers->ControllerProps(ControllerIndex).AirLoopControllerIndex) =
3154 : ControllerConvergedFlag;
3155 : }
3156 :
3157 3894287 : if (!ControllerConvergedFlag) {
3158 : // Only check abnormal termination if not yet converged
3159 : // The iteration counter has been exceeded.
3160 1349971 : if (state.dataSimAirServingZones->IterSWCC > MaxIter) {
3161 :
3162 : // The warning message will be suppressed during the warm up days.
3163 0 : if (!state.dataGlobal->WarmupFlag) {
3164 0 : ++state.dataSimAirServingZones->ErrCountSWCC;
3165 0 : if (state.dataSimAirServingZones->ErrCountSWCC < 15) {
3166 0 : state.dataSimAirServingZones->ErrEnvironmentNameSolveWaterCoilController = state.dataEnvrn->EnvironmentName;
3167 0 : const auto CharErrOut = fmt::to_string(MaxIter);
3168 0 : ShowWarningError(state,
3169 0 : "SolveAirLoopControllers: Maximum iterations (" + CharErrOut + ") exceeded for " +
3170 0 : PrimaryAirSystems(AirLoopNum).Name + ":" + ControllerName + ", at " + state.dataEnvrn->EnvironmentName +
3171 0 : ", " + state.dataEnvrn->CurMnDy + ' ' + CreateSysTimeIntervalString(state));
3172 : } else {
3173 0 : if (state.dataEnvrn->EnvironmentName != state.dataSimAirServingZones->ErrEnvironmentNameSolveWaterCoilController) {
3174 0 : state.dataSimAirServingZones->MaxErrCountSWCC = 0;
3175 0 : state.dataSimAirServingZones->ErrEnvironmentNameSolveWaterCoilController = state.dataEnvrn->EnvironmentName;
3176 : }
3177 0 : ShowRecurringWarningErrorAtEnd(state,
3178 0 : "SolveAirLoopControllers: Exceeding Maximum iterations for " +
3179 0 : PrimaryAirSystems(AirLoopNum).Name + " during " + state.dataEnvrn->EnvironmentName +
3180 : " continues",
3181 0 : state.dataSimAirServingZones->MaxErrCountSWCC);
3182 : }
3183 : }
3184 :
3185 : // It is necessary to execute this statement anytime, even if the warning message is suppressed.
3186 : // To continue the simulation it must be able to goto the Exit statement
3187 0 : break; // It will not converge this time
3188 : }
3189 :
3190 : // Re-evaluate air loop components with new actuated variables
3191 1349971 : if (HXAssistedWaterCoil) {
3192 0 : SimHXAssistedCoolingCoil(state, CompName, FirstHVACIteration, CompressorOperation::On, 0.0, CompIndex, ContFanCycCoil);
3193 : } else {
3194 1349971 : SimulateWaterCoilComponents(state, CompName, FirstHVACIteration, CompIndex);
3195 : }
3196 1349971 : IsUpToDateFlag = true;
3197 : }
3198 :
3199 : } // End of the Convergence Iteration
3200 :
3201 2544316 : IsUpToDateFlag = true;
3202 :
3203 : // Check that this controller is still converged
3204 :
3205 2544316 : ControllerConvergedFlag = false;
3206 :
3207 5088632 : ManageControllers(state,
3208 : ControllerName,
3209 : ControllerIndex,
3210 : FirstHVACIteration,
3211 : AirLoopNum,
3212 : ControllerOperation::End,
3213 : ControllerConvergedFlag,
3214 : IsUpToDateFlag,
3215 2544316 : state.dataSimAirServingZones->BypassOAControllerSWCC);
3216 :
3217 : // pass convergence of OA system water coils back to SolveAirLoopControllers via PrimaryAirSystem().ControlConverged flag
3218 2544316 : if (AirLoopCheck) {
3219 2522552 : PrimaryAirSystems(AirLoopNum).ControlConverged(state.dataHVACControllers->ControllerProps(ControllerIndex).AirLoopControllerIndex) =
3220 : ControllerConvergedFlag;
3221 2522552 : AirLoopControlInfo(AirLoopNum).ConvergedFlag = AirLoopControlInfo(AirLoopNum).ConvergedFlag && ControllerConvergedFlag;
3222 : }
3223 2544316 : }
3224 :
3225 2617032 : void ReSolveAirLoopControllers(
3226 : EnergyPlusData &state, bool const FirstHVACIteration, int const AirLoopNum, bool &AirLoopConvergedFlag, int &IterMax, int &IterTot, int &NumCalls)
3227 : {
3228 :
3229 : // SUBROUTINE INFORMATION
3230 : // AUTHOR: Dimitri Curtil (LBNL)
3231 : // DATE WRITTEN: Feb 2006
3232 : // MODIFIED:
3233 : // RE-ENGINEERED: This is new code
3234 :
3235 : // PURPOSE OF THIS SUBROUTINE:
3236 : // This subroutine solves for the controllers on the specfied air loop by reusing
3237 : // the solution from the previous HVAC iteration.
3238 : // It is used in the context of the optimization technique referred to as
3239 : // speculative warm restart.
3240 :
3241 : // METHODOLOGY EMPLOYED:
3242 : // For the specified primary air system:
3243 : // (1) each component in the system is simulated in natural order, beginning at
3244 : // the return air inlet and progressing to the supply air outlets. Node data
3245 : // is passed in the same direction.
3246 : // (2) The controllers and their actions are simulated.
3247 :
3248 : // REFERENCES: None
3249 :
3250 : // Using/Aliasing
3251 : using namespace DataHVACControllers;
3252 : using HVACControllers::ManageControllers;
3253 :
3254 : // Locals
3255 : // SUBROUTINE ARGUMENT DEFINITIONS:
3256 : // TRUE if first full HVAC iteration in an HVAC timestep
3257 : // DO loop index; there are 2 passes the 2nd is done only if mass balance fails
3258 : // TRUE when primary air system & controllers simulation has converged;
3259 : // Max number of iterations performed by controllers across all air loops
3260 : // Aggregated number of iterations across all air loops
3261 : // Total number of times SimAirLoopComponents() has been invoked
3262 :
3263 : // SUBROUTINE LOCAL VARIABLE DEFINITIONS
3264 : // Controller DO loop index
3265 : int AirLoopControlNum;
3266 : // TRUE when controller has converged
3267 : bool ControllerConvergedFlag;
3268 : // TRUE when air loop needs to be refreshed.
3269 : // Note that it is not used by ManageControllers() in the WARM_RESTART mode.
3270 : bool IsUpToDateFlag;
3271 :
3272 2617032 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
3273 :
3274 : // To track number of calls to SimAirLoopComponents() for each air loop
3275 : // Represents the most computationally expensive operation in the iteration.
3276 : // Best metric to use to assess the runtime performance of air loop simulation
3277 2617032 : NumCalls = 0;
3278 2617032 : IterMax = 0;
3279 2617032 : IterTot = 0;
3280 :
3281 2617032 : AirLoopConvergedFlag = true;
3282 2617032 : state.dataSimAirServingZones->BypassOAControllerRSALC =
3283 : false; // not exactly sure of this but it seems all controllers need to be simulated -- don't bypass
3284 2617032 : IsUpToDateFlag = false;
3285 2617032 : PrimaryAirSystems(AirLoopNum).ControlConverged = false;
3286 :
3287 : // This call to ManageControllers reinitializes the controllers actuated variables to zero
3288 : // E.g., actuator inlet water flow
3289 7718145 : for (AirLoopControlNum = 1; AirLoopControlNum <= PrimaryAirSystems(AirLoopNum).NumControllers; ++AirLoopControlNum) {
3290 :
3291 : // BypassOAController is false here since we want to simulate the controller during ReSolveAirLoopControllers calls ?
3292 20404452 : ManageControllers(state,
3293 5101113 : PrimaryAirSystems(AirLoopNum).ControllerName(AirLoopControlNum),
3294 5101113 : PrimaryAirSystems(AirLoopNum).ControllerIndex(AirLoopControlNum),
3295 : FirstHVACIteration,
3296 : AirLoopNum,
3297 : ControllerOperation::WarmRestart,
3298 : ControllerConvergedFlag,
3299 : IsUpToDateFlag,
3300 5101113 : state.dataSimAirServingZones->BypassOAControllerRSALC);
3301 : }
3302 :
3303 : // Evaluate air loop components with new actuated variables
3304 2617032 : ++NumCalls;
3305 2617032 : SimAirLoopComponents(state, AirLoopNum, FirstHVACIteration);
3306 2617032 : IsUpToDateFlag = true;
3307 :
3308 : // Check that all active controllers are still convergence
3309 : // Check that actuated variables are within min/max constraints
3310 7718145 : for (AirLoopControlNum = 1; AirLoopControlNum <= PrimaryAirSystems(AirLoopNum).NumControllers; ++AirLoopControlNum) {
3311 :
3312 5101113 : ControllerConvergedFlag = false;
3313 :
3314 20404452 : ManageControllers(state,
3315 5101113 : PrimaryAirSystems(AirLoopNum).ControllerName(AirLoopControlNum),
3316 5101113 : PrimaryAirSystems(AirLoopNum).ControllerIndex(AirLoopControlNum),
3317 : FirstHVACIteration,
3318 : AirLoopNum,
3319 : ControllerOperation::End,
3320 : ControllerConvergedFlag,
3321 : IsUpToDateFlag,
3322 5101113 : state.dataSimAirServingZones->BypassOAControllerRSALC);
3323 :
3324 5101113 : PrimaryAirSystems(AirLoopNum).ControlConverged(AirLoopControlNum) = ControllerConvergedFlag;
3325 :
3326 5101113 : AirLoopConvergedFlag = AirLoopConvergedFlag && ControllerConvergedFlag;
3327 :
3328 : // Update tracker for max iteration counter across all controllers on all air loops
3329 5101113 : IterMax = max(IterMax, 0);
3330 : // Update tracker for aggregated counter of air loop inner iterations across all controllers
3331 5101113 : IterTot += 0;
3332 :
3333 : } // end of controller loop
3334 2617032 : }
3335 :
3336 26448362 : void SimAirLoopComponents(EnergyPlusData &state,
3337 : int const AirLoopNum, // Index of the air loop being currently simulated
3338 : bool const FirstHVACIteration // TRUE if first full HVAC iteration in an HVAC timestep
3339 : )
3340 : {
3341 : // SUBROUTINE INFORMATION
3342 : // AUTHOR: Dimitri Curtil (LBNL)
3343 : // DATE WRITTEN: Feb 2006
3344 : // MODIFIED:
3345 : // RE-ENGINEERED:
3346 :
3347 : // PURPOSE OF THIS SUBROUTINE:
3348 : // This simulates all components on a particular air loop in the primary air system.
3349 : // This code used to appear in different places in SimAirLoops(). Now consolidated
3350 : // into one subroutine called many times.
3351 :
3352 : // METHODOLOGY EMPLOYED:
3353 : // For each branch in the air loop:
3354 : // (1) update branch connection with (BeforeBranchSim)
3355 : // (2) simulate each component
3356 : // (3) update branch connection with (AfterBranchSim) to enforce continuity through splitter
3357 : // Sets current branch number to CurBranchNum defined in MODULE DataSizing
3358 : // Sets duct type of current branch to CurDuctType defined in MODULE DataSizing
3359 : // Upon exiting, resets both counters to 0.
3360 :
3361 : // SUBROUTINE LOCAL VARIABLE DEFINITIONS: None
3362 : int BranchNum; // Branch DO loop index
3363 : int CompNum; // Component DO loop index
3364 : // std::string CompType; // Component type
3365 : // std::string CompName; // Component name
3366 : CompType CompType_Num; // Numeric equivalent for CompType
3367 :
3368 26448362 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
3369 :
3370 53489177 : for (BranchNum = 1; BranchNum <= PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) { // loop over all branches in air system
3371 :
3372 27040815 : UpdateBranchConnections(state, AirLoopNum, BranchNum, BeforeBranchSim);
3373 :
3374 27040815 : state.dataSize->CurBranchNum = BranchNum;
3375 27040815 : state.dataSize->CurDuctType = PrimaryAirSystems(AirLoopNum).Branch(BranchNum).DuctType;
3376 :
3377 : // Loop over components in branch
3378 117976056 : for (CompNum = 1; CompNum <= PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents; ++CompNum) {
3379 : // CompType = PrimaryAirSystem( AirLoopNum ).Branch( BranchNum ).Comp( CompNum ).TypeOf;
3380 : // CompName = PrimaryAirSystem( AirLoopNum ).Branch( BranchNum ).Comp( CompNum ).Name;
3381 90935241 : CompType_Num = PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).CompType_Num;
3382 :
3383 : // Simulate each component on PrimaryAirSystem(AirLoopNum)%Branch(BranchNum)%Name
3384 272805723 : SimAirLoopComponent(state,
3385 90935241 : PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).Name,
3386 : CompType_Num,
3387 : FirstHVACIteration,
3388 : AirLoopNum,
3389 90935241 : PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).CompIndex,
3390 90935241 : PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).compPointer,
3391 : AirLoopNum,
3392 : BranchNum,
3393 : CompNum);
3394 : } // End of component loop
3395 :
3396 : // Enforce continuity through the splitter
3397 27040815 : UpdateBranchConnections(state, AirLoopNum, BranchNum, AfterBranchSim);
3398 :
3399 : } // End of branch loop
3400 :
3401 26448362 : state.dataSize->CurBranchNum = 0;
3402 26448362 : state.dataSize->CurDuctType = DataHVACGlobals::AirDuctType::Invalid;
3403 26448362 : }
3404 :
3405 90935241 : void SimAirLoopComponent(EnergyPlusData &state,
3406 : std::string const &CompName, // the component Name
3407 : CompType const CompType_Num, // numeric equivalent for component type
3408 : bool const FirstHVACIteration, // TRUE if first full HVAC iteration in an HVAC timestep
3409 : int const AirLoopNum, // Primary air loop number
3410 : int &CompIndex, // numeric pointer for CompType/CompName -- passed back from other routines
3411 : HVACSystemData *CompPointer, // equipment actual pointer
3412 : int const airLoopNum, // index to AirloopHVAC
3413 : int const branchNum, // index to AirloopHVAC branch
3414 : int const compNum // index to AirloopHVAC branch component
3415 : )
3416 : {
3417 :
3418 : // SUBROUTINE INFORMATION
3419 : // AUTHOR: Russ Taylor, Dan Fisher, Fred Buhl
3420 : // DATE WRITTEN: Oct 1997
3421 : // MODIFIED: Dec 1997 Fred Buhl, Richard Raustad,FSEC Sept 2003
3422 : // RE-ENGINEERED: This is new code, not reengineered
3423 :
3424 : // PURPOSE OF THIS SUBROUTINE:
3425 : // Calls the individual air loop component simulation routines
3426 :
3427 : // METHODOLOGY EMPLOYED: None
3428 :
3429 : // REFERENCES: None
3430 :
3431 : // USE Statements
3432 : // Using/Aliasing
3433 : using DesiccantDehumidifiers::SimDesiccantDehumidifier;
3434 : using EvaporativeCoolers::SimEvapCooler;
3435 : using Fans::SimulateFanComponents;
3436 : using Furnaces::SimFurnace;
3437 : using HeatingCoils::SimulateHeatingCoilComponents;
3438 : using HeatRecovery::SimHeatRecovery;
3439 : using Humidifiers::SimHumidifier;
3440 : using HVACDuct::SimDuct;
3441 : using HVACDXHeatPumpSystem::SimDXHeatPumpSystem;
3442 : using HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil;
3443 : using HVACMultiSpeedHeatPump::SimMSHeatPump;
3444 : using HVACUnitaryBypassVAV::SimUnitaryBypassVAV;
3445 : using MixedAir::ManageOutsideAirSystem;
3446 : using SteamCoils::SimulateSteamCoilComponents;
3447 : using UserDefinedComponents::SimCoilUserDefined;
3448 : using WaterCoils::SimulateWaterCoilComponents;
3449 :
3450 : // SUBROUTINE LOCAL VARIABLE DEFINITIONS:
3451 : Real64 QActual;
3452 90935241 : int OAUnitNum = 0; // used only for UnitarySystem call
3453 90935241 : Real64 OAUCoilOutTemp = 0.0; // used only for UnitarySystem call
3454 90935241 : bool ZoneEquipFlag = false; // used only for UnitarySystem call
3455 90935241 : bool CoolingActive = false;
3456 90935241 : bool HeatingActive = false;
3457 :
3458 90935241 : auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo);
3459 :
3460 90935241 : switch (CompType_Num) {
3461 24257718 : case CompType::OAMixer_Num: { // 'OUTSIDE AIR SYSTEM'
3462 24257718 : ManageOutsideAirSystem(state, CompName, FirstHVACIteration, AirLoopNum, CompIndex);
3463 : // Fan Types for the air sys simulation
3464 24257718 : } break;
3465 4409270 : case CompType::Fan_Simple_CV: { // 'Fan:ConstantVolume'
3466 4409270 : Fans::SimulateFanComponents(state, CompName, FirstHVACIteration, CompIndex);
3467 4409270 : } break;
3468 14024316 : case CompType::Fan_Simple_VAV: { // 'Fan:VariableVolume'
3469 14024316 : Fans::SimulateFanComponents(state, CompName, FirstHVACIteration, CompIndex);
3470 14024316 : } break;
3471 121808 : case CompType::Fan_System_Object: { // "Fan:SystemModel" new for V8.6
3472 121808 : if (CompIndex == 0) { // 0 means has not been filled because of 1-based arrays in old fortran
3473 0 : CompIndex = HVACFan::getFanObjectVectorIndex(state, CompName) + 1; // + 1 for shift from zero-based vector to 1-based compIndex
3474 : }
3475 : // if the fan is here, it can't (yet) really be cycling fan operation, set this ugly global in the event that there are dx coils
3476 : // involved but the fan should really run like constant volume and not cycle with compressor
3477 121808 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
3478 121808 : state.dataHVACFan->fanObjs[CompIndex - 1]->simulate(state, _, _, _, _); // vector is 0 based, but CompIndex is 1 based so shift
3479 121808 : } break;
3480 31069 : case CompType::Fan_ComponentModel: { // 'Fan:ComponentModel'
3481 31069 : Fans::SimulateFanComponents(state, CompName, FirstHVACIteration, CompIndex);
3482 :
3483 : // Coil Types for the air sys simulation
3484 : // Currently no control for HX Assisted coils
3485 : // CASE(DXCoil_CoolingHXAsst) ! 'CoilSystem:Cooling:DX:HeatExchangerAssisted'
3486 : // CALL SimHXAssistedCoolingCoil(CompName,FirstHVACIteration,CoilOn,0.0,CompIndex,ContFanCycCoil)
3487 31069 : } break;
3488 126536 : case CompType::WaterCoil_CoolingHXAsst: { // 'CoilSystem:Cooling:Water:HeatExchangerAssisted'
3489 126536 : SimHXAssistedCoolingCoil(state,
3490 : CompName,
3491 : FirstHVACIteration,
3492 : CompressorOperation::On,
3493 : DataPrecisionGlobals::constant_zero,
3494 : CompIndex,
3495 : ContFanCycCoil,
3496 : _,
3497 : _,
3498 : _,
3499 : QActual);
3500 126536 : if (QActual > 0.0) CoolingActive = true; // determine if coil is ON
3501 126536 : } break;
3502 16216198 : case CompType::WaterCoil_SimpleHeat: { // 'Coil:Heating:Water'
3503 16216198 : SimulateWaterCoilComponents(state, CompName, FirstHVACIteration, CompIndex, QActual);
3504 16216198 : if (QActual > 0.0) HeatingActive = true; // determine if coil is ON
3505 16216198 : } break;
3506 34258 : case CompType::SteamCoil_AirHeat: { // 'Coil:Heating:Steam'
3507 34258 : SimulateSteamCoilComponents(state, CompName, FirstHVACIteration, CompIndex, DataPrecisionGlobals::constant_zero, QActual);
3508 34258 : if (QActual > 0.0) HeatingActive = true; // determine if coil is ON
3509 34258 : } break;
3510 2847311 : case CompType::WaterCoil_DetailedCool: { // 'Coil:Cooling:Water:DetailedGeometry'
3511 2847311 : SimulateWaterCoilComponents(state, CompName, FirstHVACIteration, CompIndex, QActual);
3512 2847311 : if (QActual > 0.0) CoolingActive = true; // determine if coil is ON
3513 2847311 : } break;
3514 12577871 : case CompType::WaterCoil_Cooling: { // 'Coil:Cooling:Water'
3515 12577871 : SimulateWaterCoilComponents(state, CompName, FirstHVACIteration, CompIndex, QActual);
3516 12577871 : if (QActual > 0.0) CoolingActive = true; // determine if coil is ON
3517 : // stand-alone coils are temperature controlled (do not pass QCoilReq in argument list, QCoilReq overrides temp SP)
3518 12577871 : } break;
3519 508714 : case CompType::Coil_ElectricHeat: { // 'Coil:Heating:Electric'
3520 508714 : SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, _, CompIndex, QActual);
3521 508714 : if (QActual > 0.0) HeatingActive = true; // determine if coil is ON
3522 : // stand-alone coils are temperature controlled (do not pass QCoilReq in argument list, QCoilReq overrides temp SP)
3523 508714 : } break;
3524 2729615 : case CompType::Coil_GasHeat: { // 'Coil:Heating:Fuel'
3525 2729615 : SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, _, CompIndex, QActual);
3526 2729615 : if (QActual > 0.0) HeatingActive = true; // determine if coil is ON
3527 : // stand-alone coils are temperature controlled (do not pass QCoilReq in argument list, QCoilReq overrides temp SP)
3528 2729615 : } break;
3529 0 : case CompType::Coil_DeSuperHeat: { // 'Coil:Heating:Desuperheater' - heat reclaim
3530 0 : SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, _, CompIndex, QActual);
3531 0 : if (QActual > 0.0) HeatingActive = true; // determine if coil is ON
3532 0 : } break;
3533 3329811 : case CompType::DXSystem: { // CoilSystem:Cooling:DX old 'AirLoopHVAC:UnitaryCoolOnly'
3534 3329811 : if (CompPointer == nullptr) {
3535 556 : UnitarySystems::UnitarySys thisSys;
3536 278 : CompPointer = thisSys.factory(state, DataHVACGlobals::UnitarySys_AnyCoilType, CompName, false, 0);
3537 : // temporary fix for saving pointer, eventually apply to UnitarySystem 25 lines down
3538 278 : state.dataAirSystemsData->PrimaryAirSystems(airLoopNum).Branch(branchNum).Comp(compNum).compPointer = CompPointer;
3539 : }
3540 3329811 : Real64 sensOut = 0.0;
3541 3329811 : Real64 latOut = 0.0;
3542 3329811 : CompPointer->simulate(state,
3543 : CompName,
3544 : FirstHVACIteration,
3545 : AirLoopNum,
3546 : CompIndex,
3547 : HeatingActive,
3548 : CoolingActive,
3549 : OAUnitNum,
3550 : OAUCoilOutTemp,
3551 : ZoneEquipFlag,
3552 : sensOut,
3553 6659622 : latOut);
3554 :
3555 3329811 : } break;
3556 8182 : case CompType::DXHeatPumpSystem: { // 'CoilSystem:Heating:DX'
3557 8182 : SimDXHeatPumpSystem(state, CompName, FirstHVACIteration, AirLoopNum, CompIndex, _, _, QActual);
3558 8182 : if (QActual > 0.0) HeatingActive = true; // determine if coil is ON
3559 8182 : } break;
3560 53564 : case CompType::CoilUserDefined: { // Coil:UserDefined
3561 53564 : SimCoilUserDefined(state, CompName, CompIndex, AirLoopNum, HeatingActive, CoolingActive);
3562 53564 : } break;
3563 1339278 : case CompType::UnitarySystemModel: { // 'AirLoopHVAC:UnitarySystem'
3564 1339278 : Real64 sensOut = 0.0;
3565 1339278 : Real64 latOut = 0.0;
3566 1339278 : CompPointer->simulate(state,
3567 : CompName,
3568 : FirstHVACIteration,
3569 : AirLoopNum,
3570 : CompIndex,
3571 : HeatingActive,
3572 : CoolingActive,
3573 : OAUnitNum,
3574 : OAUCoilOutTemp,
3575 : ZoneEquipFlag,
3576 : sensOut,
3577 2678556 : latOut);
3578 1339278 : } break;
3579 41294 : case CompType::CoilSystemWater: { // 'CoilSystemCooling:Water'
3580 41294 : if (CompPointer == nullptr) {
3581 0 : UnitarySystems::UnitarySys thisSys;
3582 0 : CompPointer = thisSys.factory(state, DataHVACGlobals::UnitarySys_AnyCoilType, CompName, false, 0);
3583 : // temporary fix for saving pointer, eventually apply to UnitarySystem 16 lines above
3584 0 : state.dataAirSystemsData->PrimaryAirSystems(airLoopNum).Branch(branchNum).Comp(compNum).compPointer = CompPointer;
3585 : }
3586 41294 : Real64 sensOut = 0.0;
3587 41294 : Real64 latOut = 0.0;
3588 41294 : CompPointer->simulate(state,
3589 : CompName,
3590 : FirstHVACIteration,
3591 : AirLoopNum,
3592 : CompIndex,
3593 : HeatingActive,
3594 : CoolingActive,
3595 : OAUnitNum,
3596 : OAUCoilOutTemp,
3597 : ZoneEquipFlag,
3598 : sensOut,
3599 82588 : latOut);
3600 41294 : } break;
3601 6396161 : case CompType::Furnace_UnitarySys_HeatOnly:
3602 : case CompType::Furnace_UnitarySys_HeatCool: {
3603 : // 'AirLoopHVAC:Unitary:Furnace:HeatOnly', 'AirLoopHVAC:Unitary:Furnace:HeatCool',
3604 : // 'AirLoopHVAC:UnitaryHeatOnly', 'AirLoopHVAC:UnitaryHeatCool'
3605 : // 'AirLoopHVAC:UnitaryHeatPump:AirToAir', 'AirLoopHVAC:UnitaryHeatPump:WaterToAir'
3606 6396161 : SimFurnace(state, CompName, FirstHVACIteration, AirLoopNum, CompIndex);
3607 6396161 : } break;
3608 22842 : case CompType::UnitarySystem_BypassVAVSys: { // 'AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass'
3609 22842 : SimUnitaryBypassVAV(state, CompName, FirstHVACIteration, AirLoopNum, CompIndex);
3610 22842 : } break;
3611 251050 : case CompType::UnitarySystem_MSHeatPump: { // 'AirLoopHVAC:UnitaryHeatPump:AirToAir:Multispeed'
3612 251050 : SimMSHeatPump(state, CompName, FirstHVACIteration, AirLoopNum, CompIndex);
3613 : // Humidifier Types for the air system simulation
3614 251050 : } break;
3615 1203119 : case CompType::Humidifier: { // 'Humidifier:Steam:Electric' and 'Humidifier:Steam:Gas'
3616 1203119 : SimHumidifier(state, CompName, FirstHVACIteration, CompIndex);
3617 : // Evap Cooler Types for the air system simulation
3618 1203119 : } break;
3619 276446 : case CompType::EvapCooler: { // 'EvaporativeCooler:Direct:CelDekPad', 'EvaporativeCooler:Indirect:CelDekPad'
3620 : // 'EvaporativeCooler:Indirect:WetCoil', 'EvaporativeCooler:Indirect:ResearchSpecial'
3621 276446 : SimEvapCooler(state, CompName, CompIndex, state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR);
3622 : // Desiccant Dehumidifier Types for the air system simulation
3623 276446 : } break;
3624 17404 : case CompType::Desiccant: { // 'Dehumidifier:Desiccant:NoFans', 'Dehumidifier:Desiccant:System'
3625 17404 : SimDesiccantDehumidifier(state, CompName, FirstHVACIteration, CompIndex);
3626 : // Heat recovery
3627 17404 : } break;
3628 15695 : case CompType::HeatXchngr: { // 'HeatExchanger:AirToAir:FlatPlate', 'HeatExchanger:AirToAir:SensibleAndLatent'
3629 : // 'HeatExchanger:Desiccant:BalancedFlow'
3630 78475 : SimHeatRecovery(state,
3631 : CompName,
3632 : FirstHVACIteration,
3633 : CompIndex,
3634 15695 : AirLoopControlInfo(AirLoopNum).FanOpMode,
3635 15695 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR,
3636 : _,
3637 : _,
3638 : _,
3639 15695 : AirLoopControlInfo(AirLoopNum).EconoActive,
3640 15695 : AirLoopControlInfo(AirLoopNum).HighHumCtrlActive);
3641 :
3642 : // Ducts
3643 15695 : } break;
3644 3184 : case CompType::ZoneVRFasAirLoopEquip: { // 'ZoneHVAC:TerminalUnit:VariableRefrigerantFlow'
3645 3184 : int ControlledZoneNum = 0;
3646 3184 : int constexpr OAUnitNumLocal = 0;
3647 3184 : Real64 constexpr OAUCoilOutTempLocal = 0.0;
3648 3184 : bool constexpr ZoneEquipment = false;
3649 3184 : Real64 sysOut = 0.0;
3650 3184 : Real64 latOut = 0.0;
3651 3184 : HVACVariableRefrigerantFlow::SimulateVRF(state,
3652 : CompName,
3653 : FirstHVACIteration,
3654 : ControlledZoneNum,
3655 : CompIndex,
3656 : HeatingActive,
3657 : CoolingActive,
3658 : OAUnitNumLocal,
3659 : OAUCoilOutTempLocal,
3660 : ZoneEquipment,
3661 : sysOut,
3662 3184 : latOut);
3663 :
3664 3184 : } break;
3665 92527 : case CompType::Duct: { // 'Duct'
3666 92527 : SimDuct(state, CompName, FirstHVACIteration, CompIndex);
3667 92527 : } break;
3668 0 : default:
3669 0 : break;
3670 : }
3671 :
3672 : // Set AirLoopControlInfo flag to identify coil operation for "Air Loop Coils"
3673 : // Any coil operation from multiple coils causes flag to be TRUE
3674 : // Flag is reset at beginning of each iteration (Subroutine SimHVAC)
3675 90935241 : AirLoopControlInfo(AirLoopNum).CoolingActiveFlag = AirLoopControlInfo(AirLoopNum).CoolingActiveFlag || CoolingActive;
3676 90935241 : AirLoopControlInfo(AirLoopNum).HeatingActiveFlag = AirLoopControlInfo(AirLoopNum).HeatingActiveFlag || HeatingActive;
3677 90935241 : }
3678 :
3679 54081630 : void UpdateBranchConnections(EnergyPlusData &state,
3680 : int const AirLoopNum, // primary air system number
3681 : int const BranchNum, // branch reference number
3682 : int const Update // 1=BeforeBranchSim; 2=AfterBranchSim
3683 : )
3684 : {
3685 :
3686 : // SUBROUTINE INFORMATION
3687 : // AUTHOR: Fred Buhl
3688 : // DATE WRITTEN: Nov 1999
3689 : // MODIFIED:
3690 : // RE-ENGINEERED: This is new code, not reengineered
3691 :
3692 : // PURPOSE OF THIS SUBROUTINE:
3693 : // This routine passes node data from a branch exit node through a
3694 : // splitter.
3695 :
3696 : // METHODOLOGY EMPLOYED:
3697 : // Temperature, humidity ratio, and enthalpy are passed through from
3698 : // the inlet to the outlets. The mass flow is divided among the outlets
3699 : // according to the required mass flows established by the zone equipment
3700 : // simulation. The required mass flows are were stored in the node data
3701 : // as MassFlowRateSetPoints in the InitAirLoops routine.
3702 :
3703 : // Using/Aliasing
3704 : using Psychrometrics::PsyTdbFnHW;
3705 :
3706 : int OutletNum; // splitter outlet DO loop index
3707 : int InletNum; // mixer inlet DO loop index
3708 : int InletNodeNum; // node number of splitter inlet node
3709 : int OutletNodeNum; // node number of a splitter outlet node
3710 : int RABNodeNum; // splitter outlet RAB node
3711 : int NonRABNodeNum; // splitter outlet nonRAB node
3712 : Real64 MassFlowRateSetSum; // sum of mass flow rate setpoints for splitter outlet nodes
3713 : Real64 MassFlowRateOut; // outlet mass flow rate of mixer
3714 : Real64 MassFlowRateMinAvailOut; // outlet minimum available mass flow rate
3715 : Real64 OutletHumRat; // outlet humidity ratio of mixer
3716 : Real64 OutletEnthalpy; // outlet enthalpy of mixer
3717 : Real64 OutletPress;
3718 : Real64 OutletCO2; // outlet CO2 of mixer
3719 : Real64 OutletGC; // outlet generic contaminant of mixer
3720 54081630 : MassFlowRateSetSum = 0.0;
3721 54081630 : MassFlowRateOut = 0.0;
3722 54081630 : MassFlowRateMinAvailOut = 0.0;
3723 54081630 : OutletHumRat = 0.0;
3724 54081630 : OutletEnthalpy = 0.0;
3725 54081630 : OutletPress = 0.0;
3726 54081630 : RABNodeNum = 0;
3727 54081630 : NonRABNodeNum = 0;
3728 54081630 : OutletCO2 = 0.0;
3729 54081630 : OutletGC = 0.0;
3730 :
3731 54081630 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
3732 54081630 : auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo);
3733 :
3734 54081630 : if (PrimaryAirSystems(AirLoopNum).Splitter.Exists && Update == AfterBranchSim) {
3735 : // if we are at an inlet branch, pass data through the splitter
3736 881009 : if (PrimaryAirSystems(AirLoopNum).Splitter.BranchNumIn == BranchNum) {
3737 288556 : InletNodeNum = PrimaryAirSystems(AirLoopNum).Splitter.NodeNumIn;
3738 : // Pass node data through the splitter
3739 865668 : for (OutletNum = 1; OutletNum <= PrimaryAirSystems(AirLoopNum).Splitter.TotalOutletNodes; ++OutletNum) {
3740 577112 : OutletNodeNum = PrimaryAirSystems(AirLoopNum).Splitter.NodeNumOut(OutletNum);
3741 577112 : state.dataLoopNodes->Node(OutletNodeNum).Temp = state.dataLoopNodes->Node(InletNodeNum).Temp;
3742 577112 : state.dataLoopNodes->Node(OutletNodeNum).HumRat = state.dataLoopNodes->Node(InletNodeNum).HumRat;
3743 577112 : state.dataLoopNodes->Node(OutletNodeNum).Enthalpy = state.dataLoopNodes->Node(InletNodeNum).Enthalpy;
3744 577112 : state.dataLoopNodes->Node(OutletNodeNum).Press = state.dataLoopNodes->Node(InletNodeNum).Press;
3745 577112 : MassFlowRateSetSum +=
3746 577112 : min(state.dataLoopNodes->Node(OutletNodeNum).MassFlowRateSetPoint, state.dataLoopNodes->Node(OutletNodeNum).MassFlowRateMaxAvail);
3747 577112 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
3748 0 : state.dataLoopNodes->Node(OutletNodeNum).CO2 = state.dataLoopNodes->Node(InletNodeNum).CO2;
3749 : }
3750 577112 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
3751 0 : state.dataLoopNodes->Node(OutletNodeNum).GenContam = state.dataLoopNodes->Node(InletNodeNum).GenContam;
3752 : }
3753 : }
3754 288556 : if (!PrimaryAirSystems(AirLoopNum).RABExists) {
3755 : // set the outlet mass flows
3756 819645 : for (OutletNum = 1; OutletNum <= PrimaryAirSystems(AirLoopNum).Splitter.TotalOutletNodes; ++OutletNum) {
3757 546430 : OutletNodeNum = PrimaryAirSystems(AirLoopNum).Splitter.NodeNumOut(OutletNum);
3758 546430 : if (MassFlowRateSetSum < SmallMassFlow || state.dataLoopNodes->Node(InletNodeNum).MassFlowRate < SmallMassFlow) {
3759 30414 : state.dataLoopNodes->Node(OutletNodeNum).MassFlowRate = 0.0;
3760 : } else {
3761 1032032 : state.dataLoopNodes->Node(OutletNodeNum).MassFlowRate = state.dataLoopNodes->Node(InletNodeNum).MassFlowRate *
3762 516016 : (min(state.dataLoopNodes->Node(OutletNodeNum).MassFlowRateSetPoint,
3763 1032032 : state.dataLoopNodes->Node(OutletNodeNum).MassFlowRateMaxAvail) /
3764 : MassFlowRateSetSum);
3765 : }
3766 546430 : state.dataLoopNodes->Node(OutletNodeNum).MassFlowRateMaxAvail = state.dataLoopNodes->Node(InletNodeNum).MassFlowRateMaxAvail;
3767 546430 : state.dataLoopNodes->Node(OutletNodeNum).MassFlowRateMinAvail = 0.0;
3768 : }
3769 : } else { // set the RAB flow rates
3770 15341 : RABNodeNum = PrimaryAirSystems(AirLoopNum).RABSplitOutNode;
3771 15341 : NonRABNodeNum = PrimaryAirSystems(AirLoopNum).OtherSplitOutNode;
3772 15341 : if (AirLoopControlInfo(AirLoopNum).EconoActive) {
3773 0 : state.dataLoopNodes->Node(RABNodeNum).MassFlowRate = 0.0;
3774 0 : state.dataLoopNodes->Node(NonRABNodeNum).MassFlowRate = state.dataLoopNodes->Node(InletNodeNum).MassFlowRate;
3775 : } else {
3776 15341 : state.dataLoopNodes->Node(RABNodeNum).MassFlowRate = state.dataLoopNodes->Node(RABNodeNum).MassFlowRateSetPoint;
3777 15341 : state.dataLoopNodes->Node(NonRABNodeNum).MassFlowRate =
3778 15341 : state.dataLoopNodes->Node(InletNodeNum).MassFlowRate - state.dataLoopNodes->Node(RABNodeNum).MassFlowRate;
3779 15341 : if (state.dataLoopNodes->Node(NonRABNodeNum).MassFlowRate <= state.dataAirLoop->AirLoopFlow(AirLoopNum).MinOutAir) {
3780 3290 : state.dataLoopNodes->Node(NonRABNodeNum).MassFlowRate =
3781 3290 : min(state.dataAirLoop->AirLoopFlow(AirLoopNum).MinOutAir, state.dataLoopNodes->Node(InletNodeNum).MassFlowRate);
3782 3290 : state.dataLoopNodes->Node(RABNodeNum).MassFlowRate =
3783 3290 : state.dataLoopNodes->Node(InletNodeNum).MassFlowRate - state.dataLoopNodes->Node(NonRABNodeNum).MassFlowRate;
3784 : }
3785 : }
3786 : }
3787 : }
3788 : }
3789 :
3790 54081630 : if (PrimaryAirSystems(AirLoopNum).Mixer.Exists && Update == BeforeBranchSim) {
3791 : // if we are at a mixer outlet branch, calculate the outlet branch conditions
3792 61364 : if (PrimaryAirSystems(AirLoopNum).Mixer.BranchNumOut == BranchNum) {
3793 15341 : OutletNodeNum = PrimaryAirSystems(AirLoopNum).Mixer.NodeNumOut;
3794 : // get the outlet mass flow rate and the outlet minavail mass flow rate
3795 46023 : for (InletNum = 1; InletNum <= PrimaryAirSystems(AirLoopNum).Mixer.TotalInletNodes; ++InletNum) {
3796 30682 : InletNodeNum = PrimaryAirSystems(AirLoopNum).Mixer.NodeNumIn(InletNum);
3797 30682 : MassFlowRateOut += state.dataLoopNodes->Node(InletNodeNum).MassFlowRate;
3798 30682 : MassFlowRateMinAvailOut += state.dataLoopNodes->Node(InletNodeNum).MassFlowRateMinAvail;
3799 : }
3800 : // set the outlet mass flow
3801 15341 : state.dataLoopNodes->Node(OutletNodeNum).MassFlowRate = MassFlowRateOut;
3802 15341 : state.dataLoopNodes->Node(OutletNodeNum).MassFlowRateMinAvail = MassFlowRateMinAvailOut;
3803 15341 : state.dataLoopNodes->Node(OutletNodeNum).MassFlowRateMaxAvail = state.dataLoopNodes->Node(OutletNodeNum).MassFlowRateMax;
3804 : // calculate the outlet humidity ratio and enthalpy and pressure
3805 15341 : if (MassFlowRateOut > 0.0) {
3806 46005 : for (InletNum = 1; InletNum <= PrimaryAirSystems(AirLoopNum).Mixer.TotalInletNodes; ++InletNum) {
3807 30670 : InletNodeNum = PrimaryAirSystems(AirLoopNum).Mixer.NodeNumIn(InletNum);
3808 30670 : OutletHumRat +=
3809 30670 : (state.dataLoopNodes->Node(InletNodeNum).MassFlowRate * state.dataLoopNodes->Node(InletNodeNum).HumRat) / MassFlowRateOut;
3810 30670 : OutletEnthalpy +=
3811 30670 : (state.dataLoopNodes->Node(InletNodeNum).MassFlowRate * state.dataLoopNodes->Node(InletNodeNum).Enthalpy) / MassFlowRateOut;
3812 30670 : OutletPress +=
3813 30670 : (state.dataLoopNodes->Node(InletNodeNum).MassFlowRate * state.dataLoopNodes->Node(InletNodeNum).Press) / MassFlowRateOut;
3814 30670 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
3815 0 : OutletCO2 +=
3816 0 : (state.dataLoopNodes->Node(InletNodeNum).MassFlowRate * state.dataLoopNodes->Node(InletNodeNum).CO2) / MassFlowRateOut;
3817 : }
3818 30670 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
3819 0 : OutletGC += (state.dataLoopNodes->Node(InletNodeNum).MassFlowRate * state.dataLoopNodes->Node(InletNodeNum).GenContam) /
3820 : MassFlowRateOut;
3821 : }
3822 : }
3823 : } else {
3824 6 : InletNodeNum = PrimaryAirSystems(AirLoopNum).Mixer.NodeNumIn(1);
3825 6 : OutletHumRat = state.dataLoopNodes->Node(InletNodeNum).HumRat;
3826 6 : OutletEnthalpy = state.dataLoopNodes->Node(InletNodeNum).Enthalpy;
3827 6 : OutletPress = state.dataLoopNodes->Node(InletNodeNum).Press;
3828 6 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
3829 0 : OutletCO2 = state.dataLoopNodes->Node(InletNodeNum).CO2;
3830 : }
3831 6 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
3832 0 : OutletGC = state.dataLoopNodes->Node(InletNodeNum).GenContam;
3833 : }
3834 : }
3835 15341 : state.dataLoopNodes->Node(OutletNodeNum).HumRat = OutletHumRat;
3836 15341 : state.dataLoopNodes->Node(OutletNodeNum).Enthalpy = OutletEnthalpy;
3837 15341 : state.dataLoopNodes->Node(OutletNodeNum).Press = OutletPress;
3838 : // calculate the outlet temperature
3839 15341 : state.dataLoopNodes->Node(OutletNodeNum).Temp = PsyTdbFnHW(OutletEnthalpy, OutletHumRat);
3840 15341 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
3841 0 : state.dataLoopNodes->Node(OutletNodeNum).CO2 = OutletCO2;
3842 : }
3843 15341 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
3844 0 : state.dataLoopNodes->Node(OutletNodeNum).GenContam = OutletGC;
3845 : }
3846 : }
3847 : }
3848 54081630 : }
3849 :
3850 11063254 : void ResolveSysFlow(EnergyPlusData &state,
3851 : int const SysNum, // the primary air system number
3852 : bool &SysReSim // Set to TRUE if mass balance fails and resimulation is needed
3853 : )
3854 : {
3855 :
3856 : // SUBROUTINE INFORMATION
3857 : // AUTHOR: Fred Buhl
3858 : // DATE WRITTEN: Dec 1999
3859 : // MODIFIED:
3860 : // RE-ENGINEERED: This is new code, not reengineered
3861 :
3862 : // PURPOSE OF THIS SUBROUTINE:
3863 : // This subroutines checks for mass flow balance in all air system branches
3864 : // and across all connections. If there is a failure of mass flow
3865 : // balance, mass flows are imposed to achieve mass flow balance and
3866 : // the resimulate flag SysReSim is set to true.
3867 :
3868 : // METHODOLOGY EMPLOYED:
3869 : // Node()%MassFlowRateMaxAvail for every node is set to the minimum
3870 : // Node()%MassFlowRateMaxAvail on each branch. Mass balance is imposed
3871 : // at the branch connections. System inlet mass flows are forced to
3872 : // be less than or equal to the resulting inlet MassFlowRateMaxAvails.
3873 :
3874 : int BranchNum; // branch DO loop index
3875 : int NodeIndex; // node on branch DO loop index
3876 : Real64 MassFlowRateOutSum; // sum of splitter outlet mass flow rates (imposed)
3877 : Real64 BranchMassFlowMaxAvail; // branch level maximum flow rate possible
3878 : int OutletNum; // splitter outlet DO loop index
3879 : int OutletNodeNum; // a splitter outlet node number
3880 : int InletNodeNum; // splitter inlet node number
3881 : int NodeNum; // a node number
3882 : int NodeNumNext; // node number of next node on a branch
3883 : int InNodeNum; // air system inlet node
3884 : int InBranchNum; // air system inlet branch number
3885 : int InBranchIndex; // air sys inlet branch DO loop index
3886 :
3887 11063254 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
3888 11063254 : auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo);
3889 :
3890 : // Find the minimum MassFlowMaxAvail for each branch in the system and store it on the branch inlet node.
3891 : // Check for mass flow conservation on each branch. Set SysReSim to TRUE is mass flow not conserved.
3892 22249377 : for (BranchNum = 1; BranchNum <= PrimaryAirSystems(SysNum).NumBranches; ++BranchNum) { // loop over branches in system
3893 : // Initialize branch max avail mass flow to max avail mass flow at outlet node
3894 11186123 : BranchMassFlowMaxAvail = state.dataLoopNodes->Node(PrimaryAirSystems(SysNum).Branch(BranchNum).NodeNumOut).MassFlowRateMaxAvail;
3895 58493799 : for (NodeIndex = 1; NodeIndex <= PrimaryAirSystems(SysNum).Branch(BranchNum).TotalNodes; ++NodeIndex) { // loop over nodes on branch
3896 : // Get the new smallest max avail mass flow
3897 47307676 : NodeNum = PrimaryAirSystems(SysNum).Branch(BranchNum).NodeNum(NodeIndex);
3898 47307676 : BranchMassFlowMaxAvail = min(BranchMassFlowMaxAvail, state.dataLoopNodes->Node(NodeNum).MassFlowRateMaxAvail);
3899 : // Check for mass flow conservation on the branch
3900 47307676 : if (NodeIndex < PrimaryAirSystems(SysNum).Branch(BranchNum).TotalNodes) {
3901 : // Set ReSim flag to TRUE if mass flow not conserved on this branch
3902 36121553 : NodeNumNext = PrimaryAirSystems(SysNum).Branch(BranchNum).NodeNum(NodeIndex + 1);
3903 36121553 : if (NodeNum == PrimaryAirSystems(SysNum).OASysInletNodeNum) continue; // don't enforce mass balance across OA Sys
3904 : // Changeover bypass system connected to a plenum or mixer will need to include the bypass flow rate
3905 76815519 : if (std::abs(state.dataLoopNodes->Node(NodeNum).MassFlowRate - state.dataLoopNodes->Node(NodeNumNext).MassFlowRate -
3906 51210346 : state.dataAirLoop->AirLoopFlow(SysNum).BypassMassFlow) > SmallMassFlow)
3907 1528772 : SysReSim = true;
3908 : }
3909 : } // end node loop
3910 : // Store the minimum MassFlowMaxAvail for this branch on the branch inlet node (AirloopHVAC supply inlet node)
3911 11186123 : state.dataLoopNodes->Node(PrimaryAirSystems(SysNum).Branch(BranchNum).NodeNumIn).MassFlowRateMaxAvail = BranchMassFlowMaxAvail;
3912 : } // end branch loop
3913 : // force resimulation for fan-cycling, nonsimple systems
3914 11063254 : if (!AirLoopControlInfo(SysNum).Simple && AirLoopControlInfo(SysNum).CyclingFan) {
3915 2820106 : SysReSim = true;
3916 : }
3917 :
3918 : // If mass flow conserved on each branch, check for mass balance across splitter
3919 11063254 : if (!SysReSim && PrimaryAirSystems(SysNum).Splitter.Exists) {
3920 54180 : MassFlowRateOutSum = 0.0;
3921 54180 : InletNodeNum = PrimaryAirSystems(SysNum).Splitter.NodeNumIn;
3922 : // Get sum of splitter outlet mass flows
3923 162540 : for (OutletNum = 1; OutletNum <= PrimaryAirSystems(SysNum).Splitter.TotalOutletNodes; ++OutletNum) {
3924 108360 : OutletNodeNum = PrimaryAirSystems(SysNum).Splitter.NodeNumOut(OutletNum);
3925 108360 : MassFlowRateOutSum += state.dataLoopNodes->Node(OutletNodeNum).MassFlowRate;
3926 : }
3927 : // Check whether sum of splitter outlet mass flows equals splitter inlet flow.
3928 54180 : if (std::abs(MassFlowRateOutSum - state.dataLoopNodes->Node(InletNodeNum).MassFlowRate) > SmallMassFlow) SysReSim = true;
3929 : }
3930 :
3931 : //// Resimulate if the zone air mass flow conservation convergence critreon is not met
3932 11063254 : if (state.dataHVACGlobal->ZoneMassBalanceHVACReSim) SysReSim = true;
3933 :
3934 : // If mass balance failed, resimulation is needed. Impose a mass balance for the new simulation.
3935 11063254 : if (SysReSim) {
3936 : // Set the MassFlowRateMaxAvail on each node to the minimum MassFlowRateMaxAvail for the branch.
3937 7527859 : for (BranchNum = 1; BranchNum <= PrimaryAirSystems(SysNum).NumBranches; ++BranchNum) { // loop over branches in system
3938 13098336 : for (NodeIndex = 2; NodeIndex <= PrimaryAirSystems(SysNum).Branch(BranchNum).TotalNodes; ++NodeIndex) { // loop over nodes on branch
3939 9329337 : NodeNum = PrimaryAirSystems(SysNum).Branch(BranchNum).NodeNum(NodeIndex);
3940 9329337 : state.dataLoopNodes->Node(NodeNum).MassFlowRateMaxAvail =
3941 9329337 : state.dataLoopNodes->Node(PrimaryAirSystems(SysNum).Branch(BranchNum).NodeNumIn).MassFlowRateMaxAvail;
3942 : }
3943 : }
3944 :
3945 : // Impose mass balance at splitter
3946 3758860 : if (PrimaryAirSystems(SysNum).Splitter.Exists) {
3947 5068 : InBranchNum = PrimaryAirSystems(SysNum).Splitter.BranchNumIn;
3948 5068 : MassFlowRateOutSum = 0.0;
3949 5068 : InletNodeNum = PrimaryAirSystems(SysNum).Splitter.NodeNumIn;
3950 15204 : for (OutletNum = 1; OutletNum <= PrimaryAirSystems(SysNum).Splitter.TotalOutletNodes; ++OutletNum) {
3951 10136 : OutletNodeNum = PrimaryAirSystems(SysNum).Splitter.NodeNumOut(OutletNum);
3952 10136 : MassFlowRateOutSum +=
3953 10136 : min(state.dataLoopNodes->Node(OutletNodeNum).MassFlowRateMaxAvail, state.dataLoopNodes->Node(OutletNodeNum).MassFlowRateSetPoint);
3954 : }
3955 : // set the splitter inlet Max Avail mass flow rate
3956 5068 : if (state.dataLoopNodes->Node(InletNodeNum).MassFlowRateMaxAvail > MassFlowRateOutSum + SmallMassFlow) {
3957 3 : state.dataLoopNodes->Node(InletNodeNum).MassFlowRateMaxAvail = MassFlowRateOutSum;
3958 : }
3959 : // Pass the splitter inlet Max Avail mass flow rate upstream to the mixed air node
3960 10142 : for (NodeIndex = PrimaryAirSystems(SysNum).Branch(InBranchNum).TotalNodes - 1; NodeIndex >= 1; --NodeIndex) {
3961 5074 : NodeNum = PrimaryAirSystems(SysNum).Branch(InBranchNum).NodeNum(NodeIndex);
3962 5074 : state.dataLoopNodes->Node(NodeNum).MassFlowRateMaxAvail = state.dataLoopNodes->Node(InletNodeNum).MassFlowRateMaxAvail;
3963 5074 : if (NodeNum == PrimaryAirSystems(SysNum).OASysOutletNodeNum) break;
3964 : }
3965 : }
3966 :
3967 : // Make sure air system inlet nodes have flow consistent with MassFlowRateMaxAvail
3968 7517720 : for (InBranchIndex = 1; InBranchIndex <= PrimaryAirSystems(SysNum).NumInletBranches; ++InBranchIndex) {
3969 3758860 : InBranchNum = PrimaryAirSystems(SysNum).InletBranchNum[InBranchIndex - 1];
3970 3758860 : InNodeNum = PrimaryAirSystems(SysNum).Branch(InBranchNum).NodeNumIn;
3971 3758860 : state.dataLoopNodes->Node(InNodeNum).MassFlowRate =
3972 3758860 : min(state.dataLoopNodes->Node(InNodeNum).MassFlowRate, state.dataLoopNodes->Node(InNodeNum).MassFlowRateMaxAvail);
3973 : }
3974 : }
3975 11063254 : }
3976 :
3977 329 : void SizeAirLoops(EnergyPlusData &state)
3978 : {
3979 :
3980 : // SUBROUTINE INFORMATION:
3981 : // AUTHOR Fred Buhl
3982 : // DATE WRITTEN February 2001
3983 : // MODIFIED na
3984 : // RE-ENGINEERED na
3985 :
3986 : // PURPOSE OF THIS SUBROUTINE:
3987 : // Will perform central air system sizing simulations. Right now just
3988 : // initializes system sizing arrays. Calculations based on System Sizing
3989 : // input and the Zone Sizing simulations are done in UpdateSysSizing.
3990 :
3991 : // METHODOLOGY EMPLOYED:
3992 : // Will run purchased hot and chilled water type simulations to determine
3993 : // central plant flow rates. Right now just uses one time flag to call
3994 : // SetUpSysSizingArrays.
3995 :
3996 329 : if (state.dataSimAirServingZones->SizeAirLoopsOneTimeFlag) {
3997 329 : SetUpSysSizingArrays(state);
3998 329 : state.dataSimAirServingZones->SizeAirLoopsOneTimeFlag = false;
3999 : }
4000 329 : }
4001 :
4002 1191 : void SizeAirLoopBranches(EnergyPlusData &state, int const AirLoopNum, int const BranchNum)
4003 : {
4004 :
4005 : // SUBROUTINE INFORMATION:
4006 : // AUTHOR Fred Buhl
4007 : // DATE WRITTEN September 2001
4008 : // MODIFIED na
4009 : // RE-ENGINEERED na
4010 :
4011 : // PURPOSE OF THIS SUBROUTINE:
4012 : // This subroutine is for sizing air loop branches for which flow rates have not been
4013 : // specified in the input.
4014 :
4015 : // METHODOLOGY EMPLOYED:
4016 : // Obtains flow rates from the zone or system sizing arrays.
4017 :
4018 : // Using/Aliasing
4019 : using namespace DataSizing;
4020 : using HVACHXAssistedCoolingCoil::GetHXCoilType;
4021 : using HVACHXAssistedCoolingCoil::GetHXDXCoilName;
4022 : using WaterCoils::SetCoilDesFlow;
4023 :
4024 2382 : std::string CompType; // Component type
4025 2382 : std::string CompName; // Component name
4026 2382 : std::string CoilName;
4027 2382 : std::string CoilType;
4028 2382 : std::string ScalableSM; // scalable sizing methods label for reporting
4029 : SimAirServingZones::CompType CompType_Num; // Numeric equivalent for CompType
4030 : int CompNum;
4031 : bool ErrorsFound;
4032 :
4033 1191 : auto &FinalSysSizing(state.dataSize->FinalSysSizing);
4034 1191 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
4035 :
4036 1191 : ErrorsFound = false;
4037 :
4038 1191 : if (BranchNum == 1) {
4039 :
4040 1172 : if (PrimaryAirSystems(AirLoopNum).DesignVolFlowRate == AutoSize) {
4041 908 : CheckSysSizing(state, "AirLoopHVAC", PrimaryAirSystems(AirLoopNum).Name);
4042 908 : PrimaryAirSystems(AirLoopNum).DesignVolFlowRate = FinalSysSizing(AirLoopNum).DesMainVolFlow;
4043 908 : switch (FinalSysSizing(AirLoopNum).ScaleCoolSAFMethod) {
4044 0 : case FlowPerFloorArea: {
4045 0 : ScalableSM = "User-Specified(scaled by flow / area) ";
4046 0 : } break;
4047 0 : case FractionOfAutosizedCoolingAirflow: {
4048 0 : ScalableSM = "User-Specified(scaled by fractional multiplier) ";
4049 0 : } break;
4050 1 : case FlowPerCoolingCapacity: {
4051 1 : ScalableSM = "User-Specified(scaled by flow / capacity) ";
4052 1 : } break;
4053 907 : default: {
4054 907 : ScalableSM = "Design ";
4055 907 : } break;
4056 : }
4057 5448 : BaseSizer::reportSizerOutput(state,
4058 : "AirLoopHVAC",
4059 908 : PrimaryAirSystems(AirLoopNum).Name,
4060 1816 : ScalableSM + "Supply Air Flow Rate [m3/s]",
4061 1816 : PrimaryAirSystems(AirLoopNum).DesignVolFlowRate);
4062 : // Initialize MaxOutAir for DOAS loops with no actual OASys, systems with an OA controller will overwrite this is
4063 : // CalcOAController
4064 908 : if (PrimaryAirSystems(AirLoopNum).isAllOA)
4065 4 : state.dataAirLoop->AirLoopFlow(AirLoopNum).MaxOutAir = PrimaryAirSystems(AirLoopNum).DesignVolFlowRate * state.dataEnvrn->StdRhoAir;
4066 : }
4067 :
4068 1172 : if (allocated(FinalSysSizing) && FinalSysSizing(AirLoopNum).SysAirMinFlowRatWasAutoSized) {
4069 0 : BaseSizer::reportSizerOutput(state,
4070 : "AirLoopHVAC",
4071 0 : PrimaryAirSystems(AirLoopNum).Name,
4072 : "Central Heating Maximum System Air Flow Ratio",
4073 0 : FinalSysSizing(AirLoopNum).SysAirMinFlowRat);
4074 : }
4075 :
4076 1172 : if (PrimaryAirSystems(AirLoopNum).DesignVolFlowRate < SmallAirVolFlow) {
4077 0 : ShowSevereError(state,
4078 0 : format("SizeAirLoopBranches: AirLoopHVAC {} has air flow less than {:.4R} m3/s.",
4079 0 : PrimaryAirSystems(AirLoopNum).Name,
4080 0 : SmallAirVolFlow));
4081 0 : ShowContinueError(state,
4082 0 : format("Primary air system volumetric flow rate = {:.4R} m3/s.", PrimaryAirSystems(AirLoopNum).DesignVolFlowRate));
4083 0 : ShowContinueError(state, "Check flow rate inputs for components in this air loop and,");
4084 0 : ShowContinueError(state, "if autosized, check Sizing:Zone and Sizing:System objects and related inputs.");
4085 0 : ShowFatalError(state, "Previous condition causes termination.");
4086 : }
4087 : }
4088 :
4089 : // Loop over components in branch; pass the design air flow rate to the coil components that don't have
4090 : // design air flow as an input
4091 4797 : for (CompNum = 1; CompNum <= PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents; ++CompNum) {
4092 3606 : CompType = PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).TypeOf;
4093 3606 : CompName = PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).Name;
4094 3606 : CompType_Num = PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).CompType_Num;
4095 3606 : if (CompType_Num == CompType::WaterCoil_DetailedCool || CompType_Num == CompType::WaterCoil_SimpleHeat ||
4096 : CompType_Num == CompType::WaterCoil_CoolingHXAsst) {
4097 501 : if (CompType_Num == CompType::WaterCoil_CoolingHXAsst) {
4098 5 : CoilName = GetHXDXCoilName(state, CompType, CompName, ErrorsFound);
4099 5 : CoilType = GetHXCoilType(state, CompType, CompName, ErrorsFound);
4100 : } else {
4101 496 : CoilName = CompName;
4102 496 : CoilType = CompType;
4103 : }
4104 501 : SetCoilDesFlow(state, CoilType, CoilName, PrimaryAirSystems(AirLoopNum).DesignVolFlowRate, ErrorsFound);
4105 : }
4106 : } // End of component loop
4107 1191 : if (ErrorsFound) {
4108 0 : ShowFatalError(state, "Preceding sizing errors cause program termination");
4109 : }
4110 1191 : }
4111 :
4112 329 : void SetUpSysSizingArrays(EnergyPlusData &state)
4113 : {
4114 :
4115 : // SUBROUTINE INFORMATION:
4116 : // AUTHOR Fred Buhl
4117 : // DATE WRITTEN February 2001
4118 :
4119 : // PURPOSE OF THIS SUBROUTINE:
4120 : // Allocate and fill the SysSizing data array.
4121 :
4122 : // METHODOLOGY EMPLOYED:
4123 : // Uses data from System Sizing input and the system to zone connection data
4124 : // calculated in InitAirLoops and stored in AirToZoneNodeInfo in DataLoopNode..
4125 :
4126 329 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
4127 329 : int numAirTerminalUnits = state.dataSize->NumAirTerminalUnits;
4128 329 : int numPrimaryAirSys = state.dataHVACGlobal->NumPrimaryAirSys;
4129 : // have moved a large number of std 62.1 variables to DataSizing.hh so they can be used outside of this routine
4130 :
4131 : // allocate arrays used to store values for standard 62.1 tabular report
4132 329 : if (!allocated(state.dataSize->VpzClgByZone)) {
4133 329 : state.dataSize->VdzClgByZone.dimension(numAirTerminalUnits, 0.0);
4134 329 : state.dataSize->VdzMinClgByZone.dimension(numAirTerminalUnits, 0.0);
4135 329 : state.dataSize->VdzHtgByZone.dimension(numAirTerminalUnits, 0.0);
4136 329 : state.dataSize->VdzMinHtgByZone.dimension(numAirTerminalUnits, 0.0);
4137 329 : state.dataSize->ZdzClgByZone.dimension(numAirTerminalUnits, 0.0);
4138 329 : state.dataSize->ZdzHtgByZone.dimension(numAirTerminalUnits, 0.0);
4139 329 : state.dataSize->VpzClgByZone.dimension(numAirTerminalUnits, 0.0);
4140 329 : state.dataSize->VpzMinClgByZone.dimension(numAirTerminalUnits, 0.0);
4141 329 : state.dataSize->VpzHtgByZone.dimension(numAirTerminalUnits, 0.0);
4142 329 : state.dataSize->VpzMinHtgByZone.dimension(numAirTerminalUnits, 0.0);
4143 329 : state.dataSize->VbzByZone.dimension(numAirTerminalUnits, 0.0);
4144 329 : state.dataSize->VpzClgSumBySys.dimension(numPrimaryAirSys, 0.0);
4145 329 : state.dataSize->VpzHtgSumBySys.dimension(numPrimaryAirSys, 0.0);
4146 329 : state.dataSize->PzSumBySys.dimension(numPrimaryAirSys, 0.0);
4147 329 : state.dataSize->PsBySys.dimension(numPrimaryAirSys, 0.0);
4148 329 : state.dataSize->DBySys.dimension(numPrimaryAirSys, 0.0);
4149 329 : state.dataSize->SumRpxPzBySys.dimension(numPrimaryAirSys, 0.0);
4150 329 : state.dataSize->SumRaxAzBySys.dimension(numPrimaryAirSys, 0.0);
4151 329 : state.dataSize->PeakPsOccurrenceDateTimeStringBySys.dimension(numPrimaryAirSys, "");
4152 329 : state.dataSize->PeakPsOccurrenceEnvironmentStringBySys.dimension(numPrimaryAirSys, "");
4153 329 : state.dataSize->VouBySys.dimension(numPrimaryAirSys, 0.0);
4154 329 : state.dataSize->VpsClgBySys.dimension(numPrimaryAirSys, 0.0);
4155 329 : state.dataSize->VpsHtgBySys.dimension(numPrimaryAirSys, 0.0);
4156 : }
4157 :
4158 1250 : for (int SysSizIndex = 1; SysSizIndex <= state.dataSize->NumSysSizInput; ++SysSizIndex) {
4159 921 : auto &sysSizInput = state.dataSize->SysSizInput(SysSizIndex);
4160 921 : int PrimAirIndex = UtilityRoutines::FindItemInList(sysSizInput.AirPriLoopName, state.dataAirSystemsData->PrimaryAirSystems);
4161 921 : if (PrimAirIndex == 0) {
4162 0 : ShowSevereError(state, format("Sizing:System: {} references unknown AirLoopHVAC", sysSizInput.AirPriLoopName));
4163 0 : ErrorsFound = true;
4164 : } else {
4165 921 : sysSizInput.AirLoopNum = PrimAirIndex;
4166 : }
4167 : }
4168 329 : if (ErrorsFound) {
4169 0 : ShowFatalError(state, "Errors found in Sizing:System input");
4170 : }
4171 :
4172 329 : state.dataSize->SysSizing.allocate(state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays, numPrimaryAirSys);
4173 329 : state.dataSize->FinalSysSizing.allocate(numPrimaryAirSys);
4174 329 : state.dataSize->CalcSysSizing.allocate(numPrimaryAirSys);
4175 329 : state.dataSize->SysSizPeakDDNum.allocate(numPrimaryAirSys);
4176 :
4177 1254 : for (int AirLoopNum = 1; AirLoopNum <= numPrimaryAirSys; ++AirLoopNum) {
4178 925 : auto &primaryAirSystems = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
4179 925 : int SysSizNum = UtilityRoutines::FindItemInList(primaryAirSystems.Name, state.dataSize->SysSizInput, &SystemSizingInputData::AirPriLoopName);
4180 925 : if (SysSizNum <= 0) {
4181 4 : SysSizNum = 1;
4182 12 : ShowWarningError(
4183 : state,
4184 12 : format(
4185 : "SetUpSysSizingArrays: Sizing for System (HVACAirLoop)=\" {}\" will use Sizing:System specifications listed for System=\" {}\".",
4186 : primaryAirSystems.Name,
4187 8 : state.dataSize->SysSizInput(1).AirPriLoopName));
4188 : }
4189 925 : auto &sysSizInput = state.dataSize->SysSizInput(SysSizNum);
4190 2871 : for (int DesDayEnvrnNum = 1; DesDayEnvrnNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DesDayEnvrnNum) {
4191 1946 : auto &sysSizing = state.dataSize->SysSizing(DesDayEnvrnNum, AirLoopNum);
4192 : // move data from system sizing input
4193 1946 : sysSizing.AirPriLoopName = primaryAirSystems.Name;
4194 1946 : sysSizing.loadSizingType = sysSizInput.loadSizingType;
4195 1946 : sysSizing.coolingPeakLoad = sysSizInput.coolingPeakLoad;
4196 1946 : sysSizing.CoolCapControl = sysSizInput.CoolCapControl;
4197 1946 : sysSizing.DesOutAirVolFlow = sysSizInput.DesOutAirVolFlow;
4198 1946 : sysSizing.SysAirMinFlowRat = sysSizInput.SysAirMinFlowRat;
4199 1946 : sysSizing.SysAirMinFlowRatWasAutoSized = sysSizInput.SysAirMinFlowRatWasAutoSized;
4200 1946 : sysSizing.PreheatTemp = sysSizInput.PreheatTemp;
4201 1946 : sysSizing.PreheatHumRat = sysSizInput.PreheatHumRat;
4202 1946 : sysSizing.PrecoolTemp = sysSizInput.PrecoolTemp;
4203 1946 : sysSizing.PrecoolHumRat = sysSizInput.PrecoolHumRat;
4204 1946 : sysSizing.CoolSupTemp = sysSizInput.CoolSupTemp;
4205 1946 : sysSizing.HeatSupTemp = sysSizInput.HeatSupTemp;
4206 1946 : sysSizing.CoolSupHumRat = sysSizInput.CoolSupHumRat;
4207 1946 : sysSizing.HeatSupHumRat = sysSizInput.HeatSupHumRat;
4208 1946 : sysSizing.SizingOption = sysSizInput.SizingOption;
4209 1946 : if (primaryAirSystems.isAllOA) {
4210 8 : sysSizing.CoolOAOption = AllOA;
4211 8 : sysSizing.HeatOAOption = AllOA;
4212 : } else {
4213 1938 : sysSizing.CoolOAOption = sysSizInput.CoolOAOption;
4214 1938 : sysSizing.HeatOAOption = sysSizInput.HeatOAOption;
4215 : }
4216 1946 : sysSizing.CoolAirDesMethod = sysSizInput.CoolAirDesMethod;
4217 1946 : sysSizing.HeatAirDesMethod = sysSizInput.HeatAirDesMethod;
4218 1946 : sysSizing.ScaleCoolSAFMethod = sysSizInput.ScaleCoolSAFMethod;
4219 1946 : sysSizing.ScaleHeatSAFMethod = sysSizInput.ScaleHeatSAFMethod;
4220 1946 : sysSizing.CoolingCapMethod = sysSizInput.CoolingCapMethod;
4221 1946 : sysSizing.HeatingCapMethod = sysSizInput.HeatingCapMethod;
4222 1946 : sysSizing.InpDesCoolAirFlow = sysSizInput.DesCoolAirFlow;
4223 1946 : sysSizing.InpDesHeatAirFlow = sysSizInput.DesHeatAirFlow;
4224 1946 : sysSizing.MaxZoneOAFraction = sysSizInput.MaxZoneOAFraction;
4225 1946 : sysSizing.OAAutoSized = sysSizInput.OAAutoSized;
4226 :
4227 1946 : sysSizing.HeatFlowSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4228 1946 : sysSizing.SumZoneHeatLoadSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4229 1946 : sysSizing.CoolFlowSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4230 1946 : sysSizing.SumZoneCoolLoadSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4231 1946 : sysSizing.CoolZoneAvgTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4232 1946 : sysSizing.HeatZoneAvgTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4233 1946 : sysSizing.SensCoolCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4234 1946 : sysSizing.TotCoolCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4235 1946 : sysSizing.HeatCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4236 1946 : sysSizing.PreheatCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4237 1946 : sysSizing.SysCoolRetTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4238 1946 : sysSizing.SysCoolRetHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4239 1946 : sysSizing.SysHeatRetTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4240 1946 : sysSizing.SysHeatRetHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4241 1946 : sysSizing.SysCoolOutTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4242 1946 : sysSizing.SysCoolOutHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4243 1946 : sysSizing.SysHeatOutTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4244 1946 : sysSizing.SysHeatOutHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4245 1946 : sysSizing.SysDOASHeatAddSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4246 1946 : sysSizing.SysDOASLatAddSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4247 : } // end the design day loop
4248 :
4249 925 : auto &finalSysSizing = state.dataSize->FinalSysSizing(AirLoopNum);
4250 925 : auto &calcSysSizing = state.dataSize->CalcSysSizing(AirLoopNum);
4251 925 : finalSysSizing.AirPriLoopName = primaryAirSystems.Name;
4252 925 : calcSysSizing.AirPriLoopName = primaryAirSystems.Name;
4253 :
4254 : // move data from system sizing input
4255 925 : finalSysSizing.loadSizingType = sysSizInput.loadSizingType;
4256 925 : finalSysSizing.coolingPeakLoad = sysSizInput.coolingPeakLoad;
4257 925 : finalSysSizing.CoolCapControl = sysSizInput.CoolCapControl;
4258 925 : finalSysSizing.DesOutAirVolFlow = sysSizInput.DesOutAirVolFlow;
4259 925 : finalSysSizing.SysAirMinFlowRat = sysSizInput.SysAirMinFlowRat;
4260 925 : finalSysSizing.SysAirMinFlowRatWasAutoSized = sysSizInput.SysAirMinFlowRatWasAutoSized;
4261 925 : finalSysSizing.PreheatTemp = sysSizInput.PreheatTemp;
4262 925 : finalSysSizing.PreheatHumRat = sysSizInput.PreheatHumRat;
4263 925 : finalSysSizing.PrecoolTemp = sysSizInput.PrecoolTemp;
4264 925 : finalSysSizing.PrecoolHumRat = sysSizInput.PrecoolHumRat;
4265 925 : finalSysSizing.CoolSupTemp = sysSizInput.CoolSupTemp;
4266 925 : finalSysSizing.HeatSupTemp = sysSizInput.HeatSupTemp;
4267 925 : finalSysSizing.CoolSupHumRat = sysSizInput.CoolSupHumRat;
4268 925 : finalSysSizing.HeatSupHumRat = sysSizInput.HeatSupHumRat;
4269 925 : finalSysSizing.SizingOption = sysSizInput.SizingOption;
4270 925 : finalSysSizing.CoolAirDesMethod = sysSizInput.CoolAirDesMethod;
4271 925 : finalSysSizing.HeatAirDesMethod = sysSizInput.HeatAirDesMethod;
4272 925 : finalSysSizing.ScaleCoolSAFMethod = sysSizInput.ScaleCoolSAFMethod;
4273 925 : finalSysSizing.ScaleHeatSAFMethod = sysSizInput.ScaleHeatSAFMethod;
4274 925 : finalSysSizing.CoolingCapMethod = sysSizInput.CoolingCapMethod;
4275 925 : finalSysSizing.HeatingCapMethod = sysSizInput.HeatingCapMethod;
4276 925 : finalSysSizing.ScaledCoolingCapacity = sysSizInput.ScaledCoolingCapacity;
4277 925 : finalSysSizing.ScaledHeatingCapacity = sysSizInput.ScaledHeatingCapacity;
4278 925 : finalSysSizing.InpDesCoolAirFlow = sysSizInput.DesCoolAirFlow;
4279 925 : finalSysSizing.InpDesHeatAirFlow = sysSizInput.DesHeatAirFlow;
4280 925 : finalSysSizing.SystemOAMethod = sysSizInput.SystemOAMethod;
4281 925 : finalSysSizing.MaxZoneOAFraction = sysSizInput.MaxZoneOAFraction;
4282 925 : finalSysSizing.OAAutoSized = sysSizInput.OAAutoSized;
4283 925 : finalSysSizing.FlowPerFloorAreaCooled = sysSizInput.FlowPerFloorAreaCooled;
4284 925 : finalSysSizing.FlowPerFloorAreaHeated = sysSizInput.FlowPerFloorAreaHeated;
4285 925 : finalSysSizing.FractionOfAutosizedCoolingAirflow = sysSizInput.FractionOfAutosizedCoolingAirflow;
4286 925 : finalSysSizing.FractionOfAutosizedHeatingAirflow = sysSizInput.FractionOfAutosizedHeatingAirflow;
4287 925 : finalSysSizing.FlowPerCoolingCapacity = sysSizInput.FlowPerCoolingCapacity;
4288 925 : finalSysSizing.FlowPerHeatingCapacity = sysSizInput.FlowPerHeatingCapacity;
4289 :
4290 925 : if (primaryAirSystems.isAllOA) {
4291 4 : finalSysSizing.CoolOAOption = AllOA;
4292 4 : finalSysSizing.HeatOAOption = AllOA;
4293 4 : calcSysSizing.CoolOAOption = AllOA;
4294 4 : calcSysSizing.HeatOAOption = AllOA;
4295 : } else {
4296 921 : finalSysSizing.CoolOAOption = sysSizInput.CoolOAOption;
4297 921 : finalSysSizing.HeatOAOption = sysSizInput.HeatOAOption;
4298 921 : calcSysSizing.CoolOAOption = sysSizInput.CoolOAOption;
4299 921 : calcSysSizing.HeatOAOption = sysSizInput.HeatOAOption;
4300 : }
4301 :
4302 925 : calcSysSizing.loadSizingType = sysSizInput.loadSizingType;
4303 925 : calcSysSizing.coolingPeakLoad = sysSizInput.coolingPeakLoad;
4304 925 : calcSysSizing.CoolCapControl = sysSizInput.CoolCapControl;
4305 925 : calcSysSizing.DesOutAirVolFlow = sysSizInput.DesOutAirVolFlow;
4306 925 : calcSysSizing.SysAirMinFlowRat = sysSizInput.SysAirMinFlowRat;
4307 925 : calcSysSizing.SysAirMinFlowRatWasAutoSized = sysSizInput.SysAirMinFlowRatWasAutoSized;
4308 925 : calcSysSizing.PreheatTemp = sysSizInput.PreheatTemp;
4309 925 : calcSysSizing.PreheatHumRat = sysSizInput.PreheatHumRat;
4310 925 : calcSysSizing.PrecoolTemp = sysSizInput.PrecoolTemp;
4311 925 : calcSysSizing.PrecoolHumRat = sysSizInput.PrecoolHumRat;
4312 925 : calcSysSizing.CoolSupTemp = sysSizInput.CoolSupTemp;
4313 925 : calcSysSizing.HeatSupTemp = sysSizInput.HeatSupTemp;
4314 925 : calcSysSizing.CoolSupHumRat = sysSizInput.CoolSupHumRat;
4315 925 : calcSysSizing.HeatSupHumRat = sysSizInput.HeatSupHumRat;
4316 925 : calcSysSizing.SizingOption = sysSizInput.SizingOption;
4317 925 : calcSysSizing.CoolAirDesMethod = sysSizInput.CoolAirDesMethod;
4318 925 : calcSysSizing.HeatAirDesMethod = sysSizInput.HeatAirDesMethod;
4319 925 : calcSysSizing.ScaleCoolSAFMethod = sysSizInput.ScaleCoolSAFMethod;
4320 925 : calcSysSizing.ScaleHeatSAFMethod = sysSizInput.ScaleHeatSAFMethod;
4321 925 : calcSysSizing.CoolingCapMethod = sysSizInput.CoolingCapMethod;
4322 925 : calcSysSizing.HeatingCapMethod = sysSizInput.HeatingCapMethod;
4323 925 : calcSysSizing.ScaledCoolingCapacity = sysSizInput.ScaledCoolingCapacity;
4324 925 : calcSysSizing.ScaledHeatingCapacity = sysSizInput.ScaledHeatingCapacity;
4325 925 : calcSysSizing.InpDesCoolAirFlow = sysSizInput.DesCoolAirFlow;
4326 925 : calcSysSizing.InpDesHeatAirFlow = sysSizInput.DesHeatAirFlow;
4327 925 : calcSysSizing.SystemOAMethod = sysSizInput.SystemOAMethod;
4328 925 : calcSysSizing.MaxZoneOAFraction = sysSizInput.MaxZoneOAFraction;
4329 925 : calcSysSizing.OAAutoSized = sysSizInput.OAAutoSized;
4330 925 : calcSysSizing.FlowPerFloorAreaCooled = sysSizInput.FlowPerFloorAreaCooled;
4331 925 : calcSysSizing.FlowPerFloorAreaHeated = sysSizInput.FlowPerFloorAreaHeated;
4332 925 : calcSysSizing.FractionOfAutosizedCoolingAirflow = sysSizInput.FractionOfAutosizedCoolingAirflow;
4333 925 : calcSysSizing.FractionOfAutosizedHeatingAirflow = sysSizInput.FractionOfAutosizedHeatingAirflow;
4334 925 : calcSysSizing.FlowPerCoolingCapacity = sysSizInput.FlowPerCoolingCapacity;
4335 925 : calcSysSizing.FlowPerHeatingCapacity = sysSizInput.FlowPerHeatingCapacity;
4336 :
4337 925 : finalSysSizing.HeatFlowSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4338 925 : finalSysSizing.SumZoneHeatLoadSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4339 925 : finalSysSizing.CoolFlowSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4340 925 : finalSysSizing.SumZoneCoolLoadSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4341 925 : finalSysSizing.CoolZoneAvgTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4342 925 : finalSysSizing.HeatZoneAvgTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4343 925 : finalSysSizing.SensCoolCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4344 925 : finalSysSizing.TotCoolCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4345 925 : finalSysSizing.HeatCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4346 925 : finalSysSizing.PreheatCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4347 925 : finalSysSizing.SysCoolRetTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4348 925 : finalSysSizing.SysCoolRetHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4349 925 : finalSysSizing.SysHeatRetTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4350 925 : finalSysSizing.SysHeatRetHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4351 925 : finalSysSizing.SysCoolOutTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4352 925 : finalSysSizing.SysCoolOutHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4353 925 : finalSysSizing.SysHeatOutTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4354 925 : finalSysSizing.SysHeatOutHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4355 925 : finalSysSizing.SysDOASHeatAddSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4356 925 : finalSysSizing.SysDOASLatAddSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4357 925 : finalSysSizing.FloorAreaOnAirLoopCooled = 0.0;
4358 925 : finalSysSizing.FloorAreaOnAirLoopHeated = 0.0;
4359 925 : calcSysSizing.HeatFlowSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4360 925 : calcSysSizing.SumZoneHeatLoadSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4361 925 : calcSysSizing.CoolFlowSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4362 925 : calcSysSizing.SumZoneCoolLoadSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4363 925 : calcSysSizing.CoolZoneAvgTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4364 925 : calcSysSizing.HeatZoneAvgTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4365 925 : calcSysSizing.SensCoolCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4366 925 : calcSysSizing.TotCoolCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4367 925 : calcSysSizing.HeatCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4368 925 : calcSysSizing.PreheatCapSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4369 925 : calcSysSizing.SysCoolRetTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4370 925 : calcSysSizing.SysCoolRetHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4371 925 : calcSysSizing.SysHeatRetTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4372 925 : calcSysSizing.SysHeatRetHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4373 925 : calcSysSizing.SysCoolOutTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4374 925 : calcSysSizing.SysCoolOutHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4375 925 : calcSysSizing.SysHeatOutTempSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4376 925 : calcSysSizing.SysHeatOutHumRatSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4377 925 : calcSysSizing.SysDOASHeatAddSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4378 925 : calcSysSizing.SysDOASLatAddSeq.dimension(state.dataSimAirServingZones->NumOfTimeStepInDay, 0.0);
4379 925 : calcSysSizing.FloorAreaOnAirLoopCooled = 0.0;
4380 925 : calcSysSizing.FloorAreaOnAirLoopHeated = 0.0;
4381 :
4382 925 : auto &sysSizePeakDDNum = state.dataSize->SysSizPeakDDNum(AirLoopNum);
4383 925 : sysSizePeakDDNum.TimeStepAtSensCoolPk.dimension(state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays, 0);
4384 925 : sysSizePeakDDNum.TimeStepAtTotCoolPk.dimension(state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays, 0);
4385 925 : sysSizePeakDDNum.TimeStepAtCoolFlowPk.dimension(state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays, 0);
4386 925 : sysSizePeakDDNum.TimeStepAtHeatPk.dimension(state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays, 0);
4387 :
4388 925 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
4389 :
4390 969 : SetupEMSInternalVariable(state,
4391 : "Intermediate Air System Main Supply Volume Flow Rate",
4392 : finalSysSizing.AirPriLoopName,
4393 : "[m3/s]",
4394 646 : finalSysSizing.DesMainVolFlow);
4395 969 : SetupEMSActuator(state,
4396 : "Sizing:System",
4397 : finalSysSizing.AirPriLoopName,
4398 : "Main Supply Volume Flow Rate",
4399 : "[m3/s]",
4400 : finalSysSizing.EMSOverrideDesMainVolFlowOn,
4401 646 : finalSysSizing.EMSValueDesMainVolFlow);
4402 :
4403 969 : SetupEMSInternalVariable(state,
4404 : "Intermediate Air System Coincident Peak Cooling Mass Flow Rate",
4405 : finalSysSizing.AirPriLoopName,
4406 : "[kg/s]",
4407 646 : finalSysSizing.CoinCoolMassFlow);
4408 969 : SetupEMSActuator(state,
4409 : "Sizing:System",
4410 : finalSysSizing.AirPriLoopName,
4411 : "Main Supply Coincident Peak Cooling Mass Flow Rate",
4412 : "[kg/s]",
4413 : finalSysSizing.EMSOverrideCoinCoolMassFlowOn,
4414 646 : finalSysSizing.EMSValueCoinCoolMassFlow);
4415 :
4416 969 : SetupEMSInternalVariable(state,
4417 : "Intermediate Air System Coincident Peak Heating Mass Flow Rate",
4418 : finalSysSizing.AirPriLoopName,
4419 : "[kg/s]",
4420 646 : finalSysSizing.CoinHeatMassFlow);
4421 969 : SetupEMSActuator(state,
4422 : "Sizing:System",
4423 : finalSysSizing.AirPriLoopName,
4424 : "Main Supply Coincident Peak Heating Mass Flow Rate",
4425 : "[kg/s]",
4426 : finalSysSizing.EMSOverrideCoinHeatMassFlowOn,
4427 646 : finalSysSizing.EMSValueCoinHeatMassFlow);
4428 :
4429 969 : SetupEMSInternalVariable(state,
4430 : "Intermediate Air System Noncoincident Peak Cooling Mass Flow Rate",
4431 : finalSysSizing.AirPriLoopName,
4432 : "[kg/s]",
4433 646 : finalSysSizing.NonCoinCoolMassFlow);
4434 969 : SetupEMSActuator(state,
4435 : "Sizing:System",
4436 : finalSysSizing.AirPriLoopName,
4437 : "Main Supply Noncoincident Peak Cooling Mass Flow Rate",
4438 : "[kg/s]",
4439 : finalSysSizing.EMSOverrideNonCoinCoolMassFlowOn,
4440 646 : finalSysSizing.EMSValueNonCoinCoolMassFlow);
4441 969 : SetupEMSInternalVariable(state,
4442 : "Intermediate Air System Noncoincident Peak Heating Mass Flow Rate",
4443 : finalSysSizing.AirPriLoopName,
4444 : "[kg/s]",
4445 646 : finalSysSizing.NonCoinHeatMassFlow);
4446 969 : SetupEMSActuator(state,
4447 : "Sizing:System",
4448 : finalSysSizing.AirPriLoopName,
4449 : "Main Supply Noncoincident Peak Heating Mass Flow Rate",
4450 : "[kg/s]",
4451 : finalSysSizing.EMSOverrideNonCoinHeatMassFlowOn,
4452 646 : finalSysSizing.EMSValueNonCoinHeatMassFlow);
4453 :
4454 969 : SetupEMSInternalVariable(
4455 646 : state, "Intermediate Air System Heating Volume Flow Rate", finalSysSizing.AirPriLoopName, "[m3/s]", finalSysSizing.DesHeatVolFlow);
4456 969 : SetupEMSActuator(state,
4457 : "Sizing:System",
4458 : finalSysSizing.AirPriLoopName,
4459 : "Main Heating Volume Flow Rate",
4460 : "[m3/s]",
4461 : finalSysSizing.EMSOverrideDesHeatVolFlowOn,
4462 646 : finalSysSizing.EMSValueDesHeatVolFlow);
4463 :
4464 969 : SetupEMSInternalVariable(
4465 646 : state, "Intermediate Air System Cooling Volume Flow Rate", finalSysSizing.AirPriLoopName, "[m3/s]", finalSysSizing.DesCoolVolFlow);
4466 969 : SetupEMSActuator(state,
4467 : "Sizing:System",
4468 : finalSysSizing.AirPriLoopName,
4469 : "Main Cooling Volume Flow Rate",
4470 : "[m3/s]",
4471 : finalSysSizing.EMSOverrideDesCoolVolFlowOn,
4472 646 : finalSysSizing.EMSValueDesCoolVolFlow);
4473 : // internal variables useful for sizing air system component models
4474 969 : SetupEMSInternalVariable(
4475 646 : state, "Air System Cooling Design Sensible Capacity", finalSysSizing.AirPriLoopName, "[W]", finalSysSizing.SensCoolCap);
4476 969 : SetupEMSInternalVariable(
4477 646 : state, "Air System Cooling Design Total Capacity", finalSysSizing.AirPriLoopName, "[W]", finalSysSizing.TotCoolCap);
4478 969 : SetupEMSInternalVariable(
4479 646 : state, "Air System Heating Design Sensible Capacity", finalSysSizing.AirPriLoopName, "[W]", finalSysSizing.HeatCap);
4480 969 : SetupEMSInternalVariable(
4481 646 : state, "Air System Preheating Design Sensible Capacity", finalSysSizing.AirPriLoopName, "[W]", finalSysSizing.PreheatCap);
4482 :
4483 969 : SetupEMSInternalVariable(
4484 646 : state, "Air System Outdoor Air Design Volume Flow Rate", finalSysSizing.AirPriLoopName, "[m3/s]", finalSysSizing.DesOutAirVolFlow);
4485 :
4486 969 : SetupEMSInternalVariable(
4487 646 : state, "Air System Cooling Design Mixed Air Temperature", finalSysSizing.AirPriLoopName, "[C]", finalSysSizing.MixTempAtCoolPeak);
4488 969 : SetupEMSInternalVariable(state,
4489 : "Air System Cooling Design Mixed Air Humidity Ratio",
4490 : finalSysSizing.AirPriLoopName,
4491 : "[kgWater/kgDryAir]",
4492 646 : finalSysSizing.MixHumRatAtCoolPeak);
4493 969 : SetupEMSInternalVariable(
4494 646 : state, "Air System Cooling Design Return Air Temperature", finalSysSizing.AirPriLoopName, "[C]", finalSysSizing.RetTempAtCoolPeak);
4495 969 : SetupEMSInternalVariable(state,
4496 : "Air System Cooling Design Return Air Humidity Ratio",
4497 : finalSysSizing.AirPriLoopName,
4498 : "[kgWater/kgDryAir]",
4499 646 : finalSysSizing.RetHumRatAtCoolPeak);
4500 969 : SetupEMSInternalVariable(
4501 646 : state, "Air System Cooling Design Outdoor Air Temperature", finalSysSizing.AirPriLoopName, "[C]", finalSysSizing.OutTempAtCoolPeak);
4502 969 : SetupEMSInternalVariable(state,
4503 : "Air System Cooling Design Outdoor Air Humidity Ratio",
4504 : finalSysSizing.AirPriLoopName,
4505 : "[kgWater/kgDryAir]",
4506 646 : finalSysSizing.OutHumRatAtCoolPeak);
4507 :
4508 969 : SetupEMSInternalVariable(
4509 646 : state, "Air System Heating Design Mixed Air Temperature", finalSysSizing.AirPriLoopName, "[C]", finalSysSizing.HeatMixTemp);
4510 969 : SetupEMSInternalVariable(state,
4511 : "Air System Heating Design Mixed Air Humidity Ratio",
4512 : finalSysSizing.AirPriLoopName,
4513 : "[kgWater/kgDryAir]",
4514 646 : finalSysSizing.HeatMixHumRat);
4515 969 : SetupEMSInternalVariable(
4516 646 : state, "Air System Heating Design Return Air Temperature", finalSysSizing.AirPriLoopName, "[C]", finalSysSizing.HeatRetTemp);
4517 969 : SetupEMSInternalVariable(state,
4518 : "Air System Heating Design Return Air Humidity Ratio",
4519 : finalSysSizing.AirPriLoopName,
4520 : "[kgWater/kgDryAir]",
4521 646 : finalSysSizing.HeatRetHumRat);
4522 969 : SetupEMSInternalVariable(
4523 646 : state, "Air System Heating Design Outdoor Air Temperature", finalSysSizing.AirPriLoopName, "[C]", finalSysSizing.HeatOutTemp);
4524 969 : SetupEMSInternalVariable(state,
4525 : "Air System Heating Design Outdoor Air Humidity Ratio",
4526 : finalSysSizing.AirPriLoopName,
4527 : "[kgWater/kgDryAir]",
4528 646 : finalSysSizing.HeatOutHumRat);
4529 : }
4530 :
4531 : } // end the primary air system loop
4532 329 : }
4533 :
4534 329 : void SizeSysOutdoorAir(EnergyPlusData &state)
4535 : {
4536 :
4537 : using namespace OutputReportPredefined;
4538 :
4539 : Real64 MinOAFlow; // design minimum outside air flow for a system
4540 : Real64 ZoneOAFracCooling; // zone OA fraction for cooling design air flow
4541 : Real64 ZoneOAFracHeating; // zone OA fraction for heating design air flow
4542 : Real64 ZoneSA; // Zone supply air flow rate
4543 : Real64 ZonePA; // Zone primary air flow rate
4544 : Real64 ClgSupplyAirAdjustFactor; // temporary variable
4545 : Real64 HtgSupplyAirAdjustFactor; // temporary variable
4546 : Real64 SysOAUnc; // uncorrected system OA summing up people and area based OA for all zones for VRP
4547 : Real64 ZoneOAUnc; // uncorrected zone OA summing up people and area based OA for each zone
4548 :
4549 : // begin system OA calcs, this is the first pass, std 62.1 calcs are redone after adjustments and zone units are set up
4550 : // call refactored routine for Pz, Ps and D
4551 329 : SizingManager::DetermineSystemPopulationDiversity(state);
4552 :
4553 : // If the system design minimum outside air flow rate is autosized, calculate it from the zone data
4554 : // Note that all TermUnitFinalZoneSizing values have already been scaled by air terminal sizing factors
4555 1254 : for (int AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
4556 925 : auto &finalSysSizing = state.dataSize->FinalSysSizing(AirLoopNum);
4557 925 : auto &airToZoneNodeInfo = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum);
4558 925 : MinOAFlow = 0.0;
4559 925 : SysOAUnc = 0.0;
4560 925 : ClgSupplyAirAdjustFactor = 1.0;
4561 925 : HtgSupplyAirAdjustFactor = 1.0;
4562 : int SysSizNum =
4563 925 : UtilityRoutines::FindItemInList(finalSysSizing.AirPriLoopName, state.dataSize->SysSizInput, &SystemSizingInputData::AirPriLoopName);
4564 925 : if (SysSizNum == 0) SysSizNum = 1; // use first when none applicable
4565 925 : if (finalSysSizing.OAAutoSized) {
4566 886 : int NumZonesCooled = airToZoneNodeInfo.NumZonesCooled;
4567 :
4568 : // people related code removed, see SizingManager::DetermineSystemPopulationDiversity
4569 :
4570 3481 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) {
4571 2595 : int TermUnitSizingIndex = airToZoneNodeInfo.TermUnitCoolSizingIndex(ZonesCooledNum);
4572 2595 : if (TermUnitSizingIndex == 0) {
4573 0 : ShowSevereError(state,
4574 0 : "SetUpSysSizingArray: TermUnitSizingIndex = 0 for AirLoop=" + airToZoneNodeInfo.AirLoopName +
4575 0 : ", Zone =" + state.dataHeatBal->Zone(airToZoneNodeInfo.CoolCtrlZoneNums(ZonesCooledNum)).Name);
4576 0 : ShowFatalError(state, "This is a defect. Please report this issue.");
4577 : }
4578 2595 : auto &termUnitSizing = state.dataSize->TermUnitSizing(TermUnitSizingIndex);
4579 2595 : auto &termUnitFinalZoneSizing = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex);
4580 2595 : if (SysSizNum > 0) {
4581 2595 : ZoneOAUnc =
4582 2595 : termUnitFinalZoneSizing.TotalOAFromPeople +
4583 2595 : termUnitFinalZoneSizing.TotalOAFromArea; // should not have diversity at this point (no should have diversity in Vou if VRP)
4584 2595 : if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::ZoneSum) { // ZoneSum Method
4585 2555 : SysOAUnc += ZoneOAUnc;
4586 45 : } else if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::VRP ||
4587 5 : state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::SP) { // Ventilation Rate Procedure
4588 80 : SysOAUnc += termUnitFinalZoneSizing.TotalOAFromPeople * state.dataSize->DBySys(AirLoopNum) +
4589 40 : termUnitFinalZoneSizing.TotalOAFromArea; // apply D to people term
4590 : }
4591 2595 : state.dataSize->SumRpxPzBySys(AirLoopNum) += termUnitFinalZoneSizing.TotalOAFromPeople;
4592 2595 : state.dataSize->SumRaxAzBySys(AirLoopNum) += termUnitFinalZoneSizing.TotalOAFromArea;
4593 :
4594 : // save for Standard 62 tabular report
4595 2595 : state.dataSize->VbzByZone(TermUnitSizingIndex) = ZoneOAUnc; // fixed now, previously RHS already had Ez factored in.
4596 : // Save Std 62.1 cooling ventilation required by zone
4597 2595 : if (termUnitFinalZoneSizing.ZoneADEffCooling > 0.0) {
4598 2595 : termUnitFinalZoneSizing.VozClgByZone = ZoneOAUnc / termUnitFinalZoneSizing.ZoneADEffCooling;
4599 : } else {
4600 0 : termUnitFinalZoneSizing.VozClgByZone = ZoneOAUnc;
4601 : }
4602 :
4603 2595 : if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::ZoneSum) { // ZoneSum Method
4604 2555 : MinOAFlow += termUnitFinalZoneSizing.MinOA;
4605 2555 : if (termUnitFinalZoneSizing.DesCoolVolFlow > 0.0) {
4606 5110 : ZoneOAFracCooling = termUnitFinalZoneSizing.VozClgByZone /
4607 2555 : termUnitFinalZoneSizing.DesCoolVolFlow; // calculate anyway for use with zone OA max fraction below
4608 : } else {
4609 0 : ZoneOAFracCooling = 0.0;
4610 : }
4611 45 : } else if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::VRP ||
4612 5 : state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::SP) { // Ventilation Rate Procedure
4613 : // CR 8872 - check to see if uncorrected OA is calculated to be greater than 0
4614 40 : if (!(ZoneOAUnc > 0.0)) {
4615 0 : ShowSevereError(state, "Sizing:System - The system outdoor air method is set to VRP in " + finalSysSizing.AirPriLoopName);
4616 0 : ShowContinueError(
4617 0 : state, "But zone \"" + termUnitFinalZoneSizing.ZoneName + "\" associated with system does not have OA flow/person");
4618 0 : ShowContinueError(state,
4619 : "or flow/area values specified in DesignSpecification:OutdoorAir object associated with the zone");
4620 : }
4621 :
4622 : // Save Std 62.1 cooling ventilation required by zone
4623 40 : MinOAFlow += termUnitFinalZoneSizing.VozClgByZone; // Don't include D
4624 :
4625 40 : if (termUnitFinalZoneSizing.DesCoolVolFlow > 0.0) {
4626 40 : if (termUnitFinalZoneSizing.ZoneSecondaryRecirculation > 0.0 || termUnitFinalZoneSizing.DesCoolVolFlowMin <= 0) {
4627 : // multi-path system or VAV Minimum not defined
4628 1 : ZoneOAFracCooling =
4629 1 : termUnitFinalZoneSizing.VozClgByZone /
4630 1 : termUnitFinalZoneSizing.DesCoolVolFlow; // this should be based on final atu flows, not sizing design
4631 :
4632 : } else {
4633 : // Single path; Use VAV Minimum as the Vpz in the Zp = Voz / Vpz equations
4634 39 : ZoneOAFracCooling =
4635 39 : termUnitFinalZoneSizing.VozClgByZone /
4636 39 : termUnitFinalZoneSizing.DesCoolVolFlowMin; // this should be based on final atu flows, not sizing design
4637 : }
4638 : } else {
4639 0 : ZoneOAFracCooling = 0.0;
4640 : }
4641 : } else { // error
4642 : }
4643 : } else { // ZoneSum Method
4644 0 : MinOAFlow += termUnitFinalZoneSizing.MinOA;
4645 0 : ZoneOAFracCooling = 0.0;
4646 : }
4647 :
4648 : // Calc maximum zone OA fraction and supply air adjustment factor based on
4649 : // user entered max allowed OA fraction
4650 2595 : if (finalSysSizing.MaxZoneOAFraction > 0 && ZoneOAFracCooling > finalSysSizing.MaxZoneOAFraction) {
4651 18 : if (finalSysSizing.CoolAirDesMethod == FromDDCalc) { // DesignDay Method
4652 9 : ClgSupplyAirAdjustFactor = ZoneOAFracCooling / finalSysSizing.MaxZoneOAFraction;
4653 9 : if (termUnitFinalZoneSizing.ZoneSecondaryRecirculation > 0.0 || termUnitFinalZoneSizing.DesCoolVolFlowMin <= 0) {
4654 : // multi-path system or VAV Minimum not defined
4655 0 : termUnitFinalZoneSizing.DesCoolVolFlow *= ClgSupplyAirAdjustFactor;
4656 : } else {
4657 : // Single path; Use VAV Minimum as the Vpz in the Zp = Voz / Vpz equations
4658 9 : termUnitFinalZoneSizing.DesCoolVolFlowMin *=
4659 : ClgSupplyAirAdjustFactor; // from code inspection value set here is used above, before being set.
4660 :
4661 : // Don't allow the design cooling airflow to be less than the VAV minimum airflow
4662 9 : termUnitFinalZoneSizing.DesCoolVolFlow =
4663 9 : max(termUnitFinalZoneSizing.DesCoolVolFlow, termUnitFinalZoneSizing.DesCoolVolFlowMin);
4664 : }
4665 : // Don't allow the design terminal airflow to be less than the design cooling airflow
4666 9 : termUnitSizing.AirVolFlow = max(termUnitSizing.AirVolFlow, termUnitFinalZoneSizing.DesCoolVolFlow);
4667 9 : ZoneOAFracCooling = finalSysSizing.MaxZoneOAFraction;
4668 : } else {
4669 0 : ClgSupplyAirAdjustFactor = 1.0;
4670 : }
4671 : } else {
4672 2586 : ClgSupplyAirAdjustFactor = 1.0;
4673 : }
4674 :
4675 2595 : ZoneSA = 0.0;
4676 2595 : ZonePA = 0.0;
4677 2595 : state.dataSimAirServingZones->EpSSOA = 1.0;
4678 2595 : if (termUnitFinalZoneSizing.ZoneSecondaryRecirculation > 0.0) { // multi-path system
4679 : // Vpz: "Primary" supply air from main air handler served by an oa mixer
4680 1 : ZonePA = termUnitFinalZoneSizing.DesCoolVolFlow;
4681 : // Vdz: "Discharge" supply air delivered to zone by terminal unit
4682 1 : ZoneSA = max(termUnitSizing.AirVolFlow, ZonePA);
4683 :
4684 : // For re-circulation systems, Vpz used to determine Zpz is the design terminal airflow
4685 : // Std 62.1-2010, section 6.2.5.1: "Vpz (used to determin Zpz) is the primary airflow rate
4686 : // rate to the ventilation zone from the air handler, including outdoor air and recirculated air.
4687 : // MJW - Not sure this is correct, seems like it should be ZonePA - above comments contradict each other
4688 1 : state.dataSize->VpzMinClgByZone(TermUnitSizingIndex) = ZoneSA;
4689 :
4690 : } else { // single path system
4691 : // Vdz: "Discharge" supply air delivered to zone by terminal unit
4692 2594 : ZonePA = termUnitFinalZoneSizing.DesCoolVolFlow;
4693 : // Vpz: "Primary" supply air from main air handler served by an oa mixer
4694 2594 : ZoneSA = termUnitFinalZoneSizing.DesCoolVolFlow;
4695 :
4696 : // Save VpzMin in case this is a single path VAV system.
4697 : // Std 62.1-2010, section 6.2.5.1: "For VAV-system design purposes, Vpz is the lowest zone primary
4698 : // airflow value expected at the design condition analyzed."
4699 2594 : state.dataSize->VpzMinClgByZone(TermUnitSizingIndex) =
4700 2594 : termUnitFinalZoneSizing.DesCoolVolFlowMin; // this may be getting used before it gets filled ??
4701 :
4702 : // In case for some reason the VAV minimum has not been defined, use the design primary airflow
4703 2594 : if (termUnitFinalZoneSizing.DesCoolVolFlowMin <= 0) state.dataSize->VpzMinClgByZone(TermUnitSizingIndex) = ZonePA;
4704 : }
4705 :
4706 : // save zone discharge supply airflow
4707 2595 : state.dataSize->VdzClgByZone(TermUnitSizingIndex) = ZoneSA;
4708 :
4709 : // save Vpz zone primary airflow for standard 62.1 report
4710 2595 : state.dataSize->VpzClgByZone(TermUnitSizingIndex) = ZonePA;
4711 2595 : state.dataSize->VpzClgSumBySys(AirLoopNum) += ZonePA;
4712 :
4713 : // Fraction of required zone ventilation to minimum primary airflow expected at condition analyzed
4714 2595 : termUnitFinalZoneSizing.ZpzClgByZone = 0.0;
4715 2595 : if (state.dataSize->VpzMinClgByZone(TermUnitSizingIndex) > 0) {
4716 2595 : termUnitFinalZoneSizing.ZpzClgByZone =
4717 2595 : min(1.0, termUnitFinalZoneSizing.VozClgByZone / state.dataSize->VpzMinClgByZone(TermUnitSizingIndex));
4718 : }
4719 :
4720 : // calc zone primary air fraction
4721 2595 : if (ZoneSA > 0.0) state.dataSimAirServingZones->EpSSOA = ZonePA / ZoneSA;
4722 2595 : if (state.dataSimAirServingZones->EpSSOA > 1.0) state.dataSimAirServingZones->EpSSOA = 1.0;
4723 2595 : termUnitFinalZoneSizing.ZonePrimaryAirFraction = state.dataSimAirServingZones->EpSSOA;
4724 2595 : termUnitFinalZoneSizing.ZoneOAFracCooling = ZoneOAFracCooling;
4725 :
4726 : // determined cooled zone floor area in an airloop
4727 2595 : finalSysSizing.FloorAreaOnAirLoopCooled += termUnitFinalZoneSizing.TotalZoneFloorArea;
4728 :
4729 2595 : termUnitFinalZoneSizing.SupplyAirAdjustFactor = max(ClgSupplyAirAdjustFactor, HtgSupplyAirAdjustFactor);
4730 : }
4731 :
4732 886 : int NumZonesHeated = airToZoneNodeInfo.NumZonesHeated;
4733 886 : if (NumZonesHeated > 0) {
4734 17 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesHeated; ++ZonesHeatedNum) {
4735 14 : int TermUnitSizingIndex = airToZoneNodeInfo.TermUnitHeatSizingIndex(ZonesHeatedNum);
4736 14 : if (TermUnitSizingIndex == 0) {
4737 0 : ShowSevereError(state,
4738 0 : "SetUpSysSizingArray: TermUnitSizingIndex = 0 for AirLoop=" + airToZoneNodeInfo.AirLoopName +
4739 0 : ", Zone =" + state.dataHeatBal->Zone(airToZoneNodeInfo.HeatCtrlZoneNums(ZonesHeatedNum)).Name);
4740 0 : ShowFatalError(state, "This is a defect. Please report this issue.");
4741 : }
4742 14 : auto &termUnitSizing = state.dataSize->TermUnitSizing(TermUnitSizingIndex);
4743 14 : auto &termUnitFinalZoneSizing = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex);
4744 : int MatchingCooledZoneNum =
4745 14 : General::FindNumberInList(TermUnitSizingIndex, airToZoneNodeInfo.TermUnitCoolSizingIndex, NumZonesCooled);
4746 14 : if (MatchingCooledZoneNum == 0) {
4747 0 : if (SysSizNum > 0) {
4748 0 : ZoneOAUnc = termUnitFinalZoneSizing.TotalOAFromPeople +
4749 0 : termUnitFinalZoneSizing.TotalOAFromArea; // should not have diversity at this point
4750 0 : if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::ZoneSum) { // ZoneSum Method
4751 0 : SysOAUnc += ZoneOAUnc;
4752 0 : } else if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::VRP ||
4753 0 : state.dataSize->SysSizInput(SysSizNum).SystemOAMethod ==
4754 : SysOAMethod::SP) { // Ventilation Rate and Simplified Procedure
4755 0 : SysOAUnc += termUnitFinalZoneSizing.TotalOAFromPeople * state.dataSize->DBySys(AirLoopNum) +
4756 0 : termUnitFinalZoneSizing.TotalOAFromArea; // apply D to people term
4757 : }
4758 0 : state.dataSize->SumRpxPzBySys(AirLoopNum) += termUnitFinalZoneSizing.TotalOAFromPeople;
4759 0 : state.dataSize->SumRaxAzBySys(AirLoopNum) += termUnitFinalZoneSizing.TotalOAFromArea;
4760 : // save for Standard 62 tabular report
4761 0 : state.dataSize->VbzByZone(TermUnitSizingIndex) = ZoneOAUnc; // fixed now, previously RHS already had Ez factored in.
4762 : // Save Std 62.1 heating ventilation required by zone
4763 0 : if (termUnitFinalZoneSizing.ZoneADEffHeating > 0.0) {
4764 0 : termUnitFinalZoneSizing.VozHtgByZone = ZoneOAUnc / termUnitFinalZoneSizing.ZoneADEffHeating;
4765 : } else {
4766 0 : termUnitFinalZoneSizing.VozHtgByZone = ZoneOAUnc;
4767 : }
4768 :
4769 0 : if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::ZoneSum) { // ZoneSum Method
4770 0 : MinOAFlow += termUnitFinalZoneSizing.MinOA;
4771 0 : if (termUnitFinalZoneSizing.DesHeatVolFlow > 0.0) {
4772 0 : ZoneOAFracHeating =
4773 0 : termUnitFinalZoneSizing.VozHtgByZone /
4774 0 : termUnitFinalZoneSizing.DesHeatVolFlow; // calculate anyway for use with zone OA max fraction below
4775 : } else {
4776 0 : ZoneOAFracHeating = 0.0;
4777 : }
4778 :
4779 0 : } else if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::VRP ||
4780 0 : state.dataSize->SysSizInput(SysSizNum).SystemOAMethod ==
4781 : SysOAMethod::SP) { // Ventilation Rate and Simplified Procedure
4782 : // CR 8872 - check to see if uncorrected OA is calculated to be greater than 0
4783 0 : if (!(ZoneOAUnc > 0.0)) {
4784 0 : ShowSevereError(
4785 0 : state, "Sizing:System - The system outdoor air method is set to VRP in " + finalSysSizing.AirPriLoopName);
4786 0 : ShowContinueError(state,
4787 0 : "But zone \"" + termUnitFinalZoneSizing.ZoneName +
4788 : "\" associated with system does not have OA flow/person");
4789 0 : ShowContinueError(state,
4790 : "or flow/area values specified in DesignSpecification:OutdoorAir object associated "
4791 : "with the zone");
4792 : }
4793 :
4794 : // Save Std 62.1 heating ventilation required by zone
4795 0 : MinOAFlow += termUnitFinalZoneSizing.VozHtgByZone; // Don't include D
4796 :
4797 0 : if (termUnitFinalZoneSizing.DesHeatVolFlow > 0.0) {
4798 0 : if (termUnitFinalZoneSizing.ZoneSecondaryRecirculation > 0.0) { // multi-path system
4799 : // multi-path system
4800 0 : ZoneOAFracHeating = termUnitFinalZoneSizing.VozHtgByZone / termUnitSizing.AirVolFlow;
4801 : } else {
4802 : // Single path system
4803 0 : ZoneOAFracHeating = termUnitFinalZoneSizing.VozHtgByZone / termUnitFinalZoneSizing.DesHeatVolFlow;
4804 : }
4805 : } else {
4806 0 : ZoneOAFracHeating = 0.0;
4807 : }
4808 : } else { // would be error
4809 : }
4810 : } else { // ZoneSum Method
4811 0 : MinOAFlow += termUnitFinalZoneSizing.MinOA;
4812 0 : ZoneOAFracHeating = 0.0;
4813 : }
4814 : } else { // matching cooled zone > 0
4815 : //?? so what happens if zone is both heated and cooled this makes little sense? Don't want to double count in
4816 : // MinOAFlow
4817 : // but still need to do std62.1 heating calcs ??
4818 14 : ZoneOAFracHeating = 0.0;
4819 : }
4820 :
4821 : // Calc maximum zone OA fraction and supply air adjustment factor based
4822 : // on user entered max allowed OA fraction
4823 14 : if (finalSysSizing.MaxZoneOAFraction > 0 && ZoneOAFracHeating > finalSysSizing.MaxZoneOAFraction) {
4824 0 : if (finalSysSizing.CoolAirDesMethod == FromDDCalc) { // DesignDay Method
4825 0 : HtgSupplyAirAdjustFactor = ZoneOAFracHeating / finalSysSizing.MaxZoneOAFraction;
4826 0 : if (termUnitFinalZoneSizing.ZoneSecondaryRecirculation > 0.0 || termUnitFinalZoneSizing.DesCoolVolFlowMin <= 0) {
4827 : // multi-path system or VAV Heating airflow max not defined
4828 0 : termUnitSizing.AirVolFlow *= HtgSupplyAirAdjustFactor;
4829 : } else {
4830 : // Single path; Use VAV Heating airflow max as the Vpz in the Zp = Voz / Vpz equations
4831 0 : termUnitFinalZoneSizing.DesHeatVolFlow *= HtgSupplyAirAdjustFactor;
4832 : // Don't allow the design terminal airflow to be less than the design heating airflow
4833 0 : termUnitSizing.AirVolFlow = max(termUnitSizing.AirVolFlow, termUnitFinalZoneSizing.DesHeatVolFlow);
4834 : }
4835 0 : ZoneOAFracHeating = finalSysSizing.MaxZoneOAFraction;
4836 : } else {
4837 0 : HtgSupplyAirAdjustFactor = 1.0;
4838 : }
4839 : } else {
4840 14 : HtgSupplyAirAdjustFactor = 1.0;
4841 : }
4842 :
4843 14 : ZoneSA = 0.0;
4844 14 : ZonePA = 0.0;
4845 14 : state.dataSimAirServingZones->EpSSOA = 1.0;
4846 14 : if (termUnitFinalZoneSizing.ZoneSecondaryRecirculation > 0.0) { // multi-path system
4847 : // Vpz: "Primary" supply air from main air handler served by an oa mixer
4848 0 : ZonePA = termUnitFinalZoneSizing.DesHeatVolFlow;
4849 : // Vdz: "Discharge" supply air delivered to zone by terminal unit
4850 0 : ZoneSA = max(termUnitSizing.AirVolFlow, ZonePA);
4851 :
4852 : // For re-circulation systems, Vpz used to determine Zpz is the design terminal airflow
4853 : // Std 62.1-2010, section 6.2.5.1: "Vpz (used to determin Zpz) is the primary airflow rate
4854 : // rate to the ventilation zone from the air handler, including outdoor air and recirculated air.
4855 0 : state.dataSize->VpzMinHtgByZone(TermUnitSizingIndex) = ZoneSA;
4856 :
4857 : } else { // single path system
4858 :
4859 14 : ZonePA = termUnitFinalZoneSizing.DesHeatVolFlow;
4860 14 : ZoneSA = termUnitFinalZoneSizing.DesHeatVolFlow;
4861 :
4862 : // We do not use the cooling VAV min for heating because the VAV-box heating maximum may be larger.
4863 14 : state.dataSize->VpzMinHtgByZone(TermUnitSizingIndex) = ZoneSA;
4864 : }
4865 :
4866 : // save Vdz zone discharge supply airflow for standard 62.1 report
4867 14 : state.dataSize->VdzHtgByZone(TermUnitSizingIndex) = ZoneSA;
4868 :
4869 : // save Vpz zone primary airflow for standard 62.1 report
4870 14 : state.dataSize->VpzHtgByZone(TermUnitSizingIndex) = ZonePA;
4871 14 : state.dataSize->VpzHtgSumBySys(AirLoopNum) += ZonePA;
4872 :
4873 : // Fraction of required zone ventilation to minimum primary airflow expected at condition analyzed
4874 14 : termUnitFinalZoneSizing.ZpzHtgByZone = 0.0;
4875 14 : if (state.dataSize->VpzMinHtgByZone(TermUnitSizingIndex) > 0) {
4876 14 : termUnitFinalZoneSizing.ZpzHtgByZone =
4877 14 : min(1.0, termUnitFinalZoneSizing.VozHtgByZone / state.dataSize->VpzMinHtgByZone(TermUnitSizingIndex));
4878 : }
4879 :
4880 : // calc zone primary air fraction
4881 14 : if (ZoneSA > 0.0) state.dataSimAirServingZones->EpSSOA = ZonePA / ZoneSA;
4882 14 : if (state.dataSimAirServingZones->EpSSOA > 1.0) state.dataSimAirServingZones->EpSSOA = 1.0;
4883 14 : termUnitFinalZoneSizing.ZonePrimaryAirFractionHtg = state.dataSimAirServingZones->EpSSOA;
4884 14 : termUnitFinalZoneSizing.ZoneOAFracHeating = ZoneOAFracHeating;
4885 :
4886 : // determined heated zone floor area in an airloop
4887 14 : finalSysSizing.FloorAreaOnAirLoopHeated += termUnitFinalZoneSizing.TotalZoneFloorArea;
4888 :
4889 14 : termUnitFinalZoneSizing.SupplyAirAdjustFactor = max(ClgSupplyAirAdjustFactor, HtgSupplyAirAdjustFactor);
4890 :
4891 : } // end for loop of heated zones
4892 :
4893 : } else { // getting heating flow based values for Std 62.1 report for single path systems
4894 883 : ZoneOAFracHeating = 0.0;
4895 3464 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesCooled; ++ZonesHeatedNum) {
4896 2581 : int TermUnitSizingIndex = airToZoneNodeInfo.TermUnitCoolSizingIndex(ZonesHeatedNum);
4897 2581 : if (TermUnitSizingIndex == 0) {
4898 0 : ShowSevereError(state,
4899 0 : "SetUpSysSizingArray: TermUnitSizingIndex = 0 for AirLoop=" + airToZoneNodeInfo.AirLoopName +
4900 0 : ", Zone =" + state.dataHeatBal->Zone(airToZoneNodeInfo.CoolCtrlZoneNums(ZonesHeatedNum)).Name);
4901 0 : ShowFatalError(state, "This is a defect. Please report this issue.");
4902 : }
4903 2581 : auto &termUnitSizing = state.dataSize->TermUnitSizing(TermUnitSizingIndex);
4904 2581 : auto &termUnitFinalZoneSizing = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex);
4905 : // Save Std 62.1 heating ventilation required by zone
4906 2581 : if (termUnitFinalZoneSizing.ZoneADEffHeating > 0.0) {
4907 2581 : termUnitFinalZoneSizing.VozHtgByZone =
4908 2581 : state.dataSize->VbzByZone(TermUnitSizingIndex) / termUnitFinalZoneSizing.ZoneADEffHeating;
4909 : } else {
4910 0 : termUnitFinalZoneSizing.VozHtgByZone = state.dataSize->VbzByZone(TermUnitSizingIndex);
4911 : }
4912 :
4913 2581 : if (termUnitFinalZoneSizing.DesHeatVolFlow > 0.0) {
4914 2575 : if (termUnitFinalZoneSizing.ZoneSecondaryRecirculation > 0.0) { // multi-path system
4915 : // multi-path system
4916 1 : if (termUnitSizing.AirVolFlow != 0) {
4917 0 : ZoneOAFracHeating = termUnitFinalZoneSizing.VozHtgByZone / termUnitSizing.AirVolFlow;
4918 : }
4919 : } else {
4920 : // Single path system
4921 2574 : ZoneOAFracHeating = termUnitFinalZoneSizing.VozHtgByZone / termUnitFinalZoneSizing.DesHeatVolFlow;
4922 : }
4923 : } else {
4924 6 : ZoneOAFracHeating = 0.0;
4925 : }
4926 :
4927 : // Calc maximum zone OA fraction and supply air adjustment factor based
4928 : // on user entered max allowed OA fraction - a TRACE feature
4929 2581 : if (finalSysSizing.MaxZoneOAFraction > 0 && ZoneOAFracHeating > finalSysSizing.MaxZoneOAFraction) {
4930 6 : if (finalSysSizing.HeatAirDesMethod == FromDDCalc) { // DesignDay Method
4931 6 : HtgSupplyAirAdjustFactor = ZoneOAFracHeating / finalSysSizing.MaxZoneOAFraction;
4932 6 : if (termUnitFinalZoneSizing.ZoneSecondaryRecirculation > 0.0 || termUnitFinalZoneSizing.DesCoolVolFlowMin <= 0) {
4933 : // multi-path system or VAV Heating airflow max not defined
4934 0 : termUnitSizing.AirVolFlow *= HtgSupplyAirAdjustFactor;
4935 : } else {
4936 : // Single path; Use VAV Heating airflow max as the Vpz in the Zp = Voz / Vpz equations
4937 6 : termUnitFinalZoneSizing.DesHeatVolFlow *= HtgSupplyAirAdjustFactor;
4938 : // Don't allow the design terminal airflow to be less than the design heating airflow
4939 6 : termUnitSizing.AirVolFlow = max(termUnitSizing.AirVolFlow, termUnitFinalZoneSizing.DesHeatVolFlow);
4940 : }
4941 6 : ZoneOAFracHeating = finalSysSizing.MaxZoneOAFraction;
4942 : }
4943 : }
4944 2581 : ZonePA = termUnitFinalZoneSizing.DesHeatVolFlow;
4945 2581 : ZoneSA = termUnitFinalZoneSizing.DesHeatVolFlow;
4946 : // save Vdz zone discharge airflow for standard 62.1 report
4947 2581 : state.dataSize->VdzHtgByZone(TermUnitSizingIndex) = ZoneSA;
4948 : // save Vpz zone primary airflow for standard 62.1 report
4949 2581 : state.dataSize->VpzHtgByZone(TermUnitSizingIndex) = ZonePA;
4950 2581 : state.dataSize->VpzHtgSumBySys(AirLoopNum) += ZonePA;
4951 :
4952 : // We do not use the cooling VAV min for heating because the VAV-box heating maximum may be larger.
4953 2581 : state.dataSize->VpzMinHtgByZone(TermUnitSizingIndex) = ZoneSA;
4954 :
4955 : // Fraction of required zone ventilation to minimum primary airflow expected at condition analyzed
4956 2581 : termUnitFinalZoneSizing.ZpzHtgByZone = 0.0;
4957 2581 : if (state.dataSize->VpzMinHtgByZone(TermUnitSizingIndex) > 0) {
4958 2575 : termUnitFinalZoneSizing.ZpzHtgByZone =
4959 2575 : termUnitFinalZoneSizing.VozHtgByZone / state.dataSize->VpzMinHtgByZone(TermUnitSizingIndex);
4960 : }
4961 :
4962 : // calc zone primary air fraction
4963 2581 : state.dataSimAirServingZones->EpSSOA = 1.0;
4964 2581 : if (ZoneSA > 0.0) state.dataSimAirServingZones->EpSSOA = ZonePA / ZoneSA;
4965 2581 : if (state.dataSimAirServingZones->EpSSOA > 1.0) state.dataSimAirServingZones->EpSSOA = 1.0;
4966 2581 : termUnitFinalZoneSizing.ZonePrimaryAirFractionHtg = state.dataSimAirServingZones->EpSSOA;
4967 2581 : termUnitFinalZoneSizing.ZoneOAFracHeating = ZoneOAFracHeating;
4968 2581 : termUnitFinalZoneSizing.SupplyAirAdjustFactor = max(ClgSupplyAirAdjustFactor, HtgSupplyAirAdjustFactor);
4969 :
4970 : } // end for loop over cooled zones (for htg calcs though)
4971 883 : finalSysSizing.FloorAreaOnAirLoopHeated = finalSysSizing.FloorAreaOnAirLoopCooled;
4972 : }
4973 :
4974 886 : finalSysSizing.SysUncOA = SysOAUnc;
4975 886 : state.dataSize->CalcSysSizing(AirLoopNum).SysUncOA = SysOAUnc;
4976 886 : state.dataSize->VouBySys(AirLoopNum) = SysOAUnc;
4977 :
4978 886 : finalSysSizing.DesOutAirVolFlow = MinOAFlow;
4979 886 : state.dataSize->CalcSysSizing(AirLoopNum).DesOutAirVolFlow = MinOAFlow;
4980 :
4981 2754 : for (int DesDayEnvrnNum = 1; DesDayEnvrnNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DesDayEnvrnNum) {
4982 1868 : state.dataSize->SysSizing(DesDayEnvrnNum, AirLoopNum).DesOutAirVolFlow = finalSysSizing.DesOutAirVolFlow;
4983 : }
4984 : }
4985 : }
4986 :
4987 : // END SYSTEM OA CALCS
4988 :
4989 : // have moved std 62.1 table report writing to ManageSystemVentilationAdjustments in SizingManager
4990 329 : }
4991 :
4992 85815 : void UpdateSysSizing(EnergyPlusData &state, DataGlobalConstants::CallIndicator const CallIndicator)
4993 : {
4994 :
4995 : // SUBROUTINE INFORMATION:
4996 : // AUTHOR Fred Buhl
4997 : // DATE WRITTEN February 2001
4998 :
4999 : // PURPOSE OF THIS SUBROUTINE:
5000 : // Update the result variables of the zone sizing calculation
5001 :
5002 : // METHODOLOGY EMPLOYED:
5003 : // CallIndicator = 1 (BeginDay) zero the result arrays
5004 : // CallIndicator = 2 (DuringDay) fill arrays, averaging over 1 zone time step
5005 : // CallIndicator = 3 (EndDay) calculate daily maxima
5006 : // CallIndicator = 5 (EndSysSizingCalc) write out results
5007 :
5008 : // Using/Aliasing
5009 : using EMSManager::ManageEMS;
5010 : using General::FindNumberInList;
5011 : using Psychrometrics::PsyCpAirFnW;
5012 : using Psychrometrics::PsyHFnTdbW;
5013 : using Psychrometrics::PsyRhoAirFnPbTdbW;
5014 : using namespace OutputReportPredefined;
5015 : using namespace DataSizing;
5016 :
5017 : // Locals
5018 : int numOfTimeStepInDay; // number of zone time steps in a day
5019 :
5020 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5021 : int AirLoopNum; // primary air system index
5022 : int TimeStepInDay; // zone time step in day
5023 : int TimeStepIndex; // zone time step index
5024 : int I; // write statement index
5025 : int J; // write statement index
5026 : Real64 SysCoolRetTemp; // system cooling return temperature for a time step [C]
5027 : Real64 SysHeatRetTemp; // system heating return temperature for a time step [C]
5028 : Real64 RhoAir; // density of air kg/m3
5029 : Real64 OutAirFrac; // outside air fraction
5030 : Real64 SysCoolMixTemp; // system cooling mixed air temperature [C]
5031 : Real64 SysHeatMixTemp; // system heating mixed air temperature [C]
5032 : Real64 SysSensCoolCap; // system sensible cooling capacity [W]
5033 : Real64 SysTotCoolCap; // system total cooling capacity [W]
5034 : Real64 SysCoolZoneAvgTemp; // system cooling zone average temperature [C]
5035 : Real64 SysHeatZoneAvgTemp; // system heating zone average temperature [C]
5036 : Real64 SysHeatCap; // system heating capacity [W]
5037 : int HourCounter; // Hour Counter
5038 : int TimeStepCounter; // Time Step Counter
5039 : int Minutes; // Current Minutes Counter
5040 : int HourPrint; // Hour to print (timestamp)
5041 : int DDNum; // design day index
5042 : int CoolDDNum; // design day index of a peak cooling day
5043 : int HeatDDNum; // design day index of a peak cooling day
5044 : int CoolTimeStepNum; // time step index (in day) of a cooling peak
5045 : int HeatTimeStepNum; // time step index (in day) of a cooling peak
5046 : Real64 OutAirTemp; // outside air temperature
5047 : Real64 OutAirHumRat; // outside air humifity ratio
5048 : Real64 SysCoolMixHumRat; // system cooling mixed air humidity ratio [kg water/kg dry air]
5049 : Real64 SysCoolRetHumRat; // system coolingreturn air humifity ratio [kg water/kg dry air]
5050 : Real64 SysHeatMixHumRat; // system heating mixed air humidity ratio [kg water/kg dry air]
5051 : Real64 SysHeatRetHumRat; // system heatingreturn air humifity ratio [kg water/kg dry air]
5052 : Real64 SysCoolOutTemp; // system cooling outside air temperature [C]
5053 : Real64 SysCoolOutHumRat; // system cooling outside air humidity ratio [kg water/kg dry air]
5054 : Real64 SysHeatOutTemp; // system heating outside air temperature [C]
5055 : Real64 SysHeatOutHumRat; // system heating outside air humidity ratio [kg water/kg dry air]
5056 : Real64 SysDOASHeatAdd; // system DOAS heat addition rate [W]
5057 : Real64 SysDOASLatAdd; // system DOAS latent heat addition rate [W]
5058 : Real64 SysCoolSizingRat; // ratio of user input design flow for cooling divided by calculated design cooling flow
5059 : Real64 SysHeatSizingRat; // ratio of user input design flow for heating divided by calculated design heating flow
5060 : Real64 ZoneOARatio; // ratio of zone OA flow to zone design cooling or heating flow
5061 : Real64 RetTempRise; // difference between zone return temperature and zone temperature [delta K]
5062 : Real64 SysCoolingEv; // System level ventilation effectiveness for cooling mode
5063 : Real64 SysHeatingEv; // System level ventilation effectiveness for heating mode
5064 : Real64 SysHtgPeakAirflow; // Peak heating airflow
5065 : int MatchingCooledZoneNum; // temporary variable
5066 : Real64 termunitsizingtempfrac; // 1.0/(1.0+termunitsizing(ctrlzone)%inducrat)
5067 : Real64 termunitsizingtemp; // (1.0+termunitsizing(ctrlzone)%inducrat)
5068 85815 : Real64 VozClg(0.0); // corrected (for ventilation efficiency) zone outside air flow rate [m3/s]
5069 :
5070 85815 : numOfTimeStepInDay = state.dataGlobal->NumOfTimeStepInHour * 24;
5071 :
5072 : // allocate scratch arrays
5073 85815 : if (!allocated(state.dataSize->SensCoolCapTemp)) {
5074 329 : state.dataSize->SensCoolCapTemp.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 0.0);
5075 329 : state.dataSize->TotCoolCapTemp.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 0.0);
5076 : }
5077 :
5078 : // allocate arrays used to store values for standard 62.1 tabular report
5079 85815 : if (!allocated(state.dataSize->FaByZoneCool)) {
5080 329 : state.dataSize->FaByZoneCool.dimension(state.dataSize->NumAirTerminalUnits, 0.0);
5081 329 : state.dataSize->FaByZoneHeat.dimension(state.dataSize->NumAirTerminalUnits, 0.0);
5082 329 : state.dataSize->FbByZoneCool.dimension(state.dataSize->NumAirTerminalUnits, 0.0);
5083 329 : state.dataSize->FbByZoneHeat.dimension(state.dataSize->NumAirTerminalUnits, 0.0);
5084 329 : state.dataSize->FcByZoneCool.dimension(state.dataSize->NumAirTerminalUnits, 0.0);
5085 329 : state.dataSize->FcByZoneHeat.dimension(state.dataSize->NumAirTerminalUnits, 0.0);
5086 329 : state.dataSimAirServingZones->EvBySysCool.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 1.0);
5087 329 : state.dataSimAirServingZones->EvBySysHeat.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 1.0);
5088 329 : state.dataSize->XsBySysCool.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 1.0);
5089 329 : state.dataSize->XsBySysHeat.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 1.0);
5090 329 : state.dataSize->EvzByZoneCool.dimension(state.dataSize->NumAirTerminalUnits, 1.0);
5091 329 : state.dataSize->EvzByZoneCoolPrev.dimension(state.dataSize->NumAirTerminalUnits, 1.0);
5092 329 : state.dataSize->EvzByZoneHeat.dimension(state.dataSize->NumAirTerminalUnits, 1.0);
5093 329 : state.dataSize->EvzByZoneHeatPrev.dimension(state.dataSize->NumAirTerminalUnits, 1.0);
5094 329 : state.dataSize->EvzMinBySysCool.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 1.0);
5095 329 : state.dataSize->EvzMinBySysHeat.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 1.0);
5096 329 : state.dataSize->VotClgBySys.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 0.0);
5097 329 : state.dataSize->VotHtgBySys.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 0.0);
5098 329 : state.dataSize->VozSumClgBySys.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 0.0);
5099 329 : state.dataSize->VozSumHtgBySys.dimension(state.dataHVACGlobal->NumPrimaryAirSys, 0.0);
5100 : }
5101 :
5102 85815 : switch (CallIndicator) {
5103 695 : case DataGlobalConstants::CallIndicator::BeginDay: {
5104 : // Correct the zone return temperature in ZoneSizing for the case of induction units. The calc in
5105 : // ZoneEquipmentManager assumes all the air entering the zone goes into the return node.
5106 8078 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
5107 7383 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum);
5108 7383 : auto &zoneSizing = state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum);
5109 7383 : if (!zoneEquipConfig.IsControlled) continue;
5110 : // Use first non-zero airdistunit for now
5111 6497 : int TermUnitSizingIndex = 0;
5112 6497 : for (int InletNode = 1; InletNode <= zoneEquipConfig.NumInletNodes; ++InletNode) {
5113 6497 : TermUnitSizingIndex = zoneEquipConfig.AirDistUnitCool(InletNode).TermUnitSizingIndex;
5114 6497 : if (TermUnitSizingIndex == 0) continue;
5115 6497 : termunitsizingtemp = (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat);
5116 6497 : termunitsizingtempfrac = (1.0 / termunitsizingtemp);
5117 6497 : if (TermUnitSizingIndex > 0) break;
5118 : }
5119 6497 : if (TermUnitSizingIndex == 0) continue; // Skip this if there are no terminal units
5120 6497 : RetTempRise = zoneSizing.ZoneRetTempAtCoolPeak - zoneSizing.ZoneTempAtCoolPeak;
5121 6497 : if (RetTempRise > 0.01) {
5122 3185 : zoneSizing.ZoneRetTempAtCoolPeak = zoneSizing.ZoneTempAtCoolPeak + RetTempRise * termunitsizingtempfrac;
5123 : }
5124 6497 : RetTempRise = zoneSizing.ZoneRetTempAtHeatPeak - zoneSizing.ZoneTempAtHeatPeak;
5125 6497 : if (RetTempRise > 0.01) {
5126 779 : zoneSizing.ZoneRetTempAtHeatPeak = zoneSizing.ZoneTempAtHeatPeak + RetTempRise * termunitsizingtempfrac;
5127 : }
5128 : }
5129 :
5130 2641 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) { // start of begin day loop over primary air systems
5131 1946 : auto &airToZoneNodeInfo = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum);
5132 1946 : int NumZonesCooled = airToZoneNodeInfo.NumZonesCooled;
5133 1946 : int NumZonesHeated = airToZoneNodeInfo.NumZonesHeated;
5134 1946 : state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum).CoolDesDay = state.dataEnvrn->EnvironmentName;
5135 1946 : state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum).HeatDesDay = state.dataEnvrn->EnvironmentName;
5136 1946 : state.dataSize->SensCoolCapTemp(AirLoopNum) = 0.0;
5137 1946 : state.dataSize->TotCoolCapTemp(AirLoopNum) = 0.0;
5138 :
5139 8159 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) { // loop over cooled zones
5140 6213 : int CtrlZoneNum = airToZoneNodeInfo.CoolCtrlZoneNums(ZonesCooledNum);
5141 6213 : int TermUnitSizingIndex = airToZoneNodeInfo.TermUnitCoolSizingIndex(ZonesCooledNum);
5142 : Real64 adjCoolMassFlow =
5143 6213 : state.dataSize->TermUnitSizing(TermUnitSizingIndex)
5144 6213 : .applyTermUnitSizingCoolFlow(state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum).DesCoolMassFlow,
5145 12426 : state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum).DesCoolMassFlowNoOA);
5146 6213 : state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum).NonCoinCoolMassFlow +=
5147 6213 : adjCoolMassFlow / (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat);
5148 6223 : if (state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum).loadSizingType == DataSizing::LoadSizing::Latent &&
5149 10 : !state.dataSize->FinalZoneSizing.empty()) {
5150 10 : if (!state.dataSize->FinalZoneSizing(CtrlZoneNum).zoneLatentSizing && state.dataSize->CurOverallSimDay == 1) {
5151 0 : ShowWarningError(state,
5152 0 : format("Latent Sizing for AirLoop = {} requires latent sizing in Sizing:Zone object for Zone = {}",
5153 : airToZoneNodeInfo.AirLoopName,
5154 0 : state.dataSize->FinalZoneSizing(CtrlZoneNum).ZoneName));
5155 : }
5156 6203 : } else if (!state.dataSize->FinalZoneSizing.empty()) { // not latent sizing for air loop
5157 6203 : if (state.dataSize->FinalZoneSizing(CtrlZoneNum).zoneLatentSizing && state.dataSize->CurOverallSimDay == 1) {
5158 0 : ShowWarningError(state,
5159 0 : format("Sizing for AirLoop = {} includes latent sizing in Sizing:Zone object for Zone = {}",
5160 : airToZoneNodeInfo.AirLoopName,
5161 0 : state.dataSize->FinalZoneSizing(CtrlZoneNum).ZoneName));
5162 : }
5163 : }
5164 : } // end of loop over cooled zones
5165 :
5166 1946 : if (NumZonesHeated > 0) { // if there are zones supplied with central hot air
5167 97 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesHeated; ++ZonesHeatedNum) { // loop over heated zones
5168 76 : int CtrlZoneNum = airToZoneNodeInfo.HeatCtrlZoneNums(ZonesHeatedNum);
5169 76 : int TermUnitSizingIndex = airToZoneNodeInfo.TermUnitHeatSizingIndex(ZonesHeatedNum);
5170 76 : Real64 adjHeatMassFlow = state.dataSize->TermUnitSizing(TermUnitSizingIndex)
5171 152 : .applyTermUnitSizingHeatFlow(
5172 76 : state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum).DesHeatMassFlow,
5173 152 : state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum).DesHeatMassFlowNoOA);
5174 76 : state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum).NonCoinHeatMassFlow +=
5175 76 : adjHeatMassFlow / (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat);
5176 : } // end of loop over heated zones
5177 : } else { // otherwise use cool supply zones
5178 8062 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) { // loop over cooled zones
5179 6137 : int CtrlZoneNum = airToZoneNodeInfo.CoolCtrlZoneNums(ZonesCooledNum);
5180 6137 : int TermUnitSizingIndex = airToZoneNodeInfo.TermUnitCoolSizingIndex(ZonesCooledNum);
5181 6137 : Real64 adjHeatMassFlow = state.dataSize->TermUnitSizing(TermUnitSizingIndex)
5182 12274 : .applyTermUnitSizingHeatFlow(
5183 6137 : state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum).DesHeatMassFlow,
5184 12274 : state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum).DesHeatMassFlowNoOA);
5185 6137 : state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum).NonCoinHeatMassFlow +=
5186 6137 : adjHeatMassFlow / (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat);
5187 : } // end of loop over cooled zones
5188 : } // End of heat / cool zone if - else
5189 :
5190 695 : } // End of begin day loop over primary air systems
5191 695 : } break;
5192 84096 : case DataGlobalConstants::CallIndicator::DuringDay: {
5193 168192 : TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->NumOfTimeStepInHour +
5194 84096 : state.dataGlobal->TimeStep; // calculate current zone time step index
5195 :
5196 : // Correct the zone return temperature in ZoneSizing for the case of induction units. The calc in
5197 : // ZoneEquipmentManager assumes all the air entering the zone goes into the return node.
5198 988176 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
5199 904080 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
5200 : // Use first non-zero airdistunit for now, if there is one
5201 802320 : termunitsizingtempfrac = 1.0;
5202 802320 : int TermUnitSizingIndex = 0;
5203 802320 : for (int InletNode = 1; InletNode <= state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumInletNodes; ++InletNode) {
5204 802320 : TermUnitSizingIndex = state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitCool(InletNode).TermUnitSizingIndex;
5205 802320 : if (TermUnitSizingIndex == 0) continue;
5206 802320 : termunitsizingtemp = (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat);
5207 802320 : termunitsizingtempfrac = (1.0 / termunitsizingtemp);
5208 802320 : if (TermUnitSizingIndex > 0) break;
5209 : }
5210 802320 : if (TermUnitSizingIndex == 0) continue; // Skip this if there are no terminal units
5211 802320 : auto &zoneSizing = state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum);
5212 802320 : RetTempRise = zoneSizing.CoolZoneRetTempSeq(TimeStepInDay) - zoneSizing.CoolZoneTempSeq(TimeStepInDay);
5213 802320 : if (RetTempRise > 0.01) {
5214 413640 : zoneSizing.CoolZoneRetTempSeq(TimeStepInDay) = zoneSizing.CoolZoneTempSeq(TimeStepInDay) + RetTempRise * termunitsizingtempfrac;
5215 : }
5216 802320 : RetTempRise = zoneSizing.HeatZoneRetTempSeq(TimeStepInDay) - zoneSizing.HeatZoneTempSeq(TimeStepInDay);
5217 802320 : if (RetTempRise > 0.01) {
5218 117721 : zoneSizing.HeatZoneRetTempSeq(TimeStepInDay) = zoneSizing.HeatZoneTempSeq(TimeStepInDay) + RetTempRise * termunitsizingtempfrac;
5219 : }
5220 : }
5221 : // start of zone time step loop over primary air systems
5222 314352 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
5223 :
5224 230256 : int NumZonesCooled = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled;
5225 230256 : int NumZonesHeated = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
5226 :
5227 230256 : SysCoolRetTemp = 0.0;
5228 230256 : OutAirFrac = 0.0;
5229 230256 : SysCoolMixTemp = 0.0;
5230 230256 : SysSensCoolCap = 0.0;
5231 230256 : SysCoolRetHumRat = 0.0;
5232 230256 : SysCoolMixHumRat = 0.0;
5233 230256 : SysCoolZoneAvgTemp = 0.0;
5234 230256 : SysHeatZoneAvgTemp = 0.0;
5235 230256 : SysTotCoolCap = 0.0;
5236 230256 : SysDOASHeatAdd = 0.0;
5237 230256 : SysDOASLatAdd = 0.0;
5238 230256 : Real64 SysLatCoolHumRat = 0.0;
5239 :
5240 1005216 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) { // loop over zones cooled by central system
5241 774960 : int CtrlZoneNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(ZonesCooledNum);
5242 774960 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
5243 774960 : auto &termUnitSizing = state.dataSize->TermUnitSizing(TermUnitSizingIndex);
5244 774960 : auto &zoneSizing = state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum);
5245 : // sum up the system mass flow rate for this time step
5246 : Real64 adjCoolFlowSeq =
5247 774960 : termUnitSizing.applyTermUnitSizingCoolFlow(zoneSizing.CoolFlowSeq(TimeStepInDay), zoneSizing.CoolFlowSeqNoOA(TimeStepInDay));
5248 1549920 : state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum).CoolFlowSeq(TimeStepInDay) +=
5249 774960 : adjCoolFlowSeq / (1.0 + termUnitSizing.InducRat);
5250 : // sum up the zone cooling load to be met by this system for this time step
5251 774960 : state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum).SumZoneCoolLoadSeq(TimeStepInDay) +=
5252 774960 : zoneSizing.CoolLoadSeq(TimeStepInDay);
5253 : // calculate the return air temperature for this time step
5254 774960 : SysCoolRetTemp +=
5255 774960 : zoneSizing.CoolZoneRetTempSeq(TimeStepInDay) * zoneSizing.CoolFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5256 774960 : SysCoolRetHumRat +=
5257 774960 : zoneSizing.CoolZoneHumRatSeq(TimeStepInDay) * zoneSizing.CoolFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5258 774960 : SysCoolZoneAvgTemp +=
5259 774960 : zoneSizing.CoolZoneTempSeq(TimeStepInDay) * zoneSizing.CoolFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5260 774960 : SysDOASHeatAdd += zoneSizing.DOASHeatAddSeq(TimeStepInDay) * zoneSizing.CoolFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5261 774960 : SysDOASLatAdd += zoneSizing.DOASLatAddSeq(TimeStepInDay) * zoneSizing.CoolFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5262 774960 : SysLatCoolHumRat += zoneSizing.CoolDesHumRat * zoneSizing.CoolFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5263 : } // end of loop over zones cooled by central system
5264 : // Get peak system cooling load with coincident
5265 230256 : auto &sysSizing = state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum);
5266 230256 : if (sysSizing.SysDesCoolLoad < sysSizing.SumZoneCoolLoadSeq(TimeStepInDay)) {
5267 32605 : sysSizing.SysDesCoolLoad = sysSizing.SumZoneCoolLoadSeq(TimeStepInDay);
5268 32605 : sysSizing.SysCoolLoadTimeStepPk = TimeStepInDay;
5269 : }
5270 : // check that there is system mass flow
5271 230256 : if (sysSizing.CoolFlowSeq(TimeStepInDay) > 0.0) {
5272 : // complete return air temp calc
5273 226375 : SysLatCoolHumRat /= sysSizing.CoolFlowSeq(TimeStepInDay);
5274 226375 : SysCoolRetTemp /= sysSizing.CoolFlowSeq(TimeStepInDay);
5275 226375 : SysCoolRetHumRat /= sysSizing.CoolFlowSeq(TimeStepInDay);
5276 226375 : SysCoolZoneAvgTemp /= sysSizing.CoolFlowSeq(TimeStepInDay);
5277 226375 : sysSizing.SysCoolRetTempSeq(TimeStepInDay) = SysCoolRetTemp;
5278 226375 : sysSizing.SysCoolRetHumRatSeq(TimeStepInDay) = SysCoolRetHumRat;
5279 226375 : sysSizing.CoolZoneAvgTempSeq(TimeStepInDay) = SysCoolZoneAvgTemp;
5280 : // calculate the outside air fraction for this time step
5281 226375 : RhoAir = state.dataEnvrn->StdRhoAir;
5282 226375 : if (sysSizing.CoolOAOption == MinOA) {
5283 218671 : OutAirFrac = RhoAir * sysSizing.DesOutAirVolFlow / sysSizing.CoolFlowSeq(TimeStepInDay);
5284 218671 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
5285 : } else {
5286 7704 : OutAirFrac = 1.0;
5287 : }
5288 : // now calculate the mixed air temperature
5289 226375 : SysCoolMixTemp = state.dataEnvrn->OutDryBulbTemp * OutAirFrac + SysCoolRetTemp * (1.0 - OutAirFrac);
5290 226375 : SysCoolMixHumRat = state.dataEnvrn->OutHumRat * OutAirFrac + SysCoolRetHumRat * (1.0 - OutAirFrac);
5291 226375 : sysSizing.SysCoolOutTempSeq(TimeStepInDay) = state.dataEnvrn->OutDryBulbTemp;
5292 226375 : sysSizing.SysCoolOutHumRatSeq(TimeStepInDay) = state.dataEnvrn->OutHumRat;
5293 : // adjust supply air humidity ratio to meet latent load
5294 226375 : if (sysSizing.loadSizingType == DataSizing::LoadSizing::Latent) {
5295 192 : if (state.dataHeatBal->isAnyLatentLoad) {
5296 192 : sysSizing.CoolSupHumRat = std::min(SysLatCoolHumRat, sysSizing.CoolSupHumRat);
5297 192 : state.dataSize->FinalSysSizing(AirLoopNum).CoolSupHumRat = sysSizing.CoolSupHumRat;
5298 : } else {
5299 : // switch back to sensible load if all latent zone loads are smaller than sensible load
5300 0 : sysSizing.coolingPeakLoad = DataSizing::PeakLoad::SensibleCooling;
5301 0 : state.dataSize->FinalSysSizing(AirLoopNum).coolingPeakLoad = DataSizing::PeakLoad::SensibleCooling;
5302 : }
5303 : }
5304 : // From the mixed air temp, system design supply air temp, and the mass flow rate
5305 : // calculate the system sensible cooling capacity
5306 452750 : SysSensCoolCap = PsyCpAirFnW(DataPrecisionGlobals::constant_zero) * sysSizing.CoolFlowSeq(TimeStepInDay) *
5307 226375 : (SysCoolMixTemp - sysSizing.CoolSupTemp);
5308 226375 : SysSensCoolCap = max(0.0, SysSensCoolCap);
5309 : // calculate the system total cooling capacity
5310 452750 : SysTotCoolCap = sysSizing.CoolFlowSeq(TimeStepInDay) *
5311 226375 : (PsyHFnTdbW(SysCoolMixTemp, SysCoolMixHumRat) - PsyHFnTdbW(sysSizing.CoolSupTemp, sysSizing.CoolSupHumRat));
5312 226375 : SysTotCoolCap = max(0.0, SysTotCoolCap);
5313 : // Save the sens cool cap for this time step
5314 226375 : sysSizing.SensCoolCapSeq(TimeStepInDay) = SysSensCoolCap;
5315 : // Save the tot cool cap for this time step
5316 226375 : sysSizing.TotCoolCapSeq(TimeStepInDay) = SysTotCoolCap;
5317 : // Save the DOAS flows
5318 226375 : sysSizing.SysDOASHeatAddSeq(TimeStepInDay) = SysDOASHeatAdd;
5319 226375 : sysSizing.SysDOASLatAddSeq(TimeStepInDay) = SysDOASLatAdd;
5320 : } // end of system mass flow check
5321 :
5322 : // get the maximum system sensible cooling capacity
5323 230256 : if (SysSensCoolCap > state.dataSize->SensCoolCapTemp(AirLoopNum)) {
5324 34056 : state.dataSize->SysSizPeakDDNum(AirLoopNum).TimeStepAtSensCoolPk(state.dataSize->CurOverallSimDay) = TimeStepInDay;
5325 34056 : state.dataSize->SensCoolCapTemp(AirLoopNum) = SysSensCoolCap;
5326 34056 : if (sysSizing.coolingPeakLoad == DataSizing::PeakLoad::SensibleCooling) {
5327 31884 : sysSizing.SensCoolCap = SysSensCoolCap;
5328 31884 : sysSizing.TotCoolCap = SysTotCoolCap;
5329 31884 : sysSizing.MixTempAtCoolPeak = SysCoolMixTemp;
5330 31884 : sysSizing.MixHumRatAtCoolPeak = SysCoolMixHumRat;
5331 31884 : sysSizing.RetTempAtCoolPeak = SysCoolRetTemp;
5332 31884 : sysSizing.RetHumRatAtCoolPeak = SysCoolRetHumRat;
5333 31884 : sysSizing.OutTempAtCoolPeak = state.dataEnvrn->OutDryBulbTemp;
5334 31884 : sysSizing.OutHumRatAtCoolPeak = state.dataEnvrn->OutHumRat;
5335 31884 : sysSizing.MassFlowAtCoolPeak = sysSizing.CoolFlowSeq(TimeStepInDay);
5336 : }
5337 : }
5338 : // get the maximum system total cooling capacity
5339 230256 : if (SysTotCoolCap > state.dataSize->TotCoolCapTemp(AirLoopNum)) {
5340 33322 : state.dataSize->SysSizPeakDDNum(AirLoopNum).TimeStepAtTotCoolPk(state.dataSize->CurOverallSimDay) = TimeStepInDay;
5341 33322 : state.dataSize->TotCoolCapTemp(AirLoopNum) = SysTotCoolCap;
5342 33322 : if (sysSizing.coolingPeakLoad == DataSizing::PeakLoad::TotalCooling) {
5343 2066 : sysSizing.SensCoolCap = SysSensCoolCap;
5344 2066 : sysSizing.TotCoolCap = SysTotCoolCap;
5345 2066 : sysSizing.MixTempAtCoolPeak = SysCoolMixTemp;
5346 2066 : sysSizing.MixHumRatAtCoolPeak = SysCoolMixHumRat;
5347 2066 : sysSizing.RetTempAtCoolPeak = SysCoolRetTemp;
5348 2066 : sysSizing.RetHumRatAtCoolPeak = SysCoolRetHumRat;
5349 2066 : sysSizing.OutTempAtCoolPeak = state.dataEnvrn->OutDryBulbTemp;
5350 2066 : sysSizing.OutHumRatAtCoolPeak = state.dataEnvrn->OutHumRat;
5351 2066 : sysSizing.MassFlowAtCoolPeak = sysSizing.CoolFlowSeq(TimeStepInDay);
5352 : }
5353 33322 : sysSizing.SysCoolCoinSpaceSens = 0.0;
5354 158861 : for (int zonesCoolLoop = 1; zonesCoolLoop <= state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled; ++zonesCoolLoop) {
5355 125539 : int zoneNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(zonesCoolLoop);
5356 125539 : sysSizing.SysCoolCoinSpaceSens +=
5357 125539 : state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, zoneNum).CoolLoadSeq(TimeStepInDay);
5358 : }
5359 : }
5360 : // get the maximum cooling mass flow rate
5361 230256 : if (sysSizing.CoolFlowSeq(TimeStepInDay) > sysSizing.CoinCoolMassFlow) {
5362 29316 : sysSizing.CoinCoolMassFlow = sysSizing.CoolFlowSeq(TimeStepInDay);
5363 29316 : state.dataSize->SysSizPeakDDNum(AirLoopNum).TimeStepAtCoolFlowPk(state.dataSize->CurOverallSimDay) = TimeStepInDay;
5364 : }
5365 230256 : SysHeatRetTemp = 0.0;
5366 230256 : OutAirFrac = 0.0;
5367 230256 : SysHeatMixTemp = 0.0;
5368 230256 : SysHeatCap = 0.0;
5369 230256 : SysHeatRetHumRat = 0.0;
5370 230256 : SysHeatMixHumRat = 0.0;
5371 :
5372 230256 : if (NumZonesHeated > 0) { // IF there are centrally heated zones
5373 :
5374 13392 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesHeated; ++ZonesHeatedNum) { // loop over the heated zones
5375 10464 : int CtrlZoneNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).HeatCtrlZoneNums(ZonesHeatedNum);
5376 10464 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(ZonesHeatedNum);
5377 10464 : auto &termUnitSizing = state.dataSize->TermUnitSizing(TermUnitSizingIndex);
5378 10464 : auto &zoneSizing = state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum);
5379 : // sum up the heating mass flow rate for this time step
5380 : Real64 adjHeatFlowSeq =
5381 10464 : termUnitSizing.applyTermUnitSizingHeatFlow(zoneSizing.HeatFlowSeq(TimeStepInDay), zoneSizing.HeatFlowSeqNoOA(TimeStepInDay));
5382 10464 : sysSizing.HeatFlowSeq(TimeStepInDay) += adjHeatFlowSeq / (1.0 + termUnitSizing.InducRat);
5383 : // sum up the zone heating load to be met by this system for this time step
5384 10464 : sysSizing.SumZoneHeatLoadSeq(TimeStepInDay) += zoneSizing.HeatLoadSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5385 : // calculate the return air temperature for this time step
5386 10464 : SysHeatRetTemp +=
5387 10464 : zoneSizing.HeatZoneRetTempSeq(TimeStepInDay) * zoneSizing.HeatFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5388 10464 : SysHeatRetHumRat +=
5389 10464 : zoneSizing.HeatZoneHumRatSeq(TimeStepInDay) * zoneSizing.HeatFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5390 10464 : SysHeatZoneAvgTemp +=
5391 10464 : zoneSizing.HeatZoneTempSeq(TimeStepInDay) * zoneSizing.HeatFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5392 : } // end heated zones loop
5393 : // Get peak system heating load with coincident
5394 2928 : if (abs(sysSizing.SysDesHeatLoad) > abs(sysSizing.SumZoneHeatLoadSeq(TimeStepInDay))) {
5395 0 : sysSizing.SysDesHeatLoad = sysSizing.SumZoneHeatLoadSeq(TimeStepInDay);
5396 0 : sysSizing.SysHeatLoadTimeStepPk = TimeStepInDay;
5397 : }
5398 : // check that the system flow rate is nonzero
5399 2928 : if (sysSizing.HeatFlowSeq(TimeStepInDay) > 0.0) {
5400 : // complete return air temp calc
5401 2928 : SysHeatRetTemp /= sysSizing.HeatFlowSeq(TimeStepInDay);
5402 2928 : SysHeatRetHumRat /= sysSizing.HeatFlowSeq(TimeStepInDay);
5403 2928 : SysHeatZoneAvgTemp /= sysSizing.HeatFlowSeq(TimeStepInDay);
5404 2928 : sysSizing.SysHeatRetTempSeq(TimeStepInDay) = SysHeatRetTemp;
5405 2928 : sysSizing.SysHeatRetHumRatSeq(TimeStepInDay) = SysHeatRetHumRat;
5406 2928 : sysSizing.HeatZoneAvgTempSeq(TimeStepInDay) = SysHeatZoneAvgTemp;
5407 : // calculate the outside air fraction for this time step
5408 2928 : RhoAir = state.dataEnvrn->StdRhoAir;
5409 2928 : if (sysSizing.HeatOAOption == MinOA) {
5410 2928 : OutAirFrac = RhoAir * sysSizing.DesOutAirVolFlow / sysSizing.HeatFlowSeq(TimeStepInDay);
5411 2928 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
5412 : } else {
5413 0 : OutAirFrac = 1.0;
5414 : }
5415 : // calculate the mixed air temperature
5416 2928 : SysHeatMixTemp = state.dataEnvrn->OutDryBulbTemp * OutAirFrac + SysHeatRetTemp * (1.0 - OutAirFrac);
5417 2928 : SysHeatMixHumRat = state.dataEnvrn->OutHumRat * OutAirFrac + SysHeatRetHumRat * (1.0 - OutAirFrac);
5418 2928 : sysSizing.SysHeatOutTempSeq(TimeStepInDay) = state.dataEnvrn->OutDryBulbTemp;
5419 2928 : sysSizing.SysHeatOutHumRatSeq(TimeStepInDay) = state.dataEnvrn->OutHumRat;
5420 : // From the mixed air temp, heating supply air temp, and mass flow rate calculate the system heating capacity
5421 5856 : SysHeatCap = PsyCpAirFnW(DataPrecisionGlobals::constant_zero) * sysSizing.HeatFlowSeq(TimeStepInDay) *
5422 2928 : (sysSizing.HeatSupTemp - SysHeatMixTemp);
5423 2928 : SysHeatCap = max(0.0, SysHeatCap);
5424 : // save the system heating capacity for the time step
5425 2928 : sysSizing.HeatCapSeq(TimeStepInDay) = SysHeatCap;
5426 : } // end system flow rate IF
5427 :
5428 : // Get the maximum system heating capacity
5429 2928 : if (SysHeatCap > sysSizing.HeatCap) {
5430 680 : state.dataSize->SysSizPeakDDNum(AirLoopNum).TimeStepAtHeatPk(state.dataSize->CurOverallSimDay) = TimeStepInDay;
5431 680 : sysSizing.HeatCap = SysHeatCap;
5432 680 : sysSizing.HeatMixTemp = SysHeatMixTemp;
5433 680 : sysSizing.HeatMixHumRat = SysHeatMixHumRat;
5434 680 : sysSizing.HeatRetTemp = SysHeatRetTemp;
5435 680 : sysSizing.HeatRetHumRat = SysHeatRetHumRat;
5436 680 : sysSizing.HeatOutTemp = state.dataEnvrn->OutDryBulbTemp;
5437 680 : sysSizing.HeatOutHumRat = state.dataEnvrn->OutHumRat;
5438 : // save time of system coincident heating coil peak
5439 680 : sysSizing.SysHeatCoilTimeStepPk = TimeStepInDay;
5440 680 : sysSizing.SysHeatCoinSpaceSens = 0.0;
5441 680 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated > 0) {
5442 3279 : for (int zonesHeatLoop = 1; zonesHeatLoop <= state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
5443 : ++zonesHeatLoop) {
5444 2599 : int zoneNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).HeatCtrlZoneNums(zonesHeatLoop);
5445 2599 : sysSizing.SysHeatCoinSpaceSens +=
5446 2599 : state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, zoneNum).HeatLoadSeq(TimeStepInDay);
5447 : }
5448 : }
5449 : }
5450 : //! save time of system coincident heating airflow peak
5451 2928 : if (sysSizing.HeatFlowSeq(TimeStepInDay) > sysSizing.CoinHeatMassFlow) {
5452 476 : sysSizing.SysHeatAirTimeStepPk = TimeStepInDay;
5453 : }
5454 :
5455 : // Get the maximum system heating flow rate
5456 2928 : sysSizing.CoinHeatMassFlow = max(sysSizing.CoinHeatMassFlow, sysSizing.HeatFlowSeq(TimeStepInDay));
5457 :
5458 : } else { // No centrally heated zones: use cooled zones
5459 :
5460 991824 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) { // loop over the cooled zones
5461 764496 : int CtrlZoneNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(ZonesCooledNum);
5462 : auto &termUnitSizing =
5463 764496 : state.dataSize->TermUnitSizing(state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum));
5464 764496 : auto &zoneSizing = state.dataSize->ZoneSizing(state.dataSize->CurOverallSimDay, CtrlZoneNum);
5465 : // sum up the heating mass flow rate for this time step
5466 : Real64 adjHeatFlowSeq =
5467 764496 : termUnitSizing.applyTermUnitSizingHeatFlow(zoneSizing.HeatFlowSeq(TimeStepInDay), zoneSizing.HeatFlowSeqNoOA(TimeStepInDay));
5468 764496 : sysSizing.HeatFlowSeq(TimeStepInDay) += adjHeatFlowSeq / (1.0 + termUnitSizing.InducRat);
5469 : // sum up the zone heating load to be met by this system for this time step
5470 764496 : sysSizing.SumZoneHeatLoadSeq(TimeStepInDay) += zoneSizing.HeatLoadSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5471 : // calculate the return air temperature for this time step
5472 764496 : SysHeatRetTemp +=
5473 764496 : zoneSizing.HeatZoneRetTempSeq(TimeStepInDay) * zoneSizing.HeatFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5474 764496 : SysHeatRetHumRat +=
5475 764496 : zoneSizing.HeatZoneHumRatSeq(TimeStepInDay) * zoneSizing.HeatFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5476 764496 : SysHeatZoneAvgTemp +=
5477 764496 : zoneSizing.HeatZoneTempSeq(TimeStepInDay) * zoneSizing.HeatFlowSeq(TimeStepInDay) / (1.0 + termUnitSizing.InducRat);
5478 : } // end of cooled zones loop
5479 : // Get peak system heating load with coincident
5480 227328 : if (fabs(sysSizing.SysDesHeatLoad) < fabs(sysSizing.SumZoneHeatLoadSeq(TimeStepInDay))) {
5481 36047 : sysSizing.SysDesHeatLoad = sysSizing.SumZoneHeatLoadSeq(TimeStepInDay);
5482 36047 : sysSizing.SysHeatLoadTimeStepPk = TimeStepInDay;
5483 : }
5484 :
5485 227328 : if (sysSizing.HeatFlowSeq(TimeStepInDay) > 0.0) {
5486 : // complete return air temp calc
5487 222816 : SysHeatRetTemp /= sysSizing.HeatFlowSeq(TimeStepInDay);
5488 222816 : SysHeatRetHumRat /= sysSizing.HeatFlowSeq(TimeStepInDay);
5489 222816 : SysHeatZoneAvgTemp /= sysSizing.HeatFlowSeq(TimeStepInDay);
5490 222816 : sysSizing.SysHeatRetTempSeq(TimeStepInDay) = SysHeatRetTemp;
5491 222816 : sysSizing.SysHeatRetHumRatSeq(TimeStepInDay) = SysHeatRetHumRat;
5492 222816 : sysSizing.HeatZoneAvgTempSeq(TimeStepInDay) = SysHeatZoneAvgTemp;
5493 : // calculate the outside air fraction for this time step
5494 222816 : RhoAir = state.dataEnvrn->StdRhoAir;
5495 222816 : if (sysSizing.HeatOAOption == MinOA) {
5496 215472 : OutAirFrac = RhoAir * sysSizing.DesOutAirVolFlow / sysSizing.HeatFlowSeq(TimeStepInDay);
5497 215472 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
5498 : } else {
5499 7344 : OutAirFrac = 1.0;
5500 : }
5501 : // calculate the mixed air temperature
5502 222816 : SysHeatMixTemp = state.dataEnvrn->OutDryBulbTemp * OutAirFrac + SysHeatRetTemp * (1.0 - OutAirFrac);
5503 222816 : SysHeatMixHumRat = state.dataEnvrn->OutHumRat * OutAirFrac + SysHeatRetHumRat * (1.0 - OutAirFrac);
5504 222816 : sysSizing.SysHeatOutTempSeq(TimeStepInDay) = state.dataEnvrn->OutDryBulbTemp;
5505 222816 : sysSizing.SysHeatOutHumRatSeq(TimeStepInDay) = state.dataEnvrn->OutHumRat;
5506 : // From the mixed air temp, heating supply air temp, and mass flow rate calculate the system heating capacity
5507 445632 : SysHeatCap = PsyCpAirFnW(DataPrecisionGlobals::constant_zero) * sysSizing.HeatFlowSeq(TimeStepInDay) *
5508 222816 : (sysSizing.HeatSupTemp - SysHeatMixTemp);
5509 222816 : SysHeatCap = max(0.0, SysHeatCap);
5510 : // save the system heating capacity for the time step
5511 222816 : sysSizing.HeatCapSeq(TimeStepInDay) = SysHeatCap;
5512 : } // end system flow rate IF
5513 :
5514 : // Get the maximum system heating capacity
5515 227328 : if (SysHeatCap > sysSizing.HeatCap) {
5516 38367 : state.dataSize->SysSizPeakDDNum(AirLoopNum).TimeStepAtHeatPk(state.dataSize->CurOverallSimDay) = TimeStepInDay;
5517 38367 : sysSizing.HeatCap = SysHeatCap;
5518 38367 : sysSizing.HeatMixTemp = SysHeatMixTemp;
5519 38367 : sysSizing.HeatMixHumRat = SysHeatMixHumRat;
5520 38367 : sysSizing.HeatRetTemp = SysHeatRetTemp;
5521 38367 : sysSizing.HeatRetHumRat = SysHeatRetHumRat;
5522 38367 : sysSizing.HeatOutTemp = state.dataEnvrn->OutDryBulbTemp;
5523 38367 : sysSizing.HeatOutHumRat = state.dataEnvrn->OutHumRat;
5524 : // save time of system coincident heating coil peak
5525 38367 : sysSizing.SysHeatCoilTimeStepPk = TimeStepInDay;
5526 :
5527 38367 : sysSizing.SysHeatCoinSpaceSens = 0.0;
5528 127842 : for (int zonesCoolLoop = 1; zonesCoolLoop <= state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled; ++zonesCoolLoop) {
5529 89475 : int zoneNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(zonesCoolLoop);
5530 89475 : sysSizing.SysHeatCoinSpaceSens +=
5531 89475 : state.dataSize->CalcZoneSizing(state.dataSize->CurOverallSimDay, zoneNum).HeatLoadSeq(TimeStepInDay);
5532 : }
5533 : } // Get the maximum system heating flow rate
5534 : // save time of system coincident heating airflow peak
5535 227328 : if (sysSizing.HeatFlowSeq(TimeStepInDay) > sysSizing.CoinHeatMassFlow) {
5536 29875 : sysSizing.SysHeatAirTimeStepPk = TimeStepInDay;
5537 : }
5538 :
5539 227328 : sysSizing.CoinHeatMassFlow = max(sysSizing.CoinHeatMassFlow, sysSizing.HeatFlowSeq(TimeStepInDay));
5540 : }
5541 :
5542 84096 : } // end of loop over primary air systems
5543 84096 : } break;
5544 695 : case DataGlobalConstants::CallIndicator::EndDay: {
5545 : // the entire set of std. 62.1 code here seems misplaced, should have been placed in EndSysSizCalc block
5546 : // Get design flows
5547 695 : SysCoolingEv = 1.0;
5548 695 : SysHeatingEv = 1.0;
5549 2641 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
5550 1946 : auto &finalSysSizing = state.dataSize->FinalSysSizing(AirLoopNum);
5551 1946 : int NumZonesCooled = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled;
5552 1946 : int NumZonesHeated = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
5553 1946 : auto &sysSizing = state.dataSize->SysSizing(state.dataSize->CurOverallSimDay, AirLoopNum);
5554 :
5555 1946 : switch (sysSizing.SizingOption) {
5556 190 : case Coincident: {
5557 190 : if (finalSysSizing.SystemOAMethod == SysOAMethod::ZoneSum) {
5558 190 : sysSizing.DesCoolVolFlow = sysSizing.CoinCoolMassFlow / state.dataEnvrn->StdRhoAir;
5559 190 : sysSizing.DesHeatVolFlow = sysSizing.CoinHeatMassFlow / state.dataEnvrn->StdRhoAir;
5560 190 : state.dataSize->VotClgBySys(AirLoopNum) = finalSysSizing.SysUncOA;
5561 190 : state.dataSize->VotHtgBySys(AirLoopNum) = finalSysSizing.SysUncOA;
5562 1080 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) {
5563 890 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
5564 1780 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffCooling <
5565 890 : state.dataSize->EvzMinBySysCool(AirLoopNum))
5566 0 : state.dataSize->EvzMinBySysCool(AirLoopNum) =
5567 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffCooling;
5568 1780 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating <
5569 890 : state.dataSize->EvzMinBySysHeat(AirLoopNum))
5570 0 : state.dataSize->EvzMinBySysHeat(AirLoopNum) =
5571 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating;
5572 : }
5573 190 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesHeated; ++ZonesHeatedNum) {
5574 0 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(ZonesHeatedNum);
5575 0 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffCooling <
5576 0 : state.dataSize->EvzMinBySysCool(AirLoopNum))
5577 0 : state.dataSize->EvzMinBySysCool(AirLoopNum) =
5578 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffCooling;
5579 0 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating <
5580 0 : state.dataSize->EvzMinBySysHeat(AirLoopNum))
5581 0 : state.dataSize->EvzMinBySysHeat(AirLoopNum) =
5582 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating;
5583 : }
5584 190 : if (sysSizing.DesCoolVolFlow > 0) {
5585 190 : state.dataSize->XsBySysCool(AirLoopNum) = min(1.0, finalSysSizing.SysUncOA / sysSizing.DesCoolVolFlow);
5586 : } else {
5587 0 : state.dataSize->XsBySysCool(AirLoopNum) = 0.0;
5588 : }
5589 190 : if (sysSizing.DesHeatVolFlow > 0) {
5590 190 : state.dataSize->XsBySysHeat(AirLoopNum) = min(1.0, finalSysSizing.SysUncOA / sysSizing.DesHeatVolFlow);
5591 : } else {
5592 0 : state.dataSize->XsBySysHeat(AirLoopNum) = 0.0;
5593 : }
5594 0 : } else if (finalSysSizing.SystemOAMethod == SysOAMethod::VRP ||
5595 0 : finalSysSizing.SystemOAMethod == SysOAMethod::SP) { // Ventilation Rate and Simplified Procedure
5596 : // cooling
5597 0 : sysSizing.DesCoolVolFlow = sysSizing.CoinCoolMassFlow / state.dataEnvrn->StdRhoAir;
5598 0 : if (sysSizing.DesCoolVolFlow > 0) {
5599 0 : OutAirFrac = sysSizing.DesOutAirVolFlow / sysSizing.DesCoolVolFlow;
5600 : } else {
5601 0 : OutAirFrac = 0.0;
5602 : }
5603 0 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
5604 0 : if (sysSizing.DesCoolVolFlow > 0) {
5605 0 : state.dataSimAirServingZones->Xs = min(1.0, finalSysSizing.SysUncOA / sysSizing.DesCoolVolFlow);
5606 : } else {
5607 0 : state.dataSimAirServingZones->Xs = 0.0;
5608 : }
5609 0 : if (finalSysSizing.OAAutoSized && sysSizing.DesCoolVolFlow > 0) {
5610 0 : int numZonesCooled = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled;
5611 0 : state.dataSimAirServingZones->MinCoolingEvz = 1.0;
5612 0 : state.dataSize->VozSumClgBySys(AirLoopNum) = 0.0;
5613 0 : for (int ZonesCooledNum = 1; ZonesCooledNum <= numZonesCooled; ++ZonesCooledNum) {
5614 0 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
5615 :
5616 : // Zone air secondary recirculation fraction
5617 0 : state.dataSimAirServingZones->Er =
5618 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneSecondaryRecirculation;
5619 0 : state.dataSimAirServingZones->Ep = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZonePrimaryAirFraction;
5620 0 : state.dataSimAirServingZones->ZoneOAFrac = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZpzClgByZone;
5621 0 : state.dataSimAirServingZones->ZoneEz = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffCooling;
5622 0 : VozClg = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozClgByZone;
5623 0 : if (finalSysSizing.SystemOAMethod == SysOAMethod::SP) { // 62.1 simplified procedure
5624 0 : if (state.dataSize->DBySys(AirLoopNum) < 0.60) {
5625 0 : state.dataSize->EvzByZoneCool(TermUnitSizingIndex) = 0.88 * state.dataSize->DBySys(AirLoopNum) + 0.22;
5626 : } else {
5627 0 : state.dataSize->EvzByZoneCool(TermUnitSizingIndex) = 0.75;
5628 : }
5629 0 : state.dataSimAirServingZones->MinCoolingEvz = state.dataSize->EvzByZoneCool(TermUnitSizingIndex);
5630 : } else {
5631 0 : if (state.dataSimAirServingZones->Er > 0.0) {
5632 : // multi-path ventilation system using VRP
5633 0 : state.dataSimAirServingZones->Fa = state.dataSimAirServingZones->Ep +
5634 0 : (1.0 - state.dataSimAirServingZones->Ep) * state.dataSimAirServingZones->Er;
5635 0 : state.dataSimAirServingZones->Fb = state.dataSimAirServingZones->Ep;
5636 0 : state.dataSimAirServingZones->Fc = 1.0 - (1.0 - state.dataSimAirServingZones->ZoneEz) *
5637 0 : (1.0 - state.dataSimAirServingZones->Er) *
5638 0 : (1.0 - state.dataSimAirServingZones->Ep);
5639 : // save Fa Fb and Fc for standard 62.1 report
5640 0 : state.dataSize->FaByZoneCool(TermUnitSizingIndex) = state.dataSimAirServingZones->Fa;
5641 0 : state.dataSize->FbByZoneCool(TermUnitSizingIndex) = state.dataSimAirServingZones->Fb;
5642 0 : state.dataSize->FcByZoneCool(TermUnitSizingIndex) = state.dataSimAirServingZones->Fc;
5643 :
5644 : // Calc zone ventilation efficiency
5645 0 : if (state.dataSimAirServingZones->Fa > 0.0) {
5646 0 : SysCoolingEv =
5647 0 : 1.0 +
5648 0 : state.dataSimAirServingZones->Xs * state.dataSimAirServingZones->Fb / state.dataSimAirServingZones->Fa -
5649 0 : state.dataSimAirServingZones->ZoneOAFrac * state.dataSimAirServingZones->Ep *
5650 0 : state.dataSimAirServingZones->Fc / state.dataSimAirServingZones->Fa;
5651 : } else {
5652 0 : SysCoolingEv = 1.0;
5653 : }
5654 :
5655 : } else {
5656 : // single-path ventilation system
5657 0 : SysCoolingEv = 1.0 + state.dataSimAirServingZones->Xs - state.dataSimAirServingZones->ZoneOAFrac;
5658 : // Apply ventilation efficiency limit; reset SysCoolingEv if necessary
5659 0 : LimitZoneVentEff(state, state.dataSimAirServingZones->Xs, VozClg, TermUnitSizingIndex, SysCoolingEv);
5660 : }
5661 0 : if (SysCoolingEv < state.dataSimAirServingZones->MinCoolingEvz)
5662 0 : state.dataSimAirServingZones->MinCoolingEvz = SysCoolingEv;
5663 0 : state.dataSize->EvzByZoneCoolPrev(TermUnitSizingIndex) =
5664 0 : state.dataSize->EvzByZoneCool(TermUnitSizingIndex); // Save previous EvzByZoneCool
5665 0 : state.dataSize->EvzByZoneCool(TermUnitSizingIndex) = SysCoolingEv;
5666 : }
5667 0 : state.dataSize->VozSumClgBySys(AirLoopNum) += state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozClgByZone;
5668 : }
5669 :
5670 0 : if (state.dataSimAirServingZones->MinCoolingEvz > 0) {
5671 : // (However, I don't think people diversity can be done correctly in E+ Sizing so assuming D=1 in this
5672 : // equation
5673 : // Vou = Diversity*(Rp*Pz) + Ra*Az
5674 0 : state.dataSimAirServingZones->Vou = finalSysSizing.SysUncOA;
5675 0 : state.dataSimAirServingZones->Vot = state.dataSimAirServingZones->Vou / state.dataSimAirServingZones->MinCoolingEvz;
5676 0 : if (state.dataSimAirServingZones->Vot > state.dataSize->VotClgBySys(AirLoopNum)) {
5677 : // This might be the cooling design day so only update if Vot is larger than the previous
5678 0 : state.dataSize->VotClgBySys(AirLoopNum) = state.dataSimAirServingZones->Vot;
5679 0 : state.dataSize->XsBySysCool(AirLoopNum) = state.dataSimAirServingZones->Xs;
5680 0 : state.dataSize->EvzMinBySysCool(AirLoopNum) = state.dataSimAirServingZones->MinCoolingEvz;
5681 : } else {
5682 : // Restore EvzByZoneCool() since it was reset by the current (but not highest Vot) design day
5683 0 : for (int ZonesCooledNum = 1; ZonesCooledNum <= numZonesCooled; ++ZonesCooledNum) {
5684 : int TermUnitSizingIndex =
5685 0 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
5686 0 : state.dataSize->EvzByZoneCool(TermUnitSizingIndex) = state.dataSize->EvzByZoneCoolPrev(TermUnitSizingIndex);
5687 : }
5688 : }
5689 : }
5690 : }
5691 :
5692 : // heating
5693 0 : sysSizing.DesHeatVolFlow = sysSizing.CoinHeatMassFlow / state.dataEnvrn->StdRhoAir;
5694 0 : if (sysSizing.DesHeatVolFlow > 0) {
5695 0 : OutAirFrac = sysSizing.DesOutAirVolFlow / sysSizing.DesHeatVolFlow;
5696 : } else {
5697 0 : OutAirFrac = 0.0;
5698 : }
5699 0 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
5700 :
5701 : // This is a bit of a cludge. If the design zone heating airflows were increased due to
5702 : // the MaxZoneOaFraction, then the SysSizing(AirLoopNum,state.dataSize->CurOverallSimDay)%DesHeatVolFlow
5703 : // variable will be out of sync with the
5704 0 : if (finalSysSizing.MaxZoneOAFraction > 0 && finalSysSizing.HeatAirDesMethod == FromDDCalc) {
5705 0 : SysHtgPeakAirflow = 0.0;
5706 0 : if (NumZonesHeated > 0) {
5707 0 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesHeated; ++ZonesHeatedNum) {
5708 0 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(ZonesHeatedNum);
5709 0 : SysHtgPeakAirflow += state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesHeatVolFlow;
5710 : }
5711 : } else {
5712 0 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesCooled; ++ZonesHeatedNum) {
5713 0 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesHeatedNum);
5714 0 : SysHtgPeakAirflow += state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesHeatVolFlow;
5715 : }
5716 0 : }
5717 : } else {
5718 0 : SysHtgPeakAirflow = sysSizing.DesHeatVolFlow;
5719 : }
5720 :
5721 0 : if (sysSizing.DesHeatVolFlow > 0) {
5722 : // SysSizing(AirLoopNum,state.dataSize->CurOverallSimDay)%DesHeatVolFlow may be out of sync with
5723 : // FinalZoneSizing(CtrlZoneNum)%DesHeatVolFlow
5724 0 : state.dataSimAirServingZones->Xs = min(1.0, finalSysSizing.SysUncOA / max(sysSizing.DesHeatVolFlow, SysHtgPeakAirflow));
5725 : } else {
5726 0 : state.dataSimAirServingZones->Xs = 0.0;
5727 : }
5728 :
5729 0 : if (finalSysSizing.OAAutoSized && sysSizing.DesHeatVolFlow > 0) {
5730 0 : int numZonesHeated = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
5731 0 : state.dataSimAirServingZones->MinHeatingEvz = 1.0;
5732 0 : state.dataSize->VozSumHtgBySys(AirLoopNum) = 0.0;
5733 0 : if (numZonesHeated > 0) {
5734 0 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= numZonesHeated; ++ZonesHeatedNum) {
5735 0 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(ZonesHeatedNum);
5736 0 : MatchingCooledZoneNum = FindNumberInList(
5737 0 : TermUnitSizingIndex, state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex, NumZonesCooled);
5738 0 : if (MatchingCooledZoneNum == 0) {
5739 : // Zone air secondary recirculation fraction
5740 0 : state.dataSimAirServingZones->Er =
5741 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneSecondaryRecirculation;
5742 0 : state.dataSimAirServingZones->Ep =
5743 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZonePrimaryAirFractionHtg;
5744 0 : state.dataSimAirServingZones->ZoneOAFrac =
5745 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZpzHtgByZone;
5746 0 : state.dataSimAirServingZones->ZoneEz =
5747 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating;
5748 0 : if (finalSysSizing.SystemOAMethod == SysOAMethod::SP) { // 62.1 simplified procedure
5749 0 : if (state.dataSize->DBySys(AirLoopNum) < 0.60) {
5750 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = 0.88 * state.dataSize->DBySys(AirLoopNum) + 0.22;
5751 : } else {
5752 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = 0.75;
5753 : }
5754 0 : state.dataSimAirServingZones->MinHeatingEvz = state.dataSize->EvzByZoneHeat(TermUnitSizingIndex);
5755 : } else {
5756 0 : if (state.dataSimAirServingZones->Er > 0.0) {
5757 : // multi-path ventilation system using VRP
5758 0 : state.dataSimAirServingZones->Fa =
5759 0 : state.dataSimAirServingZones->Ep +
5760 0 : (1.0 - state.dataSimAirServingZones->Ep) * state.dataSimAirServingZones->Er;
5761 0 : state.dataSimAirServingZones->Fb = state.dataSimAirServingZones->Ep;
5762 0 : state.dataSimAirServingZones->Fc = 1.0 - (1.0 - state.dataSimAirServingZones->ZoneEz) *
5763 0 : (1.0 - state.dataSimAirServingZones->Er) *
5764 0 : (1.0 - state.dataSimAirServingZones->Ep);
5765 : // save Fa Fb and Fc for standard 62.1 report
5766 0 : state.dataSize->FaByZoneHeat(TermUnitSizingIndex) = state.dataSimAirServingZones->Fa;
5767 0 : state.dataSize->FbByZoneHeat(TermUnitSizingIndex) = state.dataSimAirServingZones->Fb;
5768 0 : state.dataSize->FcByZoneHeat(TermUnitSizingIndex) = state.dataSimAirServingZones->Fc;
5769 :
5770 : // Calc zone ventilation efficiency
5771 0 : if (state.dataSimAirServingZones->Fa > 0.0) {
5772 0 : SysHeatingEv = 1.0 +
5773 0 : state.dataSimAirServingZones->Xs * state.dataSimAirServingZones->Fb /
5774 0 : state.dataSimAirServingZones->Fa -
5775 0 : state.dataSimAirServingZones->ZoneOAFrac * state.dataSimAirServingZones->Ep *
5776 0 : state.dataSimAirServingZones->Fc / state.dataSimAirServingZones->Fa;
5777 : } else {
5778 0 : SysHeatingEv = 1.0;
5779 : }
5780 : } else {
5781 : // single-path ventilation system
5782 0 : SysHeatingEv = 1.0 + state.dataSimAirServingZones->Xs - state.dataSimAirServingZones->ZoneOAFrac;
5783 : }
5784 0 : if (SysHeatingEv < state.dataSimAirServingZones->MinHeatingEvz)
5785 0 : state.dataSimAirServingZones->MinHeatingEvz = SysHeatingEv;
5786 0 : state.dataSize->EvzByZoneHeatPrev(TermUnitSizingIndex) =
5787 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex); // Save previous EvzByZoneHeat
5788 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = SysHeatingEv;
5789 : }
5790 0 : state.dataSize->VozSumHtgBySys(AirLoopNum) +=
5791 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozHtgByZone;
5792 : }
5793 : }
5794 : } else {
5795 0 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesCooled; ++ZonesHeatedNum) {
5796 0 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesHeatedNum);
5797 : // Zone air secondary recirculation fraction
5798 0 : state.dataSimAirServingZones->Er =
5799 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneSecondaryRecirculation;
5800 0 : state.dataSimAirServingZones->Ep =
5801 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZonePrimaryAirFractionHtg;
5802 0 : state.dataSimAirServingZones->ZoneOAFrac = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZpzHtgByZone;
5803 0 : state.dataSimAirServingZones->ZoneEz = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating;
5804 0 : if (finalSysSizing.SystemOAMethod == SysOAMethod::SP) { // 62.1 simplified procedure
5805 0 : if (state.dataSize->DBySys(AirLoopNum) < 0.60) {
5806 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = 0.88 * state.dataSize->DBySys(AirLoopNum) + 0.22;
5807 : } else {
5808 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = 0.75;
5809 : }
5810 0 : state.dataSimAirServingZones->MinHeatingEvz = state.dataSize->EvzByZoneHeat(TermUnitSizingIndex);
5811 : } else {
5812 0 : if (state.dataSimAirServingZones->Er > 0.0) {
5813 : // multi-path ventilation system using VRP
5814 0 : state.dataSimAirServingZones->Fa =
5815 0 : state.dataSimAirServingZones->Ep +
5816 0 : (1.0 - state.dataSimAirServingZones->Ep) * state.dataSimAirServingZones->Er;
5817 0 : state.dataSimAirServingZones->Fb = state.dataSimAirServingZones->Ep;
5818 0 : state.dataSimAirServingZones->Fc = 1.0 - (1.0 - state.dataSimAirServingZones->ZoneEz) *
5819 0 : (1.0 - state.dataSimAirServingZones->Er) *
5820 0 : (1.0 - state.dataSimAirServingZones->Ep);
5821 : // save Fa Fb and Fc for standard 62.1 report
5822 0 : state.dataSize->FaByZoneHeat(TermUnitSizingIndex) = state.dataSimAirServingZones->Fa;
5823 0 : state.dataSize->FbByZoneHeat(TermUnitSizingIndex) = state.dataSimAirServingZones->Fb;
5824 0 : state.dataSize->FcByZoneHeat(TermUnitSizingIndex) = state.dataSimAirServingZones->Fc;
5825 :
5826 : // Calc zone ventilation efficiency
5827 0 : if (state.dataSimAirServingZones->Fa > 0.0) {
5828 0 : SysHeatingEv = 1.0 +
5829 0 : state.dataSimAirServingZones->Xs * state.dataSimAirServingZones->Fb /
5830 0 : state.dataSimAirServingZones->Fa -
5831 0 : state.dataSimAirServingZones->ZoneOAFrac * state.dataSimAirServingZones->Ep *
5832 0 : state.dataSimAirServingZones->Fc / state.dataSimAirServingZones->Fa;
5833 : } else {
5834 0 : SysHeatingEv = 1.0;
5835 : }
5836 : } else {
5837 : // single-path ventilation system
5838 0 : SysHeatingEv = 1.0 + state.dataSimAirServingZones->Xs - state.dataSimAirServingZones->ZoneOAFrac;
5839 : }
5840 0 : if (SysHeatingEv < state.dataSimAirServingZones->MinHeatingEvz)
5841 0 : state.dataSimAirServingZones->MinHeatingEvz = SysHeatingEv;
5842 0 : state.dataSize->EvzByZoneHeatPrev(TermUnitSizingIndex) =
5843 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex); // Save previous EvzByZoneHeat
5844 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = SysHeatingEv;
5845 0 : state.dataSize->VozSumHtgBySys(AirLoopNum) +=
5846 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozHtgByZone;
5847 : }
5848 : }
5849 : }
5850 :
5851 0 : if (state.dataSimAirServingZones->MinHeatingEvz > 0) {
5852 : // Std 62.1-2010, section 6.2.5.4: Eq. 6.6
5853 : // (However, I don't think people diversity can be done correctly in E+ Sizing so assuming D=1 in this
5854 : // equation
5855 : // Vou = Diversity*(Rp*Pz) + Ra*Az
5856 0 : state.dataSimAirServingZones->Vou = finalSysSizing.SysUncOA;
5857 0 : state.dataSimAirServingZones->Vot = state.dataSimAirServingZones->Vou / state.dataSimAirServingZones->MinHeatingEvz;
5858 0 : if (state.dataSimAirServingZones->Vot > state.dataSize->VotHtgBySys(AirLoopNum)) {
5859 : // This might be the cooling design day so only update if Vot is larger than the previous
5860 0 : state.dataSize->VotHtgBySys(AirLoopNum) = state.dataSimAirServingZones->Vot;
5861 0 : state.dataSize->XsBySysHeat(AirLoopNum) = state.dataSimAirServingZones->Xs;
5862 0 : state.dataSize->EvzMinBySysHeat(AirLoopNum) = state.dataSimAirServingZones->MinHeatingEvz;
5863 : } else {
5864 : // Restore EvzByZoneHeat() since it was reset by the current (but not highest Vot) design day
5865 : // This kludge is probably because inside EndDay block and code gets called for each design day.
5866 0 : if (numZonesHeated > 0) {
5867 0 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= numZonesHeated; ++ZonesHeatedNum) {
5868 : int TermUnitSizingIndex =
5869 0 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(ZonesHeatedNum);
5870 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = state.dataSize->EvzByZoneHeatPrev(TermUnitSizingIndex);
5871 : }
5872 : } else {
5873 0 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesCooled; ++ZonesHeatedNum) {
5874 : int TermUnitSizingIndex =
5875 0 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesHeatedNum);
5876 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = state.dataSize->EvzByZoneHeatPrev(TermUnitSizingIndex);
5877 : }
5878 : }
5879 : }
5880 : }
5881 : }
5882 : } else { // error
5883 : }
5884 190 : sysSizing.DesMainVolFlow = max(sysSizing.DesCoolVolFlow, sysSizing.DesHeatVolFlow);
5885 : // this should also be as least as big as is needed for Vot
5886 190 : } break;
5887 1756 : case NonCoincident: {
5888 1756 : if (finalSysSizing.SystemOAMethod == SysOAMethod::ZoneSum) {
5889 1736 : sysSizing.DesCoolVolFlow = sysSizing.NonCoinCoolMassFlow / state.dataEnvrn->StdRhoAir;
5890 1736 : sysSizing.DesHeatVolFlow = sysSizing.NonCoinHeatMassFlow / state.dataEnvrn->StdRhoAir;
5891 1736 : state.dataSize->VotClgBySys(AirLoopNum) = finalSysSizing.SysUncOA;
5892 1736 : state.dataSize->VotHtgBySys(AirLoopNum) = finalSysSizing.SysUncOA;
5893 6973 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) {
5894 5237 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
5895 10474 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffCooling <
5896 5237 : state.dataSize->EvzMinBySysCool(AirLoopNum))
5897 0 : state.dataSize->EvzMinBySysCool(AirLoopNum) =
5898 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffCooling;
5899 10474 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating <
5900 5237 : state.dataSize->EvzMinBySysHeat(AirLoopNum))
5901 0 : state.dataSize->EvzMinBySysHeat(AirLoopNum) =
5902 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating;
5903 : }
5904 1812 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesHeated; ++ZonesHeatedNum) {
5905 76 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(ZonesHeatedNum);
5906 152 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffCooling <
5907 76 : state.dataSize->EvzMinBySysCool(AirLoopNum))
5908 0 : state.dataSize->EvzMinBySysCool(AirLoopNum) =
5909 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffCooling;
5910 152 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating <
5911 76 : state.dataSize->EvzMinBySysHeat(AirLoopNum))
5912 0 : state.dataSize->EvzMinBySysHeat(AirLoopNum) =
5913 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating;
5914 : }
5915 1736 : if (sysSizing.DesCoolVolFlow > 0) {
5916 1707 : state.dataSize->XsBySysCool(AirLoopNum) = min(1.0, finalSysSizing.SysUncOA / sysSizing.DesCoolVolFlow);
5917 : } else {
5918 29 : state.dataSize->XsBySysCool(AirLoopNum) = 0.0;
5919 : }
5920 1736 : if (sysSizing.DesHeatVolFlow > 0) {
5921 1699 : state.dataSize->XsBySysHeat(AirLoopNum) = min(1.0, finalSysSizing.SysUncOA / sysSizing.DesHeatVolFlow);
5922 : } else {
5923 37 : state.dataSize->XsBySysHeat(AirLoopNum) = 0.0;
5924 : }
5925 26 : } else if (finalSysSizing.SystemOAMethod == SysOAMethod::VRP ||
5926 6 : finalSysSizing.SystemOAMethod == SysOAMethod::SP) { // Ventilation Rate and Simplified Procedure
5927 : // cooling
5928 20 : sysSizing.DesCoolVolFlow = sysSizing.NonCoinCoolMassFlow / state.dataEnvrn->StdRhoAir;
5929 20 : if (sysSizing.DesCoolVolFlow > 0) {
5930 20 : OutAirFrac = sysSizing.DesOutAirVolFlow / sysSizing.DesCoolVolFlow;
5931 : } else {
5932 0 : OutAirFrac = 0.0;
5933 : }
5934 20 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
5935 :
5936 20 : if (sysSizing.DesCoolVolFlow > 0) {
5937 20 : state.dataSimAirServingZones->Xs = min(1.0, finalSysSizing.SysUncOA / sysSizing.DesCoolVolFlow);
5938 : } else {
5939 0 : state.dataSimAirServingZones->Xs = 0.0;
5940 : }
5941 20 : if (finalSysSizing.OAAutoSized && sysSizing.DesCoolVolFlow > 0) {
5942 18 : int numZonesCooled = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled;
5943 18 : state.dataSimAirServingZones->MinCoolingEvz = 1.0;
5944 18 : state.dataSize->VozSumClgBySys(AirLoopNum) = 0.0;
5945 98 : for (int ZonesCooledNum = 1; ZonesCooledNum <= numZonesCooled; ++ZonesCooledNum) {
5946 80 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
5947 :
5948 : // Zone air secondary recirculation fraction
5949 80 : state.dataSimAirServingZones->Er =
5950 80 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneSecondaryRecirculation;
5951 80 : state.dataSimAirServingZones->Ep = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZonePrimaryAirFraction;
5952 80 : state.dataSimAirServingZones->ZoneOAFrac = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZpzClgByZone;
5953 80 : state.dataSimAirServingZones->ZoneEz = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffCooling;
5954 80 : VozClg = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozClgByZone;
5955 80 : if (finalSysSizing.SystemOAMethod == SysOAMethod::SP) { // 62.1 simplified procedure
5956 10 : if (state.dataSize->DBySys(AirLoopNum) < 0.60) {
5957 4 : state.dataSize->EvzByZoneCool(TermUnitSizingIndex) = 0.88 * state.dataSize->DBySys(AirLoopNum) + 0.22;
5958 : } else {
5959 6 : state.dataSize->EvzByZoneCool(TermUnitSizingIndex) = 0.75;
5960 : }
5961 10 : state.dataSimAirServingZones->MinCoolingEvz = state.dataSize->EvzByZoneCool(TermUnitSizingIndex);
5962 : } else {
5963 70 : if (state.dataSimAirServingZones->Er > 0.0) {
5964 : // multi-path ventilation system using VRP
5965 4 : state.dataSimAirServingZones->Fa = state.dataSimAirServingZones->Ep +
5966 2 : (1.0 - state.dataSimAirServingZones->Ep) * state.dataSimAirServingZones->Er;
5967 2 : state.dataSimAirServingZones->Fb = state.dataSimAirServingZones->Ep;
5968 6 : state.dataSimAirServingZones->Fc = 1.0 - (1.0 - state.dataSimAirServingZones->ZoneEz) *
5969 4 : (1.0 - state.dataSimAirServingZones->Er) *
5970 2 : (1.0 - state.dataSimAirServingZones->Ep);
5971 : // save Fa Fb and Fc for standard 62.1 report
5972 2 : state.dataSize->FaByZoneCool(TermUnitSizingIndex) = state.dataSimAirServingZones->Fa;
5973 2 : state.dataSize->FbByZoneCool(TermUnitSizingIndex) = state.dataSimAirServingZones->Fb;
5974 2 : state.dataSize->FcByZoneCool(TermUnitSizingIndex) = state.dataSimAirServingZones->Fc;
5975 :
5976 : // Calc zone ventilation efficiency
5977 2 : if (state.dataSimAirServingZones->Fa > 0.0) {
5978 2 : SysCoolingEv =
5979 2 : 1.0 +
5980 4 : state.dataSimAirServingZones->Xs * state.dataSimAirServingZones->Fb / state.dataSimAirServingZones->Fa -
5981 4 : state.dataSimAirServingZones->ZoneOAFrac * state.dataSimAirServingZones->Ep *
5982 4 : state.dataSimAirServingZones->Fc / state.dataSimAirServingZones->Fa;
5983 : } else {
5984 0 : SysCoolingEv = 1.0;
5985 : }
5986 : } else {
5987 : // single-path ventilation system
5988 68 : SysCoolingEv = 1.0 + state.dataSimAirServingZones->Xs - state.dataSimAirServingZones->ZoneOAFrac;
5989 : // Apply ventilation efficiency limit; reset SysCoolingEv if necessary
5990 68 : LimitZoneVentEff(state, state.dataSimAirServingZones->Xs, VozClg, TermUnitSizingIndex, SysCoolingEv);
5991 : }
5992 70 : if (SysCoolingEv < state.dataSimAirServingZones->MinCoolingEvz)
5993 14 : state.dataSimAirServingZones->MinCoolingEvz = SysCoolingEv;
5994 70 : state.dataSize->EvzByZoneCoolPrev(TermUnitSizingIndex) = state.dataSize->EvzByZoneCool(TermUnitSizingIndex);
5995 70 : state.dataSize->EvzByZoneCool(TermUnitSizingIndex) = SysCoolingEv;
5996 70 : state.dataSize->VozSumClgBySys(AirLoopNum) +=
5997 70 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozClgByZone;
5998 : }
5999 80 : state.dataSize->VozSumClgBySys(AirLoopNum) += state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozClgByZone;
6000 : }
6001 :
6002 18 : if (state.dataSimAirServingZones->MinCoolingEvz > 0) {
6003 : // Std 62.1-2010, section 6.2.5.4: Eq. 6.6
6004 : // (However, I don't think people diversity can be done correctly in E+ Sizing so assuming D=1 in this
6005 : // equation
6006 : // Vou = Diversity*(Rp*Pz) + Ra*Az
6007 18 : state.dataSimAirServingZones->Vou = finalSysSizing.SysUncOA;
6008 18 : state.dataSimAirServingZones->Vot = state.dataSimAirServingZones->Vou / state.dataSimAirServingZones->MinCoolingEvz;
6009 18 : if (state.dataSimAirServingZones->Vot > state.dataSize->VotClgBySys(AirLoopNum)) {
6010 : // This might be the cooling design day so only update if Vot is larger than the previous
6011 16 : state.dataSize->VotClgBySys(AirLoopNum) = state.dataSimAirServingZones->Vot;
6012 16 : state.dataSize->XsBySysCool(AirLoopNum) = state.dataSimAirServingZones->Xs;
6013 16 : state.dataSize->EvzMinBySysCool(AirLoopNum) = state.dataSimAirServingZones->MinCoolingEvz;
6014 : } else {
6015 : // Restore EvzByZoneCool() since it was reset by the current (but not highest Vot) design day
6016 7 : for (int ZonesCooledNum = 1; ZonesCooledNum <= numZonesCooled; ++ZonesCooledNum) {
6017 : int TermUnitSizingIndex =
6018 5 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
6019 5 : state.dataSize->EvzByZoneCool(TermUnitSizingIndex) = state.dataSize->EvzByZoneCoolPrev(TermUnitSizingIndex);
6020 : }
6021 : }
6022 : }
6023 : }
6024 :
6025 : // heating
6026 20 : sysSizing.DesHeatVolFlow = sysSizing.NonCoinHeatMassFlow / state.dataEnvrn->StdRhoAir;
6027 20 : if (sysSizing.DesHeatVolFlow > 0) {
6028 20 : OutAirFrac = sysSizing.DesOutAirVolFlow / sysSizing.DesHeatVolFlow;
6029 : } else {
6030 0 : OutAirFrac = 0.0;
6031 : }
6032 20 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
6033 :
6034 20 : if (sysSizing.DesHeatVolFlow > 0) {
6035 20 : state.dataSimAirServingZones->Xs = min(1.0, finalSysSizing.SysUncOA / sysSizing.DesHeatVolFlow);
6036 : } else {
6037 0 : state.dataSimAirServingZones->Xs = 0.0;
6038 : }
6039 20 : if (finalSysSizing.OAAutoSized && sysSizing.DesHeatVolFlow > 0) {
6040 18 : int numZonesHeated = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
6041 18 : state.dataSimAirServingZones->MinHeatingEvz = 1.0;
6042 18 : state.dataSize->VozSumHtgBySys(AirLoopNum) = 0.0;
6043 18 : if (numZonesHeated > 0) {
6044 0 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= numZonesHeated; ++ZonesHeatedNum) {
6045 0 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(ZonesHeatedNum);
6046 0 : MatchingCooledZoneNum = FindNumberInList(
6047 0 : TermUnitSizingIndex, state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex, NumZonesCooled);
6048 0 : if (MatchingCooledZoneNum == 0) {
6049 : // Zone air secondary recirculation fraction
6050 0 : state.dataSimAirServingZones->Er =
6051 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneSecondaryRecirculation;
6052 0 : state.dataSimAirServingZones->Ep =
6053 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZonePrimaryAirFractionHtg;
6054 0 : state.dataSimAirServingZones->ZoneOAFrac =
6055 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZpzHtgByZone;
6056 0 : state.dataSimAirServingZones->ZoneEz =
6057 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating;
6058 0 : if (finalSysSizing.SystemOAMethod == SysOAMethod::SP) { // 62.1 simplified procedure
6059 0 : if (state.dataSize->DBySys(AirLoopNum) < 0.60) {
6060 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = 0.88 * state.dataSize->DBySys(AirLoopNum) + 0.22;
6061 : } else {
6062 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = 0.75;
6063 : }
6064 0 : state.dataSimAirServingZones->MinHeatingEvz = state.dataSize->EvzByZoneHeat(TermUnitSizingIndex);
6065 : } else {
6066 0 : if (state.dataSimAirServingZones->Er > 0.0) {
6067 : // multi-path ventilation system using VRP
6068 0 : state.dataSimAirServingZones->Fa =
6069 0 : state.dataSimAirServingZones->Ep +
6070 0 : (1.0 - state.dataSimAirServingZones->Ep) * state.dataSimAirServingZones->Er;
6071 0 : state.dataSimAirServingZones->Fb = state.dataSimAirServingZones->Ep;
6072 0 : state.dataSimAirServingZones->Fc = 1.0 - (1.0 - state.dataSimAirServingZones->ZoneEz) *
6073 0 : (1.0 - state.dataSimAirServingZones->Er) *
6074 0 : (1.0 - state.dataSimAirServingZones->Ep);
6075 :
6076 : // Calc zone ventilation efficiency
6077 0 : if (state.dataSimAirServingZones->Fa > 0.0) {
6078 0 : SysHeatingEv = 1.0 +
6079 0 : state.dataSimAirServingZones->Xs * state.dataSimAirServingZones->Fb /
6080 0 : state.dataSimAirServingZones->Fa -
6081 0 : state.dataSimAirServingZones->ZoneOAFrac * state.dataSimAirServingZones->Ep *
6082 0 : state.dataSimAirServingZones->Fc / state.dataSimAirServingZones->Fa;
6083 : } else {
6084 0 : SysHeatingEv = 1.0;
6085 : }
6086 : } else {
6087 : // single-path ventilation system
6088 0 : SysHeatingEv = 1.0 + state.dataSimAirServingZones->Xs - state.dataSimAirServingZones->ZoneOAFrac;
6089 : }
6090 : }
6091 : }
6092 0 : if (finalSysSizing.SystemOAMethod == SysOAMethod::SP) { // 62.1 simplified procedure
6093 0 : state.dataSize->VozSumHtgBySys(AirLoopNum) +=
6094 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozHtgByZone;
6095 : } else {
6096 0 : if (SysHeatingEv < state.dataSimAirServingZones->MinHeatingEvz)
6097 0 : state.dataSimAirServingZones->MinHeatingEvz = SysHeatingEv;
6098 0 : state.dataSize->EvzByZoneHeatPrev(TermUnitSizingIndex) =
6099 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex); // Save previous EvzByZoneHeat
6100 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = SysHeatingEv;
6101 0 : state.dataSize->VozSumHtgBySys(AirLoopNum) +=
6102 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozHtgByZone;
6103 : }
6104 : }
6105 : } else {
6106 18 : int numZonesCooled = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled;
6107 98 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= numZonesCooled; ++ZonesHeatedNum) {
6108 80 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesHeatedNum);
6109 : // Zone air secondary recirculation fraction
6110 80 : state.dataSimAirServingZones->Er =
6111 80 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneSecondaryRecirculation;
6112 80 : state.dataSimAirServingZones->Ep =
6113 80 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZonePrimaryAirFractionHtg;
6114 80 : state.dataSimAirServingZones->ZoneOAFrac = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZpzHtgByZone;
6115 80 : state.dataSimAirServingZones->ZoneEz = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneADEffHeating;
6116 80 : if (finalSysSizing.SystemOAMethod == SysOAMethod::SP) { // 62.1 simplified procedure
6117 10 : if (state.dataSize->DBySys(AirLoopNum) < 0.60) {
6118 4 : state.dataSize->EvzByZoneCool(TermUnitSizingIndex) = 0.88 * state.dataSize->DBySys(AirLoopNum) + 0.22;
6119 : } else {
6120 6 : state.dataSize->EvzByZoneCool(TermUnitSizingIndex) = 0.75;
6121 : }
6122 10 : state.dataSimAirServingZones->MinCoolingEvz = state.dataSize->EvzByZoneCool(TermUnitSizingIndex);
6123 : } else {
6124 70 : if (state.dataSimAirServingZones->Er > 0.0) {
6125 : // multi-path ventilation system using VRP
6126 2 : state.dataSimAirServingZones->Fa =
6127 4 : state.dataSimAirServingZones->Ep +
6128 2 : (1.0 - state.dataSimAirServingZones->Ep) * state.dataSimAirServingZones->Er;
6129 2 : state.dataSimAirServingZones->Fb = state.dataSimAirServingZones->Ep;
6130 6 : state.dataSimAirServingZones->Fc = 1.0 - (1.0 - state.dataSimAirServingZones->ZoneEz) *
6131 4 : (1.0 - state.dataSimAirServingZones->Er) *
6132 2 : (1.0 - state.dataSimAirServingZones->Ep);
6133 :
6134 : // Calc zone ventilation efficiency
6135 2 : if (state.dataSimAirServingZones->Fa > 0.0) {
6136 4 : SysHeatingEv = 1.0 +
6137 4 : state.dataSimAirServingZones->Xs * state.dataSimAirServingZones->Fb /
6138 2 : state.dataSimAirServingZones->Fa -
6139 4 : state.dataSimAirServingZones->ZoneOAFrac * state.dataSimAirServingZones->Ep *
6140 4 : state.dataSimAirServingZones->Fc / state.dataSimAirServingZones->Fa;
6141 : } else {
6142 0 : SysHeatingEv = 1.0;
6143 : }
6144 : } else {
6145 : // single-path ventilation system
6146 68 : SysHeatingEv = 1.0 + state.dataSimAirServingZones->Xs - state.dataSimAirServingZones->ZoneOAFrac;
6147 : }
6148 70 : if (SysHeatingEv < state.dataSimAirServingZones->MinHeatingEvz)
6149 12 : state.dataSimAirServingZones->MinHeatingEvz = SysHeatingEv;
6150 70 : state.dataSize->EvzByZoneHeatPrev(TermUnitSizingIndex) =
6151 70 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex); // Save previous EvzByZoneHeat
6152 70 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = SysHeatingEv;
6153 : }
6154 80 : state.dataSize->VozSumHtgBySys(AirLoopNum) +=
6155 80 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozHtgByZone;
6156 : }
6157 : }
6158 :
6159 18 : if (state.dataSimAirServingZones->MinHeatingEvz > 0) {
6160 : // Std 62.1-2010, section 6.2.5.4: Eq. 6.6
6161 : // (However, I don't think people diversity can be done correctly in E+ Sizing so assuming D=1 in this
6162 : // equation
6163 : // Vou = Diversity*(Rp*Pz) + Ra*Az
6164 18 : state.dataSimAirServingZones->Vou = finalSysSizing.SysUncOA;
6165 18 : state.dataSimAirServingZones->Vot = state.dataSimAirServingZones->Vou / state.dataSimAirServingZones->MinHeatingEvz;
6166 18 : if (state.dataSimAirServingZones->Vot > state.dataSize->VotHtgBySys(AirLoopNum)) {
6167 : // This might be the cooling design day so only update if Vot is larger than the previous
6168 9 : state.dataSize->VotHtgBySys(AirLoopNum) = state.dataSimAirServingZones->Vot;
6169 9 : state.dataSize->XsBySysHeat(AirLoopNum) = state.dataSimAirServingZones->Xs;
6170 9 : state.dataSize->EvzMinBySysHeat(AirLoopNum) = state.dataSimAirServingZones->MinHeatingEvz;
6171 : } else {
6172 : // Restore EvzByZoneHeat() since it was just reset by the current (but not highest Vot) design day
6173 : // This kludge is probably because inside EndDay block and code gets called for each design day.
6174 9 : if (numZonesHeated > 0) {
6175 0 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= numZonesHeated; ++ZonesHeatedNum) {
6176 : int TermUnitSizingIndex =
6177 0 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(ZonesHeatedNum);
6178 0 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = state.dataSize->EvzByZoneHeatPrev(TermUnitSizingIndex);
6179 : }
6180 : } else {
6181 49 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesCooled; ++ZonesHeatedNum) {
6182 : int TermUnitSizingIndex =
6183 40 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesHeatedNum);
6184 40 : state.dataSize->EvzByZoneHeat(TermUnitSizingIndex) = state.dataSize->EvzByZoneHeatPrev(TermUnitSizingIndex);
6185 : }
6186 : }
6187 : }
6188 : }
6189 : }
6190 : } else { // error
6191 : }
6192 :
6193 1756 : sysSizing.DesMainVolFlow = max(sysSizing.DesCoolVolFlow, sysSizing.DesHeatVolFlow);
6194 : // this should also be as least as big as is needed for Vot
6195 1756 : } break;
6196 0 : default:
6197 0 : break;
6198 : }
6199 :
6200 : // If the ventilation was autosized using the ASHRAE VRP method, then the design zone and system ventilation values
6201 : // must be based on the larger of the cooling or heating OA
6202 3814 : if (finalSysSizing.OAAutoSized &&
6203 3722 : (finalSysSizing.SystemOAMethod == SysOAMethod::VRP || finalSysSizing.SystemOAMethod == SysOAMethod::SP)) {
6204 18 : Real64 VotMax = max(state.dataSize->VotClgBySys(AirLoopNum), state.dataSize->VotHtgBySys(AirLoopNum));
6205 :
6206 : // Reset the system level ventilation to the larger of the system-level cooling or heating Vot
6207 18 : finalSysSizing.DesOutAirVolFlow = VotMax;
6208 18 : state.dataSize->CalcSysSizing(AirLoopNum).DesOutAirVolFlow = VotMax;
6209 :
6210 : // Reset the zone level ventilation to the larger of the zone-level cooling or heating Voz
6211 : // Loop through cooled zones and heated zones - ok if there's overlap
6212 98 : for (int zoneNum = 1; zoneNum <= NumZonesCooled; ++zoneNum) {
6213 80 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(zoneNum);
6214 80 : Real64 VozMax = max(state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozClgByZone,
6215 160 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozHtgByZone);
6216 80 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).MinOA = VozMax;
6217 : }
6218 18 : for (int zoneNum = 1; zoneNum <= NumZonesHeated; ++zoneNum) {
6219 0 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(zoneNum);
6220 0 : Real64 VozMax = max(state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozClgByZone,
6221 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).VozHtgByZone);
6222 0 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).MinOA = VozMax;
6223 : }
6224 : }
6225 695 : }
6226 695 : } break;
6227 329 : case DataGlobalConstants::CallIndicator::EndSysSizingCalc: {
6228 : // Correct the zone return temperature in FinalZoneSizing for the case of induction units. The calc in
6229 : // ZoneEquipmentManager assumes all the air entering the zone goes into the return node.
6230 3820 : for (int CtrlZoneNum = 1; CtrlZoneNum <= state.dataGlobal->NumOfZones; ++CtrlZoneNum) {
6231 3491 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).IsControlled) continue;
6232 : // Use first non-zero airdistunit for now, if there is one
6233 3050 : termunitsizingtempfrac = 1.0;
6234 3050 : int TermUnitSizingIndex = 0;
6235 3050 : for (int InletNode = 1; InletNode <= state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).NumInletNodes; ++InletNode) {
6236 3050 : TermUnitSizingIndex = state.dataZoneEquip->ZoneEquipConfig(CtrlZoneNum).AirDistUnitCool(InletNode).TermUnitSizingIndex;
6237 3050 : if (TermUnitSizingIndex == 0) continue;
6238 3050 : termunitsizingtemp = (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat);
6239 3050 : termunitsizingtempfrac = (1.0 / termunitsizingtemp);
6240 3050 : if (TermUnitSizingIndex > 0) break;
6241 : }
6242 3050 : if (TermUnitSizingIndex == 0) continue; // Skip this if there are no terminal units
6243 6100 : RetTempRise = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneRetTempAtCoolPeak -
6244 3050 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneTempAtCoolPeak;
6245 3050 : if (RetTempRise > 0.01) {
6246 : // avoid possible compiler bug
6247 : // FinalZoneSizing(CtrlZoneNum)%ZoneRetTempAtCoolPeak = &
6248 : // FinalZoneSizing(CtrlZoneNum)%ZoneTempAtCoolPeak + RetTempRise * &
6249 : // (1.0d0/(1.0d0+TermUnitSizing(CtrlZoneNum)%InducRat))
6250 1232 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneRetTempAtCoolPeak =
6251 1232 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneTempAtCoolPeak + RetTempRise * termunitsizingtempfrac;
6252 : }
6253 6100 : RetTempRise = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneRetTempAtHeatPeak -
6254 3050 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneTempAtHeatPeak;
6255 3050 : if (RetTempRise > 0.01) {
6256 : // avoid possible compiler bug
6257 : // FinalZoneSizing(CtrlZoneNum)%ZoneRetTempAtHeatPeak = &
6258 : // FinalZoneSizing(CtrlZoneNum)%ZoneTempAtHeatPeak + RetTempRise * &
6259 : // (1.0d0/(1.0d0+TermUnitSizing(CtrlZoneNum)%InducRat))
6260 737 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneRetTempAtHeatPeak =
6261 737 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneTempAtHeatPeak + RetTempRise * termunitsizingtempfrac;
6262 : }
6263 376106 : for (TimeStepIndex = 1; TimeStepIndex <= numOfTimeStepInDay; ++TimeStepIndex) {
6264 746112 : RetTempRise = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).CoolZoneRetTempSeq(TimeStepIndex) -
6265 373056 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).CoolZoneTempSeq(TimeStepIndex);
6266 373056 : if (RetTempRise > 0.01) {
6267 : // avoid possible compiler bug
6268 : // FinalZoneSizing(CtrlZoneNum)%CoolZoneRetTempSeq(TimeStepIndex) = &
6269 : // FinalZoneSizing(CtrlZoneNum)%CoolZoneTempSeq(TimeStepIndex) + RetTempRise * &
6270 : // (1.0d0/(1.0d0+TermUnitSizing(CtrlZoneNum)%InducRat))
6271 126407 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).CoolZoneRetTempSeq(TimeStepIndex) =
6272 252814 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).CoolZoneTempSeq(TimeStepIndex) +
6273 126407 : RetTempRise * termunitsizingtempfrac;
6274 : }
6275 746112 : RetTempRise = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).HeatZoneRetTempSeq(TimeStepIndex) -
6276 373056 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).HeatZoneTempSeq(TimeStepIndex);
6277 373056 : if (RetTempRise > 0.01) {
6278 : // avoid possible compiler bug
6279 : // FinalZoneSizing(CtrlZoneNum)%HeatZoneRetTempSeq(TimeStepIndex) = &
6280 : // FinalZoneSizing(CtrlZoneNum)%HeatZoneTempSeq(TimeStepIndex) + RetTempRise * &
6281 : // (1.0d0/(1.0d0+TermUnitSizing(CtrlZoneNum)%InducRat))
6282 111371 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).HeatZoneRetTempSeq(TimeStepIndex) =
6283 222742 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).HeatZoneTempSeq(TimeStepIndex) +
6284 111371 : RetTempRise * termunitsizingtempfrac;
6285 : }
6286 : }
6287 : }
6288 :
6289 : // Get final design flows
6290 1254 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
6291 925 : state.dataSize->SensCoolCapTemp(AirLoopNum) = 0.0;
6292 925 : state.dataSize->TotCoolCapTemp(AirLoopNum) = 0.0;
6293 :
6294 : // For coincident sizing, loop over design days and pick out the largest central heating amd
6295 : // cooling flow rates and associated data
6296 :
6297 2871 : for (DDNum = 1; DDNum <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++DDNum) {
6298 1946 : auto &sysSizing = state.dataSize->SysSizing(DDNum, AirLoopNum);
6299 1946 : if (sysSizing.SensCoolCap > state.dataSize->SensCoolCapTemp(AirLoopNum)) {
6300 939 : state.dataSize->SysSizPeakDDNum(AirLoopNum).SensCoolPeakDD = DDNum;
6301 939 : state.dataSize->SysSizPeakDDNum(AirLoopNum).cSensCoolPeakDDDate = state.dataSize->DesDayWeath(DDNum).DateString;
6302 939 : state.dataSize->SensCoolCapTemp(AirLoopNum) = sysSizing.SensCoolCap;
6303 939 : if (sysSizing.coolingPeakLoad == DataSizing::PeakLoad::SensibleCooling) {
6304 929 : state.dataSize->CalcSysSizing(AirLoopNum).DesCoolVolFlow = sysSizing.DesCoolVolFlow;
6305 929 : state.dataSize->CalcSysSizing(AirLoopNum).CoolDesDay = sysSizing.CoolDesDay;
6306 : // state.dataSize->CalcSysSizing( AirLoopNum ).CoinCoolMassFlow = SysSizing( DDNum, AirLoopNum ).CoinCoolMassFlow;
6307 929 : state.dataSize->CalcSysSizing(AirLoopNum).MassFlowAtCoolPeak = sysSizing.MassFlowAtCoolPeak;
6308 929 : state.dataSize->CalcSysSizing(AirLoopNum).SensCoolCap = sysSizing.SensCoolCap;
6309 929 : state.dataSize->CalcSysSizing(AirLoopNum).TotCoolCap = sysSizing.TotCoolCap;
6310 929 : state.dataSize->CalcSysSizing(AirLoopNum).CoolFlowSeq = sysSizing.CoolFlowSeq;
6311 929 : state.dataSize->CalcSysSizing(AirLoopNum).SumZoneCoolLoadSeq = sysSizing.SumZoneCoolLoadSeq;
6312 929 : state.dataSize->CalcSysSizing(AirLoopNum).CoolZoneAvgTempSeq = sysSizing.CoolZoneAvgTempSeq;
6313 929 : state.dataSize->CalcSysSizing(AirLoopNum).SensCoolCapSeq = sysSizing.SensCoolCapSeq;
6314 929 : state.dataSize->CalcSysSizing(AirLoopNum).TotCoolCapSeq = sysSizing.TotCoolCapSeq;
6315 929 : state.dataSize->CalcSysSizing(AirLoopNum).MixTempAtCoolPeak = sysSizing.MixTempAtCoolPeak;
6316 929 : state.dataSize->CalcSysSizing(AirLoopNum).RetTempAtCoolPeak = sysSizing.RetTempAtCoolPeak;
6317 929 : state.dataSize->CalcSysSizing(AirLoopNum).MixHumRatAtCoolPeak = sysSizing.MixHumRatAtCoolPeak;
6318 929 : state.dataSize->CalcSysSizing(AirLoopNum).RetHumRatAtCoolPeak = sysSizing.RetHumRatAtCoolPeak;
6319 929 : state.dataSize->CalcSysSizing(AirLoopNum).OutTempAtCoolPeak = sysSizing.OutTempAtCoolPeak;
6320 929 : state.dataSize->CalcSysSizing(AirLoopNum).OutHumRatAtCoolPeak = sysSizing.OutHumRatAtCoolPeak;
6321 929 : state.dataSize->CalcSysSizing(AirLoopNum).SysCoolRetTempSeq = sysSizing.SysCoolRetTempSeq;
6322 929 : state.dataSize->CalcSysSizing(AirLoopNum).SysCoolRetHumRatSeq = sysSizing.SysCoolRetHumRatSeq;
6323 929 : state.dataSize->CalcSysSizing(AirLoopNum).SysCoolOutTempSeq = sysSizing.SysCoolOutTempSeq;
6324 929 : state.dataSize->CalcSysSizing(AirLoopNum).SysCoolOutHumRatSeq = sysSizing.SysCoolOutHumRatSeq;
6325 929 : state.dataSize->CalcSysSizing(AirLoopNum).SysDOASHeatAddSeq = sysSizing.SysDOASHeatAddSeq;
6326 929 : state.dataSize->CalcSysSizing(AirLoopNum).SysDOASLatAddSeq = sysSizing.SysDOASLatAddSeq;
6327 929 : state.dataSize->CalcSysSizing(AirLoopNum).SysCoolCoinSpaceSens = sysSizing.SysCoolCoinSpaceSens;
6328 929 : state.dataSize->CalcSysSizing(AirLoopNum).SysDesCoolLoad = sysSizing.SysDesCoolLoad;
6329 929 : state.dataSize->CalcSysSizing(AirLoopNum).SysCoolLoadTimeStepPk = sysSizing.SysCoolLoadTimeStepPk;
6330 : }
6331 : }
6332 :
6333 1946 : if (sysSizing.TotCoolCap > state.dataSize->TotCoolCapTemp(AirLoopNum)) {
6334 955 : state.dataSize->SysSizPeakDDNum(AirLoopNum).TotCoolPeakDD = DDNum;
6335 955 : state.dataSize->SysSizPeakDDNum(AirLoopNum).cTotCoolPeakDDDate = state.dataSize->DesDayWeath(DDNum).DateString;
6336 955 : state.dataSize->TotCoolCapTemp(AirLoopNum) = sysSizing.TotCoolCap;
6337 955 : if (sysSizing.coolingPeakLoad == DataSizing::PeakLoad::TotalCooling) {
6338 14 : state.dataSize->CalcSysSizing(AirLoopNum).DesCoolVolFlow = sysSizing.DesCoolVolFlow;
6339 14 : state.dataSize->CalcSysSizing(AirLoopNum).CoolDesDay = sysSizing.CoolDesDay;
6340 : // state.dataSize->CalcSysSizing( AirLoopNum ).CoinCoolMassFlow = SysSizing( DDNum, AirLoopNum ).CoinCoolMassFlow;
6341 14 : state.dataSize->CalcSysSizing(AirLoopNum).MassFlowAtCoolPeak = sysSizing.MassFlowAtCoolPeak;
6342 14 : state.dataSize->CalcSysSizing(AirLoopNum).SensCoolCap = sysSizing.SensCoolCap;
6343 14 : state.dataSize->CalcSysSizing(AirLoopNum).TotCoolCap = sysSizing.TotCoolCap;
6344 14 : state.dataSize->CalcSysSizing(AirLoopNum).CoolFlowSeq = sysSizing.CoolFlowSeq;
6345 14 : state.dataSize->CalcSysSizing(AirLoopNum).SumZoneCoolLoadSeq = sysSizing.SumZoneCoolLoadSeq;
6346 14 : state.dataSize->CalcSysSizing(AirLoopNum).CoolZoneAvgTempSeq = sysSizing.CoolZoneAvgTempSeq;
6347 14 : state.dataSize->CalcSysSizing(AirLoopNum).SensCoolCapSeq = sysSizing.SensCoolCapSeq;
6348 14 : state.dataSize->CalcSysSizing(AirLoopNum).TotCoolCapSeq = sysSizing.TotCoolCapSeq;
6349 14 : state.dataSize->CalcSysSizing(AirLoopNum).MixTempAtCoolPeak = sysSizing.MixTempAtCoolPeak;
6350 14 : state.dataSize->CalcSysSizing(AirLoopNum).RetTempAtCoolPeak = sysSizing.RetTempAtCoolPeak;
6351 14 : state.dataSize->CalcSysSizing(AirLoopNum).MixHumRatAtCoolPeak = sysSizing.MixHumRatAtCoolPeak;
6352 14 : state.dataSize->CalcSysSizing(AirLoopNum).RetHumRatAtCoolPeak = sysSizing.RetHumRatAtCoolPeak;
6353 14 : state.dataSize->CalcSysSizing(AirLoopNum).OutTempAtCoolPeak = sysSizing.OutTempAtCoolPeak;
6354 14 : state.dataSize->CalcSysSizing(AirLoopNum).OutHumRatAtCoolPeak = sysSizing.OutHumRatAtCoolPeak;
6355 14 : state.dataSize->CalcSysSizing(AirLoopNum).SysCoolRetTempSeq = sysSizing.SysCoolRetTempSeq;
6356 14 : state.dataSize->CalcSysSizing(AirLoopNum).SysCoolRetHumRatSeq = sysSizing.SysCoolRetHumRatSeq;
6357 14 : state.dataSize->CalcSysSizing(AirLoopNum).SysCoolOutTempSeq = sysSizing.SysCoolOutTempSeq;
6358 14 : state.dataSize->CalcSysSizing(AirLoopNum).SysCoolOutHumRatSeq = sysSizing.SysCoolOutHumRatSeq;
6359 14 : state.dataSize->CalcSysSizing(AirLoopNum).SysDOASHeatAddSeq = sysSizing.SysDOASHeatAddSeq;
6360 14 : state.dataSize->CalcSysSizing(AirLoopNum).SysDOASLatAddSeq = sysSizing.SysDOASLatAddSeq;
6361 : }
6362 955 : state.dataSize->CalcSysSizing(AirLoopNum).SysCoolCoinSpaceSens = sysSizing.SysCoolCoinSpaceSens;
6363 : }
6364 :
6365 1946 : if (sysSizing.CoinCoolMassFlow > state.dataSize->CalcSysSizing(AirLoopNum).CoinCoolMassFlow) {
6366 1768 : state.dataSize->CalcSysSizing(AirLoopNum).CoinCoolMassFlow = sysSizing.CoinCoolMassFlow;
6367 1768 : state.dataSize->SysSizPeakDDNum(AirLoopNum).CoolFlowPeakDD = DDNum;
6368 1768 : state.dataSize->SysSizPeakDDNum(AirLoopNum).cCoolFlowPeakDDDate = state.dataSize->DesDayWeath(DDNum).DateString;
6369 : }
6370 :
6371 1946 : if (sysSizing.HeatCap > state.dataSize->CalcSysSizing(AirLoopNum).HeatCap) {
6372 916 : state.dataSize->SysSizPeakDDNum(AirLoopNum).HeatPeakDD = DDNum;
6373 916 : state.dataSize->SysSizPeakDDNum(AirLoopNum).cHeatPeakDDDate = state.dataSize->DesDayWeath(DDNum).DateString;
6374 916 : state.dataSize->CalcSysSizing(AirLoopNum).DesHeatVolFlow = sysSizing.DesHeatVolFlow;
6375 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatDesDay = sysSizing.HeatDesDay;
6376 916 : state.dataSize->CalcSysSizing(AirLoopNum).CoinHeatMassFlow = sysSizing.CoinHeatMassFlow;
6377 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatCap = sysSizing.HeatCap;
6378 916 : state.dataSize->CalcSysSizing(AirLoopNum).PreheatCap = sysSizing.PreheatCap;
6379 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatFlowSeq = sysSizing.HeatFlowSeq;
6380 916 : state.dataSize->CalcSysSizing(AirLoopNum).SumZoneHeatLoadSeq = sysSizing.SumZoneHeatLoadSeq;
6381 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatCapSeq = sysSizing.HeatCapSeq;
6382 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatZoneAvgTempSeq = sysSizing.HeatZoneAvgTempSeq;
6383 916 : state.dataSize->CalcSysSizing(AirLoopNum).PreheatCapSeq = sysSizing.PreheatCapSeq;
6384 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatMixTemp = sysSizing.HeatMixTemp;
6385 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatRetTemp = sysSizing.HeatRetTemp;
6386 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatMixHumRat = sysSizing.HeatMixHumRat;
6387 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatRetHumRat = sysSizing.HeatRetHumRat;
6388 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatOutTemp = sysSizing.HeatOutTemp;
6389 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatOutHumRat = sysSizing.HeatOutHumRat;
6390 916 : state.dataSize->CalcSysSizing(AirLoopNum).SysHeatRetTempSeq = sysSizing.SysHeatRetTempSeq;
6391 916 : state.dataSize->CalcSysSizing(AirLoopNum).SysHeatRetHumRatSeq = sysSizing.SysHeatRetHumRatSeq;
6392 916 : state.dataSize->CalcSysSizing(AirLoopNum).SysHeatOutTempSeq = sysSizing.SysHeatOutTempSeq;
6393 916 : state.dataSize->CalcSysSizing(AirLoopNum).SysHeatOutHumRatSeq = sysSizing.SysHeatOutHumRatSeq;
6394 :
6395 916 : state.dataSize->CalcSysSizing(AirLoopNum).SysHeatCoilTimeStepPk = sysSizing.SysHeatCoilTimeStepPk;
6396 :
6397 916 : state.dataSize->CalcSysSizing(AirLoopNum).SysHeatAirTimeStepPk = sysSizing.SysHeatAirTimeStepPk;
6398 916 : state.dataSize->CalcSysSizing(AirLoopNum).HeatDDNum = DDNum;
6399 916 : state.dataSize->CalcSysSizing(AirLoopNum).SysHeatCoinSpaceSens = sysSizing.SysHeatCoinSpaceSens;
6400 916 : state.dataSize->CalcSysSizing(AirLoopNum).SysDesHeatLoad = sysSizing.SysDesHeatLoad;
6401 916 : state.dataSize->CalcSysSizing(AirLoopNum).SysHeatLoadTimeStepPk = sysSizing.SysHeatLoadTimeStepPk;
6402 : }
6403 : }
6404 :
6405 925 : state.dataSize->CalcSysSizing(AirLoopNum).DesMainVolFlow =
6406 925 : max(state.dataSize->CalcSysSizing(AirLoopNum).DesCoolVolFlow, state.dataSize->CalcSysSizing(AirLoopNum).DesHeatVolFlow);
6407 :
6408 : // For noncoincident sizing, find the max heat and cool mass flow for each zone over all the
6409 : // design days. Then calculate the associated heating and cooling capacities.
6410 :
6411 925 : int NumZonesCooled = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled;
6412 925 : int NumZonesHeated = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
6413 925 : SysCoolRetTemp = 0.0;
6414 925 : OutAirFrac = 0.0;
6415 925 : SysCoolMixTemp = 0.0;
6416 925 : SysSensCoolCap = 0.0;
6417 925 : SysTotCoolCap = 0.0;
6418 925 : CoolTimeStepNum = 0;
6419 925 : CoolDDNum = 0;
6420 925 : OutAirTemp = 0.0;
6421 925 : OutAirHumRat = 0.0;
6422 925 : SysCoolMixHumRat = 0.0;
6423 925 : SysCoolRetHumRat = 0.0;
6424 925 : SysCoolOutTemp = 0.0;
6425 925 : SysCoolOutHumRat = 0.0;
6426 :
6427 3833 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) { // loop over cooled zones
6428 2908 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
6429 2908 : auto &termUnitSizing = state.dataSize->TermUnitSizing(TermUnitSizingIndex);
6430 : // save the system cooling supply air temp
6431 2908 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesCoolCoilInTempTU =
6432 2908 : state.dataSize->CalcSysSizing(AirLoopNum).CoolSupTemp;
6433 : // save the system cooling supply air hum rat
6434 2908 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesCoolCoilInHumRatTU =
6435 2908 : state.dataSize->CalcSysSizing(AirLoopNum).CoolSupHumRat;
6436 2908 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesCoolMassFlow <= 0.0) continue;
6437 2908 : Real64 coolMassFlow = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex)
6438 2908 : .DesCoolMassFlow; // already scaled for term unit sizing in Updatestate.dataSize->TermUnitFinalZoneSizing
6439 2908 : state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow += coolMassFlow / (1.0 + termUnitSizing.InducRat);
6440 5816 : SysCoolRetTemp += state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneRetTempAtCoolPeak * coolMassFlow /
6441 2908 : (1.0 + termUnitSizing.InducRat);
6442 5816 : SysCoolRetHumRat += state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneHumRatAtCoolPeak * coolMassFlow /
6443 2908 : (1.0 + termUnitSizing.InducRat);
6444 2908 : CoolDDNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).CoolDDNum;
6445 2908 : CoolTimeStepNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).TimeStepNumAtCoolMax;
6446 2908 : OutAirTemp += state.dataSize->DesDayWeath(CoolDDNum).Temp(CoolTimeStepNum) * coolMassFlow / (1.0 + termUnitSizing.InducRat);
6447 2908 : OutAirHumRat += state.dataSize->DesDayWeath(CoolDDNum).HumRat(CoolTimeStepNum) * coolMassFlow / (1.0 + termUnitSizing.InducRat);
6448 : }
6449 925 : if (state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow > 0.0) {
6450 925 : SysCoolRetTemp /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow;
6451 925 : SysCoolRetHumRat /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow;
6452 925 : OutAirTemp /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow;
6453 925 : OutAirHumRat /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow;
6454 925 : SysCoolOutTemp = OutAirTemp;
6455 925 : SysCoolOutHumRat = OutAirHumRat;
6456 925 : RhoAir = state.dataEnvrn->StdRhoAir;
6457 925 : if (state.dataSize->CalcSysSizing(AirLoopNum).CoolOAOption == MinOA) {
6458 1776 : OutAirFrac = RhoAir * state.dataSize->CalcSysSizing(AirLoopNum).DesOutAirVolFlow /
6459 888 : state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow;
6460 888 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
6461 : } else {
6462 37 : OutAirFrac = 1.0;
6463 : }
6464 925 : SysCoolMixTemp = OutAirTemp * OutAirFrac + SysCoolRetTemp * (1.0 - OutAirFrac);
6465 925 : SysCoolMixHumRat = OutAirHumRat * OutAirFrac + SysCoolRetHumRat * (1.0 - OutAirFrac);
6466 1850 : SysSensCoolCap = PsyCpAirFnW(DataPrecisionGlobals::constant_zero) * state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow *
6467 925 : (SysCoolMixTemp - state.dataSize->CalcSysSizing(AirLoopNum).CoolSupTemp);
6468 925 : SysSensCoolCap = max(0.0, SysSensCoolCap);
6469 1850 : SysTotCoolCap = state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow *
6470 1850 : (PsyHFnTdbW(SysCoolMixTemp, SysCoolMixHumRat) - PsyHFnTdbW(state.dataSize->CalcSysSizing(AirLoopNum).CoolSupTemp,
6471 925 : state.dataSize->CalcSysSizing(AirLoopNum).CoolSupHumRat));
6472 925 : SysTotCoolCap = max(0.0, SysTotCoolCap);
6473 : }
6474 :
6475 925 : SysHeatRetTemp = 0.0;
6476 925 : OutAirFrac = 0.0;
6477 925 : SysHeatMixTemp = 0.0;
6478 925 : SysHeatCap = 0.0;
6479 925 : HeatTimeStepNum = 0;
6480 925 : HeatDDNum = 0;
6481 925 : OutAirTemp = 0.0;
6482 925 : OutAirHumRat = 0.0;
6483 925 : SysHeatMixHumRat = 0.0;
6484 925 : SysHeatRetHumRat = 0.0;
6485 925 : SysHeatOutTemp = 0.0;
6486 925 : SysHeatOutHumRat = 0.0;
6487 :
6488 925 : if (NumZonesHeated > 0) { // IF there are centrally heated zones
6489 :
6490 17 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesHeated; ++ZonesHeatedNum) { // loop over the heated zones
6491 14 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(ZonesHeatedNum);
6492 14 : auto &termUnitSizing = state.dataSize->TermUnitSizing(TermUnitSizingIndex);
6493 : // save the system heating supply air temp
6494 14 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesHeatCoilInTempTU =
6495 14 : state.dataSize->CalcSysSizing(AirLoopNum).HeatSupTemp;
6496 : // save the system heating supply air hum rat
6497 14 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesHeatCoilInHumRatTU =
6498 14 : state.dataSize->CalcSysSizing(AirLoopNum).HeatSupHumRat;
6499 14 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesHeatMassFlow <= 0.0) continue;
6500 : Real64 heatMassFlow =
6501 14 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex)
6502 14 : .DesHeatMassFlow; // already scaled for term unit sizing in Updatestate.dataSize->TermUnitFinalZoneSizing
6503 14 : state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow += heatMassFlow / (1.0 + termUnitSizing.InducRat);
6504 28 : SysHeatRetTemp += state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneRetTempAtHeatPeak * heatMassFlow /
6505 14 : (1.0 + termUnitSizing.InducRat);
6506 28 : SysHeatRetHumRat += state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneHumRatAtHeatPeak * heatMassFlow /
6507 14 : (1.0 + termUnitSizing.InducRat);
6508 14 : HeatDDNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).HeatDDNum;
6509 14 : HeatTimeStepNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).TimeStepNumAtHeatMax;
6510 14 : OutAirTemp += state.dataSize->DesDayWeath(HeatDDNum).Temp(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat);
6511 14 : OutAirHumRat += state.dataSize->DesDayWeath(HeatDDNum).HumRat(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat);
6512 : }
6513 3 : if (state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow > 0.0) {
6514 3 : SysHeatRetTemp /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow;
6515 3 : SysHeatRetHumRat /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow;
6516 3 : OutAirTemp /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow;
6517 3 : OutAirHumRat /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow;
6518 3 : SysHeatOutTemp = OutAirTemp;
6519 3 : SysHeatOutHumRat = OutAirHumRat;
6520 3 : RhoAir = state.dataEnvrn->StdRhoAir;
6521 3 : if (state.dataSize->CalcSysSizing(AirLoopNum).HeatOAOption == MinOA) {
6522 6 : OutAirFrac = RhoAir * state.dataSize->CalcSysSizing(AirLoopNum).DesOutAirVolFlow /
6523 3 : state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow;
6524 3 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
6525 : } else {
6526 0 : OutAirFrac = 1.0;
6527 : }
6528 3 : SysHeatMixTemp = OutAirTemp * OutAirFrac + SysHeatRetTemp * (1.0 - OutAirFrac);
6529 3 : SysHeatMixHumRat = OutAirHumRat * OutAirFrac + SysHeatRetHumRat * (1.0 - OutAirFrac);
6530 6 : SysHeatCap = PsyCpAirFnW(DataPrecisionGlobals::constant_zero) * state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow *
6531 3 : (state.dataSize->CalcSysSizing(AirLoopNum).HeatSupTemp - SysHeatMixTemp);
6532 3 : SysHeatCap = max(0.0, SysHeatCap);
6533 : }
6534 :
6535 : } else { // No centrally heated zones: use cooled zones
6536 :
6537 3816 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) { // loop over the cooled zones
6538 2894 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
6539 2894 : auto &termUnitSizing = state.dataSize->TermUnitSizing(TermUnitSizingIndex);
6540 : // save the system heating supply air temp
6541 2894 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesHeatCoilInTempTU =
6542 2894 : state.dataSize->CalcSysSizing(AirLoopNum).HeatSupTemp;
6543 : // save the system heating supply air hum rat
6544 2894 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesHeatCoilInHumRatTU =
6545 2894 : state.dataSize->CalcSysSizing(AirLoopNum).HeatSupHumRat;
6546 2894 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesHeatMassFlow <= 0.0) continue;
6547 : Real64 heatMassFlow =
6548 2886 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex)
6549 2886 : .DesHeatMassFlow; // already scaled for term unit sizing in Updatestate.dataSize->TermUnitFinalZoneSizing
6550 2886 : state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow += heatMassFlow / (1.0 + termUnitSizing.InducRat);
6551 5772 : SysHeatRetTemp += state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneRetTempAtHeatPeak * heatMassFlow /
6552 2886 : (1.0 + termUnitSizing.InducRat);
6553 5772 : SysHeatRetHumRat += state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).ZoneHumRatAtHeatPeak * heatMassFlow /
6554 2886 : (1.0 + termUnitSizing.InducRat);
6555 2886 : HeatDDNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).HeatDDNum;
6556 2886 : HeatTimeStepNum = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).TimeStepNumAtHeatMax;
6557 2886 : OutAirTemp += state.dataSize->DesDayWeath(HeatDDNum).Temp(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat);
6558 2886 : OutAirHumRat += state.dataSize->DesDayWeath(HeatDDNum).HumRat(HeatTimeStepNum) * heatMassFlow / (1.0 + termUnitSizing.InducRat);
6559 : }
6560 922 : if (state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow > 0.0) {
6561 918 : SysHeatRetTemp /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow;
6562 918 : SysHeatRetHumRat /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow;
6563 918 : OutAirTemp /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow;
6564 918 : OutAirHumRat /= state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow;
6565 918 : SysHeatOutTemp = OutAirTemp;
6566 918 : SysHeatOutHumRat = OutAirHumRat;
6567 918 : RhoAir = state.dataEnvrn->StdRhoAir;
6568 918 : if (state.dataSize->CalcSysSizing(AirLoopNum).HeatOAOption == MinOA) {
6569 1766 : OutAirFrac = RhoAir * state.dataSize->CalcSysSizing(AirLoopNum).DesOutAirVolFlow /
6570 883 : state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow;
6571 883 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
6572 : } else {
6573 35 : OutAirFrac = 1.0;
6574 : }
6575 918 : SysHeatMixTemp = OutAirTemp * OutAirFrac + SysHeatRetTemp * (1.0 - OutAirFrac);
6576 918 : SysHeatMixHumRat = OutAirHumRat * OutAirFrac + SysHeatRetHumRat * (1.0 - OutAirFrac);
6577 1836 : SysHeatCap = PsyCpAirFnW(DataPrecisionGlobals::constant_zero) * state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow *
6578 918 : (state.dataSize->CalcSysSizing(AirLoopNum).HeatSupTemp - SysHeatMixTemp);
6579 918 : SysHeatCap = max(0.0, SysHeatCap);
6580 : }
6581 : }
6582 :
6583 : // move the noncoincident results into the system sizing array
6584 925 : if (state.dataSize->CalcSysSizing(AirLoopNum).SizingOption == NonCoincident) {
6585 : // But first check to see if the noncoincident result is actually bigger than the coincident (for 100% outside air)
6586 832 : if (!(state.dataSize->FinalSysSizing(AirLoopNum).CoolOAOption == 1 && SysSensCoolCap <= 0.0)) { // CoolOAOption = Yes 100% OA
6587 832 : state.dataSize->CalcSysSizing(AirLoopNum).SensCoolCap = SysSensCoolCap;
6588 832 : state.dataSize->CalcSysSizing(AirLoopNum).TotCoolCap = SysTotCoolCap;
6589 832 : state.dataSize->CalcSysSizing(AirLoopNum).MixTempAtCoolPeak = SysCoolMixTemp;
6590 832 : state.dataSize->CalcSysSizing(AirLoopNum).RetTempAtCoolPeak = SysCoolRetTemp;
6591 832 : state.dataSize->CalcSysSizing(AirLoopNum).MixHumRatAtCoolPeak = SysCoolMixHumRat;
6592 832 : state.dataSize->CalcSysSizing(AirLoopNum).RetHumRatAtCoolPeak = SysCoolRetHumRat;
6593 832 : state.dataSize->CalcSysSizing(AirLoopNum).OutTempAtCoolPeak = SysCoolOutTemp;
6594 832 : state.dataSize->CalcSysSizing(AirLoopNum).OutHumRatAtCoolPeak = SysCoolOutHumRat;
6595 : }
6596 : // check to see if the noncoincident result is actually bigger than the coincident (for 100% outside air)
6597 : // why is this < 0.0 ? SysHeatCap cannot be < 0 ?? this code will always get executed
6598 832 : if (!(state.dataSize->FinalSysSizing(AirLoopNum).HeatOAOption == 1 && SysHeatCap < 0.0)) { // HeatOAOption = Yes 100% OA
6599 832 : state.dataSize->CalcSysSizing(AirLoopNum).HeatCap = SysHeatCap;
6600 832 : state.dataSize->CalcSysSizing(AirLoopNum).HeatMixTemp = SysHeatMixTemp;
6601 832 : state.dataSize->CalcSysSizing(AirLoopNum).HeatRetTemp = SysHeatRetTemp;
6602 832 : state.dataSize->CalcSysSizing(AirLoopNum).HeatMixHumRat = SysHeatMixHumRat;
6603 832 : state.dataSize->CalcSysSizing(AirLoopNum).HeatRetHumRat = SysHeatRetHumRat;
6604 832 : state.dataSize->CalcSysSizing(AirLoopNum).HeatOutTemp = SysHeatOutTemp;
6605 832 : state.dataSize->CalcSysSizing(AirLoopNum).HeatOutHumRat = SysHeatOutHumRat;
6606 : }
6607 832 : state.dataSize->CalcSysSizing(AirLoopNum).DesCoolVolFlow =
6608 832 : state.dataSize->CalcSysSizing(AirLoopNum).NonCoinCoolMassFlow / state.dataEnvrn->StdRhoAir;
6609 832 : state.dataSize->CalcSysSizing(AirLoopNum).DesHeatVolFlow =
6610 832 : state.dataSize->CalcSysSizing(AirLoopNum).NonCoinHeatMassFlow / state.dataEnvrn->StdRhoAir;
6611 832 : state.dataSize->CalcSysSizing(AirLoopNum).DesMainVolFlow =
6612 832 : max(state.dataSize->CalcSysSizing(AirLoopNum).DesCoolVolFlow, state.dataSize->CalcSysSizing(AirLoopNum).DesHeatVolFlow);
6613 : }
6614 : }
6615 :
6616 : // Move final system design data (calculated from zone data) to user design array
6617 1254 : for (std::size_t i = 0; i < state.dataSize->FinalSysSizing.size(); ++i) {
6618 925 : auto &z(state.dataSize->FinalSysSizing[i]);
6619 925 : auto &c(state.dataSize->CalcSysSizing[i]);
6620 925 : z.CoolDesDay = c.CoolDesDay;
6621 925 : z.HeatDesDay = c.HeatDesDay;
6622 925 : z.CoinCoolMassFlow = c.CoinCoolMassFlow;
6623 925 : z.CoinHeatMassFlow = c.CoinHeatMassFlow;
6624 925 : z.NonCoinCoolMassFlow = c.NonCoinCoolMassFlow;
6625 925 : z.NonCoinHeatMassFlow = c.NonCoinHeatMassFlow;
6626 925 : z.DesMainVolFlow = c.DesMainVolFlow;
6627 925 : z.DesHeatVolFlow = c.DesHeatVolFlow;
6628 925 : z.DesCoolVolFlow = c.DesCoolVolFlow;
6629 925 : z.MassFlowAtCoolPeak = c.MassFlowAtCoolPeak;
6630 925 : z.SensCoolCap = c.SensCoolCap;
6631 925 : z.TotCoolCap = c.TotCoolCap;
6632 925 : z.HeatCap = c.HeatCap;
6633 925 : z.PreheatCap = c.PreheatCap;
6634 925 : z.MixTempAtCoolPeak = c.MixTempAtCoolPeak;
6635 925 : z.MixHumRatAtCoolPeak = c.MixHumRatAtCoolPeak;
6636 925 : z.RetTempAtCoolPeak = c.RetTempAtCoolPeak;
6637 925 : z.RetHumRatAtCoolPeak = c.RetHumRatAtCoolPeak;
6638 925 : z.OutTempAtCoolPeak = c.OutTempAtCoolPeak;
6639 925 : z.OutHumRatAtCoolPeak = c.OutHumRatAtCoolPeak;
6640 925 : z.HeatMixTemp = c.HeatMixTemp;
6641 925 : z.HeatMixHumRat = c.HeatMixHumRat;
6642 925 : z.HeatRetTemp = c.HeatRetTemp;
6643 925 : z.HeatRetHumRat = c.HeatRetHumRat;
6644 925 : z.HeatOutTemp = c.HeatOutTemp;
6645 925 : z.HeatOutHumRat = c.HeatOutHumRat;
6646 925 : z.SysHeatCoilTimeStepPk = c.SysHeatCoilTimeStepPk;
6647 925 : z.SysHeatAirTimeStepPk = c.SysHeatAirTimeStepPk;
6648 925 : z.HeatDDNum = c.HeatDDNum;
6649 925 : z.SysCoolCoinSpaceSens = c.SysCoolCoinSpaceSens;
6650 925 : z.SysHeatCoinSpaceSens = c.SysHeatCoinSpaceSens;
6651 925 : z.SysDesCoolLoad = c.SysDesCoolLoad;
6652 925 : z.SysCoolLoadTimeStepPk = c.SysCoolLoadTimeStepPk;
6653 925 : z.SysDesHeatLoad = c.SysDesHeatLoad;
6654 925 : z.SysHeatLoadTimeStepPk = c.SysHeatLoadTimeStepPk;
6655 : }
6656 :
6657 1254 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
6658 925 : auto &finalSysSizing = state.dataSize->FinalSysSizing(AirLoopNum);
6659 925 : auto &calcSysSizing = state.dataSize->CalcSysSizing(AirLoopNum);
6660 109237 : for (TimeStepIndex = 1; TimeStepIndex <= numOfTimeStepInDay; ++TimeStepIndex) {
6661 108312 : finalSysSizing.HeatFlowSeq(TimeStepIndex) = calcSysSizing.HeatFlowSeq(TimeStepIndex);
6662 108312 : finalSysSizing.CoolFlowSeq(TimeStepIndex) = calcSysSizing.CoolFlowSeq(TimeStepIndex);
6663 108312 : finalSysSizing.SumZoneCoolLoadSeq(TimeStepIndex) = calcSysSizing.SumZoneCoolLoadSeq(TimeStepIndex);
6664 108312 : finalSysSizing.SumZoneHeatLoadSeq(TimeStepIndex) = calcSysSizing.SumZoneHeatLoadSeq(TimeStepIndex);
6665 108312 : finalSysSizing.CoolZoneAvgTempSeq(TimeStepIndex) = calcSysSizing.CoolZoneAvgTempSeq(TimeStepIndex);
6666 108312 : finalSysSizing.HeatZoneAvgTempSeq(TimeStepIndex) = calcSysSizing.HeatZoneAvgTempSeq(TimeStepIndex);
6667 108312 : finalSysSizing.SensCoolCapSeq(TimeStepIndex) = calcSysSizing.SensCoolCapSeq(TimeStepIndex);
6668 108312 : finalSysSizing.TotCoolCapSeq(TimeStepIndex) = calcSysSizing.TotCoolCapSeq(TimeStepIndex);
6669 108312 : finalSysSizing.HeatCapSeq(TimeStepIndex) = calcSysSizing.HeatCapSeq(TimeStepIndex);
6670 108312 : finalSysSizing.PreheatCapSeq(TimeStepIndex) = calcSysSizing.PreheatCapSeq(TimeStepIndex);
6671 108312 : finalSysSizing.SysCoolRetTempSeq(TimeStepIndex) = calcSysSizing.SysCoolRetTempSeq(TimeStepIndex);
6672 108312 : finalSysSizing.SysCoolRetHumRatSeq(TimeStepIndex) = calcSysSizing.SysCoolRetHumRatSeq(TimeStepIndex);
6673 108312 : finalSysSizing.SysHeatRetTempSeq(TimeStepIndex) = calcSysSizing.SysHeatRetTempSeq(TimeStepIndex);
6674 108312 : finalSysSizing.SysHeatRetHumRatSeq(TimeStepIndex) = calcSysSizing.SysHeatRetHumRatSeq(TimeStepIndex);
6675 108312 : finalSysSizing.SysCoolOutTempSeq(TimeStepIndex) = calcSysSizing.SysCoolOutTempSeq(TimeStepIndex);
6676 108312 : finalSysSizing.SysCoolOutHumRatSeq(TimeStepIndex) = calcSysSizing.SysCoolOutHumRatSeq(TimeStepIndex);
6677 108312 : finalSysSizing.SysHeatOutTempSeq(TimeStepIndex) = calcSysSizing.SysHeatOutTempSeq(TimeStepIndex);
6678 108312 : finalSysSizing.SysHeatOutHumRatSeq(TimeStepIndex) = calcSysSizing.SysHeatOutHumRatSeq(TimeStepIndex);
6679 108312 : finalSysSizing.SysDOASHeatAddSeq(TimeStepIndex) = calcSysSizing.SysDOASHeatAddSeq(TimeStepIndex);
6680 108312 : finalSysSizing.SysDOASLatAddSeq(TimeStepIndex) = calcSysSizing.SysDOASLatAddSeq(TimeStepIndex);
6681 : }
6682 : }
6683 :
6684 : // Check for user input design system flow rates. Set the sizing ratios.
6685 1254 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
6686 925 : auto &calcSysSizing = state.dataSize->CalcSysSizing(AirLoopNum);
6687 925 : auto &finalSysSizing = state.dataSize->FinalSysSizing(AirLoopNum);
6688 : // adjust system sizing flow rates for scalable flows
6689 925 : UpdateSysSizingForScalableInputs(state, AirLoopNum);
6690 :
6691 925 : int NumZonesCooled = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled;
6692 925 : int NumZonesHeated = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
6693 925 : RhoAir = state.dataEnvrn->StdRhoAir;
6694 925 : SysCoolSizingRat = 0.0;
6695 930 : if (calcSysSizing.InpDesCoolAirFlow > 0.0 && calcSysSizing.DesCoolVolFlow > 0.0 &&
6696 7 : (calcSysSizing.CoolAirDesMethod == InpDesAirFlow || calcSysSizing.ScaleCoolSAFMethod == FlowPerFloorArea ||
6697 2 : calcSysSizing.ScaleCoolSAFMethod == FractionOfAutosizedCoolingAirflow ||
6698 1 : calcSysSizing.ScaleCoolSAFMethod == FlowPerCoolingCapacity)) {
6699 5 : SysCoolSizingRat = calcSysSizing.InpDesCoolAirFlow / calcSysSizing.DesCoolVolFlow;
6700 : } else {
6701 920 : SysCoolSizingRat = 1.0;
6702 : }
6703 :
6704 925 : SysHeatSizingRat = 0.0;
6705 929 : if (calcSysSizing.InpDesHeatAirFlow > 0.0 && calcSysSizing.DesHeatVolFlow > 0.0 &&
6706 6 : (calcSysSizing.HeatAirDesMethod == InpDesAirFlow || calcSysSizing.ScaleHeatSAFMethod == FlowPerFloorArea ||
6707 2 : calcSysSizing.ScaleHeatSAFMethod == FractionOfAutosizedHeatingAirflow ||
6708 2 : calcSysSizing.ScaleHeatSAFMethod == FractionOfAutosizedCoolingAirflow ||
6709 1 : calcSysSizing.ScaleHeatSAFMethod == FlowPerHeatingCapacity)) {
6710 4 : SysHeatSizingRat = calcSysSizing.InpDesHeatAirFlow / calcSysSizing.DesHeatVolFlow;
6711 : } else {
6712 921 : SysHeatSizingRat = 1.0;
6713 : }
6714 :
6715 925 : if (calcSysSizing.loadSizingType == DataSizing::LoadSizing::Ventilation && SysCoolSizingRat == 1.0) {
6716 22 : if (calcSysSizing.DesCoolVolFlow > 0.0) {
6717 22 : SysCoolSizingRat = calcSysSizing.DesOutAirVolFlow / calcSysSizing.DesCoolVolFlow;
6718 22 : state.dataSize->VotClgBySys(AirLoopNum) = finalSysSizing.DesOutAirVolFlow;
6719 : } else {
6720 0 : SysCoolSizingRat = 1.0;
6721 : }
6722 : }
6723 925 : if (calcSysSizing.loadSizingType == DataSizing::LoadSizing::Ventilation && SysHeatSizingRat == 1.0) {
6724 22 : if (calcSysSizing.DesHeatVolFlow > 0.0) {
6725 22 : SysHeatSizingRat = calcSysSizing.DesOutAirVolFlow / calcSysSizing.DesHeatVolFlow;
6726 22 : state.dataSize->VotHtgBySys(AirLoopNum) = finalSysSizing.DesOutAirVolFlow;
6727 : } else {
6728 0 : SysHeatSizingRat = 1.0;
6729 : }
6730 : }
6731 :
6732 : // Calculate the new user modified system design quantities
6733 925 : if (std::abs(SysCoolSizingRat - 1.0) > 0.00001) {
6734 :
6735 24 : finalSysSizing.CoinCoolMassFlow = SysCoolSizingRat * calcSysSizing.CoinCoolMassFlow;
6736 24 : finalSysSizing.NonCoinCoolMassFlow = SysCoolSizingRat * calcSysSizing.NonCoinCoolMassFlow;
6737 24 : finalSysSizing.DesCoolVolFlow = SysCoolSizingRat * calcSysSizing.DesCoolVolFlow;
6738 24 : finalSysSizing.MassFlowAtCoolPeak = SysCoolSizingRat * calcSysSizing.MassFlowAtCoolPeak;
6739 :
6740 24 : if (finalSysSizing.DesCoolVolFlow > 0.0) {
6741 :
6742 2568 : for (TimeStepIndex = 1; TimeStepIndex <= numOfTimeStepInDay; ++TimeStepIndex) {
6743 :
6744 2544 : if (calcSysSizing.CoolFlowSeq(TimeStepIndex) > 0.0) {
6745 :
6746 2544 : finalSysSizing.CoolFlowSeq(TimeStepIndex) = SysCoolSizingRat * calcSysSizing.CoolFlowSeq(TimeStepIndex);
6747 2544 : if (finalSysSizing.CoolOAOption == MinOA) {
6748 384 : OutAirFrac = RhoAir * finalSysSizing.DesOutAirVolFlow / finalSysSizing.CoolFlowSeq(TimeStepIndex);
6749 384 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
6750 : } else {
6751 2160 : OutAirFrac = 1.0;
6752 : }
6753 5088 : SysCoolMixTemp = finalSysSizing.SysCoolOutTempSeq(TimeStepIndex) * OutAirFrac +
6754 2544 : finalSysSizing.SysCoolRetTempSeq(TimeStepIndex) * (1.0 - OutAirFrac);
6755 5088 : SysCoolMixHumRat = finalSysSizing.SysCoolOutHumRatSeq(TimeStepIndex) * OutAirFrac +
6756 2544 : finalSysSizing.SysCoolRetHumRatSeq(TimeStepIndex) * (1.0 - OutAirFrac);
6757 5088 : SysSensCoolCap = PsyCpAirFnW(DataPrecisionGlobals::constant_zero) * finalSysSizing.CoolFlowSeq(TimeStepIndex) *
6758 2544 : (SysCoolMixTemp - finalSysSizing.CoolSupTemp);
6759 2544 : SysSensCoolCap = max(0.0, SysSensCoolCap);
6760 2544 : SysTotCoolCap =
6761 2544 : finalSysSizing.CoolFlowSeq(TimeStepIndex) *
6762 2544 : (PsyHFnTdbW(SysCoolMixTemp, SysCoolMixHumRat) - PsyHFnTdbW(finalSysSizing.CoolSupTemp, finalSysSizing.CoolSupHumRat));
6763 2544 : SysTotCoolCap = max(0.0, SysTotCoolCap);
6764 2544 : finalSysSizing.SensCoolCapSeq(TimeStepIndex) = SysSensCoolCap;
6765 2544 : finalSysSizing.TotCoolCapSeq(TimeStepIndex) = SysTotCoolCap;
6766 : }
6767 : }
6768 :
6769 24 : if (finalSysSizing.CoolOAOption == MinOA) {
6770 3 : OutAirFrac = finalSysSizing.DesOutAirVolFlow / finalSysSizing.DesCoolVolFlow;
6771 3 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
6772 : } else {
6773 21 : OutAirFrac = 1.0;
6774 : }
6775 24 : finalSysSizing.MixTempAtCoolPeak =
6776 24 : finalSysSizing.OutTempAtCoolPeak * OutAirFrac + finalSysSizing.RetTempAtCoolPeak * (1.0 - OutAirFrac);
6777 24 : finalSysSizing.MixHumRatAtCoolPeak =
6778 24 : finalSysSizing.OutHumRatAtCoolPeak * OutAirFrac + finalSysSizing.RetHumRatAtCoolPeak * (1.0 - OutAirFrac);
6779 48 : finalSysSizing.SensCoolCap = PsyCpAirFnW(DataPrecisionGlobals::constant_zero) * RhoAir * finalSysSizing.DesCoolVolFlow *
6780 24 : (finalSysSizing.MixTempAtCoolPeak - finalSysSizing.CoolSupTemp);
6781 24 : finalSysSizing.SensCoolCap = max(0.0, finalSysSizing.SensCoolCap);
6782 48 : finalSysSizing.TotCoolCap = RhoAir * finalSysSizing.DesCoolVolFlow *
6783 48 : (PsyHFnTdbW(finalSysSizing.MixTempAtCoolPeak, finalSysSizing.MixHumRatAtCoolPeak) -
6784 24 : PsyHFnTdbW(finalSysSizing.CoolSupTemp, finalSysSizing.CoolSupHumRat));
6785 24 : finalSysSizing.TotCoolCap = max(0.0, finalSysSizing.TotCoolCap);
6786 : }
6787 :
6788 : // take account of the user input system flow rates and alter the zone flow rates to match
6789 143 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) {
6790 119 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
6791 223 : if ((SysCoolSizingRat != 1.0) && (finalSysSizing.loadSizingType == DataSizing::LoadSizing::Ventilation) &&
6792 104 : (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).MinOA > 0.0)) {
6793 : // size on ventilation load
6794 104 : if (state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).MinOA > 0.0) {
6795 208 : ZoneOARatio = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).MinOA /
6796 104 : max(state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesCoolVolFlow,
6797 104 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).MinOA);
6798 104 : ZoneOARatio *= (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat);
6799 : } else {
6800 0 : ZoneOARatio = 0.0;
6801 : }
6802 104 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).scaleZoneCooling(ZoneOARatio);
6803 15 : } else if ((SysCoolSizingRat > 1.0) || (SysCoolSizingRat < 1.0 && finalSysSizing.SizingOption == NonCoincident)) {
6804 : // size on user input system design flows
6805 6 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).scaleZoneCooling(SysCoolSizingRat);
6806 : }
6807 : }
6808 : }
6809 :
6810 925 : if (std::abs(SysHeatSizingRat - 1.0) > 0.00001) {
6811 :
6812 15 : finalSysSizing.CoinHeatMassFlow = SysHeatSizingRat * calcSysSizing.CoinHeatMassFlow;
6813 15 : finalSysSizing.NonCoinHeatMassFlow = SysHeatSizingRat * calcSysSizing.NonCoinHeatMassFlow;
6814 15 : finalSysSizing.DesHeatVolFlow = SysHeatSizingRat * calcSysSizing.DesHeatVolFlow;
6815 :
6816 15 : if (finalSysSizing.DesHeatVolFlow > 0.0) {
6817 :
6818 1647 : for (TimeStepIndex = 1; TimeStepIndex <= numOfTimeStepInDay; ++TimeStepIndex) {
6819 :
6820 1632 : if (calcSysSizing.HeatFlowSeq(TimeStepIndex) > 0.0) {
6821 :
6822 1632 : finalSysSizing.HeatFlowSeq(TimeStepIndex) = SysHeatSizingRat * calcSysSizing.HeatFlowSeq(TimeStepIndex);
6823 1632 : if (finalSysSizing.HeatOAOption == MinOA) {
6824 144 : OutAirFrac = RhoAir * finalSysSizing.DesOutAirVolFlow / finalSysSizing.HeatFlowSeq(TimeStepIndex);
6825 144 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
6826 : } else {
6827 1488 : OutAirFrac = 1.0;
6828 : }
6829 3264 : SysHeatMixTemp = finalSysSizing.SysHeatOutTempSeq(TimeStepIndex) * OutAirFrac +
6830 1632 : finalSysSizing.SysHeatRetTempSeq(TimeStepIndex) * (1.0 - OutAirFrac);
6831 3264 : SysHeatMixHumRat = finalSysSizing.SysHeatOutHumRatSeq(TimeStepIndex) * OutAirFrac +
6832 1632 : finalSysSizing.SysHeatRetHumRatSeq(TimeStepIndex) * (1.0 - OutAirFrac);
6833 3264 : SysHeatCap = PsyCpAirFnW(DataPrecisionGlobals::constant_zero) * finalSysSizing.HeatFlowSeq(TimeStepIndex) *
6834 1632 : (finalSysSizing.HeatSupTemp - SysHeatMixTemp);
6835 1632 : SysHeatCap = max(0.0, SysHeatCap);
6836 1632 : finalSysSizing.HeatCapSeq(TimeStepIndex) = SysHeatCap;
6837 : }
6838 : }
6839 :
6840 15 : if (finalSysSizing.HeatOAOption == MinOA) {
6841 1 : OutAirFrac = finalSysSizing.DesOutAirVolFlow / finalSysSizing.DesHeatVolFlow;
6842 1 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
6843 : } else {
6844 14 : OutAirFrac = 1.0;
6845 : }
6846 15 : finalSysSizing.HeatMixTemp = finalSysSizing.HeatOutTemp * OutAirFrac + finalSysSizing.HeatRetTemp * (1.0 - OutAirFrac);
6847 15 : finalSysSizing.HeatMixHumRat = finalSysSizing.HeatOutHumRat * OutAirFrac + finalSysSizing.HeatRetHumRat * (1.0 - OutAirFrac);
6848 30 : finalSysSizing.HeatCap = PsyCpAirFnW(DataPrecisionGlobals::constant_zero) * RhoAir * finalSysSizing.DesHeatVolFlow *
6849 15 : (finalSysSizing.HeatSupTemp - finalSysSizing.HeatMixTemp);
6850 15 : finalSysSizing.HeatCap = max(0.0, finalSysSizing.HeatCap);
6851 : }
6852 : // take account of the user input system flow rates and alter the zone flow rates to match (for terminal unit sizing)
6853 15 : if (NumZonesHeated > 0) { // IF there are centrally heated zones
6854 0 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesHeated; ++ZonesHeatedNum) { // loop over the heated zones
6855 0 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(ZonesHeatedNum);
6856 0 : auto &termUnitFinalZoneSizing = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex);
6857 0 : if ((SysHeatSizingRat != 1.0) && (finalSysSizing.loadSizingType == DataSizing::LoadSizing::Ventilation) &&
6858 0 : (termUnitFinalZoneSizing.MinOA > 0.0)) {
6859 : // size on ventilation load
6860 0 : if (termUnitFinalZoneSizing.MinOA > 0.0) {
6861 0 : ZoneOARatio =
6862 0 : termUnitFinalZoneSizing.MinOA / max(termUnitFinalZoneSizing.DesHeatVolFlow, termUnitFinalZoneSizing.MinOA);
6863 0 : ZoneOARatio *= (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat);
6864 : } else {
6865 0 : ZoneOARatio = 0.0;
6866 : }
6867 0 : termUnitFinalZoneSizing.scaleZoneHeating(ZoneOARatio);
6868 0 : } else if ((SysHeatSizingRat > 1.0) || (SysHeatSizingRat < 1.0 && finalSysSizing.SizingOption == NonCoincident)) {
6869 : // size on user input system design flows
6870 0 : termUnitFinalZoneSizing.scaleZoneHeating(SysHeatSizingRat);
6871 : }
6872 : }
6873 : } else { // No centrally heated zones: use cooled zones
6874 93 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) { // loop over the cooled zones
6875 78 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
6876 78 : auto &termUnitFinalZoneSizing = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex);
6877 142 : if ((SysHeatSizingRat != 1.0) && (finalSysSizing.loadSizingType == DataSizing::LoadSizing::Ventilation) &&
6878 64 : (termUnitFinalZoneSizing.MinOA <= 0.0)) {
6879 0 : ShowWarningError(state,
6880 0 : "FinalSystemSizing: AirLoop=\"" + state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).AirLoopName +
6881 : "\", Requested sizing on Ventilation,");
6882 0 : ShowContinueError(state, "but Zone has no design OA Flow. Zone=\"" + termUnitFinalZoneSizing.ZoneName + "\".");
6883 : }
6884 142 : if ((SysHeatSizingRat != 1.0) && (finalSysSizing.loadSizingType == DataSizing::LoadSizing::Ventilation) &&
6885 64 : (termUnitFinalZoneSizing.MinOA > 0.0)) {
6886 : // size on ventilation load
6887 64 : if (termUnitFinalZoneSizing.MinOA > 0.0) {
6888 64 : ZoneOARatio =
6889 64 : termUnitFinalZoneSizing.MinOA / max(termUnitFinalZoneSizing.DesHeatVolFlow, termUnitFinalZoneSizing.MinOA);
6890 64 : ZoneOARatio *= (1.0 + state.dataSize->TermUnitSizing(TermUnitSizingIndex).InducRat);
6891 : } else {
6892 0 : ZoneOARatio = 0.0;
6893 : }
6894 64 : termUnitFinalZoneSizing.scaleZoneHeating(ZoneOARatio);
6895 14 : } else if ((SysHeatSizingRat != 1.0) && (finalSysSizing.loadSizingType == DataSizing::LoadSizing::Ventilation) &&
6896 0 : (termUnitFinalZoneSizing.MinOA > 0.0)) {
6897 : // size on user input system design flows
6898 0 : termUnitFinalZoneSizing.scaleZoneHeating(SysHeatSizingRat);
6899 : }
6900 : }
6901 : }
6902 : }
6903 :
6904 925 : finalSysSizing.DesMainVolFlow = max(finalSysSizing.DesCoolVolFlow, finalSysSizing.DesHeatVolFlow);
6905 :
6906 : // loop over the zones cooled by this system and sum up the min cooling flow rates to get the
6907 : // min system cooling flow rate
6908 3833 : for (int ZonesCooledNum = 1; ZonesCooledNum <= NumZonesCooled; ++ZonesCooledNum) {
6909 2908 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolSizingIndex(ZonesCooledNum);
6910 2908 : finalSysSizing.DesCoolVolFlowMin += state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesCoolVolFlowMin;
6911 : }
6912 925 : if (finalSysSizing.DesCoolVolFlowMin <= 0.0) {
6913 0 : finalSysSizing.DesCoolVolFlowMin = finalSysSizing.DesOutAirVolFlow;
6914 : }
6915 : }
6916 :
6917 : // Specify the heating supply air Temp/HumRat for different system configurations
6918 1254 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
6919 :
6920 925 : int NumZonesHeated = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
6921 :
6922 925 : if (NumZonesHeated > 0) { // IF there are centrally heated zones
6923 17 : for (int ZonesHeatedNum = 1; ZonesHeatedNum <= NumZonesHeated; ++ZonesHeatedNum) {
6924 14 : int TermUnitSizingIndex = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatSizingIndex(ZonesHeatedNum);
6925 :
6926 14 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesHeatCoilInTempTU = GetHeatingSATempForSizing(state, AirLoopNum);
6927 14 : state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex).DesHeatCoilInHumRatTU =
6928 14 : GetHeatingSATempHumRatForSizing(state, AirLoopNum);
6929 : }
6930 : }
6931 : }
6932 :
6933 : // EMS calling point to customize system sizing results
6934 : bool anyEMSRan;
6935 329 : ManageEMS(state, EMSManager::EMSCallFrom::SystemSizing, anyEMSRan, ObjexxFCL::Optional_int_const());
6936 :
6937 : // EMS override point
6938 329 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
6939 373 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
6940 323 : auto &finalSysSizing = state.dataSize->FinalSysSizing(AirLoopNum);
6941 323 : if (finalSysSizing.EMSOverrideCoinCoolMassFlowOn) finalSysSizing.CoinCoolMassFlow = finalSysSizing.EMSValueCoinCoolMassFlow;
6942 323 : if (finalSysSizing.EMSOverrideCoinHeatMassFlowOn) finalSysSizing.CoinHeatMassFlow = finalSysSizing.EMSValueCoinHeatMassFlow;
6943 323 : if (finalSysSizing.EMSOverrideNonCoinCoolMassFlowOn) finalSysSizing.NonCoinCoolMassFlow = finalSysSizing.EMSValueNonCoinCoolMassFlow;
6944 323 : if (finalSysSizing.EMSOverrideNonCoinHeatMassFlowOn) finalSysSizing.NonCoinHeatMassFlow = finalSysSizing.EMSValueNonCoinHeatMassFlow;
6945 323 : if (finalSysSizing.EMSOverrideDesMainVolFlowOn) finalSysSizing.DesMainVolFlow = finalSysSizing.EMSValueDesMainVolFlow;
6946 323 : if (finalSysSizing.EMSOverrideDesHeatVolFlowOn) finalSysSizing.DesHeatVolFlow = finalSysSizing.EMSValueDesHeatVolFlow;
6947 323 : if (finalSysSizing.EMSOverrideDesCoolVolFlowOn) finalSysSizing.DesCoolVolFlow = finalSysSizing.EMSValueDesCoolVolFlow;
6948 :
6949 : } // over NumPrimaryAirSys
6950 : }
6951 :
6952 : // determine if main design is from cooling or heating
6953 1254 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
6954 925 : if (state.dataSize->FinalSysSizing(AirLoopNum).DesMainVolFlow == state.dataSize->FinalSysSizing(AirLoopNum).DesCoolVolFlow) {
6955 825 : state.dataSize->FinalSysSizing(AirLoopNum).sysSizeCoolingDominant = true;
6956 100 : } else if (state.dataSize->FinalSysSizing(AirLoopNum).DesMainVolFlow == state.dataSize->FinalSysSizing(AirLoopNum).DesHeatVolFlow) {
6957 80 : state.dataSize->FinalSysSizing(AirLoopNum).sysSizeHeatingDominant = true;
6958 : }
6959 : }
6960 :
6961 : // write out the sys design calc results
6962 :
6963 329 : print(state.files.ssz, "Time");
6964 1254 : for (I = 1; I <= state.dataHVACGlobal->NumPrimaryAirSys; ++I) {
6965 2871 : for (J = 1; J <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++J) {
6966 1946 : constexpr const char *SSizeFmt12("{}{}{}{:2}{}{}{}{}{:2}{}{}{}{}{:2}{}{}{}{}{:2}{}{}{}{}{:2}{}");
6967 21406 : print(state.files.ssz,
6968 : SSizeFmt12,
6969 1946 : state.dataSize->SizingFileColSep,
6970 1946 : state.dataSize->CalcSysSizing(I).AirPriLoopName,
6971 : ":DesPer",
6972 : J,
6973 : ":Des Heat Mass Flow [kg/s]",
6974 1946 : state.dataSize->SizingFileColSep,
6975 1946 : state.dataSize->CalcSysSizing(I).AirPriLoopName,
6976 : ":DesPer",
6977 : J,
6978 : ":Des Heat Cap [W]",
6979 1946 : state.dataSize->SizingFileColSep,
6980 1946 : state.dataSize->CalcSysSizing(I).AirPriLoopName,
6981 : ":DesPer",
6982 : J,
6983 : ":Des Cool Mass Flow [kg/s]",
6984 1946 : state.dataSize->SizingFileColSep,
6985 1946 : state.dataSize->CalcSysSizing(I).AirPriLoopName,
6986 : ":DesPer",
6987 : J,
6988 : ":Des Sens Cool Cap [W]",
6989 1946 : state.dataSize->SizingFileColSep,
6990 1946 : state.dataSize->CalcSysSizing(I).AirPriLoopName,
6991 : ":DesPer",
6992 : J,
6993 1946 : ":Des Tot Cool Cap [W]");
6994 : }
6995 : }
6996 329 : print(state.files.ssz, "\n");
6997 : // HourFrac = 0.0
6998 329 : Minutes = 0;
6999 329 : TimeStepIndex = 0;
7000 8225 : for (HourCounter = 1; HourCounter <= 24; ++HourCounter) {
7001 47376 : for (TimeStepCounter = 1; TimeStepCounter <= state.dataGlobal->NumOfTimeStepInHour; ++TimeStepCounter) {
7002 39480 : ++TimeStepIndex;
7003 39480 : Minutes += state.dataGlobal->MinutesPerTimeStep;
7004 39480 : if (Minutes == 60) {
7005 7896 : Minutes = 0;
7006 7896 : HourPrint = HourCounter;
7007 : } else {
7008 31584 : HourPrint = HourCounter - 1;
7009 : }
7010 39480 : constexpr const char *SSizeFmt20("{:02}:{:02}:00");
7011 39480 : print(state.files.ssz, SSizeFmt20, HourPrint, Minutes);
7012 147792 : for (I = 1; I <= state.dataHVACGlobal->NumPrimaryAirSys; ++I) {
7013 338568 : for (J = 1; J <= state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays; ++J) {
7014 230256 : constexpr const char *SSizeFmt22("{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}");
7015 :
7016 2532816 : print(state.files.ssz,
7017 : SSizeFmt22,
7018 230256 : state.dataSize->SizingFileColSep,
7019 230256 : state.dataSize->SysSizing(J, I).HeatFlowSeq(TimeStepIndex),
7020 230256 : state.dataSize->SizingFileColSep,
7021 230256 : state.dataSize->SysSizing(J, I).HeatCapSeq(TimeStepIndex),
7022 230256 : state.dataSize->SizingFileColSep,
7023 230256 : state.dataSize->SysSizing(J, I).CoolFlowSeq(TimeStepIndex),
7024 230256 : state.dataSize->SizingFileColSep,
7025 230256 : state.dataSize->SysSizing(J, I).SensCoolCapSeq(TimeStepIndex),
7026 230256 : state.dataSize->SizingFileColSep,
7027 460512 : state.dataSize->SysSizing(J, I).TotCoolCapSeq(TimeStepIndex));
7028 : }
7029 : }
7030 39480 : print(state.files.ssz, "\n");
7031 : }
7032 : }
7033 :
7034 329 : constexpr const char *SSizeFmt31("{}{:12.6E}{}{:12.6E}{}{:12.6E}{}{:12.6E}");
7035 329 : print(state.files.ssz, "Coinc Peak ");
7036 1254 : for (I = 1; I <= state.dataHVACGlobal->NumPrimaryAirSys; ++I) {
7037 8325 : print(state.files.ssz,
7038 : SSizeFmt31,
7039 925 : state.dataSize->SizingFileColSep,
7040 925 : state.dataSize->CalcSysSizing(I).CoinHeatMassFlow,
7041 925 : state.dataSize->SizingFileColSep,
7042 925 : state.dataSize->CalcSysSizing(I).CoinCoolMassFlow,
7043 925 : state.dataSize->SizingFileColSep,
7044 925 : state.dataSize->CalcSysSizing(I).HeatCap,
7045 925 : state.dataSize->SizingFileColSep,
7046 1850 : state.dataSize->CalcSysSizing(I).SensCoolCap);
7047 : }
7048 329 : print(state.files.ssz, "\n");
7049 :
7050 329 : print(state.files.ssz, "NonCoinc Peak");
7051 1254 : for (I = 1; I <= state.dataHVACGlobal->NumPrimaryAirSys; ++I) {
7052 8325 : print(state.files.ssz,
7053 : SSizeFmt31,
7054 925 : state.dataSize->SizingFileColSep,
7055 925 : state.dataSize->CalcSysSizing(I).NonCoinHeatMassFlow,
7056 925 : state.dataSize->SizingFileColSep,
7057 925 : state.dataSize->CalcSysSizing(I).NonCoinCoolMassFlow,
7058 925 : state.dataSize->SizingFileColSep,
7059 925 : state.dataSize->CalcSysSizing(I).HeatCap,
7060 925 : state.dataSize->SizingFileColSep,
7061 1850 : state.dataSize->CalcSysSizing(I).SensCoolCap);
7062 : }
7063 329 : print(state.files.ssz, "\n");
7064 : // have moved a big section to later in calling order, write predefined standard 62.1 report data
7065 329 : } break;
7066 0 : default:
7067 0 : break;
7068 : }
7069 85815 : }
7070 :
7071 925 : void UpdateSysSizingForScalableInputs(EnergyPlusData &state, int const AirLoopNum)
7072 : {
7073 :
7074 : // SUBROUTINE INFORMATION:
7075 : // AUTHOR Bereket Nigusse
7076 : // DATE WRITTEN Auguts 2014
7077 : // MODIFIED na
7078 : // RE-ENGINEERED na
7079 :
7080 : // PURPOSE OF THIS SUBROUTINE:
7081 : // Modifies the design sizing flow rates for system scalable sizing method
7082 :
7083 : // Using/Aliasing
7084 : using Psychrometrics::PsyCpAirFnW;
7085 : using Psychrometrics::PsyHFnTdbW;
7086 :
7087 : // SUBROUTINE PARAMETER DEFINITIONS:
7088 :
7089 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7090 : Real64 TempSize; // autosized value
7091 : Real64 CoilInTemp; // entering coil air temperature [C]
7092 : Real64 CoilInHumRat; // entering coil air humidity ratio [kg/kg]
7093 : Real64 CoilInEnth; // entering coil air enthalpy [J/kg]
7094 : Real64 CoilOutTemp; // coil outlet air temperature [C]
7095 : Real64 CoilOutHumRat; // coil outlet air humidity ratio [kg/kg]
7096 : Real64 CoilOutEnth; // coil outlet air enthalpy [J/kg]
7097 : Real64 OutAirFrac; // outdoor air fraction [-]
7098 : Real64 CpAirStd; // specific heat of air at standard condition
7099 : Real64 FractionOfAutosize; // user specified autosized fraction for capacity and supply air flow
7100 : Real64 AutosizedCapacity; // autosized heating and cooling capacity
7101 :
7102 925 : auto &FinalSysSizing(state.dataSize->FinalSysSizing);
7103 925 : auto &CalcSysSizing(state.dataSize->CalcSysSizing);
7104 925 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
7105 :
7106 925 : state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
7107 925 : state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
7108 :
7109 925 : if (AirLoopNum > 0) {
7110 :
7111 925 : TempSize = 0.0;
7112 925 : FractionOfAutosize = 1.0;
7113 :
7114 : // scalable sizing option for cooling supply air flow rate
7115 925 : switch (FinalSysSizing(AirLoopNum).ScaleCoolSAFMethod) {
7116 0 : case FlowPerFloorArea: {
7117 0 : TempSize = FinalSysSizing(AirLoopNum).FlowPerFloorAreaCooled * FinalSysSizing(AirLoopNum).FloorAreaOnAirLoopCooled;
7118 0 : CalcSysSizing(AirLoopNum).InpDesCoolAirFlow = TempSize;
7119 0 : FinalSysSizing(AirLoopNum).InpDesCoolAirFlow = TempSize;
7120 0 : } break;
7121 0 : case FractionOfAutosizedCoolingAirflow: {
7122 0 : FractionOfAutosize = FinalSysSizing(AirLoopNum).FractionOfAutosizedCoolingAirflow;
7123 0 : CalcSysSizing(AirLoopNum).InpDesCoolAirFlow = CalcSysSizing(AirLoopNum).DesCoolVolFlow * FractionOfAutosize;
7124 0 : FinalSysSizing(AirLoopNum).InpDesCoolAirFlow = FinalSysSizing(AirLoopNum).DesCoolVolFlow * FractionOfAutosize;
7125 0 : } break;
7126 1 : case FlowPerCoolingCapacity: {
7127 1 : if (FinalSysSizing(AirLoopNum).CoolingCapMethod == FractionOfAutosizedCoolingCapacity) {
7128 1 : FractionOfAutosize = FinalSysSizing(AirLoopNum).ScaledCoolingCapacity;
7129 1 : if (PrimaryAirSystems(AirLoopNum).NumOACoolCoils == 0) { // there is no precooling of the OA stream
7130 1 : CoilInTemp = FinalSysSizing(AirLoopNum).MixTempAtCoolPeak;
7131 1 : CoilInHumRat = FinalSysSizing(AirLoopNum).MixHumRatAtCoolPeak;
7132 : } else { // there is precooling of OA stream
7133 0 : if (FinalSysSizing(AirLoopNum).DesCoolVolFlow > 0.0) {
7134 0 : OutAirFrac = FinalSysSizing(AirLoopNum).DesOutAirVolFlow / FinalSysSizing(AirLoopNum).DesCoolVolFlow;
7135 : } else {
7136 0 : OutAirFrac = 1.0;
7137 : }
7138 0 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
7139 0 : CoilInTemp =
7140 0 : OutAirFrac * FinalSysSizing(AirLoopNum).PrecoolTemp + (1.0 - OutAirFrac) * FinalSysSizing(AirLoopNum).RetTempAtCoolPeak;
7141 0 : CoilInHumRat =
7142 0 : OutAirFrac * FinalSysSizing(AirLoopNum).PrecoolHumRat + (1.0 - OutAirFrac) * FinalSysSizing(AirLoopNum).RetHumRatAtCoolPeak;
7143 : }
7144 1 : CoilOutTemp = FinalSysSizing(AirLoopNum).CoolSupTemp;
7145 1 : CoilOutHumRat = FinalSysSizing(AirLoopNum).CoolSupHumRat;
7146 1 : CoilInEnth = PsyHFnTdbW(CoilInTemp, CoilInHumRat);
7147 1 : CoilOutEnth = PsyHFnTdbW(CoilOutTemp, CoilOutHumRat);
7148 1 : AutosizedCapacity = state.dataEnvrn->StdRhoAir * FinalSysSizing(AirLoopNum).DesCoolVolFlow * (CoilInEnth - CoilOutEnth);
7149 1 : TempSize = FinalSysSizing(AirLoopNum).FlowPerCoolingCapacity * AutosizedCapacity * FractionOfAutosize;
7150 0 : } else if (FinalSysSizing(AirLoopNum).CoolingCapMethod == CoolingDesignCapacity) {
7151 0 : if (FinalSysSizing(AirLoopNum).ScaledCoolingCapacity == DataSizing::AutoSize) {
7152 0 : if (PrimaryAirSystems(AirLoopNum).NumOACoolCoils == 0) { // there is no precooling of the OA stream
7153 0 : CoilInTemp = FinalSysSizing(AirLoopNum).MixTempAtCoolPeak;
7154 0 : CoilInHumRat = FinalSysSizing(AirLoopNum).MixHumRatAtCoolPeak;
7155 : } else { // there is precooling of OA stream
7156 0 : if (FinalSysSizing(AirLoopNum).DesCoolVolFlow > 0.0) {
7157 0 : OutAirFrac = FinalSysSizing(AirLoopNum).DesOutAirVolFlow / FinalSysSizing(AirLoopNum).DesCoolVolFlow;
7158 : } else {
7159 0 : OutAirFrac = 1.0;
7160 : }
7161 0 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
7162 0 : CoilInTemp =
7163 0 : OutAirFrac * FinalSysSizing(AirLoopNum).PrecoolTemp + (1.0 - OutAirFrac) * FinalSysSizing(AirLoopNum).RetTempAtCoolPeak;
7164 0 : CoilInHumRat = OutAirFrac * FinalSysSizing(AirLoopNum).PrecoolHumRat +
7165 0 : (1.0 - OutAirFrac) * FinalSysSizing(AirLoopNum).RetHumRatAtCoolPeak;
7166 : }
7167 0 : CoilOutTemp = FinalSysSizing(AirLoopNum).CoolSupTemp;
7168 0 : CoilOutHumRat = FinalSysSizing(AirLoopNum).CoolSupHumRat;
7169 0 : CoilInEnth = PsyHFnTdbW(CoilInTemp, CoilInHumRat);
7170 0 : CoilOutEnth = PsyHFnTdbW(CoilOutTemp, CoilOutHumRat);
7171 0 : AutosizedCapacity = state.dataEnvrn->StdRhoAir * FinalSysSizing(AirLoopNum).DesCoolVolFlow * (CoilInEnth - CoilOutEnth);
7172 0 : TempSize = FinalSysSizing(AirLoopNum).FlowPerCoolingCapacity * AutosizedCapacity * FractionOfAutosize;
7173 : } else {
7174 0 : TempSize = FinalSysSizing(AirLoopNum).FlowPerCoolingCapacity * FinalSysSizing(AirLoopNum).ScaledCoolingCapacity;
7175 : }
7176 0 : } else if (FinalSysSizing(AirLoopNum).CoolingCapMethod == CapacityPerFloorArea) {
7177 0 : TempSize = FinalSysSizing(AirLoopNum).FlowPerCoolingCapacity * FinalSysSizing(AirLoopNum).ScaledCoolingCapacity *
7178 0 : FinalSysSizing(AirLoopNum).FloorAreaOnAirLoopCooled;
7179 : }
7180 1 : CalcSysSizing(AirLoopNum).InpDesCoolAirFlow = TempSize;
7181 1 : FinalSysSizing(AirLoopNum).InpDesCoolAirFlow = TempSize;
7182 1 : } break;
7183 924 : default:
7184 924 : break;
7185 : }
7186 :
7187 : // scalable sizing option for heating supply air flow rate
7188 925 : switch (FinalSysSizing(AirLoopNum).ScaleHeatSAFMethod) {
7189 0 : case FlowPerFloorArea: {
7190 0 : TempSize = FinalSysSizing(AirLoopNum).FlowPerFloorAreaHeated * FinalSysSizing(AirLoopNum).FloorAreaOnAirLoopHeated;
7191 0 : CalcSysSizing(AirLoopNum).InpDesHeatAirFlow = TempSize;
7192 0 : FinalSysSizing(AirLoopNum).InpDesHeatAirFlow = TempSize;
7193 0 : } break;
7194 0 : case FractionOfAutosizedHeatingAirflow: {
7195 0 : FractionOfAutosize = FinalSysSizing(AirLoopNum).FractionOfAutosizedHeatingAirflow;
7196 0 : CalcSysSizing(AirLoopNum).InpDesHeatAirFlow = CalcSysSizing(AirLoopNum).DesHeatVolFlow * FractionOfAutosize;
7197 0 : FinalSysSizing(AirLoopNum).InpDesHeatAirFlow = FinalSysSizing(AirLoopNum).DesHeatVolFlow * FractionOfAutosize;
7198 0 : } break;
7199 0 : case FractionOfAutosizedCoolingAirflow: {
7200 0 : FractionOfAutosize = FinalSysSizing(AirLoopNum).FractionOfAutosizedCoolingAirflow;
7201 0 : CalcSysSizing(AirLoopNum).InpDesHeatAirFlow = CalcSysSizing(AirLoopNum).DesHeatVolFlow * FractionOfAutosize;
7202 0 : FinalSysSizing(AirLoopNum).InpDesHeatAirFlow = FinalSysSizing(AirLoopNum).DesHeatVolFlow * FractionOfAutosize;
7203 0 : } break;
7204 1 : case FlowPerHeatingCapacity: {
7205 1 : if (FinalSysSizing(AirLoopNum).HeatingCapMethod == FractionOfAutosizedHeatingCapacity) {
7206 1 : FractionOfAutosize = FinalSysSizing(AirLoopNum).ScaledHeatingCapacity;
7207 1 : if (FinalSysSizing(AirLoopNum).HeatOAOption == MinOA) {
7208 1 : if (FinalSysSizing(AirLoopNum).DesHeatVolFlow > 0.0) {
7209 1 : OutAirFrac = FinalSysSizing(AirLoopNum).DesOutAirVolFlow / FinalSysSizing(AirLoopNum).DesHeatVolFlow;
7210 : } else {
7211 0 : OutAirFrac = 1.0;
7212 : }
7213 1 : OutAirFrac = std::min(1.0, std::max(0.0, OutAirFrac));
7214 : } else {
7215 0 : OutAirFrac = 1.0;
7216 : }
7217 1 : if (state.dataSize->CurOASysNum == 0 && PrimaryAirSystems(AirLoopNum).NumOAHeatCoils > 0) {
7218 0 : CoilInTemp = OutAirFrac * FinalSysSizing(AirLoopNum).PreheatTemp + (1.0 - OutAirFrac) * FinalSysSizing(AirLoopNum).HeatRetTemp;
7219 : } else {
7220 1 : CoilInTemp = OutAirFrac * FinalSysSizing(AirLoopNum).HeatOutTemp + (1.0 - OutAirFrac) * FinalSysSizing(AirLoopNum).HeatRetTemp;
7221 : }
7222 1 : CoilOutTemp = FinalSysSizing(AirLoopNum).HeatSupTemp;
7223 1 : CpAirStd = PsyCpAirFnW(DataPrecisionGlobals::constant_zero);
7224 1 : AutosizedCapacity = state.dataEnvrn->StdRhoAir * FinalSysSizing(AirLoopNum).DesHeatVolFlow * CpAirStd * (CoilOutTemp - CoilInTemp);
7225 1 : TempSize = FinalSysSizing(AirLoopNum).FlowPerHeatingCapacity * AutosizedCapacity * FractionOfAutosize;
7226 0 : } else if (FinalSysSizing(AirLoopNum).HeatingCapMethod == HeatingDesignCapacity) {
7227 0 : if (FinalSysSizing(AirLoopNum).ScaledHeatingCapacity == DataSizing::AutoSize) {
7228 0 : if (FinalSysSizing(AirLoopNum).HeatOAOption == MinOA) {
7229 0 : if (FinalSysSizing(AirLoopNum).DesHeatVolFlow > 0.0) {
7230 0 : OutAirFrac = FinalSysSizing(AirLoopNum).DesOutAirVolFlow / FinalSysSizing(AirLoopNum).DesHeatVolFlow;
7231 : } else {
7232 0 : OutAirFrac = 1.0;
7233 : }
7234 0 : OutAirFrac = std::min(1.0, std::max(0.0, OutAirFrac));
7235 : } else {
7236 0 : OutAirFrac = 1.0;
7237 : }
7238 0 : if (state.dataSize->CurOASysNum == 0 && PrimaryAirSystems(AirLoopNum).NumOAHeatCoils > 0) {
7239 0 : CoilInTemp =
7240 0 : OutAirFrac * FinalSysSizing(AirLoopNum).PreheatTemp + (1.0 - OutAirFrac) * FinalSysSizing(AirLoopNum).HeatRetTemp;
7241 : } else {
7242 0 : CoilInTemp =
7243 0 : OutAirFrac * FinalSysSizing(AirLoopNum).HeatOutTemp + (1.0 - OutAirFrac) * FinalSysSizing(AirLoopNum).HeatRetTemp;
7244 : }
7245 0 : CoilOutTemp = FinalSysSizing(AirLoopNum).HeatSupTemp;
7246 0 : CpAirStd = PsyCpAirFnW(DataPrecisionGlobals::constant_zero);
7247 0 : AutosizedCapacity =
7248 0 : state.dataEnvrn->StdRhoAir * FinalSysSizing(AirLoopNum).DesHeatVolFlow * CpAirStd * (CoilOutTemp - CoilInTemp);
7249 0 : TempSize = FinalSysSizing(AirLoopNum).FlowPerHeatingCapacity * AutosizedCapacity * FractionOfAutosize;
7250 : } else {
7251 0 : TempSize = FinalSysSizing(AirLoopNum).FlowPerHeatingCapacity * FinalSysSizing(AirLoopNum).ScaledHeatingCapacity;
7252 : }
7253 0 : } else if (FinalSysSizing(AirLoopNum).HeatingCapMethod == CapacityPerFloorArea) {
7254 0 : TempSize = FinalSysSizing(AirLoopNum).FlowPerHeatingCapacity * FinalSysSizing(AirLoopNum).ScaledHeatingCapacity *
7255 0 : FinalSysSizing(AirLoopNum).FloorAreaOnAirLoopCooled;
7256 : }
7257 1 : CalcSysSizing(AirLoopNum).InpDesHeatAirFlow = TempSize;
7258 1 : FinalSysSizing(AirLoopNum).InpDesHeatAirFlow = TempSize;
7259 1 : } break;
7260 924 : default:
7261 924 : break;
7262 : }
7263 :
7264 : // save the total cooling capacity sizing data for scalable sizing
7265 925 : switch (FinalSysSizing(AirLoopNum).CoolingCapMethod) {
7266 924 : case CoolingDesignCapacity: {
7267 924 : if (CalcSysSizing(AirLoopNum).ScaledCoolingCapacity > 0.0) {
7268 0 : CalcSysSizing(AirLoopNum).CoolingTotalCapacity = CalcSysSizing(AirLoopNum).ScaledCoolingCapacity;
7269 0 : FinalSysSizing(AirLoopNum).CoolingTotalCapacity = CalcSysSizing(AirLoopNum).ScaledCoolingCapacity;
7270 : } else {
7271 924 : FinalSysSizing(AirLoopNum).CoolingTotalCapacity = 0.0; // autosized, set to zero initially
7272 : }
7273 924 : } break;
7274 0 : case CapacityPerFloorArea: {
7275 0 : FinalSysSizing(AirLoopNum).CoolingTotalCapacity =
7276 0 : CalcSysSizing(AirLoopNum).ScaledCoolingCapacity * FinalSysSizing(AirLoopNum).FloorAreaOnAirLoopCooled;
7277 0 : } break;
7278 1 : case FractionOfAutosizedCoolingCapacity: {
7279 1 : CalcSysSizing(AirLoopNum).FractionOfAutosizedCoolingCapacity = CalcSysSizing(AirLoopNum).ScaledCoolingCapacity;
7280 1 : FinalSysSizing(AirLoopNum).FractionOfAutosizedCoolingCapacity = CalcSysSizing(AirLoopNum).ScaledCoolingCapacity;
7281 1 : } break;
7282 0 : default:
7283 0 : break;
7284 : }
7285 :
7286 : // save the total heating capacity sizing data for scalable sizing
7287 925 : switch (FinalSysSizing(AirLoopNum).HeatingCapMethod) {
7288 924 : case HeatingDesignCapacity: {
7289 924 : if (CalcSysSizing(AirLoopNum).ScaledHeatingCapacity > 0.0) {
7290 0 : FinalSysSizing(AirLoopNum).HeatingTotalCapacity = CalcSysSizing(AirLoopNum).ScaledHeatingCapacity;
7291 : } else {
7292 924 : FinalSysSizing(AirLoopNum).HeatingTotalCapacity = 0.0; // autosized, set to zero initially
7293 : }
7294 924 : } break;
7295 0 : case CapacityPerFloorArea: {
7296 : // even for heating capacity we use cooled zones floor area ( *.FloorAreaOnAirLoopCooled ) served by the airloop
7297 0 : FinalSysSizing(AirLoopNum).HeatingTotalCapacity =
7298 0 : CalcSysSizing(AirLoopNum).ScaledHeatingCapacity * FinalSysSizing(AirLoopNum).FloorAreaOnAirLoopCooled;
7299 0 : } break;
7300 1 : case FractionOfAutosizedHeatingCapacity: {
7301 1 : FinalSysSizing(AirLoopNum).FractionOfAutosizedHeatingCapacity = CalcSysSizing(AirLoopNum).ScaledHeatingCapacity;
7302 1 : } break;
7303 0 : default:
7304 0 : break;
7305 : }
7306 : }
7307 925 : }
7308 :
7309 14 : Real64 GetHeatingSATempForSizing(EnergyPlusData &state, int const IndexAirLoop // air loop index
7310 : )
7311 : {
7312 :
7313 : // SUBROUTINE INFORMATION:
7314 : // AUTHOR Fred Buhl, Rongpeng Zhang
7315 : // DATE WRITTEN October 2015
7316 : // MODIFIED na
7317 : // RE-ENGINEERED na
7318 :
7319 : // PURPOSE OF THIS SUBROUTINE:
7320 : // This subroutine get the proper reheat coil inlet temperature for sizing, depending on
7321 : // the system configurations:
7322 : // (1) Central heating coils exist
7323 : // (2) No central heating coils, but preheating coils or OA heat-exchangers exist
7324 : // (3) No central heating coils; No preheating coils or OA heat-exchangers
7325 :
7326 : // Using/Aliasing
7327 : using namespace DataSizing;
7328 : using Psychrometrics::PsyHFnTdbW;
7329 : using Psychrometrics::PsyTdbFnHW;
7330 :
7331 : // Locals
7332 : Real64 ReheatCoilInTempForSizing; // Dry bulb temperature of the reheat coil inlet air [C]
7333 : Real64 ReheatCoilInHumRatForSizing; // Humidity ratio of the reheat coil inlet air [kg/kg]
7334 : Real64 ReheatCoilInEnthalpyForSizing; // Enthalpy of the reheat coil inlet air [J/kg]
7335 : Real64 OutAirFrac;
7336 :
7337 14 : auto &CalcSysSizing(state.dataSize->CalcSysSizing);
7338 14 : auto &FinalSysSizing(state.dataSize->FinalSysSizing);
7339 14 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
7340 :
7341 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7342 :
7343 14 : if (PrimaryAirSystems(IndexAirLoop).CentralHeatCoilExists) {
7344 : // Case: Central heating coils exist
7345 :
7346 14 : ReheatCoilInTempForSizing = CalcSysSizing(IndexAirLoop).HeatSupTemp;
7347 :
7348 0 : } else if ((PrimaryAirSystems(IndexAirLoop).NumOAHeatCoils > 0) || (PrimaryAirSystems(IndexAirLoop).NumOAHXs)) {
7349 : // Case: No central heating coils, but preheating coils or OA heat-exchangers exist
7350 :
7351 0 : if (FinalSysSizing(IndexAirLoop).DesHeatVolFlow > 0) {
7352 0 : OutAirFrac = FinalSysSizing(IndexAirLoop).DesOutAirVolFlow / FinalSysSizing(IndexAirLoop).DesHeatVolFlow;
7353 0 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
7354 : } else {
7355 0 : OutAirFrac = 0.0;
7356 : }
7357 :
7358 : // Mixed air humidity ratio and enthalpy
7359 0 : ReheatCoilInHumRatForSizing =
7360 0 : OutAirFrac * FinalSysSizing(IndexAirLoop).PreheatHumRat + (1 - OutAirFrac) * FinalSysSizing(IndexAirLoop).HeatRetHumRat;
7361 0 : ReheatCoilInEnthalpyForSizing =
7362 0 : OutAirFrac * PsyHFnTdbW(FinalSysSizing(IndexAirLoop).PreheatTemp, FinalSysSizing(IndexAirLoop).PreheatHumRat) +
7363 0 : (1 - OutAirFrac) * PsyHFnTdbW(FinalSysSizing(IndexAirLoop).HeatRetTemp, FinalSysSizing(IndexAirLoop).HeatRetHumRat);
7364 :
7365 : // Mixed air dry bulb temperature
7366 0 : ReheatCoilInTempForSizing = PsyTdbFnHW(ReheatCoilInEnthalpyForSizing, ReheatCoilInHumRatForSizing);
7367 :
7368 : } else {
7369 : // Case: No central heating coils; No preheating coils or OA heat-exchangers
7370 :
7371 0 : ReheatCoilInTempForSizing = FinalSysSizing(IndexAirLoop).HeatMixTemp;
7372 : }
7373 :
7374 14 : return ReheatCoilInTempForSizing;
7375 : }
7376 :
7377 14 : Real64 GetHeatingSATempHumRatForSizing(EnergyPlusData &state, int const IndexAirLoop // air loop index
7378 : )
7379 : {
7380 :
7381 : // SUBROUTINE INFORMATION:
7382 : // AUTHOR Fred Buhl, Rongpeng Zhang
7383 : // DATE WRITTEN October 2015
7384 : // MODIFIED na
7385 : // RE-ENGINEERED na
7386 :
7387 : // PURPOSE OF THIS SUBROUTINE:
7388 : // This subroutine get the proper reheat coil inlet humidity ratio for sizing, depending on
7389 : // the system configurations:
7390 : // (1) Central heating coils exist
7391 : // (2) No central heating coils, but preheating coils or OA heat-exchangers exist
7392 : // (3) No central heating coils; No preheating coils or OA heat-exchangers
7393 :
7394 : // Using/Aliasing
7395 : using namespace DataSizing;
7396 :
7397 : // Locals
7398 : Real64 ReheatCoilInHumRatForSizing;
7399 : Real64 OutAirFrac;
7400 :
7401 14 : auto &FinalSysSizing(state.dataSize->FinalSysSizing);
7402 14 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
7403 :
7404 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7405 :
7406 14 : if (PrimaryAirSystems(IndexAirLoop).CentralHeatCoilExists) {
7407 : // Case: Central heating coils exist
7408 :
7409 14 : ReheatCoilInHumRatForSizing = state.dataSize->CalcSysSizing(IndexAirLoop).HeatSupHumRat;
7410 :
7411 0 : } else if ((PrimaryAirSystems(IndexAirLoop).NumOAHeatCoils > 0) || (PrimaryAirSystems(IndexAirLoop).NumOAHXs)) {
7412 : // Case: No central heating coils, but preheating coils or OA heat-exchangers exist
7413 :
7414 0 : if (FinalSysSizing(IndexAirLoop).DesHeatVolFlow > 0) {
7415 0 : OutAirFrac = FinalSysSizing(IndexAirLoop).DesOutAirVolFlow / FinalSysSizing(IndexAirLoop).DesHeatVolFlow;
7416 0 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
7417 : } else {
7418 0 : OutAirFrac = 0.0;
7419 : }
7420 :
7421 0 : ReheatCoilInHumRatForSizing =
7422 0 : OutAirFrac * FinalSysSizing(IndexAirLoop).PreheatHumRat + (1 - OutAirFrac) * FinalSysSizing(IndexAirLoop).HeatRetHumRat;
7423 :
7424 : } else {
7425 : // Case: No central heating coils; No preheating coils or OA heat-exchangers
7426 :
7427 0 : ReheatCoilInHumRatForSizing = FinalSysSizing(IndexAirLoop).HeatMixHumRat;
7428 : }
7429 :
7430 14 : return ReheatCoilInHumRatForSizing;
7431 : }
7432 :
7433 822 : void CheckWaterCoilIsOnAirLoop(EnergyPlusData &state,
7434 : SimAirServingZones::CompType const CompTypeNum,
7435 : std::string const &CompType,
7436 : std::string const &CompName,
7437 : bool &WaterCoilOnAirLoop)
7438 : {
7439 : // PURPOSE OF THIS FUNCTION:
7440 : // This function returns true if a water coil that has water controller is either on
7441 : // primary air or outdoor air system branch. Searches for water coil name and type
7442 : // that match components list in primary air and outside air systems.
7443 :
7444 : // Return value
7445 822 : bool CheckWaterCoilIsOnAirLoop(false);
7446 :
7447 822 : CheckWaterCoilIsOnAirLoop = CheckWaterCoilOnPrimaryAirLoopBranch(state, CompTypeNum, CompName);
7448 822 : if (!CheckWaterCoilIsOnAirLoop) {
7449 59 : CheckWaterCoilIsOnAirLoop = CheckWaterCoilOnOASystem(state, CompTypeNum, CompName);
7450 : }
7451 :
7452 822 : if (!CheckWaterCoilIsOnAirLoop) {
7453 5 : CheckWaterCoilIsOnAirLoop = CheckWaterCoilSystemOnAirLoopOrOASystem(state, CompTypeNum, CompName);
7454 : }
7455 822 : if (!CheckWaterCoilIsOnAirLoop) {
7456 0 : ShowSevereError(state, "CheckWaterCoilIsOnAirLoop: = " + CompType + " = " + CompName + ".");
7457 0 : ShowContinueError(state,
7458 : "The water coil or coil system is neither on primary air branch nor on outdoor air system hence does not require "
7459 : "'Controller:WaterCoil' object.");
7460 : }
7461 822 : WaterCoilOnAirLoop = CheckWaterCoilIsOnAirLoop;
7462 822 : }
7463 :
7464 827 : bool CheckWaterCoilOnPrimaryAirLoopBranch(EnergyPlusData &state, SimAirServingZones::CompType const CompTypeNum, std::string const &CompName)
7465 : {
7466 : // PURPOSE OF THIS FUNCTION:
7467 : // This function returns true if a water coil that has water controller is on
7468 : // primary air loop branch. Searches for water coil name and type that match
7469 : // components list in primary air systems.
7470 :
7471 827 : auto &PrimaryAirSystems(state.dataAirSystemsData->PrimaryAirSystems);
7472 :
7473 827 : if (state.dataSimAirServingZones->GetAirLoopInputFlag) { // First time subroutine has been entered
7474 0 : GetAirPathData(state); // Get air loop descriptions from input file
7475 0 : state.dataSimAirServingZones->GetAirLoopInputFlag = false;
7476 : }
7477 :
7478 827 : if (state.dataHVACGlobal->NumPrimaryAirSys > 0) {
7479 1633 : for (int AirSysNum = 1; AirSysNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirSysNum) {
7480 2408 : for (int BranchNum = 1; BranchNum <= PrimaryAirSystems(AirSysNum).NumBranches; ++BranchNum) {
7481 7260 : for (int CompNum = 1; CompNum <= PrimaryAirSystems(AirSysNum).Branch(BranchNum).TotalComponents; ++CompNum) {
7482 8472 : if ((CompTypeNum == PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num) &&
7483 2046 : UtilityRoutines::SameString(CompName, PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name)) {
7484 768 : return true;
7485 : }
7486 : }
7487 : }
7488 : }
7489 : }
7490 59 : return false;
7491 : }
7492 :
7493 59 : bool CheckWaterCoilOnOASystem(EnergyPlusData &state, SimAirServingZones::CompType const CompTypeNum, std::string const &CompName)
7494 : {
7495 : // PURPOSE OF THIS FUNCTION:
7496 : // This function returns true if a water coil that has water controller is on
7497 : // outdoor air system. Searches for water coil name and type that match
7498 : // components list on outside air systems.
7499 :
7500 : // USE STATEMENTS:
7501 : using MixedAir::GetNumOASystems;
7502 : using MixedAir::GetOutsideAirSysInputs;
7503 :
7504 59 : auto &OutsideAirSys(state.dataAirLoop->OutsideAirSys);
7505 :
7506 59 : if (state.dataMixedAir->GetOASysInputFlag) {
7507 0 : GetOutsideAirSysInputs(state);
7508 0 : state.dataMixedAir->GetOASysInputFlag = false;
7509 : }
7510 59 : int NumOASys = GetNumOASystems(state);
7511 59 : if (NumOASys > 0) {
7512 76 : for (int OASysNum = 1; OASysNum <= NumOASys; ++OASysNum) {
7513 122 : for (int OACompNum = 1; OACompNum <= OutsideAirSys(OASysNum).NumComponents; ++OACompNum) {
7514 161 : if ((CompTypeNum == OutsideAirSys(OASysNum).ComponentTypeEnum(OACompNum)) &&
7515 56 : (UtilityRoutines::SameString(CompName, OutsideAirSys(OASysNum).ComponentName(OACompNum)))) {
7516 54 : return true;
7517 : }
7518 : }
7519 : }
7520 : }
7521 5 : return false;
7522 : }
7523 :
7524 5 : bool CheckWaterCoilSystemOnAirLoopOrOASystem(EnergyPlusData &state, SimAirServingZones::CompType const CompTypeNum, std::string const &CompName)
7525 : {
7526 : // PURPOSE OF THIS FUNCTION:
7527 : // This function returns true if a water coil which is part of CoilSystem:Cooling:Water:HeatExchangerAssisted
7528 : // and that has water controller is on primary air loop branch or outdoor air system. Searches for water coilsystem
7529 : // type and name that match components list in primary air loop or outside air systems.
7530 :
7531 : // USE STATEMENTS:
7532 : using HVACHXAssistedCoolingCoil::GetHXAssistedCoolingCoilInput;
7533 :
7534 : // Return value
7535 5 : bool CheckWaterCoilSystemIsOnAirLoopOASystem(false);
7536 :
7537 5 : if (state.dataHVACAssistedCC->GetCoilsInputFlag) {
7538 : // Get the HXAssistedCoolingCoil input
7539 5 : GetHXAssistedCoolingCoilInput(state);
7540 5 : state.dataHVACAssistedCC->GetCoilsInputFlag = false;
7541 : }
7542 :
7543 5 : bool WaterCoilIsOnWaterCoilSystem = false;
7544 10 : std::string CoilSystemName = CompName;
7545 5 : CompType CoilSystemTypeNum = CompTypeNum;
7546 :
7547 5 : if (state.dataHVACAssistedCC->TotalNumHXAssistedCoils > 0) {
7548 : // check if the water coil is placed on 'CoilSystem:Cooling:Water:HeatExchangerAssisted' object
7549 5 : for (int HXASSCoilNum = 1; HXASSCoilNum <= state.dataHVACAssistedCC->TotalNumHXAssistedCoils; ++HXASSCoilNum) {
7550 5 : std::string CompType = state.dataHVACAssistedCC->HXAssistedCoil(HXASSCoilNum).CoolingCoilType;
7551 15 : if ((UtilityRoutines::SameString(CompType, "Coil:Cooling:Water") ||
7552 10 : UtilityRoutines::SameString(CompType, "Coil:Cooling:Water:DetailedGeometry")) &&
7553 5 : UtilityRoutines::SameString(CompName, state.dataHVACAssistedCC->HXAssistedCoil(HXASSCoilNum).CoolingCoilName)) {
7554 5 : CoilSystemName = state.dataHVACAssistedCC->HXAssistedCoil(HXASSCoilNum).Name;
7555 5 : CoilSystemTypeNum = SimAirServingZones::CompType::WaterCoil_CoolingHXAsst;
7556 5 : WaterCoilIsOnWaterCoilSystem = true;
7557 5 : break;
7558 : }
7559 : }
7560 : }
7561 :
7562 : // check if the CoilSystem object that contains the water coil is placed on air loop branch or OA system
7563 5 : if (WaterCoilIsOnWaterCoilSystem) {
7564 5 : CheckWaterCoilSystemIsOnAirLoopOASystem = CheckWaterCoilOnPrimaryAirLoopBranch(state, CoilSystemTypeNum, CoilSystemName);
7565 5 : if (!CheckWaterCoilSystemIsOnAirLoopOASystem) {
7566 0 : CheckWaterCoilSystemIsOnAirLoopOASystem = CheckWaterCoilOnOASystem(state, CoilSystemTypeNum, CoilSystemName);
7567 : }
7568 : }
7569 10 : return CheckWaterCoilSystemIsOnAirLoopOASystem;
7570 : }
7571 : // namespace SimAirServingZones
7572 :
7573 : // End Algorithm Section of the Module
7574 : // *****************************************************************************
7575 :
7576 : // Beginning of Reporting subroutines for the SimAir Module
7577 : // *****************************************************************************
7578 :
7579 : // End of Reporting subroutines for the SimAir Module
7580 : // *****************************************************************************
7581 :
7582 : // Utility Subroutines for the SimAir Module
7583 : // *****************************************************************************
7584 :
7585 136 : void LimitZoneVentEff(EnergyPlusData &state,
7586 : Real64 Xs, // ratio of uncorrected system outdoor air flow rate to the design system supply flow rate
7587 : Real64 Voz, // corrected (divided by distribution efficiency) zone outside air flow rate [m3/s]
7588 : int TermUnitSizingIndex, // terminal unit sizing index
7589 : Real64 &SystemCoolingEv // system ventilation efficiency
7590 : )
7591 : {
7592 : // FUNCTION INFORMATION:
7593 : // AUTHOR Fred Buhl
7594 : // DATE WRITTEN November 2015
7595 :
7596 : // PURPOSE OF THIS FUNCTION:
7597 : // Check that system ventilation eff is not less than input minimum system ventilation efficiency.
7598 : // If it is, back calculate and reset ZpzClgByZone and DesCoolVolFlowMin and system ventilation efficiency
7599 : // Also increase DesCoolVolFlow if needed to match the new DesCoolVolFlowMin
7600 : // Why does this look only at cooling? Shouldn't heating also be checked?
7601 :
7602 : // METHODOLOGY EMPLOYED:
7603 : // Ventilation Rate Procedure for single pass system
7604 :
7605 136 : auto &TUFinalZoneSizing = state.dataSize->TermUnitFinalZoneSizing(TermUnitSizingIndex);
7606 :
7607 136 : if (SystemCoolingEv < TUFinalZoneSizing.ZoneVentilationEff) {
7608 9 : Real64 ZoneOAFrac = 1.0 + Xs - TUFinalZoneSizing.ZoneVentilationEff; // ratio of Voz to available zone supply air flow
7609 9 : Real64 AvailSAFlow = Voz / ZoneOAFrac; // reset AvailSAFlow (which in this case is minimum cooling supply air flow rate)
7610 9 : TUFinalZoneSizing.ZpzClgByZone = ZoneOAFrac; // save ZoneOAFrac
7611 9 : TUFinalZoneSizing.DesCoolVolFlowMin = AvailSAFlow; // save new (increased) minimum flow rate
7612 9 : TUFinalZoneSizing.DesCoolVolFlow = max(AvailSAFlow, TUFinalZoneSizing.DesCoolVolFlow); // make sure max flow is >= the new minimum flow rate
7613 9 : SystemCoolingEv = TUFinalZoneSizing.ZoneVentilationEff; // set the system ventilation efficiency to the user specified minimum
7614 :
7615 : // Vpz: "Primary" supply air from main air handler served by an oa mixer
7616 9 : Real64 VpzClgByZone = TUFinalZoneSizing.DesCoolVolFlow;
7617 :
7618 : // Vdz: "Discharge" supply air delivered to zone by terminal unit
7619 9 : Real64 VdzClgByZone = 0.0;
7620 : // Taken from similar section in SetUpSysSizingArrays
7621 9 : if (TUFinalZoneSizing.ZoneSecondaryRecirculation > 0.0) { // multi-path system
7622 0 : VdzClgByZone = max(state.dataSize->TermUnitSizing(TermUnitSizingIndex).AirVolFlow, VpzClgByZone);
7623 : } else { // single path system
7624 9 : VdzClgByZone = TUFinalZoneSizing.DesCoolVolFlow;
7625 : }
7626 :
7627 : // Update VRP table entries:
7628 9 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchS62zcdVpz, TUFinalZoneSizing.ZoneName, VpzClgByZone, 4);
7629 9 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchS62zcdVdz, TUFinalZoneSizing.ZoneName, VdzClgByZone, 4);
7630 18 : OutputReportPredefined::PreDefTableEntry(
7631 9 : state, state.dataOutRptPredefined->pdchS62zcdVpzmin, TUFinalZoneSizing.ZoneName, TUFinalZoneSizing.DesCoolVolFlowMin, 4);
7632 : // Zpz = Voz/Vpz
7633 18 : OutputReportPredefined::PreDefTableEntry(
7634 9 : state, state.dataOutRptPredefined->pdchS62zcdZpz, TUFinalZoneSizing.ZoneName, TUFinalZoneSizing.ZpzClgByZone, 3);
7635 : }
7636 136 : }
7637 :
7638 : // End of Utility subroutines for the SimAir Module
7639 : // *****************************************************************************
7640 :
7641 2313 : } // namespace EnergyPlus::SimAirServingZones
|