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