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