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