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