Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <algorithm>
50 : #include <cmath>
51 :
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Fmath.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <EnergyPlus/Data/EnergyPlusData.hh>
57 : #include <EnergyPlus/DataContaminantBalance.hh>
58 : #include <EnergyPlus/DataEnvironment.hh>
59 : #include <EnergyPlus/DataHeatBalance.hh>
60 : #include <EnergyPlus/DataLoopNode.hh>
61 : #include <EnergyPlus/DataZoneEquipment.hh>
62 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
63 : #include <EnergyPlus/NodeInputManager.hh>
64 : #include <EnergyPlus/PoweredInductionUnits.hh>
65 : #include <EnergyPlus/Psychrometrics.hh>
66 : #include <EnergyPlus/PurchasedAirManager.hh>
67 : #include <EnergyPlus/UtilityRoutines.hh>
68 : #include <EnergyPlus/ZonePlenum.hh>
69 :
70 : namespace EnergyPlus::ZonePlenum {
71 : // Module containing simulation routines for both zone return and zone supply plenums
72 :
73 : // MODULE INFORMATION:
74 : // AUTHOR Peter Graham Ellis
75 : // DATE WRITTEN November 2000
76 : // MODIFIED na
77 : // RE-ENGINEERED na
78 :
79 : // PURPOSE OF THIS MODULE:
80 : // To encapsulate the data and algorithms required to
81 : // manage Air Path Zone Return Plenum Components
82 :
83 : // METHODOLOGY EMPLOYED:
84 : // The Zone Plenum
85 :
86 : // Using/Aliasing
87 : using namespace DataLoopNode;
88 : using Psychrometrics::PsyHFnTdbW;
89 : using Psychrometrics::PsyTdbFnHW;
90 :
91 : // Functions
92 :
93 2607428 : void SimAirZonePlenum(EnergyPlusData &state,
94 : std::string_view CompName,
95 : DataZoneEquipment::AirLoopHVACZone const iCompType,
96 : int &CompIndex,
97 : Optional_bool_const FirstHVACIteration, // Autodesk:OPTIONAL Used without PRESENT check
98 : Optional_bool_const FirstCall, // Autodesk:OPTIONAL Used without PRESENT check
99 : Optional_bool PlenumInletChanged // Autodesk:OPTIONAL Used without PRESENT check
100 : )
101 : {
102 :
103 : // SUBROUTINE INFORMATION:
104 : // AUTHOR Peter Graham Ellis
105 : // DATE WRITTEN November 2000
106 : // MODIFIED March 2000
107 : // RE-ENGINEERED na
108 :
109 : // PURPOSE OF THIS SUBROUTINE:
110 : // This subroutine manages the ZonePlenum component simulation for both
111 : // return and supply plenums.
112 : // It is called from the SimAirLoopComponent at the system time step.
113 :
114 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
115 : int ZonePlenumNum; // The ZonePlenum that you are currently loading input into
116 :
117 : // Obtains and Allocates ZonePlenum related parameters from input file
118 2607428 : if (state.dataZonePlenum->GetInputFlag) { // First time subroutine has been entered
119 184 : GetZonePlenumInput(state);
120 184 : state.dataZonePlenum->GetInputFlag = false;
121 : }
122 :
123 2607428 : if (iCompType == DataZoneEquipment::AirLoopHVACZone::ReturnPlenum) { // 'AirLoopHVAC:ReturnPlenum'
124 : // Find the correct ZonePlenumNumber
125 2528260 : if (CompIndex == 0) {
126 271 : ZonePlenumNum =
127 271 : UtilityRoutines::FindItemInList(CompName, state.dataZonePlenum->ZoneRetPlenCond, &ZoneReturnPlenumConditions::ZonePlenumName);
128 271 : if (ZonePlenumNum == 0) {
129 0 : ShowFatalError(state, "SimAirZonePlenum: AirLoopHVAC:ReturnPlenum not found=" + std::string{CompName});
130 : }
131 271 : CompIndex = ZonePlenumNum;
132 : } else {
133 2527989 : ZonePlenumNum = CompIndex;
134 2527989 : if (ZonePlenumNum > state.dataZonePlenum->NumZoneReturnPlenums || ZonePlenumNum < 1) {
135 0 : ShowFatalError(
136 : state,
137 0 : format("SimAirZonePlenum: Invalid CompIndex passed={}, Number of AirLoopHVAC:ReturnPlenum={}, AirLoopHVAC:ReturnPlenum name={}",
138 : ZonePlenumNum,
139 0 : state.dataZonePlenum->NumZoneReturnPlenums,
140 0 : CompName));
141 : }
142 2527989 : if (state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).checkEquipName) {
143 272 : if (CompName != state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZonePlenumName) {
144 0 : ShowFatalError(state,
145 0 : format("SimAirZonePlenum: Invalid CompIndex passed={}, AirLoopHVAC:ReturnPlenum name={}, stored "
146 : "AirLoopHVAC:ReturnPlenum Name for that index={}",
147 : ZonePlenumNum,
148 : CompName,
149 0 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZonePlenumName));
150 : }
151 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).checkEquipName = false;
152 : }
153 : }
154 :
155 2528260 : InitAirZoneReturnPlenum(state, ZonePlenumNum); // Initialize all ZonePlenum related parameters
156 :
157 2528260 : CalcAirZoneReturnPlenum(state, ZonePlenumNum);
158 :
159 2528260 : UpdateAirZoneReturnPlenum(state, ZonePlenumNum); // Update the current ZonePlenum to the outlet nodes
160 :
161 79168 : } else if (iCompType == DataZoneEquipment::AirLoopHVACZone::SupplyPlenum) { // 'AirLoopHVAC:SupplyPlenum'
162 : // Find the correct ZonePlenumNumber
163 79168 : if (CompIndex == 0) {
164 8 : ZonePlenumNum =
165 8 : UtilityRoutines::FindItemInList(CompName, state.dataZonePlenum->ZoneSupPlenCond, &ZoneSupplyPlenumConditions::ZonePlenumName);
166 8 : if (ZonePlenumNum == 0) {
167 0 : ShowFatalError(state, "SimAirZonePlenum: AirLoopHVAC:SupplyPlenum not found=" + std::string{CompName});
168 : }
169 8 : CompIndex = ZonePlenumNum;
170 : } else {
171 79160 : ZonePlenumNum = CompIndex;
172 79160 : if (ZonePlenumNum > state.dataZonePlenum->NumZoneSupplyPlenums || ZonePlenumNum < 1) {
173 0 : ShowFatalError(
174 : state,
175 0 : format("SimAirZonePlenum: Invalid CompIndex passed={}, Number of AirLoopHVAC:SupplyPlenum={}, AirLoopHVAC:SupplyPlenum name={}",
176 : ZonePlenumNum,
177 0 : state.dataZonePlenum->NumZoneReturnPlenums,
178 0 : CompName));
179 : }
180 79160 : if (state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).checkEquipName) {
181 8 : if (CompName != state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZonePlenumName) {
182 0 : ShowFatalError(state,
183 0 : format("SimAirZonePlenum: Invalid CompIndex passed={}, AirLoopHVAC:SupplyPlenum name={}, stored "
184 : "AirLoopHVAC:SupplyPlenum Name for that index={}",
185 : ZonePlenumNum,
186 : CompName,
187 0 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZonePlenumName));
188 : }
189 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).checkEquipName = false;
190 : }
191 : }
192 :
193 79168 : InitAirZoneSupplyPlenum(state, ZonePlenumNum, FirstHVACIteration, FirstCall); // Initialize all ZonePlenum related parameters
194 :
195 79168 : CalcAirZoneSupplyPlenum(state, ZonePlenumNum, FirstCall);
196 : // Update the current ZonePlenum to the outlet nodes
197 79168 : UpdateAirZoneSupplyPlenum(state, ZonePlenumNum, PlenumInletChanged, FirstCall);
198 :
199 : } else {
200 0 : ShowSevereError(state, "SimAirZonePlenum: Errors in Plenum=" + std::string{CompName});
201 0 : ShowContinueError(state, format("ZonePlenum: Unhandled plenum type found:{}", iCompType));
202 0 : ShowFatalError(state, "Preceding conditions cause termination.");
203 : }
204 2607428 : }
205 :
206 190 : void GetZonePlenumInput(EnergyPlusData &state)
207 : {
208 :
209 : // SUBROUTINE INFORMATION:
210 : // AUTHOR Peter Graham Ellis
211 : // DATE WRITTEN November 2000
212 : // MODIFIED August 2003, FCW: For each zone with a return air plenum put the ZoneRetPlenCond
213 : // number for the return air plenum in the ZoneEquipConfig array for the zone
214 : // for later access to the zone's return air plenum conditions.
215 : // RE-ENGINEERED na
216 :
217 : // PURPOSE OF THIS SUBROUTINE:
218 : // This subroutine is the main routine to call other input routines and Get routines
219 :
220 : // METHODOLOGY EMPLOYED:
221 : // Uses the status flags to trigger events.
222 :
223 : // Using/Aliasing
224 : using DataZoneEquipment::EquipConfiguration;
225 : using NodeInputManager::CheckUniqueNodeNumbers;
226 : using NodeInputManager::EndUniqueNodeCheck;
227 : using NodeInputManager::GetNodeNums;
228 : using NodeInputManager::GetOnlySingleNode;
229 : using NodeInputManager::InitUniqueNodeCheck;
230 : using PoweredInductionUnits::PIUInducesPlenumAir;
231 : using PurchasedAirManager::CheckPurchasedAirForReturnPlenum;
232 :
233 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
234 : int ZonePlenumNum; // The ZonePlenum that you are currently loading input into
235 : int ZonePlenumLoop;
236 : int ZoneEquipConfigLoop;
237 : int NumAlphas;
238 : int NumNums;
239 : int NumArgs;
240 : int NumNodes;
241 380 : Array1D_int NodeNums;
242 : int MaxNums;
243 : int MaxAlphas;
244 : int NodeNum;
245 : int IOStat;
246 380 : Array1D<Real64> NumArray; // Numeric input items for object
247 380 : std::string CurrentModuleObject; // for ease in getting objects
248 380 : Array1D_string AlphArray; // Alpha input items for object
249 380 : Array1D_string cAlphaFields; // Alpha field names
250 380 : Array1D_string cNumericFields; // Numeric field names
251 380 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
252 380 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
253 190 : bool ErrorsFound(false);
254 : bool NodeListError; // Flag for node list error
255 : bool UniqueNodeError;
256 : static constexpr std::string_view RoutineName("GetZonePlenumInput: "); // include trailing blank space
257 380 : std::string InducedNodeListName;
258 :
259 190 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "AirLoopHVAC:ReturnPlenum", NumArgs, NumAlphas, NumNums);
260 190 : MaxNums = NumNums;
261 190 : MaxAlphas = NumAlphas;
262 190 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "AirLoopHVAC:SupplyPlenum", NumArgs, NumAlphas, NumNums);
263 190 : MaxNums = max(NumNums, MaxNums);
264 190 : MaxAlphas = max(NumAlphas, MaxAlphas);
265 190 : AlphArray.allocate(MaxAlphas);
266 190 : cAlphaFields.allocate(MaxAlphas);
267 190 : cNumericFields.allocate(MaxNums);
268 190 : NumArray.dimension(MaxNums, 0.0);
269 190 : lAlphaBlanks.dimension(MaxAlphas, true);
270 190 : lNumericBlanks.dimension(MaxNums, true);
271 190 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "NodeList", NumArgs, NumAlphas, NumNums);
272 190 : NodeNums.dimension(NumArgs, 0);
273 :
274 190 : InducedNodeListName = "";
275 :
276 190 : state.dataZonePlenum->NumZoneReturnPlenums = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:ReturnPlenum");
277 190 : state.dataZonePlenum->NumZoneSupplyPlenums = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:SupplyPlenum");
278 :
279 190 : if (state.dataZonePlenum->NumZoneReturnPlenums > 0) state.dataZonePlenum->ZoneRetPlenCond.allocate(state.dataZonePlenum->NumZoneReturnPlenums);
280 190 : if (state.dataZonePlenum->NumZoneSupplyPlenums > 0) state.dataZonePlenum->ZoneSupPlenCond.allocate(state.dataZonePlenum->NumZoneSupplyPlenums);
281 :
282 190 : ZonePlenumNum = 0;
283 :
284 190 : InitUniqueNodeCheck(state, "AirLoopHVAC:ReturnPlenum");
285 462 : for (ZonePlenumLoop = 1; ZonePlenumLoop <= state.dataZonePlenum->NumZoneReturnPlenums; ++ZonePlenumLoop) {
286 272 : ++ZonePlenumNum;
287 :
288 272 : CurrentModuleObject = "AirLoopHVAC:ReturnPlenum";
289 :
290 272 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
291 : CurrentModuleObject,
292 : ZonePlenumNum,
293 : AlphArray,
294 : NumAlphas,
295 : NumArray,
296 : NumNums,
297 : IOStat,
298 : lNumericBlanks,
299 : lAlphaBlanks,
300 : cAlphaFields,
301 : cNumericFields);
302 272 : UtilityRoutines::IsNameEmpty(state, AlphArray(1), CurrentModuleObject, ErrorsFound);
303 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZonePlenumName = AlphArray(1);
304 :
305 : // Check if this zone is also used in another return plenum
306 816 : IOStat = UtilityRoutines::FindItemInList(
307 544 : AlphArray(2), state.dataZonePlenum->ZoneRetPlenCond, &ZoneReturnPlenumConditions::ZoneName, ZonePlenumNum - 1);
308 272 : if (IOStat != 0) {
309 0 : ShowSevereError(state,
310 0 : std::string{RoutineName} + cAlphaFields(2) + " \"" + AlphArray(2) + "\" is used more than once as a " +
311 0 : CurrentModuleObject + '.');
312 0 : ShowContinueError(state, "..Only one " + CurrentModuleObject + " object may be connected to a given zone.");
313 0 : ShowContinueError(state, "..occurs in " + CurrentModuleObject + " = " + AlphArray(1));
314 0 : ErrorsFound = true;
315 : }
316 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneName = AlphArray(2);
317 : // put the X-Ref to the zone heat balance data structure
318 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ActualZoneNum = UtilityRoutines::FindItemInList(AlphArray(2), state.dataHeatBal->Zone);
319 272 : if (state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ActualZoneNum == 0) {
320 0 : ShowSevereError(state,
321 0 : "For " + CurrentModuleObject + " = " + AlphArray(1) + ", " + cAlphaFields(2) + " = " + AlphArray(2) + " not found.");
322 0 : ErrorsFound = true;
323 0 : continue;
324 : } else {
325 272 : state.dataHeatBal->Zone(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ActualZoneNum).IsReturnPlenum = true;
326 272 : state.dataHeatBal->Zone(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ActualZoneNum).PlenumCondNum = ZonePlenumNum;
327 : }
328 : // Check if this zone is used as a controlled zone
329 272 : ZoneEquipConfigLoop = UtilityRoutines::FindItemInList(AlphArray(2), state.dataZoneEquip->ZoneEquipConfig, &EquipConfiguration::ZoneName);
330 272 : if (ZoneEquipConfigLoop != 0) {
331 0 : ShowSevereError(state,
332 0 : std::string{RoutineName} + cAlphaFields(2) + " \"" + AlphArray(2) + "\" is a controlled zone. It cannot be used as a " +
333 : CurrentModuleObject);
334 0 : ShowContinueError(state, "..occurs in " + CurrentModuleObject + " = " + AlphArray(1));
335 0 : ErrorsFound = true;
336 : }
337 :
338 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneNodeName = AlphArray(3);
339 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneNodeNum =
340 544 : GetOnlySingleNode(state,
341 272 : AlphArray(3),
342 : ErrorsFound,
343 : DataLoopNode::ConnectionObjectType::AirLoopHVACReturnPlenum,
344 272 : AlphArray(1),
345 : DataLoopNode::NodeFluidType::Air,
346 : DataLoopNode::ConnectionType::ZoneNode,
347 : NodeInputManager::CompFluidStream::Primary,
348 272 : ObjectIsNotParent);
349 : // Insert the Plenum Zone Number into the Zone Heat Balance data structure for later reference
350 272 : state.dataHeatBal->Zone(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ActualZoneNum).SystemZoneNodeNumber =
351 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneNodeNum;
352 : // SpaceHB TODO: For now, assign the same system node to the spaces in the zone
353 544 : for (int spaceNum : state.dataHeatBal->Zone(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ActualZoneNum).spaceIndexes) {
354 272 : state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneNodeNum;
355 : }
356 :
357 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletNode =
358 544 : GetOnlySingleNode(state,
359 272 : AlphArray(4),
360 : ErrorsFound,
361 : DataLoopNode::ConnectionObjectType::AirLoopHVACReturnPlenum,
362 272 : AlphArray(1),
363 : DataLoopNode::NodeFluidType::Air,
364 : DataLoopNode::ConnectionType::Outlet,
365 : NodeInputManager::CompFluidStream::Primary,
366 272 : ObjectIsNotParent);
367 :
368 272 : InducedNodeListName = AlphArray(5);
369 272 : NodeListError = false;
370 544 : GetNodeNums(state,
371 : InducedNodeListName,
372 : NumNodes,
373 : NodeNums,
374 : NodeListError,
375 : DataLoopNode::NodeFluidType::Air,
376 : DataLoopNode::ConnectionObjectType::AirLoopHVACReturnPlenum,
377 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZonePlenumName,
378 : DataLoopNode::ConnectionType::InducedAir,
379 : NodeInputManager::CompFluidStream::Primary,
380 : ObjectIsNotParent,
381 : false,
382 272 : cAlphaFields(5));
383 :
384 272 : if (!NodeListError) {
385 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes = NumNodes;
386 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
387 272 : .InducedNode.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes);
388 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
389 272 : .InducedMassFlowRate.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes);
390 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
391 272 : .InducedMassFlowRateMaxAvail.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes);
392 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
393 272 : .InducedMassFlowRateMinAvail.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes);
394 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
395 272 : .InducedTemp.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes);
396 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
397 272 : .InducedHumRat.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes);
398 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
399 272 : .InducedEnthalpy.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes);
400 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
401 272 : .InducedPressure.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes);
402 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
403 272 : .InducedCO2.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes);
404 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
405 272 : .InducedGenContam.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes);
406 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedMassFlowRate = 0.0;
407 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedMassFlowRateMaxAvail = 0.0;
408 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedMassFlowRateMinAvail = 0.0;
409 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedTemp = 0.0;
410 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedHumRat = 0.0;
411 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedEnthalpy = 0.0;
412 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedPressure = 0.0;
413 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedCO2 = 0.0;
414 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedGenContam = 0.0;
415 281 : for (NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
416 9 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedNode(NodeNum) = NodeNums(NodeNum);
417 9 : UniqueNodeError = false;
418 9 : if (!CheckPurchasedAirForReturnPlenum(state, ZonePlenumNum)) {
419 9 : CheckUniqueNodeNumbers(state, "Return Plenum Induced Air Nodes", UniqueNodeError, NodeNums(NodeNum), CurrentModuleObject);
420 9 : if (UniqueNodeError) {
421 0 : ShowContinueError(state, "Occurs for ReturnPlenum = " + AlphArray(1));
422 0 : ErrorsFound = true;
423 : }
424 9 : PIUInducesPlenumAir(state, state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedNode(NodeNum));
425 : }
426 : }
427 : } else {
428 0 : ShowContinueError(state,
429 0 : "Invalid Induced Air Outlet Node or NodeList name in AirLoopHVAC:ReturnPlenum object = " +
430 0 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZonePlenumName);
431 0 : ErrorsFound = true;
432 : }
433 :
434 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes = NumAlphas - 5;
435 :
436 938 : for (auto &e : state.dataZonePlenum->ZoneRetPlenCond)
437 666 : e.InitFlag = true;
438 :
439 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletNode.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes);
440 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
441 272 : .InletMassFlowRate.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes);
442 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
443 272 : .InletMassFlowRateMaxAvail.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes);
444 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
445 272 : .InletMassFlowRateMinAvail.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes);
446 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletTemp.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes);
447 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletHumRat.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes);
448 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
449 272 : .InletEnthalpy.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes);
450 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum)
451 272 : .InletPressure.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes);
452 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneEqNum.allocate(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes);
453 :
454 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletNode = 0;
455 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRate = 0.0;
456 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail = 0.0;
457 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail = 0.0;
458 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletTemp = 0.0;
459 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletHumRat = 0.0;
460 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletEnthalpy = 0.0;
461 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletPressure = 0.0;
462 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate = 0.0;
463 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail = 0.0;
464 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail = 0.0;
465 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletTemp = 0.0;
466 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletHumRat = 0.0;
467 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletEnthalpy = 0.0;
468 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletPressure = 0.0;
469 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneTemp = 0.0;
470 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneHumRat = 0.0;
471 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneEnthalpy = 0.0;
472 :
473 1527 : for (NodeNum = 1; NodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes; ++NodeNum) {
474 :
475 1255 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletNode(NodeNum) =
476 2510 : GetOnlySingleNode(state,
477 1255 : AlphArray(5 + NodeNum),
478 : ErrorsFound,
479 : DataLoopNode::ConnectionObjectType::AirLoopHVACReturnPlenum,
480 1255 : AlphArray(1),
481 : DataLoopNode::NodeFluidType::Air,
482 : DataLoopNode::ConnectionType::Inlet,
483 : NodeInputManager::CompFluidStream::Primary,
484 1255 : ObjectIsNotParent);
485 : }
486 :
487 : } // end AirLoopHVAC:ReturnPlenum Loop
488 190 : EndUniqueNodeCheck(state, "AirLoopHVAC:ReturnPlenum");
489 :
490 190 : ZonePlenumNum = 0;
491 :
492 198 : for (ZonePlenumLoop = 1; ZonePlenumLoop <= state.dataZonePlenum->NumZoneSupplyPlenums; ++ZonePlenumLoop) {
493 8 : ++ZonePlenumNum;
494 :
495 8 : CurrentModuleObject = "AirLoopHVAC:SupplyPlenum";
496 :
497 8 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
498 : CurrentModuleObject,
499 : ZonePlenumNum,
500 : AlphArray,
501 : NumAlphas,
502 : NumArray,
503 : NumNums,
504 : IOStat,
505 : lNumericBlanks,
506 : lAlphaBlanks,
507 : cAlphaFields,
508 : cNumericFields);
509 8 : UtilityRoutines::IsNameEmpty(state, AlphArray(1), CurrentModuleObject, ErrorsFound);
510 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZonePlenumName = AlphArray(1);
511 :
512 : // Check if this zone is also used in another plenum
513 24 : IOStat = UtilityRoutines::FindItemInList(
514 16 : AlphArray(2), state.dataZonePlenum->ZoneSupPlenCond, &ZoneSupplyPlenumConditions::ZoneName, ZonePlenumNum - 1);
515 8 : if (IOStat != 0) {
516 0 : ShowSevereError(state,
517 0 : std::string{RoutineName} + cAlphaFields(2) + " \"" + AlphArray(2) + "\" is used more than once as a " +
518 0 : CurrentModuleObject + '.');
519 0 : ShowContinueError(state, "..Only one " + CurrentModuleObject + " object may be connected to a given zone.");
520 0 : ShowContinueError(state, "..occurs in " + CurrentModuleObject + " = " + AlphArray(1));
521 0 : ErrorsFound = true;
522 : }
523 8 : if (state.dataZonePlenum->NumZoneReturnPlenums > 0) { // Check if this zone is also used in another plenum
524 2 : IOStat = UtilityRoutines::FindItemInList(AlphArray(2), state.dataZonePlenum->ZoneRetPlenCond, &ZoneReturnPlenumConditions::ZoneName);
525 2 : if (IOStat != 0) {
526 0 : ShowSevereError(state,
527 0 : std::string{RoutineName} + cAlphaFields(2) + " \"" + AlphArray(2) + "\" is used more than once as a " +
528 0 : CurrentModuleObject + " or AirLoopHVAC:ReturnPlenum.");
529 0 : ShowContinueError(state,
530 0 : "..Only one " + CurrentModuleObject + " or AirLoopHVAC:ReturnPlenum object may be connected to a given zone.");
531 0 : ShowContinueError(state, "..occurs in " + CurrentModuleObject + " = " + AlphArray(1));
532 0 : ErrorsFound = true;
533 : }
534 : }
535 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneName = AlphArray(2);
536 : // put the X-Ref to the zone heat balance data structure
537 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ActualZoneNum = UtilityRoutines::FindItemInList(AlphArray(2), state.dataHeatBal->Zone);
538 8 : if (state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ActualZoneNum == 0) {
539 0 : ShowSevereError(state,
540 0 : "For " + CurrentModuleObject + " = " + AlphArray(1) + ", " + cAlphaFields(2) + " = " + AlphArray(2) + " not found.");
541 0 : ErrorsFound = true;
542 0 : continue;
543 : } else {
544 8 : state.dataHeatBal->Zone(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ActualZoneNum).IsSupplyPlenum = true;
545 8 : state.dataHeatBal->Zone(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ActualZoneNum).PlenumCondNum = ZonePlenumNum;
546 : }
547 : // Check if this zone is used as a controlled zone
548 18 : if (std::any_of(state.dataZoneEquip->ZoneEquipConfig.begin(), state.dataZoneEquip->ZoneEquipConfig.end(), [](EquipConfiguration const &e) {
549 : return e.IsControlled;
550 10 : })) {
551 8 : ZoneEquipConfigLoop = UtilityRoutines::FindItemInList(AlphArray(2), state.dataZoneEquip->ZoneEquipConfig, &EquipConfiguration::ZoneName);
552 8 : if (ZoneEquipConfigLoop != 0) {
553 0 : ShowSevereError(state,
554 0 : std::string{RoutineName} + cAlphaFields(2) + " \"" + AlphArray(2) +
555 0 : "\" is a controlled zone. It cannot be used as a " + CurrentModuleObject + " or AirLoopHVAC:ReturnPlenum.");
556 0 : ShowContinueError(state, "..occurs in " + CurrentModuleObject + " = " + AlphArray(1));
557 0 : ErrorsFound = true;
558 : }
559 : }
560 : // Check if this is also used as a return plenum
561 : // *** This next IF loop looks wrong. Sent e-mail to Peter/Brent 8/14/08 for clarification ****
562 : // IF (NumZoneReturnPlenums > 0) THEN
563 : // IOSTAT=UtilityRoutines::FindItemInList(AlphArray(1),ZoneRetPlenCond%ZoneName,NumZoneReturnPlenums)
564 : // IF (IOStat /= 0) THEN
565 : // CALL ShowSevereError(state, RoutineName//'Plenum "'//TRIM(AlphArray(2))// &
566 : // '" is a controlled zone. It cannot be used as a '// &
567 : // 'SUPPLY PLENUM or RETURN PLENUM.')
568 : // CALL ShowContinueError(state, '..occurs in '//TRIM(CurrentModuleObject)//' = '//TRIM(AlphArray(1)))
569 : // ErrorsFound=.TRUE.
570 : // ENDIF
571 : // ENDIF
572 :
573 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneNodeName = AlphArray(3);
574 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneNodeNum =
575 16 : GetOnlySingleNode(state,
576 8 : AlphArray(3),
577 : ErrorsFound,
578 : DataLoopNode::ConnectionObjectType::AirLoopHVACSupplyPlenum,
579 8 : AlphArray(1),
580 : DataLoopNode::NodeFluidType::Air,
581 : DataLoopNode::ConnectionType::ZoneNode,
582 : NodeInputManager::CompFluidStream::Primary,
583 8 : ObjectIsNotParent);
584 : // Insert the Plenum Zone Number into the Zone Heat Balance data structure for later reference
585 8 : state.dataHeatBal->Zone(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ActualZoneNum).SystemZoneNodeNumber =
586 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneNodeNum;
587 : // SpaceHB TODO: For now, assign the same system node to the spaces in the zone
588 16 : for (int spaceNum : state.dataHeatBal->Zone(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ActualZoneNum).spaceIndexes) {
589 8 : state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneNodeNum;
590 : }
591 :
592 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletNode =
593 16 : GetOnlySingleNode(state,
594 8 : AlphArray(4),
595 : ErrorsFound,
596 : DataLoopNode::ConnectionObjectType::AirLoopHVACSupplyPlenum,
597 8 : AlphArray(1),
598 : DataLoopNode::NodeFluidType::Air,
599 : DataLoopNode::ConnectionType::Inlet,
600 : NodeInputManager::CompFluidStream::Primary,
601 8 : ObjectIsNotParent);
602 :
603 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes = NumAlphas - 4;
604 :
605 20 : for (auto &e : state.dataZonePlenum->ZoneSupPlenCond)
606 12 : e.InitFlag = true;
607 :
608 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode.allocate(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes);
609 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum)
610 8 : .OutletMassFlowRate.allocate(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes);
611 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum)
612 8 : .OutletMassFlowRateMaxAvail.allocate(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes);
613 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum)
614 8 : .OutletMassFlowRateMinAvail.allocate(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes);
615 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletTemp.allocate(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes);
616 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum)
617 8 : .OutletHumRat.allocate(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes);
618 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum)
619 8 : .OutletEnthalpy.allocate(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes);
620 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum)
621 8 : .OutletPressure.allocate(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes);
622 :
623 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode = 0;
624 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRate = 0.0;
625 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail = 0.0;
626 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail = 0.0;
627 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletTemp = 0.0;
628 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletHumRat = 0.0;
629 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletEnthalpy = 0.0;
630 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletPressure = 0.0;
631 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRate = 0.0;
632 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail = 0.0;
633 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail = 0.0;
634 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletTemp = 0.0;
635 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletHumRat = 0.0;
636 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletEnthalpy = 0.0;
637 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletPressure = 0.0;
638 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneTemp = 0.0;
639 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneHumRat = 0.0;
640 8 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneEnthalpy = 0.0;
641 :
642 20 : for (NodeNum = 1; NodeNum <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeNum) {
643 :
644 12 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeNum) =
645 24 : GetOnlySingleNode(state,
646 12 : AlphArray(4 + NodeNum),
647 : ErrorsFound,
648 : DataLoopNode::ConnectionObjectType::AirLoopHVACSupplyPlenum,
649 12 : AlphArray(1),
650 : DataLoopNode::NodeFluidType::Air,
651 : DataLoopNode::ConnectionType::Outlet,
652 : NodeInputManager::CompFluidStream::Primary,
653 12 : ObjectIsNotParent);
654 : }
655 :
656 : } // end AirLoopHVAC:SupplyPlenum Loop
657 :
658 190 : AlphArray.deallocate();
659 190 : NumArray.deallocate();
660 190 : cAlphaFields.deallocate();
661 190 : cNumericFields.deallocate();
662 190 : lAlphaBlanks.deallocate();
663 190 : lNumericBlanks.deallocate();
664 190 : NodeNums.deallocate();
665 :
666 190 : if (ErrorsFound) {
667 0 : ShowFatalError(state, std::string{RoutineName} + "Errors found in input. Preceding condition(s) cause termination.");
668 : }
669 190 : }
670 :
671 2528260 : void InitAirZoneReturnPlenum(EnergyPlusData &state, int const ZonePlenumNum)
672 : {
673 :
674 : // SUBROUTINE INFORMATION:
675 : // AUTHOR Peter Graham Ellis
676 : // DATE WRITTEN November 2000
677 : // MODIFIED na
678 : // RE-ENGINEERED na
679 :
680 : // PURPOSE OF THIS SUBROUTINE:
681 : // This subroutine is for initializations of the ZonePlenum components.
682 :
683 : // METHODOLOGY EMPLOYED:
684 : // Uses the status flags to trigger events.
685 :
686 : // Using/Aliasing
687 :
688 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
689 : int InletNode;
690 2528260 : int InducedNode(0);
691 : int InletNodeLoop;
692 : int ZoneNodeNum;
693 : int NodeNum;
694 : int ZonePlenumLoop;
695 : int PlenumZoneNum;
696 : int ZoneEquipConfigLoop; // Loop number of ZoneEquipConfig derived type
697 : int ADUNum; // air distribution unit index
698 : int NumADUsToPlen; // number of ADUs that might leak to this plenum
699 : int ADUsToPlenIndex; // index of an ADU that might leak to this plenum in the plenum ADU list
700 :
701 : // Do the one time initializations
702 2528260 : if (state.dataZonePlenum->InitAirZoneReturnPlenumOneTimeFlag) {
703 :
704 : // For each zone with a return air plenum put the ZoneRetPlenCond number for the return air plenum
705 : // in the ZoneEquipConfig array for the zone. This allows direct access of the zone's return air
706 : // plenum conditions, such as plenum temperature and air flow. Also establish and save connections
707 : // to the Air Distribution Units. This is needed for the simple duct leakage calculation.
708 :
709 454 : for (ZonePlenumLoop = 1; ZonePlenumLoop <= state.dataZonePlenum->NumZoneReturnPlenums; ++ZonePlenumLoop) {
710 272 : ADUsToPlenIndex = 0;
711 272 : NumADUsToPlen = 0;
712 272 : if (state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).NumInletNodes > 0) {
713 1527 : for (InletNodeLoop = 1; InletNodeLoop <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).NumInletNodes; ++InletNodeLoop) {
714 1255 : InletNode = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).InletNode(InletNodeLoop);
715 : // Loop through ZoneEquipConfig's and look for return air node value = InletNode
716 15970 : for (ZoneEquipConfigLoop = 1; ZoneEquipConfigLoop <= state.dataGlobal->NumOfZones; ++ZoneEquipConfigLoop) {
717 14715 : if (!state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigLoop).IsControlled) continue;
718 24422 : for (int retNode = 1; retNode <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigLoop).NumReturnNodes; ++retNode) {
719 12211 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigLoop).ReturnNode(retNode) == InletNode) {
720 1250 : state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigLoop).ReturnNodePlenumNum = ZonePlenumLoop;
721 1250 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).ZoneEqNum(InletNodeLoop) = ZoneEquipConfigLoop;
722 : }
723 : }
724 : }
725 : // count the ADUs that can leak to this plenum
726 13516 : for (ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
727 24522 : if (state.dataDefineEquipment->AirDistUnit(ADUNum).ZoneEqNum ==
728 12261 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).ZoneEqNum(InletNodeLoop)) {
729 1255 : state.dataDefineEquipment->AirDistUnit(ADUNum).RetPlenumNum = ZonePlenumLoop;
730 1255 : ++NumADUsToPlen;
731 : }
732 : }
733 : }
734 : }
735 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).ADUIndex.allocate(NumADUsToPlen);
736 272 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).NumADUs = NumADUsToPlen;
737 : // fill the list of air distribution units that can leak to this plenum
738 272 : if (NumADUsToPlen > 0) {
739 2887 : for (ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
740 2618 : if (state.dataDefineEquipment->AirDistUnit(ADUNum).RetPlenumNum == ZonePlenumLoop) {
741 1255 : ++ADUsToPlenIndex;
742 1255 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).ADUIndex(ADUsToPlenIndex) = ADUNum;
743 : }
744 : }
745 : }
746 : }
747 :
748 : // Check that all ADUs with leakage found a return plenum
749 1492 : for (ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
750 1310 : auto &thisADU(state.dataDefineEquipment->AirDistUnit(ADUNum));
751 : // TODO: the first half of this IF condition was a duplicated OR, if issues around this code, might want to check the history of this line
752 1310 : if (thisADU.DownStreamLeak && (thisADU.RetPlenumNum == 0)) {
753 0 : ShowWarningError(state,
754 0 : "No return plenum found for simple duct leakage for ZoneHVAC:AirDistributionUnit=" + thisADU.Name +
755 0 : " in Zone=" + state.dataZoneEquip->ZoneEquipConfig(thisADU.ZoneEqNum).ZoneName);
756 0 : ShowContinueError(state, "Leakage will be ignored for this ADU.");
757 0 : thisADU.UpStreamLeak = false;
758 0 : thisADU.DownStreamLeak = false;
759 0 : thisADU.UpStreamLeakFrac = 0.0;
760 0 : thisADU.DownStreamLeakFrac = 0.0;
761 : }
762 : }
763 :
764 182 : state.dataZonePlenum->InitAirZoneReturnPlenumOneTimeFlag = false;
765 : }
766 :
767 : // Do the Begin Environment initializations
768 2528260 : if (state.dataZonePlenum->InitAirZoneReturnPlenumEnvrnFlag && state.dataGlobal->BeginEnvrnFlag) {
769 :
770 2936 : for (PlenumZoneNum = 1; PlenumZoneNum <= state.dataZonePlenum->NumZoneReturnPlenums; ++PlenumZoneNum) {
771 :
772 1794 : ZoneNodeNum = state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).ZoneNodeNum;
773 1794 : state.dataLoopNodes->Node(ZoneNodeNum).Temp = 20.0;
774 1794 : state.dataLoopNodes->Node(ZoneNodeNum).MassFlowRate = 0.0;
775 1794 : state.dataLoopNodes->Node(ZoneNodeNum).Quality = 1.0;
776 1794 : state.dataLoopNodes->Node(ZoneNodeNum).Press = state.dataEnvrn->OutBaroPress;
777 1794 : state.dataLoopNodes->Node(ZoneNodeNum).HumRat = state.dataEnvrn->OutHumRat;
778 1794 : state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy =
779 1794 : PsyHFnTdbW(state.dataLoopNodes->Node(ZoneNodeNum).Temp, state.dataLoopNodes->Node(ZoneNodeNum).HumRat);
780 :
781 1794 : state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).ZoneTemp = 20.0;
782 1794 : state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).ZoneHumRat = 0.0;
783 1794 : state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).ZoneEnthalpy = 0.0;
784 1794 : state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletTemp = 0.0;
785 1794 : state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletHumRat = 0.0;
786 1794 : state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletEnthalpy = 0.0;
787 1794 : state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletPressure = 0.0;
788 1794 : state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletMassFlowRate = 0.0;
789 1794 : state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletMassFlowRateMaxAvail = 0.0;
790 1794 : state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletMassFlowRateMinAvail = 0.0;
791 : }
792 :
793 1142 : state.dataZonePlenum->InitAirZoneReturnPlenumEnvrnFlag = false;
794 : }
795 :
796 2528260 : if (!state.dataGlobal->BeginEnvrnFlag) {
797 2514288 : state.dataZonePlenum->InitAirZoneReturnPlenumEnvrnFlag = true;
798 : }
799 :
800 : // Transfer the node data to ZoneRetPlenCond data structure
801 14720683 : for (NodeNum = 1; NodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes; ++NodeNum) {
802 :
803 12192423 : InletNode = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletNode(NodeNum);
804 : // Set all of the inlet mass flow variables from the nodes
805 12192423 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRate(NodeNum) = state.dataLoopNodes->Node(InletNode).MassFlowRate;
806 12192423 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail(NodeNum) =
807 12192423 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail;
808 12192423 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail(NodeNum) =
809 12192423 : state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail;
810 : // ! Set all of the inlet state variables from the inlet nodes
811 : // ZoneRetPlenCond(ZonePlenumNum)%InletTemp(NodeNum) = Node(InletNode)%Temp
812 : // ZoneRetPlenCond(ZonePlenumNum)%InletHumRat(NodeNum) = Node(InletNode)%HumRat
813 : // ZoneRetPlenCond(ZonePlenumNum)%InletEnthalpy(NodeNum) = Node(InletNode)%Enthalpy
814 12192423 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletPressure(NodeNum) = state.dataLoopNodes->Node(InletNode).Press;
815 : }
816 :
817 2528260 : ZoneNodeNum = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneNodeNum;
818 : // Set the induced air flow rates and conditions
819 2556322 : for (NodeNum = 1; NodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes; ++NodeNum) {
820 28062 : InducedNode = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedNode(NodeNum);
821 28062 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedMassFlowRate(NodeNum) = state.dataLoopNodes->Node(InducedNode).MassFlowRate;
822 28062 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedMassFlowRateMaxAvail(NodeNum) =
823 28062 : state.dataLoopNodes->Node(InducedNode).MassFlowRateMaxAvail;
824 28062 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedMassFlowRateMinAvail(NodeNum) =
825 28062 : state.dataLoopNodes->Node(InducedNode).MassFlowRateMinAvail;
826 :
827 28062 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedTemp(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
828 28062 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedHumRat(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).HumRat;
829 28062 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedEnthalpy(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy;
830 28062 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedPressure(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).Press;
831 28062 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
832 0 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedCO2(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).CO2;
833 : }
834 28062 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
835 0 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedGenContam(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).GenContam;
836 : }
837 : }
838 :
839 : // Add stuff to calculate conduction inputs to the zone plenum
840 : // Now load the zone conditions
841 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneTemp = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
842 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneHumRat = state.dataLoopNodes->Node(ZoneNodeNum).HumRat;
843 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneEnthalpy = state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy;
844 2528260 : }
845 :
846 79168 : void InitAirZoneSupplyPlenum(EnergyPlusData &state, int const ZonePlenumNum, bool const FirstHVACIteration, bool const FirstCall)
847 : {
848 :
849 : // SUBROUTINE INFORMATION:
850 : // AUTHOR Peter Graham Ellis
851 : // DATE WRITTEN March 2000
852 : // MODIFIED na
853 : // RE-ENGINEERED na
854 :
855 : // PURPOSE OF THIS SUBROUTINE:
856 : // This subroutine is for initializations of the ZonePlenum components.
857 :
858 : // METHODOLOGY EMPLOYED:
859 : // Similar to the Zone Splitter component but with interactions to the plenum zone.
860 :
861 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
862 : int InletNode;
863 : int OutletNode;
864 : int ZoneNodeNum;
865 : int PlenumZoneNum;
866 : int NodeIndex;
867 :
868 79168 : auto &Node(state.dataLoopNodes->Node);
869 :
870 : // Do the Begin Environment initializations
871 79168 : if (state.dataZonePlenum->MyEnvrnFlag && state.dataGlobal->BeginEnvrnFlag) {
872 :
873 92 : for (PlenumZoneNum = 1; PlenumZoneNum <= state.dataZonePlenum->NumZoneSupplyPlenums; ++PlenumZoneNum) {
874 :
875 54 : ZoneNodeNum = state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).ZoneNodeNum;
876 54 : Node(ZoneNodeNum).Temp = 20.0;
877 54 : Node(ZoneNodeNum).MassFlowRate = 0.0;
878 54 : Node(ZoneNodeNum).Quality = 1.0;
879 54 : Node(ZoneNodeNum).Press = state.dataEnvrn->OutBaroPress;
880 54 : Node(ZoneNodeNum).HumRat = state.dataEnvrn->OutHumRat;
881 54 : Node(ZoneNodeNum).Enthalpy = PsyHFnTdbW(Node(ZoneNodeNum).Temp, Node(ZoneNodeNum).HumRat);
882 :
883 54 : state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).ZoneTemp = 20.0;
884 54 : state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).ZoneHumRat = 0.0;
885 54 : state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).ZoneEnthalpy = 0.0;
886 54 : state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletTemp = 0.0;
887 54 : state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletHumRat = 0.0;
888 54 : state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletEnthalpy = 0.0;
889 54 : state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletPressure = 0.0;
890 54 : state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletMassFlowRate = 0.0;
891 54 : state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletMassFlowRateMaxAvail = 0.0;
892 54 : state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletMassFlowRateMinAvail = 0.0;
893 : }
894 :
895 38 : state.dataZonePlenum->MyEnvrnFlag = false;
896 : }
897 :
898 79168 : if (!state.dataGlobal->BeginEnvrnFlag) {
899 78312 : state.dataZonePlenum->MyEnvrnFlag = true;
900 : }
901 :
902 : // Do the following initializations (every time step): This should be the info from
903 : // the previous components outlets or the node data in this section.
904 :
905 79168 : InletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletNode;
906 79168 : ZoneNodeNum = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneNodeNum;
907 :
908 79168 : if (FirstHVACIteration && FirstCall) {
909 19824 : if (Node(InletNode).MassFlowRate > 0.0) {
910 14682 : Node(ZoneNodeNum).MassFlowRate = Node(InletNode).MassFlowRate;
911 36800 : for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
912 22118 : OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeIndex);
913 22118 : Node(OutletNode).MassFlowRate = Node(InletNode).MassFlowRate / state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes;
914 : }
915 : }
916 19824 : if (Node(InletNode).MassFlowRateMaxAvail > 0.0) {
917 14682 : Node(ZoneNodeNum).MassFlowRateMaxAvail = Node(InletNode).MassFlowRateMaxAvail;
918 36800 : for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
919 22118 : OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeIndex);
920 22118 : Node(OutletNode).MassFlowRateMaxAvail =
921 22118 : Node(InletNode).MassFlowRateMaxAvail / state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes;
922 : }
923 : }
924 :
925 : } // For FirstHVACIteration and FirstCall
926 :
927 79168 : if (FirstCall) {
928 :
929 39584 : if (Node(InletNode).MassFlowRateMaxAvail == 0.0) { // For Node inlet Max Avail = 0.0
930 :
931 20540 : for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
932 10298 : OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeIndex);
933 10298 : Node(OutletNode).MassFlowRate = 0.0;
934 10298 : Node(OutletNode).MassFlowRateMaxAvail = 0.0;
935 10298 : Node(OutletNode).MassFlowRateMinAvail = 0.0;
936 : }
937 :
938 10242 : Node(ZoneNodeNum).MassFlowRate = 0.0;
939 10242 : Node(ZoneNodeNum).MassFlowRateMaxAvail = 0.0;
940 10242 : Node(ZoneNodeNum).MassFlowRateMinAvail = 0.0;
941 :
942 : } // For Node inlet Max Avail = 0.0
943 :
944 : // Add stuff to calculate conduction inputs to the zone plenum
945 : // Now load the zone conditions
946 39584 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneTemp = Node(ZoneNodeNum).Temp;
947 39584 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneHumRat = Node(ZoneNodeNum).HumRat;
948 39584 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneEnthalpy = Node(ZoneNodeNum).Enthalpy;
949 :
950 94104 : for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
951 54520 : OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeIndex);
952 54520 : Node(OutletNode).Press = Node(InletNode).Press;
953 54520 : Node(OutletNode).Quality = Node(InletNode).Quality;
954 : }
955 :
956 39584 : Node(ZoneNodeNum).Press = Node(InletNode).Press;
957 39584 : Node(ZoneNodeNum).Quality = Node(InletNode).Quality;
958 :
959 : } else { // On the second call from the ZoneEquipManager this is where the flows are passed back to
960 : // the supply plenum inlet.
961 94104 : for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
962 54520 : OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeIndex);
963 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRate(NodeIndex) = Node(OutletNode).MassFlowRate;
964 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail(NodeIndex) = Node(OutletNode).MassFlowRateMaxAvail;
965 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail(NodeIndex) = Node(OutletNode).MassFlowRateMinAvail;
966 : }
967 :
968 : } // For FirstCall
969 79168 : }
970 :
971 2528260 : void CalcAirZoneReturnPlenum(EnergyPlusData &state, int const ZonePlenumNum)
972 : {
973 :
974 : // SUBROUTINE INFORMATION:
975 : // AUTHOR Peter Graham Ellis
976 : // DATE WRITTEN November 2000
977 : // MODIFIED na
978 : // RE-ENGINEERED na
979 :
980 : // Using/Aliasing
981 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
982 2528260 : int InletNodeNum(0); // inlet node number
983 2528260 : int IndNum(0); // induced air index
984 2528260 : int ADUNum(0); // air distribution unit number
985 2528260 : int ADUListIndex(0); // air distribution unit index in zone return plenum data structure
986 2528260 : Real64 TotIndMassFlowRate(0.0); // total induced air mass flow rate [kg/s]
987 :
988 : // Reset the totals to zero before they are summed.
989 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate = 0.0;
990 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail = 0.0;
991 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail = 0.0;
992 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletTemp = 0.0;
993 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletHumRat = 0.0;
994 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletPressure = 0.0;
995 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletEnthalpy = 0.0;
996 2528260 : TotIndMassFlowRate = 0.0;
997 :
998 14720683 : for (InletNodeNum = 1; InletNodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes; ++InletNodeNum) {
999 12192423 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate +=
1000 12192423 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRate(InletNodeNum);
1001 12192423 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail +=
1002 12192423 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail(InletNodeNum);
1003 12192423 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail +=
1004 12192423 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail(InletNodeNum);
1005 : }
1006 :
1007 2528260 : if (state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate > 0.0) {
1008 :
1009 : // "Momentum balance" to get outlet air pressure
1010 11955369 : for (InletNodeNum = 1; InletNodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes; ++InletNodeNum) {
1011 :
1012 9891206 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletPressure +=
1013 19782412 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletPressure(InletNodeNum) *
1014 19782412 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRate(InletNodeNum) /
1015 9891206 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate;
1016 : }
1017 :
1018 : } else {
1019 : // Mass Flow in air loop is zero and loop is not operating.
1020 : // Arbitrarily set the output to the first inlet leg
1021 464097 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletPressure = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletPressure(1);
1022 : }
1023 :
1024 : // add in the leak flow rate, if any. Don't alter the pressure calc (it is not used anyway)
1025 14640508 : for (ADUListIndex = 1; ADUListIndex <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumADUs; ++ADUListIndex) {
1026 12112248 : ADUNum = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ADUIndex(ADUListIndex);
1027 12112248 : if (state.dataDefineEquipment->AirDistUnit(ADUNum).UpStreamLeak || state.dataDefineEquipment->AirDistUnit(ADUNum).DownStreamLeak) {
1028 257380 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate +=
1029 514760 : state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRateUpStrLk +
1030 257380 : state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRateDnStrLk;
1031 257380 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail +=
1032 257380 : state.dataDefineEquipment->AirDistUnit(ADUNum).MaxAvailDelta;
1033 257380 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail +=
1034 257380 : state.dataDefineEquipment->AirDistUnit(ADUNum).MinAvailDelta;
1035 : }
1036 : }
1037 : // Sum up induced air flow rate
1038 2556322 : for (IndNum = 1; IndNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes; ++IndNum) {
1039 28062 : TotIndMassFlowRate += state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedMassFlowRate(IndNum);
1040 : }
1041 :
1042 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate -= TotIndMassFlowRate;
1043 :
1044 : // Set the Plenum Outlet to the Zone Node conditions
1045 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletHumRat = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneHumRat;
1046 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletEnthalpy = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneEnthalpy;
1047 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletTemp = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneTemp;
1048 : // make sure the MassFlowMaxAvail >= MassFlowRate
1049 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail =
1050 2528260 : max(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail,
1051 2528260 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate);
1052 2528260 : }
1053 :
1054 79168 : void CalcAirZoneSupplyPlenum(EnergyPlusData &state, int const ZonePlenumNum, bool const FirstCall)
1055 : {
1056 :
1057 : // SUBROUTINE INFORMATION:
1058 : // AUTHOR Peter Graham Ellis
1059 : // DATE WRITTEN March 2000
1060 : // MODIFIED na
1061 : // RE-ENGINEERED na
1062 :
1063 : // METHODOLOGY EMPLOYED:
1064 : // Similar to the Zone Splitter component but with interactions to the plenum zone.
1065 :
1066 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1067 : int NodeIndex;
1068 :
1069 : // The first time through the State properties are passed through
1070 79168 : if (FirstCall) {
1071 : // Moisture balance to get outlet air humidity ratio
1072 94104 : for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
1073 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletHumRat(NodeIndex) =
1074 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneHumRat;
1075 : }
1076 :
1077 : // Energy balance to get outlet air enthalpy
1078 94104 : for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
1079 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletEnthalpy(NodeIndex) =
1080 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneEnthalpy;
1081 : }
1082 :
1083 : // Set outlet temperatures equal to inlet temperature
1084 94104 : for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
1085 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletTemp(NodeIndex) =
1086 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneTemp;
1087 : }
1088 :
1089 : } else {
1090 : // This is the second time through and this is where the mass flows from the outlets are
1091 : // summed and then assigned upstream to the inlet node.
1092 39584 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRate = 0.0;
1093 39584 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail = 0.0;
1094 39584 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail = 0.0;
1095 94104 : for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
1096 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRate +=
1097 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRate(NodeIndex);
1098 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail +=
1099 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail(NodeIndex);
1100 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail +=
1101 54520 : state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail(NodeIndex);
1102 : }
1103 : }
1104 79168 : }
1105 :
1106 : // End Algorithm Section of the Module
1107 : // *****************************************************************************
1108 :
1109 : // Beginning of Update subroutines for the ZonePlenum Module
1110 : // *****************************************************************************
1111 :
1112 2528260 : void UpdateAirZoneReturnPlenum(EnergyPlusData &state, int const ZonePlenumNum)
1113 : {
1114 :
1115 : // SUBROUTINE INFORMATION:
1116 : // AUTHOR Peter Graham Ellis
1117 : // DATE WRITTEN November 2000
1118 : // MODIFIED na
1119 : // RE-ENGINEERED na
1120 :
1121 : // Using/Aliasing
1122 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1123 : int OutletNode;
1124 : int InletNode;
1125 : int ZoneNode;
1126 : int InletNodeNum;
1127 : int InducedNode; // the node number of an induced air outlet node
1128 : int IndNum; // the induced air outlet index in ZoneRetPlenCond
1129 :
1130 2528260 : auto &Node(state.dataLoopNodes->Node);
1131 :
1132 2528260 : OutletNode = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletNode;
1133 2528260 : InletNode = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletNode(1);
1134 2528260 : ZoneNode = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneNodeNum;
1135 :
1136 : // Set the outlet air nodes of the ZonePlenum
1137 2528260 : Node(OutletNode).MassFlowRate = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate;
1138 2528260 : Node(OutletNode).MassFlowRateMaxAvail = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail;
1139 2528260 : Node(OutletNode).MassFlowRateMinAvail = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail;
1140 :
1141 2528260 : Node(ZoneNode).MassFlowRate = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate;
1142 2528260 : Node(ZoneNode).MassFlowRateMaxAvail = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail;
1143 2528260 : Node(ZoneNode).MassFlowRateMinAvail = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail;
1144 2528260 : Node(ZoneNode).Press = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletPressure;
1145 :
1146 2528260 : Node(OutletNode).Temp = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletTemp;
1147 2528260 : Node(OutletNode).HumRat = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletHumRat;
1148 2528260 : Node(OutletNode).Enthalpy = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletEnthalpy;
1149 2528260 : Node(OutletNode).Press = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletPressure;
1150 2556322 : for (IndNum = 1; IndNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes; ++IndNum) {
1151 28062 : InducedNode = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedNode(IndNum);
1152 28062 : Node(InducedNode).Temp = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedTemp(IndNum);
1153 28062 : Node(InducedNode).HumRat = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedHumRat(IndNum);
1154 28062 : Node(InducedNode).Enthalpy = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedEnthalpy(IndNum);
1155 28062 : Node(InducedNode).Press = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedPressure(IndNum);
1156 28062 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
1157 0 : Node(InducedNode).CO2 = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedCO2(IndNum);
1158 : }
1159 28062 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
1160 0 : Node(InducedNode).GenContam = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedGenContam(IndNum);
1161 : }
1162 28062 : Node(InducedNode).Quality = Node(InletNode).Quality;
1163 : }
1164 :
1165 : // Set the outlet nodes for properties that are just pass through and not used
1166 2528260 : Node(OutletNode).Quality = Node(InletNode).Quality;
1167 2528260 : Node(ZoneNode).Quality = Node(InletNode).Quality;
1168 :
1169 : // Set the outlet node contaminant properties if needed. The zone contaminant conditions are calculated in ZoneContaminantPredictorCorrector
1170 2528260 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
1171 0 : if (state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate > 0.0) {
1172 : // CO2 balance to get outlet air CO2
1173 0 : Node(OutletNode).CO2 = 0.0;
1174 0 : for (InletNodeNum = 1; InletNodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes; ++InletNodeNum) {
1175 0 : Node(OutletNode).CO2 += Node(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletNode(InletNodeNum)).CO2 *
1176 0 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRate(InletNodeNum) /
1177 0 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate;
1178 : }
1179 0 : Node(ZoneNode).CO2 = Node(OutletNode).CO2;
1180 : } else {
1181 0 : Node(OutletNode).CO2 = Node(ZoneNode).CO2;
1182 : }
1183 : }
1184 2528260 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
1185 0 : if (state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate > 0.0) {
1186 : // GenContam balance to get outlet air GenContam
1187 0 : Node(OutletNode).GenContam = 0.0;
1188 0 : for (InletNodeNum = 1; InletNodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes; ++InletNodeNum) {
1189 0 : Node(OutletNode).GenContam += Node(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletNode(InletNodeNum)).GenContam *
1190 0 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRate(InletNodeNum) /
1191 0 : state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate;
1192 : }
1193 0 : Node(ZoneNode).GenContam = Node(OutletNode).GenContam;
1194 : } else {
1195 0 : Node(OutletNode).GenContam = Node(ZoneNode).GenContam;
1196 : }
1197 : }
1198 2528260 : }
1199 :
1200 79168 : void UpdateAirZoneSupplyPlenum(EnergyPlusData &state, int const ZonePlenumNum, bool &PlenumInletChanged, bool const FirstCall)
1201 : {
1202 :
1203 : // SUBROUTINE INFORMATION:
1204 : // AUTHOR Peter Graham Ellis
1205 : // DATE WRITTEN March 2000
1206 : // MODIFIED na
1207 : // RE-ENGINEERED na
1208 :
1209 : // METHODOLOGY EMPLOYED:
1210 : // Similar to the Zone Splitter component but with interactions to the plenum zone.
1211 :
1212 : // Using/Aliasing
1213 : // SUBROUTINE PARAMETER DEFINITIONS:
1214 79168 : Real64 constexpr FlowRateToler(0.01); // Tolerance for mass flow rate convergence (in kg/s)
1215 :
1216 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1217 : int OutletNode;
1218 : int InletNode;
1219 : int ZoneNode;
1220 : int NodeIndex;
1221 :
1222 79168 : auto &Node(state.dataLoopNodes->Node);
1223 :
1224 79168 : OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(1);
1225 79168 : InletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletNode;
1226 79168 : ZoneNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneNodeNum;
1227 :
1228 : // On the FirstCall the State properties are passed through and the mass flows are not dealt with
1229 79168 : if (FirstCall) {
1230 : // Set the outlet nodes for properties that just pass through and not used
1231 94104 : for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
1232 54520 : OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeIndex);
1233 54520 : Node(OutletNode).Temp = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletTemp(NodeIndex);
1234 54520 : Node(OutletNode).HumRat = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletHumRat(NodeIndex);
1235 54520 : Node(OutletNode).Enthalpy = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletEnthalpy(NodeIndex);
1236 54520 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
1237 0 : Node(OutletNode).CO2 = Node(InletNode).CO2;
1238 : }
1239 54520 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
1240 0 : Node(OutletNode).GenContam = Node(InletNode).GenContam;
1241 : }
1242 : }
1243 :
1244 39584 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
1245 0 : Node(ZoneNode).CO2 = Node(InletNode).CO2;
1246 : }
1247 39584 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
1248 0 : Node(ZoneNode).GenContam = Node(InletNode).GenContam;
1249 : }
1250 :
1251 : } else {
1252 : // The second time through just updates the mass flow conditions back upstream
1253 : // to the inlet.
1254 :
1255 39584 : if (std::abs(Node(InletNode).MassFlowRate - state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRate) > FlowRateToler) {
1256 10116 : PlenumInletChanged = true;
1257 : }
1258 :
1259 39584 : Node(InletNode).MassFlowRate = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRate;
1260 39584 : Node(InletNode).MassFlowRateMaxAvail = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail;
1261 39584 : Node(InletNode).MassFlowRateMinAvail = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail;
1262 :
1263 39584 : Node(ZoneNode).MassFlowRate = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRate;
1264 39584 : Node(ZoneNode).MassFlowRateMaxAvail = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail;
1265 39584 : Node(ZoneNode).MassFlowRateMinAvail = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail;
1266 :
1267 : } // For FirstCall
1268 79168 : }
1269 :
1270 5 : int GetReturnPlenumIndex(EnergyPlusData &state, int const ExNodeNum)
1271 : {
1272 :
1273 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1274 : int PlenumNum; // loop counter
1275 : int InducedNodeNum; // loop counter
1276 : int WhichPlenum; // index to return plenum
1277 :
1278 : // Obtains and Allocates ZonePlenum related parameters from input file
1279 5 : if (state.dataZonePlenum->GetInputFlag) { // First time subroutine has been entered
1280 1 : GetZonePlenumInput(state);
1281 1 : state.dataZonePlenum->GetInputFlag = false;
1282 : }
1283 :
1284 5 : WhichPlenum = 0;
1285 5 : if (state.dataZonePlenum->NumZoneReturnPlenums > 0) {
1286 9 : for (PlenumNum = 1; PlenumNum <= state.dataZonePlenum->NumZoneReturnPlenums; ++PlenumNum) {
1287 5 : if (ExNodeNum != state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).OutletNode) continue;
1288 1 : WhichPlenum = PlenumNum;
1289 1 : break;
1290 : }
1291 5 : if (WhichPlenum == 0) {
1292 4 : for (PlenumNum = 1; PlenumNum <= state.dataZonePlenum->NumZoneReturnPlenums; ++PlenumNum) {
1293 10 : for (InducedNodeNum = 1; InducedNodeNum <= state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).NumInducedNodes; ++InducedNodeNum) {
1294 10 : if (ExNodeNum != state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).InducedNode(InducedNodeNum)) continue;
1295 4 : WhichPlenum = PlenumNum;
1296 4 : break;
1297 : }
1298 4 : if (WhichPlenum > 0) break;
1299 : }
1300 : }
1301 : }
1302 :
1303 5 : return WhichPlenum;
1304 : }
1305 :
1306 5 : void GetReturnPlenumName(EnergyPlusData &state, int const ReturnPlenumIndex, std::string &ReturnPlenumName)
1307 : {
1308 :
1309 : // Obtains and Allocates ZonePlenum related parameters from input file
1310 5 : if (state.dataZonePlenum->GetInputFlag) { // First time subroutine has been entered
1311 0 : GetZonePlenumInput(state);
1312 0 : state.dataZonePlenum->GetInputFlag = false;
1313 : }
1314 :
1315 5 : ReturnPlenumName = " ";
1316 5 : if (state.dataZonePlenum->NumZoneReturnPlenums > 0) {
1317 5 : ReturnPlenumName = state.dataZonePlenum->ZoneRetPlenCond(ReturnPlenumIndex).ZonePlenumName;
1318 : }
1319 5 : }
1320 :
1321 4 : int getReturnPlenumIndexFromInletNode(EnergyPlusData &state, int const InNodeNum)
1322 : {
1323 :
1324 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1325 : int PlenumNum; // loop counter
1326 : int InNodeCtr; // loop counter
1327 : int thisPlenum;
1328 :
1329 : // Obtains and Allocates ZonePlenum related parameters from input file
1330 4 : if (state.dataZonePlenum->GetInputFlag) { // First time subroutine has been entered
1331 4 : GetZonePlenumInput(state);
1332 4 : state.dataZonePlenum->GetInputFlag = false;
1333 : }
1334 :
1335 4 : thisPlenum = 0;
1336 4 : if (state.dataZonePlenum->NumZoneReturnPlenums > 0) {
1337 0 : for (PlenumNum = 1; PlenumNum <= state.dataZonePlenum->NumZoneReturnPlenums; ++PlenumNum) {
1338 0 : for (InNodeCtr = 1; InNodeCtr <= state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).NumInletNodes; ++InNodeCtr) {
1339 0 : if (InNodeNum != state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).InletNode(InNodeCtr)) continue;
1340 0 : thisPlenum = PlenumNum;
1341 0 : break;
1342 : }
1343 0 : if (thisPlenum > 0) break;
1344 : }
1345 : }
1346 :
1347 4 : return thisPlenum;
1348 : }
1349 :
1350 3 : bool ValidateInducedNode(EnergyPlusData &state, int const InduceNodeNum, int const NumReturnNodes, Array1D<int> const &ReturnNode)
1351 : {
1352 : // Ensure induced node is used as inlet node of zoe equipment
1353 : int PlenumNum; // loop counter
1354 : int InNodeCtr; // loop counter
1355 : int InduceNodeCtr; // loop counter
1356 3 : bool Nodefound = false;
1357 :
1358 : // Obtains and Allocates ZonePlenum related parameters from input file
1359 3 : if (state.dataZonePlenum->GetInputFlag) { // First time subroutine has been entered
1360 1 : GetZonePlenumInput(state);
1361 1 : state.dataZonePlenum->GetInputFlag = false;
1362 : }
1363 :
1364 3 : if (state.dataZonePlenum->NumZoneReturnPlenums > 0) {
1365 3 : for (PlenumNum = 1; PlenumNum <= state.dataZonePlenum->NumZoneReturnPlenums; ++PlenumNum) {
1366 6 : for (InduceNodeCtr = 1; InduceNodeCtr <= state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).NumInducedNodes; ++InduceNodeCtr) {
1367 6 : if (InduceNodeNum == state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).InducedNode(InduceNodeCtr)) {
1368 10 : for (InNodeCtr = 1; InNodeCtr <= state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).NumInletNodes; ++InNodeCtr) {
1369 17 : for (int ReturnNodeNum = 1; ReturnNodeNum <= NumReturnNodes; ++ReturnNodeNum) {
1370 10 : if (ReturnNode(ReturnNodeNum) != state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).InletNode(InNodeCtr)) continue;
1371 3 : Nodefound = true;
1372 3 : break;
1373 : }
1374 10 : if (Nodefound) break;
1375 : }
1376 : }
1377 6 : if (Nodefound) break;
1378 : }
1379 3 : if (Nodefound) break;
1380 : }
1381 : }
1382 :
1383 3 : return Nodefound;
1384 : }
1385 :
1386 2313 : } // namespace EnergyPlus::ZonePlenum
|