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 : // ObjexxFCL Headers
49 : #include <ObjexxFCL/Array.functions.hh>
50 : #include <ObjexxFCL/Fmath.hh>
51 :
52 : // EnergyPlus Headers
53 : #include <EnergyPlus/BranchNodeConnections.hh>
54 : #include <EnergyPlus/Data/EnergyPlusData.hh>
55 : #include <EnergyPlus/DataContaminantBalance.hh>
56 : #include <EnergyPlus/DataDefineEquip.hh>
57 : #include <EnergyPlus/DataEnvironment.hh>
58 : #include <EnergyPlus/DataHVACGlobals.hh>
59 : #include <EnergyPlus/DataHeatBalance.hh>
60 : #include <EnergyPlus/DataLoopNode.hh>
61 : #include <EnergyPlus/DataSizing.hh>
62 : #include <EnergyPlus/DataZoneEquipment.hh>
63 : #include <EnergyPlus/General.hh>
64 : #include <EnergyPlus/GeneralRoutines.hh>
65 : #include <EnergyPlus/GlobalNames.hh>
66 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
67 : #include <EnergyPlus/NodeInputManager.hh>
68 : #include <EnergyPlus/ScheduleManager.hh>
69 : #include <EnergyPlus/UnitarySystem.hh>
70 : #include <EnergyPlus/UtilityRoutines.hh>
71 :
72 : namespace EnergyPlus::DataZoneEquipment {
73 :
74 : // MODULE INFORMATION
75 : // AUTHOR: Russ Taylor
76 : // DATE WRITTEN: June 1998
77 :
78 : // PURPOSE OF THIS MODULE:
79 : // This module contains variable declarations for zone equipment configuration data
80 :
81 771 : Array1D_string const cValidSysAvailManagerCompTypes(NumValidSysAvailZoneComponents,
82 : {"ZoneHVAC:FourPipeFanCoil",
83 : "ZoneHVAC:PackagedTerminalHeatPump",
84 : "ZoneHVAC:PackagedTerminalAirConditioner",
85 : "ZoneHVAC:WaterToAirHeatPump",
86 : "ZoneHVAC:WindowAirConditioner",
87 : "ZoneHVAC:UnitHeater",
88 : "ZoneHVAC:UnitVentilator",
89 : "ZoneHVAC:EnergyRecoveryVentilator",
90 : "ZoneHVAC:VentilatedSlab",
91 : "ZoneHVAC:OutdoorAirUnit",
92 : "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow",
93 : "ZoneHVAC:IdealLoadsAirSystem",
94 : "ZoneHVAC:EvaporativeCoolerUnit",
95 771 : "ZoneHVAC:HybridUnitaryHVAC"});
96 :
97 : constexpr std::array<std::string_view, static_cast<int>(ZoneEquip::Num)> ZoneEquipTypeNamesUC = {"NONE",
98 : "ZONEHVAC:FOURPIPEFANCOIL",
99 : "ZONEHVAC:PACKAGEDTERMINALHEATPUMP",
100 : "ZONEHVAC:PACKAGEDTERMINALAIRCONDITIONER",
101 : "ZONEHVAC:WATERTOAIRHEATPUMP",
102 : "ZONEHVAC:WINDOWAIRCONDITIONER",
103 : "ZONEHVAC:UNITHEATER",
104 : "ZONEHVAC:UNITVENTILATOR",
105 : "ZONEHVAC:ENERGYRECOVERYVENTILATOR",
106 : "ZONEHVAC:VENTILATEDSLAB",
107 : "ZONEHVAC:OUTDOORAIRUNIT",
108 : "ZONEHVAC:TERMINALUNIT:VARIABLEREFRIGERANTFLOW",
109 : "ZONEHVAC:IDEALLOADSAIRSYSTEM",
110 : "ZONEHVAC:EVAPORATIVECOOLERUNIT",
111 : "ZONEHVAC:HYBRIDUNITARYHVAC",
112 : "ZONEHVAC:AIRDISTRIBUTIONUNIT",
113 : "ZONEHVAC:BASEBOARD:CONVECTIVE:WATER",
114 : "ZONEHVAC:BASEBOARD:CONVECTIVE:ELECTRIC",
115 : "ZONEHVAC:HIGHTEMPERATURERADIANT",
116 : "ZONEHVAC:LOWTEMPERATURERADIANT:VARIABLEFLOW",
117 : "FAN:ZONEEXHAUST",
118 : "HEATEXCHANGER:AIRTOAIR:FLATPLATE",
119 : "WATERHEATER:HEATPUMP:PUMPEDCONDENSER",
120 : "ZONEHVAC:BASEBOARD:RADIANTCONVECTIVE:WATER",
121 : "ZONEHVAC:DEHUMIDIFIER:DX",
122 : "ZONEHVAC:BASEBOARD:RADIANTCONVECTIVE:STEAM",
123 : "ZONEHVAC:BASEBOARD:RADIANTCONVECTIVE:ELECTRIC",
124 : "ZONEHVAC:REFRIGERATIONCHILLERSET",
125 : "ZONEHVAC:FORCEDAIR:USERDEFINED",
126 : "ZONEHVAC:COOLINGPANEL:RADIANTCONVECTIVE:WATER",
127 : "AIRLOOPHVAC:UNITARYSYSTEM"};
128 :
129 771 : void GetZoneEquipmentData(EnergyPlusData &state)
130 : {
131 :
132 : // SUBROUTINE INFORMATION:
133 : // AUTHOR Russ Taylor
134 : // DATE WRITTEN June 1997
135 : // MODIFIED Aug 2003, FCW: set ZoneEquipConfig number for each zone
136 : // RE-ENGINEERED na
137 :
138 : // PURPOSE OF THIS SUBROUTINE:
139 : // Get all the system related equipment which may be attached to
140 : // a zone
141 :
142 : // Using/Aliasing
143 : using NodeInputManager::CheckUniqueNodeNames;
144 : using NodeInputManager::CheckUniqueNodeNumbers;
145 : using NodeInputManager::EndUniqueNodeCheck;
146 : using NodeInputManager::GetNodeNums;
147 : using NodeInputManager::GetOnlySingleNode;
148 : using NodeInputManager::InitUniqueNodeCheck;
149 : using namespace DataHVACGlobals;
150 : using namespace DataLoopNode;
151 : using namespace ScheduleManager;
152 :
153 : // SUBROUTINE PARAMETER DEFINITIONS:
154 : static constexpr std::string_view RoutineName("GetZoneEquipmentData: "); // include trailing blank space
155 :
156 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
157 : int NumAlphas;
158 : int NumNums;
159 : int NodeNum;
160 : int PathNum;
161 : int CompNum;
162 : int ControlledZoneLoop;
163 : int ZoneEquipTypeNum;
164 : int ZoneEquipListNum;
165 : int IOStat;
166 1542 : std::string InletNodeListName;
167 1542 : std::string ExhaustNodeListName;
168 1542 : std::string ReturnNodeListName;
169 1542 : std::string ReturnFlowBasisNodeListName;
170 1542 : Array1D_string AlphArray;
171 1542 : Array1D<Real64> NumArray;
172 : int MaxAlphas;
173 : int MaxNums;
174 : int NumParams;
175 : int NumNodes;
176 1542 : Array1D_int NodeNums;
177 : int Counter;
178 : bool IsNotOK; // Flag to verify nam
179 : bool NodeListError;
180 : bool UniqueNodeError;
181 1542 : std::string CurrentModuleObject; // Object type for getting and error messages
182 1542 : Array1D_string cAlphaFields; // Alpha field names
183 1542 : Array1D_string cNumericFields; // Numeric field names
184 1542 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
185 1542 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
186 : int maxEquipCount;
187 : int numEquipCount;
188 : int overallEquipCount;
189 : int Loop1;
190 : int Loop2;
191 :
192 771 : auto &TermUnitSizing(state.dataSize->TermUnitSizing);
193 :
194 9968 : struct EquipListAudit
195 : {
196 : // Members
197 : std::string ObjectType;
198 : std::string ObjectName;
199 : int OnListNum;
200 :
201 : // Default Constructor
202 678 : EquipListAudit() : OnListNum(0)
203 : {
204 678 : }
205 : };
206 :
207 : // Object Data
208 1542 : Array1D<EquipListAudit> ZoneEquipListAcct;
209 :
210 771 : ExhaustNodeListName = "";
211 771 : InletNodeListName = "";
212 771 : ReturnNodeListName = "";
213 771 : ReturnFlowBasisNodeListName = "";
214 :
215 : // Look in the input file for zones with air loop and zone equipment attached
216 :
217 771 : int NumOfControlledZones = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:EquipmentConnections");
218 1542 : state.dataZoneEquip->NumOfZoneEquipLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(
219 771 : state, "ZoneHVAC:EquipmentList"); // Look for lists of equipment data - there should
220 : // be as many of these as there are controlled zones
221 771 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "NodeList", NumParams, NumAlphas, NumNums);
222 771 : NodeNums.dimension(NumParams, 0);
223 771 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "ZoneHVAC:EquipmentList", NumParams, NumAlphas, NumNums);
224 771 : MaxAlphas = NumAlphas;
225 771 : MaxNums = NumNums;
226 771 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "ZoneHVAC:EquipmentConnections", NumParams, NumAlphas, NumNums);
227 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
228 771 : MaxNums = max(MaxNums, NumNums);
229 771 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "AirLoopHVAC:SupplyPath", NumParams, NumAlphas, NumNums);
230 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
231 771 : MaxNums = max(MaxNums, NumNums);
232 771 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "AirLoopHVAC:ReturnPath", NumParams, NumAlphas, NumNums);
233 771 : MaxAlphas = max(MaxAlphas, NumAlphas);
234 771 : MaxNums = max(MaxNums, NumNums);
235 771 : AlphArray.allocate(MaxAlphas);
236 771 : NumArray.dimension(MaxNums, 0.0);
237 771 : cAlphaFields.allocate(MaxAlphas);
238 771 : cNumericFields.allocate(MaxNums);
239 771 : lAlphaBlanks.dimension(MaxAlphas, true);
240 771 : lNumericBlanks.dimension(MaxNums, true);
241 :
242 771 : if (!allocated(state.dataZoneEquip->SupplyAirPath)) {
243 : // Look for and read in the air supply path
244 : // component (splitters) information for each zone
245 771 : state.dataZoneEquip->NumSupplyAirPaths = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:SupplyPath");
246 771 : state.dataZoneEquip->SupplyAirPath.allocate(state.dataZoneEquip->NumSupplyAirPaths);
247 : }
248 :
249 771 : if (!allocated(state.dataZoneEquip->ReturnAirPath)) {
250 : // Look for and read in the air return path
251 : // component (mixers & plenums) information for each zone
252 771 : state.dataZoneEquip->NumReturnAirPaths = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:ReturnPath");
253 771 : state.dataZoneEquip->ReturnAirPath.allocate(state.dataZoneEquip->NumReturnAirPaths);
254 : }
255 :
256 771 : state.dataZoneEquip->ZoneEquipConfig.allocate(state.dataGlobal->NumOfZones); // Allocate the array containing the configuration
257 : // data for each zone to the number of controlled zones
258 : // found in the input file. This may or may not
259 : // be the same as the number of zones in the building
260 771 : state.dataZoneEquip->ZoneEquipList.allocate(state.dataGlobal->NumOfZones);
261 771 : state.dataZoneEquip->ZoneEquipAvail.dimension(state.dataGlobal->NumOfZones, NoAction);
262 771 : state.dataZoneEquip->UniqueZoneEquipListNames.reserve(state.dataGlobal->NumOfZones);
263 :
264 771 : if (state.dataZoneEquip->NumOfZoneEquipLists != NumOfControlledZones) {
265 0 : ShowSevereError(state,
266 0 : format("{}Number of Zone Equipment lists [{}] not equal Number of Controlled Zones [{}]",
267 : RoutineName,
268 0 : state.dataZoneEquip->NumOfZoneEquipLists,
269 0 : NumOfControlledZones));
270 0 : ShowContinueError(state, "..Each Controlled Zone [ZoneHVAC:EquipmentConnections] must have a corresponding (unique) ZoneHVAC:EquipmentList");
271 0 : ShowFatalError(state, "GetZoneEquipment: Incorrect number of zone equipment lists");
272 : }
273 :
274 771 : if (NumOfControlledZones > state.dataGlobal->NumOfZones) {
275 0 : ShowSevereError(state,
276 0 : format("{}Number of Controlled Zone objects [{}] greater than Number of Zones [{}]",
277 : RoutineName,
278 : NumOfControlledZones,
279 0 : state.dataGlobal->NumOfZones));
280 0 : ShowFatalError(state, std::string{RoutineName} + "Too many ZoneHVAC:EquipmentConnections objects.");
281 : }
282 :
283 771 : InitUniqueNodeCheck(state, "ZoneHVAC:EquipmentConnections");
284 :
285 771 : overallEquipCount = 0;
286 771 : int locTermUnitSizingCounter = 0; // will increment for every zone inlet node
287 :
288 771 : auto &Zone(state.dataHeatBal->Zone);
289 :
290 4875 : for (ControlledZoneLoop = 1; ControlledZoneLoop <= NumOfControlledZones; ++ControlledZoneLoop) {
291 :
292 4104 : CurrentModuleObject = "ZoneHVAC:EquipmentConnections";
293 :
294 4104 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
295 : CurrentModuleObject,
296 : ControlledZoneLoop,
297 : AlphArray,
298 : NumAlphas,
299 : NumArray,
300 : NumNums,
301 : IOStat,
302 : lNumericBlanks,
303 : lAlphaBlanks,
304 : cAlphaFields,
305 : cNumericFields); // Get Equipment | data for one zone
306 :
307 4104 : int ControlledZoneNum = UtilityRoutines::FindItemInList(AlphArray(1), Zone);
308 :
309 4104 : if (ControlledZoneNum == 0) {
310 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + ": " + cAlphaFields(1) + "=\"" + AlphArray(1) + "\"");
311 0 : ShowContinueError(state, "..Requested Controlled Zone not among Zones, remaining items for this object not processed.");
312 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
313 0 : continue;
314 : } else {
315 4104 : if (Zone(ControlledZoneNum).IsControlled) {
316 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + ": " + cAlphaFields(1) + "=\"" + AlphArray(1) + "\"");
317 0 : ShowContinueError(state, "..Duplicate Controlled Zone entered, only one " + CurrentModuleObject + " per zone is allowed.");
318 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
319 0 : continue;
320 : }
321 4104 : Zone(ControlledZoneNum).IsControlled = true;
322 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).IsControlled = true;
323 : }
324 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName = AlphArray(1); // for x-referencing with the geometry data
325 :
326 4104 : IsNotOK = false;
327 12312 : GlobalNames::IntraObjUniquenessCheck(
328 12312 : state, AlphArray(2), CurrentModuleObject, cAlphaFields(2), state.dataZoneEquip->UniqueZoneEquipListNames, IsNotOK);
329 4104 : if (IsNotOK) {
330 0 : ShowContinueError(state, "..another Controlled Zone has been assigned that " + cAlphaFields(2) + '.');
331 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
332 : }
333 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).EquipListName = AlphArray(2); // the name of the list containing all the zone eq.
334 4104 : InletNodeListName = AlphArray(3);
335 4104 : ExhaustNodeListName = AlphArray(4);
336 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode =
337 12312 : GetOnlySingleNode(state,
338 4104 : AlphArray(5),
339 4104 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
340 : DataLoopNode::ConnectionObjectType::ZoneHVACEquipmentConnections,
341 4104 : AlphArray(1),
342 : DataLoopNode::NodeFluidType::Air,
343 : DataLoopNode::ConnectionType::ZoneNode,
344 : NodeInputManager::CompFluidStream::Primary,
345 4104 : ObjectIsNotParent); // all zone air state variables are
346 4104 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode == 0) {
347 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + ": " + cAlphaFields(1) + "=\"" + AlphArray(1) + "\", invalid");
348 0 : ShowContinueError(state, cAlphaFields(5) + " must be present.");
349 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
350 : } else {
351 4104 : UniqueNodeError = false;
352 4104 : CheckUniqueNodeNames(state, cAlphaFields(5), UniqueNodeError, AlphArray(5), AlphArray(1));
353 4104 : if (UniqueNodeError) {
354 : // ShowContinueError(state, "Occurs for " + trim( cAlphaFields( 1 ) ) + " = " + trim( AlphArray( 1 ) ) );
355 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
356 : }
357 : }
358 : // assigned to this node
359 4104 : if (ControlledZoneNum > 0) {
360 4104 : Zone(ControlledZoneNum).SystemZoneNodeNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
361 : // SpaceHB TODO: For now, assign the same system node to the spaces in the zone
362 8212 : for (int spaceNum : Zone(ControlledZoneNum).spaceIndexes) {
363 4108 : state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
364 : }
365 : } // This error already detected and program will be terminated.
366 :
367 4104 : ReturnNodeListName = AlphArray(6);
368 4104 : if (lAlphaBlanks(7)) {
369 4099 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnFlowSchedPtrNum = DataGlobalConstants::ScheduleAlwaysOn;
370 : } else {
371 5 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnFlowSchedPtrNum = GetScheduleIndex(state, AlphArray(7));
372 5 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnFlowSchedPtrNum == 0) {
373 0 : ShowSevereError(state,
374 0 : std::string{RoutineName} + CurrentModuleObject + ": invalid " + cAlphaFields(7) + " entered =" + AlphArray(7) +
375 0 : " for " + cAlphaFields(1) + '=' + AlphArray(1));
376 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
377 : }
378 : }
379 4104 : ReturnFlowBasisNodeListName = AlphArray(8);
380 :
381 : // Read in the equipment type, name and sequence information
382 : // for each equipment list
383 :
384 4104 : CurrentModuleObject = "ZoneHVAC:EquipmentList";
385 :
386 8208 : ZoneEquipListNum = state.dataInputProcessing->inputProcessor->getObjectItemNum(
387 4104 : state, CurrentModuleObject, state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).EquipListName);
388 4104 : if (ZoneEquipListNum > 0) {
389 :
390 4104 : EquipList &thisZoneEquipList = state.dataZoneEquip->ZoneEquipList(ControlledZoneNum);
391 :
392 4104 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
393 : CurrentModuleObject,
394 : ZoneEquipListNum,
395 : AlphArray,
396 : NumAlphas,
397 : NumArray,
398 : NumNums,
399 : IOStat,
400 : lNumericBlanks,
401 : lAlphaBlanks,
402 : cAlphaFields,
403 : cNumericFields); // data for one zone
404 4104 : UtilityRoutines::IsNameEmpty(state, AlphArray(1), CurrentModuleObject, state.dataZoneEquip->GetZoneEquipmentDataErrorsFound);
405 4104 : thisZoneEquipList.Name = AlphArray(1);
406 :
407 4104 : if (!lAlphaBlanks(2)) {
408 4102 : if (UtilityRoutines::SameString(AlphArray(2), "SequentialLoad")) {
409 4099 : thisZoneEquipList.LoadDistScheme = DataZoneEquipment::LoadDist::Sequential;
410 3 : } else if (UtilityRoutines::SameString(AlphArray(2), "UniformLoad")) {
411 1 : thisZoneEquipList.LoadDistScheme = DataZoneEquipment::LoadDist::Uniform;
412 2 : } else if (UtilityRoutines::SameString(AlphArray(2), "UniformPLR")) {
413 1 : thisZoneEquipList.LoadDistScheme = DataZoneEquipment::LoadDist::UniformPLR;
414 1 : } else if (UtilityRoutines::SameString(AlphArray(2), "SequentialUniformPLR")) {
415 1 : thisZoneEquipList.LoadDistScheme = DataZoneEquipment::LoadDist::SequentialUniformPLR;
416 : } else {
417 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + AlphArray(1) + "\", Invalid choice.");
418 0 : ShowContinueError(state, "..." + cAlphaFields(2) + "=\"" + AlphArray(2) + "\".");
419 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
420 : }
421 : }
422 4104 : constexpr int nAlphasInExtensible = 4;
423 4104 : constexpr int nNumsInExtensible = 2;
424 4104 : constexpr int nAlphasBeforeExtensible = 2;
425 4104 : constexpr int nNumsBeforeExtensible = 0;
426 4104 : maxEquipCount = 0;
427 4104 : numEquipCount = (NumAlphas - nAlphasBeforeExtensible) / nAlphasInExtensible;
428 4104 : if (numEquipCount * nAlphasInExtensible != (NumAlphas - nAlphasBeforeExtensible)) ++numEquipCount;
429 8749 : for (ZoneEquipTypeNum = 1; ZoneEquipTypeNum <= numEquipCount; ++ZoneEquipTypeNum) {
430 13935 : if (!lAlphaBlanks(nAlphasInExtensible * (ZoneEquipTypeNum - 1) + nAlphasBeforeExtensible + 1) &&
431 4645 : !lAlphaBlanks(nAlphasInExtensible * (ZoneEquipTypeNum - 1) + nAlphasBeforeExtensible + 2)) {
432 4645 : ++maxEquipCount;
433 4645 : continue;
434 : }
435 0 : ShowWarningError(state,
436 0 : format("{}{}=\"{}\", truncated list at blank field; object count={}",
437 : RoutineName,
438 : CurrentModuleObject,
439 : thisZoneEquipList.Name,
440 0 : maxEquipCount));
441 0 : break;
442 : }
443 :
444 4104 : overallEquipCount += maxEquipCount;
445 4104 : thisZoneEquipList.NumOfEquipTypes = maxEquipCount;
446 4104 : thisZoneEquipList.EquipType.allocate(thisZoneEquipList.NumOfEquipTypes);
447 4104 : thisZoneEquipList.EquipTypeEnum.allocate(thisZoneEquipList.NumOfEquipTypes);
448 4104 : thisZoneEquipList.compPointer.resize(thisZoneEquipList.NumOfEquipTypes + 1);
449 4104 : thisZoneEquipList.EquipName.allocate(thisZoneEquipList.NumOfEquipTypes);
450 4104 : thisZoneEquipList.EquipIndex.allocate(thisZoneEquipList.NumOfEquipTypes);
451 4104 : thisZoneEquipList.EquipData.allocate(thisZoneEquipList.NumOfEquipTypes);
452 4104 : thisZoneEquipList.CoolingPriority.allocate(thisZoneEquipList.NumOfEquipTypes);
453 4104 : thisZoneEquipList.HeatingPriority.allocate(thisZoneEquipList.NumOfEquipTypes);
454 4104 : thisZoneEquipList.CoolingCapacity.allocate(thisZoneEquipList.NumOfEquipTypes);
455 4104 : thisZoneEquipList.HeatingCapacity.allocate(thisZoneEquipList.NumOfEquipTypes);
456 4104 : thisZoneEquipList.SequentialCoolingFractionSchedPtr.allocate(thisZoneEquipList.NumOfEquipTypes);
457 4104 : thisZoneEquipList.SequentialHeatingFractionSchedPtr.allocate(thisZoneEquipList.NumOfEquipTypes);
458 4104 : thisZoneEquipList.EquipType = "";
459 4104 : thisZoneEquipList.EquipTypeEnum = DataZoneEquipment::ZoneEquip::Invalid;
460 4104 : thisZoneEquipList.EquipName = "";
461 4104 : thisZoneEquipList.EquipIndex = 0;
462 4104 : thisZoneEquipList.CoolingPriority = 0;
463 4104 : thisZoneEquipList.HeatingPriority = 0;
464 4104 : thisZoneEquipList.CoolingCapacity = 0;
465 4104 : thisZoneEquipList.HeatingCapacity = 0;
466 4104 : thisZoneEquipList.SequentialCoolingFractionSchedPtr = 0;
467 4104 : thisZoneEquipList.SequentialHeatingFractionSchedPtr = 0;
468 :
469 8749 : for (ZoneEquipTypeNum = 1; ZoneEquipTypeNum <= thisZoneEquipList.NumOfEquipTypes; ++ZoneEquipTypeNum) {
470 4645 : const int ZoneEquipTypeIdx = ZoneEquipTypeNum - 1;
471 4645 : thisZoneEquipList.EquipType(ZoneEquipTypeNum) = AlphArray(nAlphasInExtensible * ZoneEquipTypeIdx + nAlphasBeforeExtensible + 1);
472 4645 : thisZoneEquipList.EquipName(ZoneEquipTypeNum) = AlphArray(nAlphasInExtensible * ZoneEquipTypeIdx + nAlphasBeforeExtensible + 2);
473 13935 : ValidateComponent(state,
474 9290 : thisZoneEquipList.EquipType(ZoneEquipTypeNum),
475 9290 : thisZoneEquipList.EquipName(ZoneEquipTypeNum),
476 : IsNotOK,
477 : CurrentModuleObject);
478 4645 : if (IsNotOK) {
479 0 : ShowContinueError(state, "In " + CurrentModuleObject + '=' + thisZoneEquipList.Name);
480 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
481 : }
482 4645 : thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum) =
483 4645 : nint(NumArray(nNumsInExtensible * ZoneEquipTypeIdx + nNumsBeforeExtensible + 1));
484 9290 : if ((thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum) < 0) ||
485 4645 : (thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum) > thisZoneEquipList.NumOfEquipTypes)) {
486 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + AlphArray(1) + "\".");
487 0 : ShowContinueError(state,
488 0 : format("invalid {}=[{}].",
489 0 : cNumericFields(nNumsInExtensible * ZoneEquipTypeIdx + nNumsBeforeExtensible + 1),
490 0 : thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum)));
491 0 : ShowContinueError(state, "equipment sequence must be > 0 and <= number of equipments in the list.");
492 0 : if (thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum) > 0)
493 0 : ShowContinueError(state, format("only {} in the list.", thisZoneEquipList.NumOfEquipTypes));
494 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
495 : }
496 :
497 4645 : thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum) =
498 4645 : nint(NumArray(nNumsInExtensible * ZoneEquipTypeIdx + nNumsBeforeExtensible + 2));
499 9290 : if ((thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum) < 0) ||
500 4645 : (thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum) > thisZoneEquipList.NumOfEquipTypes)) {
501 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + AlphArray(1) + "\".");
502 0 : ShowContinueError(state,
503 0 : format("invalid {}=[{}].",
504 0 : cNumericFields(nNumsInExtensible * ZoneEquipTypeIdx + nNumsBeforeExtensible + 2),
505 0 : thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum)));
506 0 : ShowContinueError(state, "equipment sequence must be > 0 and <= number of equipments in the list.");
507 0 : if (thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum) > 0)
508 0 : ShowContinueError(state, format("only {} in the list.", thisZoneEquipList.NumOfEquipTypes));
509 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
510 : }
511 :
512 4645 : const int coolingFractionArrayIdx = nAlphasInExtensible * ZoneEquipTypeIdx + nAlphasBeforeExtensible + 3;
513 4645 : if (lAlphaBlanks(coolingFractionArrayIdx)) {
514 4641 : thisZoneEquipList.SequentialCoolingFractionSchedPtr(ZoneEquipTypeNum) = DataGlobalConstants::ScheduleAlwaysOn;
515 : } else {
516 4 : thisZoneEquipList.SequentialCoolingFractionSchedPtr(ZoneEquipTypeNum) =
517 4 : GetScheduleIndex(state, AlphArray(coolingFractionArrayIdx));
518 4 : if (thisZoneEquipList.SequentialCoolingFractionSchedPtr(ZoneEquipTypeNum) == 0) {
519 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + AlphArray(1) + "\".");
520 0 : ShowContinueError(state,
521 0 : "invalid " + cAlphaFields(coolingFractionArrayIdx) + "=[" + AlphArray(coolingFractionArrayIdx) + "].");
522 0 : ShowContinueError(state, "Schedule does not exist.");
523 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
524 : }
525 : }
526 :
527 4645 : const int heatingFractionArrayIdx = nAlphasInExtensible * ZoneEquipTypeIdx + nAlphasBeforeExtensible + 4;
528 4645 : if (lAlphaBlanks(heatingFractionArrayIdx)) {
529 4641 : thisZoneEquipList.SequentialHeatingFractionSchedPtr(ZoneEquipTypeNum) = DataGlobalConstants::ScheduleAlwaysOn;
530 : } else {
531 4 : thisZoneEquipList.SequentialHeatingFractionSchedPtr(ZoneEquipTypeNum) =
532 4 : GetScheduleIndex(state, AlphArray(heatingFractionArrayIdx));
533 4 : if (thisZoneEquipList.SequentialHeatingFractionSchedPtr(ZoneEquipTypeNum) == 0) {
534 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + AlphArray(1) + "\".");
535 0 : ShowContinueError(state,
536 0 : "invalid " + cAlphaFields(heatingFractionArrayIdx) + "=[" + AlphArray(heatingFractionArrayIdx) + "].");
537 0 : ShowContinueError(state, "Schedule does not exist.");
538 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
539 : }
540 : }
541 :
542 : // do this here for initial prototype, but later will call all the equipment in a separate function to see who is on - maybe
543 4645 : if (thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum) > 0) ++thisZoneEquipList.NumAvailHeatEquip;
544 4645 : if (thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum) > 0) ++thisZoneEquipList.NumAvailCoolEquip;
545 :
546 4645 : thisZoneEquipList.EquipTypeEnum(ZoneEquipTypeNum) = static_cast<ZoneEquip>(
547 9290 : getEnumerationValue(ZoneEquipTypeNamesUC, UtilityRoutines::MakeUPPERCase(thisZoneEquipList.EquipType(ZoneEquipTypeNum))));
548 :
549 13929 : if (thisZoneEquipList.EquipTypeEnum(ZoneEquipTypeNum) == ZoneEquip::ZoneUnitarySys ||
550 9136 : thisZoneEquipList.EquipTypeEnum(ZoneEquipTypeNum) == ZoneEquip::PkgTermACAirToAir ||
551 13611 : thisZoneEquipList.EquipTypeEnum(ZoneEquipTypeNum) == ZoneEquip::PkgTermHPAirToAir ||
552 4469 : thisZoneEquipList.EquipTypeEnum(ZoneEquipTypeNum) == ZoneEquip::PkgTermHPWaterToAir) {
553 396 : UnitarySystems::UnitarySys thisSys;
554 : // loop index accesses correct pointer to equipment on this equipment list
555 : // EquipIndex is used to access specific equipment for a single class of equipment (e.g., PTAC 1, 2 and 3)
556 198 : thisZoneEquipList.compPointer[ZoneEquipTypeNum] =
557 396 : thisSys.factory(state, DataHVACGlobals::UnitarySys_AnyCoilType, thisZoneEquipList.EquipName(ZoneEquipTypeNum), true, 0);
558 198 : thisZoneEquipList.EquipIndex(ZoneEquipTypeNum) = thisZoneEquipList.compPointer[ZoneEquipTypeNum]->getEquipIndex();
559 : }
560 :
561 4645 : if (thisZoneEquipList.EquipTypeEnum(ZoneEquipTypeNum) == ZoneEquip::Invalid) {
562 49 : if (thisZoneEquipList.EquipType(ZoneEquipTypeNum) == "ZONEHVAC:LOWTEMPERATURERADIANT:CONSTANTFLOW" ||
563 11 : thisZoneEquipList.EquipType(ZoneEquipTypeNum) == "ZONEHVAC:LOWTEMPERATURERADIANT:ELECTRIC") {
564 36 : thisZoneEquipList.EquipTypeEnum(ZoneEquipTypeNum) = ZoneEquip::LoTempRadiant;
565 2 : } else if (thisZoneEquipList.EquipType(ZoneEquipTypeNum) == "WATERHEATER:HEATPUMP:WRAPPEDCONDENSER") {
566 2 : thisZoneEquipList.EquipTypeEnum(ZoneEquipTypeNum) = DataZoneEquipment::ZoneEquip::HPWaterHeater;
567 : } else {
568 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + " = " + thisZoneEquipList.Name);
569 0 : ShowContinueError(state, "..Invalid Equipment Type = " + thisZoneEquipList.EquipType(ZoneEquipTypeNum));
570 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
571 : }
572 : }
573 : }
574 :
575 8749 : for (ZoneEquipTypeNum = 1; ZoneEquipTypeNum <= thisZoneEquipList.NumOfEquipTypes; ++ZoneEquipTypeNum) {
576 4645 : if (count_eq(thisZoneEquipList.CoolingPriority, ZoneEquipTypeNum) > 1) {
577 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + " = " + thisZoneEquipList.Name);
578 0 : ShowContinueError(state,
579 0 : format("...multiple assignments for Zone Equipment Cooling Sequence={}, must be 1-1 correspondence between "
580 : "sequence assignments and number of equipments.",
581 0 : ZoneEquipTypeNum));
582 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
583 4645 : } else if (count_eq(thisZoneEquipList.CoolingPriority, ZoneEquipTypeNum) == 0) {
584 0 : ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + " = " + thisZoneEquipList.Name);
585 0 : ShowContinueError(state,
586 0 : format("...zero assigned to Zone Equipment Cooling Sequence={}, apparent gap in sequence assignments in "
587 : "this equipment list.",
588 0 : ZoneEquipTypeNum));
589 : }
590 4645 : if (count_eq(thisZoneEquipList.HeatingPriority, ZoneEquipTypeNum) > 1) {
591 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + " = " + thisZoneEquipList.Name);
592 0 : ShowContinueError(state,
593 0 : format("...multiple assignments for Zone Equipment Heating or No-Load Sequence={}, must be 1-1 "
594 : "correspondence between sequence assignments and number of equipments.",
595 0 : ZoneEquipTypeNum));
596 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
597 4645 : } else if (count_eq(thisZoneEquipList.HeatingPriority, ZoneEquipTypeNum) == 0) {
598 0 : ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + " = " + thisZoneEquipList.Name);
599 0 : ShowContinueError(state,
600 0 : format("...zero assigned to Zone Equipment Heating or No-Load Sequence={}, apparent gap in sequence "
601 : "assignments in this equipment list.",
602 0 : ZoneEquipTypeNum));
603 : }
604 : }
605 :
606 : } else {
607 0 : ShowSevereError(state,
608 0 : std::string{RoutineName} + CurrentModuleObject +
609 0 : " not found = " + state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).EquipListName);
610 0 : ShowContinueError(
611 0 : state, "In ZoneHVAC:EquipmentConnections object, for Zone = " + state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName);
612 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
613 : }
614 :
615 : // End ZoneHVAC:EquipmentList
616 :
617 4104 : NodeListError = false;
618 4104 : GetNodeNums(state,
619 : InletNodeListName,
620 : NumNodes,
621 : NodeNums,
622 : NodeListError,
623 : DataLoopNode::NodeFluidType::Air,
624 : DataLoopNode::ConnectionObjectType::ZoneHVACEquipmentConnections,
625 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName,
626 : DataLoopNode::ConnectionType::ZoneInlet,
627 : NodeInputManager::CompFluidStream::Primary,
628 4104 : ObjectIsNotParent);
629 :
630 4104 : if (!NodeListError) {
631 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes = NumNodes;
632 :
633 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode.allocate(NumNodes);
634 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum.allocate(NumNodes);
635 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeADUNum.allocate(NumNodes);
636 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).AirDistUnitCool.allocate(NumNodes);
637 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).AirDistUnitHeat.allocate(NumNodes);
638 :
639 8347 : for (NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
640 4243 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(NodeNum) = NodeNums(NodeNum);
641 4243 : UniqueNodeError = false;
642 8486 : CheckUniqueNodeNumbers(state,
643 : "Zone Air Inlet Nodes",
644 : UniqueNodeError,
645 4243 : NodeNums(NodeNum),
646 4243 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName);
647 4243 : if (UniqueNodeError) {
648 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
649 : }
650 4243 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(NodeNum) = 0;
651 4243 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeADUNum(NodeNum) = 0;
652 4243 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).AirDistUnitCool(NodeNum).InNode = 0;
653 4243 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).AirDistUnitHeat(NodeNum).InNode = 0;
654 4243 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).AirDistUnitCool(NodeNum).OutNode = 0;
655 4243 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).AirDistUnitHeat(NodeNum).OutNode = 0;
656 4243 : ++locTermUnitSizingCounter;
657 4243 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).AirDistUnitCool(NodeNum).TermUnitSizingIndex = locTermUnitSizingCounter;
658 4243 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).AirDistUnitHeat(NodeNum).TermUnitSizingIndex = locTermUnitSizingCounter;
659 : }
660 : } else {
661 0 : ShowContinueError(state,
662 0 : "Invalid Zone Air Inlet Node or NodeList Name in ZoneHVAC:EquipmentConnections object, for Zone = " +
663 0 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName);
664 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
665 : }
666 :
667 4104 : NodeListError = false;
668 4104 : GetNodeNums(state,
669 : ExhaustNodeListName,
670 : NumNodes,
671 : NodeNums,
672 : NodeListError,
673 : DataLoopNode::NodeFluidType::Air,
674 : DataLoopNode::ConnectionObjectType::ZoneHVACEquipmentConnections,
675 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName,
676 : DataLoopNode::ConnectionType::ZoneExhaust,
677 : NodeInputManager::CompFluidStream::Primary,
678 4104 : ObjectIsNotParent);
679 :
680 4104 : if (!NodeListError) {
681 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumExhaustNodes = NumNodes;
682 :
683 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode.allocate(NumNodes);
684 :
685 4906 : for (NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
686 802 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(NodeNum) = NodeNums(NodeNum);
687 802 : UniqueNodeError = false;
688 1604 : CheckUniqueNodeNumbers(state,
689 : "Zone Air Exhaust Nodes",
690 : UniqueNodeError,
691 802 : NodeNums(NodeNum),
692 802 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName);
693 802 : if (UniqueNodeError) {
694 : // ShowContinueError(state, "Occurs for Zone = " + trim( AlphArray( 1 ) ) );
695 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
696 : }
697 : }
698 : } else {
699 0 : ShowContinueError(state,
700 0 : "Invalid Zone Air Exhaust Node or NodeList Name in ZoneHVAC:EquipmentConnections object, for Zone=" +
701 0 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName);
702 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
703 : }
704 :
705 4104 : NodeListError = false;
706 4104 : GetNodeNums(state,
707 : ReturnNodeListName,
708 : NumNodes,
709 : NodeNums,
710 : NodeListError,
711 : DataLoopNode::NodeFluidType::Air,
712 : DataLoopNode::ConnectionObjectType::ZoneHVACEquipmentConnections,
713 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName,
714 : DataLoopNode::ConnectionType::ZoneReturn,
715 : NodeInputManager::CompFluidStream::Primary,
716 4104 : ObjectIsNotParent);
717 :
718 4104 : if (!NodeListError) {
719 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumReturnNodes = NumNodes;
720 :
721 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNode.allocate(NumNodes);
722 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNodeAirLoopNum.allocate(NumNodes);
723 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNodeInletNum.allocate(NumNodes);
724 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).FixedReturnFlow.allocate(NumNodes);
725 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNodePlenumNum.allocate(NumNodes);
726 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNodeExhaustNodeNum.allocate(NumNodes);
727 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).SharedExhaustNode.allocate(NumNodes);
728 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNode = 0; // initialize to zero here
729 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNodeAirLoopNum = 0; // initialize to zero here
730 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNodeInletNum = 0; // initialize to zero here
731 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).FixedReturnFlow = false; // initialize to false here
732 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNodePlenumNum = 0; // initialize to zero here
733 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNodeExhaustNodeNum = 0; // initialize to zero here
734 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).SharedExhaustNode = LightReturnExhaustConfig::NoExhast; // initialize to zero here
735 :
736 8212 : for (NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
737 4108 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnNode(NodeNum) = NodeNums(NodeNum);
738 4108 : UniqueNodeError = false;
739 8216 : CheckUniqueNodeNumbers(state,
740 : "Zone Return Air Nodes",
741 : UniqueNodeError,
742 4108 : NodeNums(NodeNum),
743 4108 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName);
744 4108 : if (UniqueNodeError) {
745 : // ShowContinueError(state, "Occurs for Zone = " + trim( AlphArray( 1 ) ) );
746 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
747 : }
748 : }
749 : } else {
750 0 : ShowContinueError(state,
751 0 : "Invalid Zone Return Air Node or NodeList Name in ZoneHVAC:EquipmentConnections object, for Zone=" +
752 0 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName);
753 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
754 : }
755 :
756 4104 : NodeListError = false;
757 4104 : GetNodeNums(state,
758 : ReturnFlowBasisNodeListName,
759 : NumNodes,
760 : NodeNums,
761 : NodeListError,
762 : DataLoopNode::NodeFluidType::Air,
763 : DataLoopNode::ConnectionObjectType::ZoneHVACEquipmentConnections,
764 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName,
765 : DataLoopNode::ConnectionType::Sensor,
766 : NodeInputManager::CompFluidStream::Primary,
767 4104 : ObjectIsNotParent);
768 :
769 4104 : if (!NodeListError) {
770 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumReturnFlowBasisNodes = NumNodes;
771 :
772 4104 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnFlowBasisNode.allocate(NumNodes);
773 :
774 4104 : for (NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
775 0 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ReturnFlowBasisNode(NodeNum) = NodeNums(NodeNum);
776 : }
777 : } else {
778 0 : ShowContinueError(
779 : state,
780 0 : "Invalid Zone Return Air Node 1 Flow Rate Basis Node or NodeList Name in ZoneHVAC:EquipmentConnections object, for Zone=" +
781 0 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneName);
782 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
783 : }
784 :
785 : } // end loop over controlled zones
786 :
787 : // Allocate TermUnitSizing array and set zone number
788 771 : if (locTermUnitSizingCounter > 0) {
789 652 : state.dataSize->NumAirTerminalUnits = locTermUnitSizingCounter;
790 652 : TermUnitSizing.allocate(state.dataSize->NumAirTerminalUnits);
791 5219 : for (int loopZoneNum = 1; loopZoneNum <= state.dataGlobal->NumOfZones; ++loopZoneNum) {
792 : {
793 4567 : auto &thisZoneEqConfig(state.dataZoneEquip->ZoneEquipConfig(loopZoneNum));
794 8810 : for (int loopNodeNum = 1; loopNodeNum <= thisZoneEqConfig.NumInletNodes; ++loopNodeNum) {
795 4243 : TermUnitSizing(thisZoneEqConfig.AirDistUnitCool(loopNodeNum).TermUnitSizingIndex).CtrlZoneNum = loopZoneNum;
796 : }
797 : }
798 : }
799 : }
800 771 : if (state.dataZoneEquip->GetZoneEquipmentDataErrorsFound) {
801 0 : ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + ", duplicate items NOT CHECKED due to previous errors.");
802 0 : overallEquipCount = 0;
803 : }
804 771 : if (overallEquipCount > 0) {
805 678 : ZoneEquipListAcct.allocate(overallEquipCount);
806 678 : overallEquipCount = 0;
807 4782 : for (Loop1 = 1; Loop1 <= NumOfControlledZones; ++Loop1) {
808 8366 : for (Loop2 = 1; Loop2 <= state.dataZoneEquip->ZoneEquipList(Loop1).NumOfEquipTypes; ++Loop2) {
809 4262 : ++overallEquipCount;
810 4262 : ZoneEquipListAcct(overallEquipCount).ObjectType = state.dataZoneEquip->ZoneEquipList(Loop1).EquipType(Loop2);
811 4262 : ZoneEquipListAcct(overallEquipCount).ObjectName = state.dataZoneEquip->ZoneEquipList(Loop1).EquipName(Loop2);
812 4262 : ZoneEquipListAcct(overallEquipCount).OnListNum = Loop1;
813 : }
814 : }
815 : // Now check for uniqueness
816 4940 : for (Loop1 = 1; Loop1 <= overallEquipCount; ++Loop1) {
817 72359 : for (Loop2 = Loop1 + 1; Loop2 <= overallEquipCount; ++Loop2) {
818 117584 : if (ZoneEquipListAcct(Loop1).ObjectType != ZoneEquipListAcct(Loop2).ObjectType ||
819 49487 : ZoneEquipListAcct(Loop1).ObjectName != ZoneEquipListAcct(Loop2).ObjectName)
820 68097 : continue;
821 : // Duplicated -- not allowed
822 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + ", duplicate items in ZoneHVAC:EquipmentList.");
823 0 : ShowContinueError(state, "Equipment: Type=" + ZoneEquipListAcct(Loop1).ObjectType + ", Name=" + ZoneEquipListAcct(Loop1).ObjectName);
824 0 : ShowContinueError(state, "Found on List=\"" + state.dataZoneEquip->ZoneEquipList(ZoneEquipListAcct(Loop1).OnListNum).Name + "\".");
825 0 : ShowContinueError(
826 0 : state, "Equipment Duplicated on List=\"" + state.dataZoneEquip->ZoneEquipList(ZoneEquipListAcct(Loop2).OnListNum).Name + "\".");
827 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
828 : }
829 : }
830 678 : ZoneEquipListAcct.deallocate();
831 : }
832 :
833 : // map ZoneEquipConfig%EquipListIndex to ZoneEquipList%Name
834 :
835 5585 : for (ControlledZoneLoop = 1; ControlledZoneLoop <= state.dataGlobal->NumOfZones; ++ControlledZoneLoop) {
836 9628 : state.dataZoneEquip->GetZoneEquipmentDataFound = UtilityRoutines::FindItemInList(
837 9628 : state.dataZoneEquip->ZoneEquipList(ControlledZoneLoop).Name, state.dataZoneEquip->ZoneEquipConfig, &EquipConfiguration::EquipListName);
838 4814 : if (state.dataZoneEquip->GetZoneEquipmentDataFound > 0)
839 4814 : state.dataZoneEquip->ZoneEquipConfig(state.dataZoneEquip->GetZoneEquipmentDataFound).EquipListIndex = ControlledZoneLoop;
840 : } // end loop over controlled zones
841 :
842 771 : EndUniqueNodeCheck(state, "ZoneHVAC:EquipmentConnections");
843 :
844 771 : CurrentModuleObject = "AirLoopHVAC:SupplyPath";
845 1957 : for (PathNum = 1; PathNum <= state.dataZoneEquip->NumSupplyAirPaths; ++PathNum) {
846 :
847 1186 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
848 : CurrentModuleObject,
849 : PathNum,
850 : AlphArray,
851 : NumAlphas,
852 : NumArray,
853 : NumNums,
854 : IOStat,
855 : lNumericBlanks,
856 : lAlphaBlanks,
857 : cAlphaFields,
858 : cNumericFields); // data for one zone
859 1186 : UtilityRoutines::IsNameEmpty(state, AlphArray(1), CurrentModuleObject, state.dataZoneEquip->GetZoneEquipmentDataErrorsFound);
860 1186 : state.dataZoneEquip->SupplyAirPath(PathNum).Name = AlphArray(1);
861 1186 : state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents = nint((double(NumAlphas) - 2.0) / 2.0);
862 :
863 2372 : state.dataZoneEquip->SupplyAirPath(PathNum).InletNodeNum = GetOnlySingleNode(state,
864 1186 : AlphArray(2),
865 1186 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
866 : DataLoopNode::ConnectionObjectType::AirLoopHVACSupplyPath,
867 1186 : AlphArray(1),
868 : DataLoopNode::NodeFluidType::Air,
869 : DataLoopNode::ConnectionType::Inlet,
870 : NodeInputManager::CompFluidStream::Primary,
871 1186 : ObjectIsParent);
872 :
873 1186 : state.dataZoneEquip->SupplyAirPath(PathNum).ComponentType.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
874 1186 : state.dataZoneEquip->SupplyAirPath(PathNum).ComponentTypeEnum.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
875 1186 : state.dataZoneEquip->SupplyAirPath(PathNum).ComponentTypeEnum = DataZoneEquipment::AirLoopHVACZone::Invalid;
876 1186 : state.dataZoneEquip->SupplyAirPath(PathNum).ComponentName.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
877 1186 : state.dataZoneEquip->SupplyAirPath(PathNum).ComponentIndex.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
878 1186 : state.dataZoneEquip->SupplyAirPath(PathNum).SplitterIndex.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
879 1186 : state.dataZoneEquip->SupplyAirPath(PathNum).PlenumIndex.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
880 :
881 1186 : Counter = 3;
882 :
883 2379 : for (CompNum = 1; CompNum <= state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents; ++CompNum) {
884 :
885 1193 : if ((AlphArray(Counter) == "AIRLOOPHVAC:ZONESPLITTER") || (AlphArray(Counter) == "AIRLOOPHVAC:SUPPLYPLENUM")) {
886 :
887 1193 : state.dataZoneEquip->SupplyAirPath(PathNum).ComponentType(CompNum) = AlphArray(Counter);
888 1193 : state.dataZoneEquip->SupplyAirPath(PathNum).ComponentName(CompNum) = AlphArray(Counter + 1);
889 1193 : ValidateComponent(state,
890 1193 : state.dataZoneEquip->SupplyAirPath(PathNum).ComponentType(CompNum),
891 1193 : state.dataZoneEquip->SupplyAirPath(PathNum).ComponentName(CompNum),
892 : IsNotOK,
893 : CurrentModuleObject);
894 1193 : state.dataZoneEquip->SupplyAirPath(PathNum).ComponentIndex(CompNum) = 0;
895 1193 : state.dataZoneEquip->SupplyAirPath(PathNum).SplitterIndex(CompNum) = 0;
896 1193 : state.dataZoneEquip->SupplyAirPath(PathNum).PlenumIndex(CompNum) = 0;
897 1193 : state.dataZoneEquip->SupplyAirPath(PathNum).ComponentTypeEnum(CompNum) =
898 2386 : (AirLoopHVACZone)getEnumerationValue(AirLoopHVACTypeNamesUC, AlphArray(Counter));
899 : } else {
900 0 : ShowSevereError(state, std::string{RoutineName} + cAlphaFields(1) + "=\"" + state.dataZoneEquip->SupplyAirPath(PathNum).Name + "\"");
901 0 : ShowContinueError(state, "Unhandled component type =\"" + AlphArray(Counter) + "\".");
902 0 : ShowContinueError(state, R"(Must be "AirLoopHVAC:ZoneSplitter" or "AirLoopHVAC:SupplyPlenum")");
903 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
904 : }
905 :
906 1193 : Counter += 2;
907 : }
908 :
909 1186 : state.dataZoneEquip->SupplyAirPath(PathNum).NumOutletNodes = 0;
910 1186 : state.dataZoneEquip->SupplyAirPath(PathNum).NumNodes = 0;
911 :
912 : } // end loop over supply air paths
913 :
914 771 : CurrentModuleObject = "AirLoopHVAC:ReturnPath";
915 1940 : for (PathNum = 1; PathNum <= state.dataZoneEquip->NumReturnAirPaths; ++PathNum) {
916 :
917 1169 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
918 : CurrentModuleObject,
919 : PathNum,
920 : AlphArray,
921 : NumAlphas,
922 : NumArray,
923 : NumNums,
924 : IOStat,
925 : lNumericBlanks,
926 : lAlphaBlanks,
927 : cAlphaFields,
928 : cNumericFields); // data for one zone
929 1169 : UtilityRoutines::IsNameEmpty(state, AlphArray(1), CurrentModuleObject, state.dataZoneEquip->GetZoneEquipmentDataErrorsFound);
930 1169 : state.dataZoneEquip->ReturnAirPath(PathNum).Name = AlphArray(1);
931 1169 : state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents = nint((double(NumAlphas) - 2.0) / 2.0);
932 :
933 2338 : state.dataZoneEquip->ReturnAirPath(PathNum).OutletNodeNum = GetOnlySingleNode(state,
934 1169 : AlphArray(2),
935 1169 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
936 : DataLoopNode::ConnectionObjectType::AirLoopHVACReturnPath,
937 1169 : AlphArray(1),
938 : DataLoopNode::NodeFluidType::Air,
939 : DataLoopNode::ConnectionType::Outlet,
940 : NodeInputManager::CompFluidStream::Primary,
941 1169 : ObjectIsParent);
942 :
943 1169 : state.dataZoneEquip->ReturnAirPath(PathNum).ComponentType.allocate(state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents);
944 1169 : state.dataZoneEquip->ReturnAirPath(PathNum).ComponentTypeEnum.allocate(state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents);
945 1169 : state.dataZoneEquip->ReturnAirPath(PathNum).ComponentTypeEnum = DataZoneEquipment::AirLoopHVACZone::Invalid;
946 1169 : state.dataZoneEquip->ReturnAirPath(PathNum).ComponentName.allocate(state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents);
947 1169 : state.dataZoneEquip->ReturnAirPath(PathNum).ComponentIndex.allocate(state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents);
948 :
949 1169 : Counter = 3;
950 :
951 2447 : for (CompNum = 1; CompNum <= state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents; ++CompNum) {
952 :
953 1278 : if ((AlphArray(Counter) == "AIRLOOPHVAC:ZONEMIXER") || (AlphArray(Counter) == "AIRLOOPHVAC:RETURNPLENUM")) {
954 :
955 1278 : state.dataZoneEquip->ReturnAirPath(PathNum).ComponentType(CompNum) = AlphArray(Counter);
956 1278 : state.dataZoneEquip->ReturnAirPath(PathNum).ComponentName(CompNum) = AlphArray(Counter + 1);
957 1278 : state.dataZoneEquip->ReturnAirPath(PathNum).ComponentIndex(CompNum) = 0;
958 1278 : ValidateComponent(state,
959 1278 : state.dataZoneEquip->ReturnAirPath(PathNum).ComponentType(CompNum),
960 1278 : state.dataZoneEquip->ReturnAirPath(PathNum).ComponentName(CompNum),
961 : IsNotOK,
962 : CurrentModuleObject);
963 1278 : if (IsNotOK) {
964 0 : ShowContinueError(state, "In " + CurrentModuleObject + " = " + state.dataZoneEquip->ReturnAirPath(PathNum).Name);
965 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
966 : }
967 1278 : state.dataZoneEquip->ReturnAirPath(PathNum).ComponentTypeEnum(CompNum) =
968 2556 : static_cast<AirLoopHVACZone>(getEnumerationValue(AirLoopHVACTypeNamesUC, AlphArray(Counter)));
969 : } else {
970 0 : ShowSevereError(state, std::string{RoutineName} + cAlphaFields(1) + "=\"" + state.dataZoneEquip->ReturnAirPath(PathNum).Name + "\"");
971 0 : ShowContinueError(state, "Unhandled component type =\"" + AlphArray(Counter) + "\".");
972 0 : ShowContinueError(state, R"(Must be "AirLoopHVAC:ZoneMixer" or "AirLoopHVAC:ReturnPlenum")");
973 0 : state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
974 : }
975 :
976 1278 : Counter += 2;
977 : }
978 :
979 : } // end loop over return air paths
980 :
981 771 : AlphArray.deallocate();
982 771 : NumArray.deallocate();
983 771 : cAlphaFields.deallocate();
984 771 : cNumericFields.deallocate();
985 771 : lAlphaBlanks.deallocate();
986 771 : lNumericBlanks.deallocate();
987 :
988 : // setup zone equipment info for convection correlations
989 771 : SetupZoneEquipmentForConvectionFlowRegime(state);
990 :
991 771 : if (state.dataZoneEquip->GetZoneEquipmentDataErrorsFound) {
992 0 : ShowFatalError(state, std::string{RoutineName} + "Errors found in getting Zone Equipment input.");
993 : }
994 771 : }
995 :
996 771 : void SetupZoneEquipmentForConvectionFlowRegime(EnergyPlusData &state)
997 : {
998 :
999 : // SUBROUTINE INFORMATION:
1000 : // AUTHOR Brent Griffith
1001 : // DATE WRITTEN Aug 2010
1002 : // MODIFIED na
1003 : // RE-ENGINEERED na
1004 :
1005 : // PURPOSE OF THIS SUBROUTINE:
1006 : // Decide a few one-time things for later
1007 : // determination of flow regime for convection
1008 :
1009 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1010 : int ZoneLoop;
1011 :
1012 771 : for (ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) {
1013 : }
1014 771 : }
1015 :
1016 4203 : bool CheckZoneEquipmentList(EnergyPlusData &state,
1017 : std::string_view const ComponentType, // Type of component
1018 : std::string_view const ComponentName, // Name of component
1019 : Optional_int CtrlZoneNum)
1020 : {
1021 :
1022 : // FUNCTION INFORMATION:
1023 : // AUTHOR Linda Lawrie
1024 : // DATE WRITTEN May 2007
1025 : // MODIFIED na
1026 : // RE-ENGINEERED na
1027 :
1028 : // PURPOSE OF THIS FUNCTION:
1029 : // Provides a way to check if a component name is listed on a zone equipment list.
1030 :
1031 : // Return value
1032 : bool IsOnList; // True if item is on a list, false if not.
1033 :
1034 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1035 : int Loop;
1036 : int ListLoop;
1037 : int CtrlZoneNumLocal;
1038 :
1039 4203 : CtrlZoneNumLocal = 0;
1040 4203 : IsOnList = false;
1041 64855 : for (Loop = 1; Loop <= state.dataGlobal->NumOfZones; ++Loop) { // NumOfZoneEquipLists
1042 64855 : if (state.dataZoneEquip->ZoneEquipList(Loop).Name.empty()) continue; // dimensioned by NumOfZones. Only valid ones have names.
1043 131258 : for (ListLoop = 1; ListLoop <= state.dataZoneEquip->ZoneEquipList(Loop).NumOfEquipTypes; ++ListLoop) {
1044 74265 : if (!UtilityRoutines::SameString(state.dataZoneEquip->ZoneEquipList(Loop).EquipType(ListLoop), ComponentType)) continue;
1045 55893 : if (ComponentName == "*") {
1046 0 : IsOnList = true;
1047 0 : CtrlZoneNumLocal = Loop;
1048 0 : goto EquipList_exit;
1049 : }
1050 55893 : if (!UtilityRoutines::SameString(state.dataZoneEquip->ZoneEquipList(Loop).EquipName(ListLoop), ComponentName)) continue;
1051 4203 : IsOnList = true;
1052 4203 : CtrlZoneNumLocal = Loop;
1053 4203 : goto EquipList_exit;
1054 : }
1055 : }
1056 0 : EquipList_exit:;
1057 4203 : if (present(CtrlZoneNum)) {
1058 0 : CtrlZoneNum = CtrlZoneNumLocal;
1059 : }
1060 4203 : return IsOnList;
1061 : }
1062 :
1063 7 : int GetControlledZoneIndex(EnergyPlusData &state, std::string const &ZoneName) // Zone name to match into Controlled Zone structure
1064 : {
1065 :
1066 : // FUNCTION INFORMATION:
1067 : // AUTHOR Linda Lawrie
1068 : // DATE WRITTEN March 2008
1069 :
1070 : // PURPOSE OF THIS FUNCTION:
1071 : // This function returns the index into the Controlled Zone Equipment structure
1072 : // of the indicated zone.
1073 :
1074 7 : if (!state.dataZoneEquip->ZoneEquipInputsFilled) {
1075 3 : GetZoneEquipmentData(state);
1076 3 : state.dataZoneEquip->ZoneEquipInputsFilled = true;
1077 : }
1078 :
1079 7 : return UtilityRoutines::FindItemInList(ZoneName, state.dataZoneEquip->ZoneEquipConfig, &EquipConfiguration::ZoneName);
1080 : }
1081 :
1082 4 : int FindControlledZoneIndexFromSystemNodeNumberForZone(EnergyPlusData &state,
1083 : int const TrialZoneNodeNum) // Node number to match into Controlled Zone structure
1084 : {
1085 :
1086 : // FUNCTION INFORMATION:
1087 : // AUTHOR Brent Griffith
1088 : // DATE WRITTEN August 2013
1089 :
1090 : // PURPOSE OF THIS FUNCTION:
1091 : // This function returns the zone number for the indicated
1092 : // zone node num. Returns 0 if did not find zone node in any Zone
1093 :
1094 4 : int ControlledZoneIndex = 0; // Index into Controlled Zone structure
1095 :
1096 4 : bool FoundIt = false;
1097 :
1098 4 : if (!state.dataZoneEquip->ZoneEquipInputsFilled) {
1099 0 : GetZoneEquipmentData(state);
1100 0 : state.dataZoneEquip->ZoneEquipInputsFilled = true;
1101 : }
1102 :
1103 19 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
1104 16 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) {
1105 16 : if (TrialZoneNodeNum == state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ZoneNode) {
1106 : // found it.
1107 1 : FoundIt = true;
1108 1 : ControlledZoneIndex = ZoneNum;
1109 1 : break;
1110 : }
1111 : }
1112 : }
1113 :
1114 4 : return ControlledZoneIndex;
1115 : }
1116 :
1117 225 : int GetSystemNodeNumberForZone(EnergyPlusData &state, int const zoneNum)
1118 : {
1119 :
1120 : // FUNCTION INFORMATION:
1121 : // AUTHOR Linda Lawrie
1122 : // DATE WRITTEN March 2008
1123 :
1124 : // PURPOSE OF THIS FUNCTION:
1125 : // This function returns the system node number for the indicated
1126 : // zone. Returns 0 if the Zone is not a controlled zone.
1127 :
1128 225 : int SystemZoneNodeNumber = 0; // System node number for controlled zone
1129 :
1130 225 : if (!state.dataZoneEquip->ZoneEquipInputsFilled) {
1131 0 : GetZoneEquipmentData(state);
1132 0 : state.dataZoneEquip->ZoneEquipInputsFilled = true;
1133 : }
1134 :
1135 225 : if (zoneNum > 0) {
1136 225 : if (state.dataZoneEquip->ZoneEquipConfig(zoneNum).IsControlled) {
1137 225 : SystemZoneNodeNumber = state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneNode;
1138 : }
1139 : }
1140 :
1141 225 : return SystemZoneNodeNumber;
1142 : }
1143 :
1144 122 : int GetReturnAirNodeForZone(EnergyPlusData &state,
1145 : int const zoneNum,
1146 : std::string const &NodeName, // Return air node name to match (may be blank)
1147 : std::string const &calledFromDescription // String identifying the calling function and object
1148 : )
1149 : {
1150 :
1151 : // FUNCTION INFORMATION:
1152 : // AUTHOR Linda Lawrie
1153 : // DATE WRITTEN March 2008
1154 : // MODIFIED Feb 2017 expanded for multiple return nodes in a zone
1155 :
1156 : // PURPOSE OF THIS FUNCTION:
1157 : // This function returns the return air node number for the indicated
1158 : // zone and node name. If NodeName is blank, return the first return node number,
1159 : // otherwise return the node number of the matching return node name.
1160 : // Returns 0 if the Zone is not a controlled zone or the node name does not match.
1161 :
1162 : // Return value
1163 122 : int ReturnAirNodeNumber = 0; // Return Air node number for controlled zone
1164 :
1165 122 : if (!state.dataZoneEquip->ZoneEquipInputsFilled) {
1166 0 : GetZoneEquipmentData(state);
1167 0 : state.dataZoneEquip->ZoneEquipInputsFilled = true;
1168 : }
1169 :
1170 122 : ReturnAirNodeNumber = 0; // default is not found
1171 122 : if (zoneNum > 0) {
1172 : {
1173 122 : auto const &thisZoneEquip(state.dataZoneEquip->ZoneEquipConfig(zoneNum));
1174 122 : if (thisZoneEquip.IsControlled) {
1175 122 : if (NodeName.empty()) {
1176 : // If NodeName is blank, return first return node number, but warn if there are multiple return nodes for this zone
1177 122 : ReturnAirNodeNumber = thisZoneEquip.ReturnNode(1);
1178 122 : if (thisZoneEquip.NumReturnNodes > 1) {
1179 0 : ShowWarningError(state, "GetReturnAirNodeForZone: " + calledFromDescription + ", request for zone return node is ambiguous.");
1180 0 : ShowContinueError(state,
1181 0 : format("Zone={} has {} return nodes. First return node will be used.",
1182 : thisZoneEquip.ZoneName,
1183 0 : thisZoneEquip.NumReturnNodes));
1184 : }
1185 : } else {
1186 0 : for (int nodeCount = 1; nodeCount <= thisZoneEquip.NumReturnNodes; ++nodeCount) {
1187 0 : int curNodeNum = thisZoneEquip.ReturnNode(nodeCount);
1188 0 : if (NodeName == state.dataLoopNodes->NodeID(curNodeNum)) {
1189 0 : ReturnAirNodeNumber = curNodeNum;
1190 : }
1191 : }
1192 : }
1193 : }
1194 : }
1195 : }
1196 :
1197 122 : return ReturnAirNodeNumber;
1198 : }
1199 :
1200 4051 : int GetReturnNumForZone(EnergyPlusData &state,
1201 : int const zoneNum,
1202 : std::string const &NodeName // Return air node name to match (may be blank)
1203 : )
1204 : {
1205 :
1206 : // PURPOSE OF THIS FUNCTION:
1207 : // This function returns the zone return number (not the node number) for the indicated
1208 : // zone and node name. If NodeName is blank, return 1 (the first return node)
1209 : // otherwise return the index of the matching return node name.
1210 : // Returns 0 if the Zone is not a controlled zone or the node name does not match.
1211 :
1212 : // Return value
1213 4051 : int ReturnIndex = 0; // Return number for the given zone (not the node number)
1214 :
1215 4051 : if (!state.dataZoneEquip->ZoneEquipInputsFilled) {
1216 641 : GetZoneEquipmentData(state);
1217 641 : state.dataZoneEquip->ZoneEquipInputsFilled = true;
1218 : }
1219 :
1220 4051 : if (zoneNum > 0) {
1221 4051 : if (state.dataZoneEquip->ZoneEquipConfig(zoneNum).IsControlled) {
1222 3920 : if (NodeName.empty()) {
1223 : // If NodeName is blank, return first return node number
1224 3919 : ReturnIndex = 1;
1225 : } else {
1226 2 : for (int nodeCount = 1; nodeCount <= state.dataZoneEquip->ZoneEquipConfig(zoneNum).NumReturnNodes; ++nodeCount) {
1227 1 : int curNodeNum = state.dataZoneEquip->ZoneEquipConfig(zoneNum).ReturnNode(nodeCount);
1228 1 : if (NodeName == state.dataLoopNodes->NodeID(curNodeNum)) {
1229 1 : ReturnIndex = nodeCount;
1230 : }
1231 : }
1232 : }
1233 : }
1234 : }
1235 :
1236 4051 : return ReturnIndex;
1237 : }
1238 :
1239 1 : bool VerifyLightsExhaustNodeForZone(EnergyPlusData &state, int const ZoneNum, int const ZoneExhaustNodeNum)
1240 : {
1241 1 : bool exhaustNodeError = true;
1242 :
1243 1 : if (!state.dataZoneEquip->ZoneEquipInputsFilled) {
1244 0 : GetZoneEquipmentData(state);
1245 0 : state.dataZoneEquip->ZoneEquipInputsFilled = true;
1246 : }
1247 :
1248 1 : for (int ExhaustNum = 1; ExhaustNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumExhaustNodes; ++ExhaustNum) {
1249 1 : if (ZoneExhaustNodeNum == state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ExhaustNode(ExhaustNum)) {
1250 1 : exhaustNodeError = false;
1251 1 : break;
1252 : }
1253 : }
1254 :
1255 1 : return exhaustNodeError;
1256 : }
1257 :
1258 475 : void EquipList::getPrioritiesForInletNode(EnergyPlusData &state,
1259 : int const inletNodeNum, // Zone inlet node number to match
1260 : int &coolingPriority, // Cooling priority num for matching equipment
1261 : int &heatingPriority // Heating priority num for matching equipment
1262 : )
1263 : {
1264 475 : bool equipFound = false;
1265 591 : for (int equipNum = 1; equipNum <= this->NumOfEquipTypes; ++equipNum) {
1266 591 : if (this->EquipTypeEnum(equipNum) == DataZoneEquipment::ZoneEquip::AirDistUnit) {
1267 480 : if (inletNodeNum == state.dataDefineEquipment->AirDistUnit(this->EquipIndex(equipNum)).OutletNodeNum) {
1268 475 : equipFound = true;
1269 : }
1270 : }
1271 591 : if (equipFound) {
1272 475 : coolingPriority = this->CoolingPriority(equipNum);
1273 475 : heatingPriority = this->HeatingPriority(equipNum);
1274 475 : break;
1275 : }
1276 : }
1277 : // Set MinAirLoopIterationsAfterFirst for equipment that uses sequenced loads, based on zone equip load distribution scheme
1278 475 : int minIterations = state.dataHVACGlobal->MinAirLoopIterationsAfterFirst;
1279 475 : if (this->LoadDistScheme == DataZoneEquipment::LoadDist::Sequential) {
1280 : // Sequential needs one extra iterations up to the highest airterminal unit equipment number
1281 469 : minIterations = max(coolingPriority, heatingPriority, minIterations);
1282 6 : } else if (this->LoadDistScheme == DataZoneEquipment::LoadDist::Uniform) {
1283 : // Uniform needs one extra iteration which is the default
1284 4 : } else if (this->LoadDistScheme == DataZoneEquipment::LoadDist::UniformPLR) {
1285 : // UniformPLR needs two extra iterations, regardless of unit equipment number
1286 2 : minIterations = max(2, minIterations);
1287 2 : } else if (this->LoadDistScheme == DataZoneEquipment::LoadDist::SequentialUniformPLR) {
1288 : // SequentialUniformPLR needs one extra iterations up to the highest airterminal unit equipment number plus one more
1289 2 : minIterations = max((coolingPriority + 1), (heatingPriority + 1), minIterations);
1290 : }
1291 475 : state.dataHVACGlobal->MinAirLoopIterationsAfterFirst = minIterations;
1292 475 : }
1293 :
1294 78637833 : Real64 EquipList::SequentialHeatingFraction(EnergyPlusData &state, const int equipNum)
1295 : {
1296 78637833 : return ScheduleManager::GetCurrentScheduleValue(state, SequentialHeatingFractionSchedPtr(equipNum));
1297 : }
1298 :
1299 78508961 : Real64 EquipList::SequentialCoolingFraction(EnergyPlusData &state, const int equipNum)
1300 : {
1301 78508961 : return ScheduleManager::GetCurrentScheduleValue(state, SequentialCoolingFractionSchedPtr(equipNum));
1302 : }
1303 :
1304 206 : int GetZoneEquipControlledZoneNum(EnergyPlusData &state, DataZoneEquipment::ZoneEquip const ZoneEquipTypeNum, std::string const &EquipmentName)
1305 : {
1306 : static constexpr std::string_view RoutineName("GetZoneEquipControlledZoneNum: ");
1307 206 : int ControlZoneNum = 0;
1308 :
1309 990 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
1310 990 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
1311 2240 : for (int Num = 1; Num <= state.dataZoneEquip->ZoneEquipList(CtrlZone).NumOfEquipTypes; ++Num) {
1312 2212 : if (ZoneEquipTypeNum == state.dataZoneEquip->ZoneEquipList(CtrlZone).EquipTypeEnum(Num) &&
1313 667 : UtilityRoutines::SameString(EquipmentName, state.dataZoneEquip->ZoneEquipList(CtrlZone).EquipName(Num))) {
1314 206 : return ControlZoneNum = CtrlZone;
1315 : }
1316 : }
1317 : }
1318 0 : ShowSevereError(state,
1319 0 : fmt::format("{}{}=\"{}\" is not on any ZoneHVAC:Equipmentlist. It will not be simulated.",
1320 : RoutineName,
1321 0 : DataZoneEquipment::ZoneEquipTypeNamesUC[ZoneEquipTypeNum],
1322 : EquipmentName));
1323 0 : return ControlZoneNum;
1324 : }
1325 :
1326 1 : void CheckSharedExhaust(EnergyPlusData &state)
1327 : {
1328 1 : int ExhastNodeNum = 0;
1329 7 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
1330 6 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes < 2) continue;
1331 0 : for (int nodeCount = 1; nodeCount <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes; ++nodeCount) {
1332 0 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).SharedExhaustNode(nodeCount) == LightReturnExhaustConfig::Shared) continue;
1333 0 : ExhastNodeNum = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ReturnNodeExhaustNodeNum(nodeCount);
1334 0 : if (ExhastNodeNum > 0) {
1335 0 : state.dataZoneEquip->ZoneEquipConfig(ZoneNum).SharedExhaustNode(nodeCount) = LightReturnExhaustConfig::Single;
1336 0 : for (int nodeCount1 = nodeCount + 1; nodeCount1 <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes; ++nodeCount1) {
1337 0 : if (ExhastNodeNum == state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ReturnNodeExhaustNodeNum(nodeCount1)) {
1338 0 : state.dataZoneEquip->ZoneEquipConfig(ZoneNum).SharedExhaustNode(nodeCount) = LightReturnExhaustConfig::Multi;
1339 0 : state.dataZoneEquip->ZoneEquipConfig(ZoneNum).SharedExhaustNode(nodeCount1) = LightReturnExhaustConfig::Shared;
1340 : }
1341 : }
1342 : }
1343 : }
1344 : }
1345 1 : }
1346 :
1347 2313 : } // namespace EnergyPlus::DataZoneEquipment
|