Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // ObjexxFCL Headers
49 : #include <ObjexxFCL/Array.functions.hh>
50 : #include <ObjexxFCL/member.functions.hh>
51 : #include <ObjexxFCL/string.functions.hh>
52 :
53 : // EnergyPlus Headers
54 : #include <EnergyPlus/BranchNodeConnections.hh>
55 : #include <EnergyPlus/Data/EnergyPlusData.hh>
56 : #include <EnergyPlus/DataBranchNodeConnections.hh>
57 : #include <EnergyPlus/DataLoopNode.hh>
58 : #include <EnergyPlus/NodeInputManager.hh>
59 : #include <EnergyPlus/UtilityRoutines.hh>
60 :
61 : namespace EnergyPlus::BranchNodeConnections {
62 :
63 : // Module containing the routines dealing with the Branch/Node Connections (CompSets, etc)
64 :
65 : // MODULE INFORMATION:
66 : // AUTHOR Linda Lawrie
67 : // DATE WRITTEN May 2005
68 :
69 : // PURPOSE OF THIS MODULE:
70 : // This module encapsulates the connection data necessary for some of the checks
71 : // needed in the branch-node data
72 :
73 : // Using/Aliasing
74 : using namespace DataLoopNode;
75 : using namespace DataBranchNodeConnections;
76 :
77 : static constexpr std::string_view undefined("UNDEFINED");
78 :
79 : constexpr std::array<std::string_view, static_cast<int>(DataLoopNode::ConnectionObjectType::Num)> ConnectionObjectTypeNames = {
80 : "Undefined",
81 : "AirConditioner:VariableRefrigerantFlow",
82 : "AirLoopHVAC",
83 : "AirLoopHVAC:DedicatedOutdoorAirSystem",
84 : "AirLoopHVAC:ExhaustSystem",
85 : "AirLoopHVAC:Mixer",
86 : "AirLoopHVAC:OutdoorAirSystem",
87 : "AirLoopHVAC:ReturnPath",
88 : "AirLoopHVAC:ReturnPlenum",
89 : "AirLoopHVAC:Splitter",
90 : "AirLoopHVAC:SupplyPath",
91 : "AirLoopHVAC:SupplyPlenum",
92 : "AirLoopHVAC:Unitary:Furnace:HeatCool",
93 : "AirLoopHVAC:Unitary:Furnace:HeatOnly",
94 : "AirLoopHVAC:UnitaryHeatCool",
95 : "AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass",
96 : "AirLoopHVAC:UnitaryHeatOnly",
97 : "AirLoopHVAC:UnitaryHeatPump:AirToAir",
98 : "AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed",
99 : "AirLoopHVAC:UnitaryHeatPump:WaterToAir",
100 : "AirLoopHVAC:UnitarySystem",
101 : "AirLoopHVAC:ZoneMixer",
102 : "AirLoopHVAC:ZoneSplitter",
103 : "AirTerminal:DualDuct:ConstantVolume",
104 : "AirTerminal:DualDuct:ConstantVolume:Cool",
105 : "AirTerminal:DualDuct:ConstantVolume:Heat",
106 : "AirTerminal:DualDuct:VAV",
107 : "AirTerminal:DualDuct:VAV:Cool",
108 : "AirTerminal:DualDuct:VAV:Heat",
109 : "AirTerminal:DualDuct:VAV:OutdoorAir",
110 : "AirTerminal:DualDuct:VAV:OutdoorAir:OutdoorAir",
111 : "AirTerminal:DualDuct:VAV:OutdoorAir:RecirculatedAir",
112 : "AirTerminal:SingleDuct:ConstantVolume:CooledBeam",
113 : "AirTerminal:SingleDuct:ConstantVolume:FourPipeBeam",
114 : "AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction",
115 : "AirTerminal:SingleDuct:ConstantVolume:NoReheat",
116 : "AirTerminal:SingleDuct:ConstantVolume:Reheat",
117 : "AirTerminal:SingleDuct:Mixer",
118 : "AirTerminal:SingleDuct:ParallelPIU:Reheat",
119 : "AirTerminal:SingleDuct:SeriesPIU:Reheat",
120 : "AirTerminal:SingleDuct:UserDefined",
121 : "AirTerminal:SingleDuct:VAV:HeatAndCool:NoReheat",
122 : "AirTerminal:SingleDuct:VAV:HeatAndCool:Reheat",
123 : "AirTerminal:SingleDuct:VAV:NoReheat",
124 : "AirTerminal:SingleDuct:VAV:Reheat",
125 : "AirTerminal:SingleDuct:VAV:Reheat:VariableSpeedFan",
126 : "AvailabilityManager:DifferentialThermostat",
127 : "AvailabilityManager:HighTemperatureTurnOff",
128 : "AvailabilityManager:HighTemperatureTurnOn",
129 : "AvailabilityManager:LowTemperatureTurnOff",
130 : "AvailabilityManager:LowTemperatureTurnOn",
131 : "Boiler:HotWater",
132 : "Boiler:Steam",
133 : "Branch",
134 : "CentralHeatPumpSystem",
135 : "Chiller:Absorption",
136 : "Chiller:Absorption:Indirect",
137 : "Chiller:CombustionTurbine",
138 : "Chiller:ConstantCOP",
139 : "Chiller:Electric",
140 : "Chiller:Electric:EIR",
141 : "Chiller:Electric:ReformulatedEIR",
142 : "Chiller:Electric:ASHRAE205",
143 : "Chiller:EngineDriven",
144 : "ChillerHeater:Absorption:DirectFired",
145 : "ChillerHeater:Absorption:DoubleEffect",
146 : "Coil:Cooling:DX",
147 : "Coil:Cooling:DX:CurveFit:Speed",
148 : "Coil:Cooling:DX:MultiSpeed",
149 : "Coil:Cooling:DX:SingleSpeed",
150 : "Coil:Cooling:DX:SingleSpeed:ThermalStorage",
151 : "Coil:Cooling:DX:SubcoolReheat",
152 : "Coil:Cooling:DX:TwoSpeed",
153 : "Coil:Cooling:DX:TwoStageWithHumidityControlMode",
154 : "Coil:Cooling:DX:VariableRefrigerantFlow",
155 : "Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl",
156 : "Coil:Cooling:DX:VariableSpeed",
157 : "Coil:Cooling:Water",
158 : "Coil:Cooling:Water:DetailedGeometry",
159 : "Coil:Cooling:WaterToAirHeatPump:EquationFit",
160 : "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation",
161 : "Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit",
162 : "Coil:Heating:DX:MultiSpeed",
163 : "Coil:Heating:DX:SingleSpeed",
164 : "Coil:Heating:DX:VariableRefrigerantFlow",
165 : "Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl",
166 : "Coil:Heating:DX:VariableSpeed",
167 : "Coil:Heating:Desuperheater",
168 : "Coil:Heating:Electric",
169 : "Coil:Heating:Electric:MultiStage",
170 : "Coil:Heating:Fuel",
171 : "Coil:Heating:Gas:MultiStage",
172 : "Coil:Heating:Steam",
173 : "Coil:Heating:Water",
174 : "Coil:Heating:WaterToAirHeatPump:EquationFit",
175 : "Coil:Heating:WaterToAirHeatPump:ParameterEstimation",
176 : "Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit",
177 : "Coil:UserDefined",
178 : "Coil:WaterHeating:AirToWaterHeatPump:Pumped",
179 : "Coil:WaterHeating:AirToWaterHeatPump:VariableSpeed",
180 : "Coil:WaterHeating:AirToWaterHeatPump:Wrapped",
181 : "Coil:WaterHeating:Desuperheater",
182 : "CoilSystem:Cooling:DX",
183 : "CoilSystem:Cooling:DX:HeatExchangerAssisted",
184 : "CoilSystem:Cooling:Water",
185 : "CoilSystem:Cooling:Water:HeatExchangerAssisted",
186 : "CoilSystem:Heating:DX",
187 : "CoilSystem:IntegratedHeatPump:AirSource",
188 : "Condenser",
189 : "CondenserLoop",
190 : "Connector:Mixer",
191 : "Connector:Splitter",
192 : "Controller:OutdoorAir",
193 : "Controller:WaterCoil",
194 : "CoolingTower:SingleSpeed",
195 : "CoolingTower:TwoSpeed",
196 : "CoolingTower:VariableSpeed",
197 : "CoolingTower:VariableSpeed:Merkel",
198 : "Dehumidifier:Desiccant:NoFans",
199 : "Dehumidifier:Desiccant:System",
200 : "DistrictCooling",
201 : "DistrictHeating:Water",
202 : "DistrictHeating:Steam",
203 : "Duct",
204 : "ElectricEquipment:ITE:AirCooled",
205 : "EvaporativeCooler:Direct:CelDekPad",
206 : "EvaporativeCooler:Direct:ResearchSpecial",
207 : "EvaporativeCooler:Indirect:CelDekPad",
208 : "EvaporativeCooler:Indirect:ResearchSpecial",
209 : "EvaporativeCooler:Indirect:WetCoil",
210 : "EvaporativeFluidCooler:SingleSpeed",
211 : "EvaporativeFluidCooler:TwoSpeed",
212 : "Fan:ComponentModel",
213 : "Fan:ConstantVolume",
214 : "Fan:OnOff",
215 : "Fan:SystemModel",
216 : "Fan:VariableVolume",
217 : "Fan:ZoneExhaust",
218 : "FluidCooler:SingleSpeed",
219 : "FluidCooler:TwoSpeed",
220 : "Generator:CombustionTurbine",
221 : "Generator:FuelCell:AirSupply",
222 : "Generator:FuelCell:ExhaustGasToWaterHeatExchanger",
223 : "Generator:FuelCell:PowerModule",
224 : "Generator:FuelCell:StackCooler",
225 : "Generator:FuelCell:WaterSupply",
226 : "Generator:FuelSupply",
227 : "Generator:InternalCombustionEngine",
228 : "Generator:MicroCHP",
229 : "Generator:MicroTurbine",
230 : "GroundHeatExchanger:HorizontalTrench",
231 : "GroundHeatExchanger:Pond",
232 : "GroundHeatExchanger:Slinky",
233 : "GroundHeatExchanger:Surface",
234 : "GroundHeatExchanger:System",
235 : "HeaderedPumps:ConstantSpeed",
236 : "HeaderedPumps:VariableSpeed",
237 : "HeatExchanger:AirToAir:FlatPlate",
238 : "HeatExchanger:AirToAir:SensibleAndLatent",
239 : "HeatExchanger:Desiccant:BalancedFlow",
240 : "HeatExchanger:FluidToFluid",
241 : "HeatPump:AirToWater:FuelFired:Cooling",
242 : "HeatPump:AirToWater:FuelFired:Heating",
243 : "HeatPump:PlantLoop:EIR:Cooling",
244 : "HeatPump:PlantLoop:EIR:Heating",
245 : "HeatPump:WaterToWater:EquationFit:Cooling",
246 : "HeatPump:WaterToWater:EquationFit:Heating",
247 : "HeatPump:WaterToWater:ParameterEstimation:Cooling",
248 : "HeatPump:WaterToWater:ParameterEstimation:Heating",
249 : "Humidifier:Steam:Electric",
250 : "Humidifier:Steam:Gas",
251 : "Lights",
252 : "LoadProfile:Plant",
253 : "OutdoorAir:Mixer",
254 : "OutdoorAir:Node",
255 : "OutdoorAir:NodeList",
256 : "Pipe:Adiabatic",
257 : "Pipe:Adiabatic:Steam",
258 : "Pipe:Indoor",
259 : "Pipe:Outdoor",
260 : "Pipe:Underground",
261 : "PipingSystem:Underground:PipeCircuit",
262 : "PlantComponent:TemperatureSource",
263 : "PlantComponent:UserDefined",
264 : "PlantEquipmentOperation:ChillerHeaterChangeover",
265 : "PlantEquipmentOperation:ComponentSetpoint",
266 : "PlantEquipmentOperation:OutdoorDewpointDifference",
267 : "PlantEquipmentOperation:OutdoorDrybulbDifference",
268 : "PlantEquipmentOperation:OutdoorWetbulbDifference",
269 : "PlantEquipmentOperation:ThermalEnergyStorage",
270 : "PlantLoop",
271 : "Pump:ConstantSpeed",
272 : "Pump:ConstantVolume",
273 : "Pump:VariableSpeed",
274 : "Pump:VariableSpeed:Condensate",
275 : "Refrigeration:CompressorRack",
276 : "Refrigeration:Condenser:AirCooled",
277 : "Refrigeration:Condenser:EvaporativeCooled",
278 : "Refrigeration:Condenser:WaterCooled",
279 : "Refrigeration:GasCooler:AirCooled",
280 : "SetpointManager:Coldest",
281 : "SetpointManager:CondenserEnteringReset",
282 : "SetpointManager:CondenserEnteringReset:Ideal",
283 : "SetpointManager:FollowGroundTemperature",
284 : "SetpointManager:FollowOutdoorAirTemperature",
285 : "SetpointManager:FollowSystemNodeTemperature",
286 : "SetpointManager:MixedAir",
287 : "SetpointManager:MultiZone:Cooling:Average",
288 : "SetpointManager:MultiZone:Heating:Average",
289 : "SetpointManager:MultiZone:Humidity:Maximum",
290 : "SetpointManager:MultiZone:Humidity:Minimum",
291 : "SetpointManager:MultiZone:MaximumHumidity:Average",
292 : "SetpointManager:MultiZone:MinimumHumidity:Average",
293 : "SetpointManager:OutdoorAirPretreat",
294 : "SetpointManager:OutdoorAirReset",
295 : "SetpointManager:ReturnTemperature:ChilledWater",
296 : "SetpointManager:ReturnTemperature:HotWater",
297 : "SetpointManager:Scheduled",
298 : "SetpointManager:Scheduled:DualSetpoint",
299 : "SetpointManager:SingleZone:Cooling",
300 : "SetpointManager:SingleZone:Heating",
301 : "SetpointManager:SingleZone:Humidity:Maximum",
302 : "SetpointManager:SingleZone:Humidity:Minimum",
303 : "SetpointManager:SingleZone:OneStageCooling",
304 : "SetpointManager:SingleZone:OneStageHeating",
305 : "SetpointManager:SingleZone:Reheat",
306 : "SetpointManager:SystemNodeReset:Temperature",
307 : "SetpointManager:SystemNodeReset:Humidity",
308 : "SetpointManager:Warmest",
309 : "SetpointManager:WarmestTemperatureFlow",
310 : "SolarCollector:FlatPlate:PhotovoltaicThermal",
311 : "SolarCollector:FlatPlate:Water",
312 : "SolarCollector:IntegralCollectorStorage",
313 : "SolarCollector:UnglazedTranspired",
314 : "SurfaceProperty:LocalEnvironment",
315 : "SwimmingPool:Indoor",
316 : "TemperingValve",
317 : "ThermalStorage:ChilledWater:Mixed",
318 : "ThermalStorage:ChilledWater:Stratified",
319 : "ThermalStorage:Ice:Detailed",
320 : "ThermalStorage:Ice:Simple",
321 : "WaterHeater:HeatPump",
322 : "WaterHeater:HeatPump:PumpedCondenser",
323 : "WaterHeater:HeatPump:WrappedCondenser",
324 : "WaterHeater:Mixed",
325 : "WaterHeater:Stratified",
326 : "WaterUse:Connections",
327 : "ZoneHVAC:AirDistributionUnit",
328 : "ZoneHVAC:Baseboard:Convective:Electric",
329 : "ZoneHVAC:Baseboard:Convective:Water",
330 : "ZoneHVAC:Baseboard:RadiantConvective:Electric",
331 : "ZoneHVAC:Baseboard:RadiantConvective:Steam",
332 : "ZoneHVAC:Baseboard:RadiantConvective:Water",
333 : "ZoneHVAC:CoolingPanel:RadiantConvective:Water",
334 : "ZoneHVAC:Dehumidifier:DX",
335 : "ZoneHVAC:EnergyRecoveryVentilator",
336 : "ZoneHVAC:EquipmentConnections",
337 : "ZoneHVAC:EvaporativeCoolerUnit",
338 : "ZoneHVAC:ExhaustControl",
339 : "ZoneHVAC:ForcedAir:UserDefined",
340 : "ZoneHVAC:FourPipeFanCoil",
341 : "ZoneHVAC:HighTemperatureRadiant",
342 : "ZoneHVAC:HybridUnitaryHVAC",
343 : "ZoneHVAC:IdealLoadsAirSystem",
344 : "ZoneHVAC:LowTemperatureRadiant:ConstantFlow",
345 : "ZoneHVAC:LowTemperatureRadiant:VariableFlow",
346 : "ZoneHVAC:OutdoorAirUnit",
347 : "ZoneHVAC:PackagedTerminalAirConditioner",
348 : "ZoneHVAC:PackagedTerminalHeatPump",
349 : "ZoneHVAC:RefrigerationChillerSet",
350 : "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow",
351 : "ZoneHVAC:UnitHeater",
352 : "ZoneHVAC:UnitVentilator",
353 : "ZoneHVAC:VentilatedSlab",
354 : "ZoneHVAC:WaterToAirHeatPump",
355 : "ZoneHVAC:WindowAirConditioner",
356 : "ZoneProperty:LocalEnvironment",
357 : "SpaceHVAC:EquipmentConnections",
358 : "SpaceHVAC:ZoneEquipmentSplitter",
359 : "SpaceHVAC:ZoneEquipmentMixer"};
360 :
361 : constexpr std::array<std::string_view, static_cast<int>(DataLoopNode::ConnectionObjectType::Num)> ConnectionObjectTypeNamesUC = {
362 : undefined,
363 : "AIRCONDITIONER:VARIABLEREFRIGERANTFLOW",
364 : "AIRLOOPHVAC",
365 : "AIRLOOPHVAC:DEDICATEDOUTDOORAIRSYSTEM",
366 : "AIRLOOPHVAC:EXHAUSTSYSTEM",
367 : "AIRLOOPHVAC:MIXER",
368 : "AIRLOOPHVAC:OUTDOORAIRSYSTEM",
369 : "AIRLOOPHVAC:RETURNPATH",
370 : "AIRLOOPHVAC:RETURNPLENUM",
371 : "AIALOOPHVAC:SPLITTER",
372 : "AIRLOOPHVAC:SUPPLYPATH",
373 : "AIRLOOPHVAC:SUPPLYPLENUM",
374 : "AIRLOOPHVAC:UNITARY:FURNACE:HEATCOOL",
375 : "AIRLOOPHVAC:UNITARY:FURNACE:HEATONLY",
376 : "AIRLOOPHVAC:UNITARYHEATCOOL",
377 : "AIRLOOPHVAC:UNITARYHEATCOOL:VAVCHANGEOVERBYPASS",
378 : "AIRLOOPHVAC:UNITARYHEATONLY",
379 : "AIRLOOPHVAC:UNITARYHEATPUMP:AIRTOAIR",
380 : "AIRLOOPHVAC:UNITARYHEATPUMP:AIRTOAIR:MULTISPEED",
381 : "AIRLOOPHVAC:UNITARYHEATPUMP:WATERTOAIR",
382 : "AIRLOOPHVAC:UNITARYSYSTEM",
383 : "AIRLOOPHVAC:ZONEMIXER",
384 : "AIRLOOPHVAC:ZONESPLITTER",
385 : "AIRTERMINAL:DUALDUCT:CONSTANTVOLUME",
386 : "AIRTERMINAL:DUALDUCT:CONSTANTVOLUME:COOL",
387 : "AIRTERMINAL:DUALDUCT:CONSTANTVOLUME:HEAT",
388 : "AIRTERMINAL:DUALDUCT:VAV",
389 : "AIRTERMINAL:DUALDUCT:VAV:COOL",
390 : "AIRTERMINAL:DUALDUCT:VAV:HEAT",
391 : "AIRTERMINAL:DUALDUCT:VAV:OUTDOORAIR",
392 : "AIRTERMINAL:DUALDUCT:VAV:OUTDOORAIR:OUTDOORAIR",
393 : "AIRTERMINAL:DUALDUCT:VAV:OUTDOORAIR:RECIRCULATEDAIR",
394 : "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:COOLEDBEAM",
395 : "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:FOURPIPEBEAM",
396 : "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:FOURPIPEINDUCTION",
397 : "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:NOREHEAT",
398 : "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:REHEAT",
399 : "AIRTERMINAL:SINGLEDUCT:MIXER",
400 : "AIRTERMINAL:SINGLEDUCT:PARALLELPIU:REHEAT",
401 : "AIRTERMINAL:SINGLEDUCT:SERIESPIU:REHEAT",
402 : "AIRTERMINAL:SINGLEDUCT:USERDEFINED",
403 : "AIRTERMINAL:SINGLEDUCT:VAV:HEATANDCOOL:NOREHEAT",
404 : "AIRTERMINAL:SINGLEDUCT:VAV:HEATANDCOOL:REHEAT",
405 : "AIRTERMINAL:SINGLEDUCT:VAV:NOREHEAT",
406 : "AIRTERMINAL:SINGLEDUCT:VAV:REHEAT",
407 : "AIRTERMINAL:SINGLEDUCT:VAV:REHEAT:VARIABLESPEEDFAN",
408 : "AVAILABILITYMANAGER:DIFFERENTIALTHERMOSTAT",
409 : "AVAILABILITYMANAGER:HIGHTEMPERATURETURNOFF",
410 : "AVAILABILITYMANAGER:HIGHTEMPERATURETURNON",
411 : "AVAILABILITYMANAGER:LOWTEMPERATURETURNOFF",
412 : "AVAILABILITYMANAGER:LOWTEMPERATURETURNON",
413 : "BOILER:HOTWATER",
414 : "BOILER:STEAM",
415 : "BRANCH",
416 : "CENTRALHEATPUMPSYSTEM",
417 : "CHILLER:ABSORPTION",
418 : "CHILLER:ABSORPTION:INDIRECT",
419 : "CHILLER:COMBUSTIONTURBINE",
420 : "CHILLER:CONSTANTCOP",
421 : "CHILLER:ELECTRIC",
422 : "CHILLER:ELECTRIC:EIR",
423 : "CHILLER:ELECTRIC:REFORMULATEDEIR",
424 : "CHILLER:ELECTRIC:ASHRAE205",
425 : "CHILLER:ENGINEDRIVEN",
426 : "CHILLERHEATER:ABSORPTION:DIRECTFIRED",
427 : "CHILLERHEATER:ABSORPTION:DOUBLEEFFECT",
428 : "COIL:COOLING:DX",
429 : "COIL:COOLING:DX:CURVEFIT:SPEED",
430 : "COIL:COOLING:DX:MULTISPEED",
431 : "COIL:COOLING:DX:SINGLESPEED",
432 : "COIL:COOLING:DX:SINGLESPEED:THERMALSTORAGE",
433 : "COIL:COOLING:DX:SUBCOOLREHEAT",
434 : "COIL:COOLING:DX:TWOSPEED",
435 : "COIL:COOLING:DX:TWOSTAGEWITHHUMIDITYCONTROLMODE",
436 : "COIL:COOLING:DX:VARIABLEREFRIGERANTFLOW",
437 : "COIL:COOLING:DX:VARIABLEREFRIGERANTFLOW:FLUIDTEMPERATURECONTROL",
438 : "COIL:COOLING:DX:VARIABLESPEED",
439 : "COIL:COOLING:WATER",
440 : "COIL:COOLING:WATER:DETAILEDGEOMETRY",
441 : "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT",
442 : "COIL:COOLING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION",
443 : "COIL:COOLING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT",
444 : "COIL:HEATING:DX:MULTISPEED",
445 : "COIL:HEATING:DX:SINGLESPEED",
446 : "COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW",
447 : "COIL:HEATING:DX:VARIABLEREFRIGERANTFLOW:FLUIDTEMPERATURECONTROL",
448 : "COIL:HEATING:DX:VARIABLESPEED",
449 : "COIL:HEATING:DESUPERHEATER",
450 : "COIL:HEATING:ELECTRIC",
451 : "COIL:HEATING:ELECTRIC:MULTISTAGE",
452 : "COIL:HEATING:FUEL",
453 : "COIL:HEATING:GAS:MULTISTAGE",
454 : "COIL:HEATING:STEAM",
455 : "COIL:HEATING:WATER",
456 : "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT",
457 : "COIL:HEATING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION",
458 : "COIL:HEATING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT",
459 : "COIL:USERDEFINED",
460 : "COIL:WATERHEATING:AIRTOWATERHEATPUMP:PUMPED",
461 : "COIL:WATERHEATING:AIRTOWATERHEATPUMP:VARIABLESPEED",
462 : "COIL:WATERHEATING:AIRTOWATERHEATPUMP:WRAPPED",
463 : "COIL:WATERHEATING:DESUPERHEATER",
464 : "COILSYSTEM:COOLING:DX",
465 : "COILSYSTEM:COOLING:DX:HEATEXCHANGERASSISTED",
466 : "COILSYSTEM:COOLING:WATER",
467 : "COILSYSTEM:COOLING:WATER:HEATEXCHANGERASSISTED",
468 : "COILSYSTEM:HEATING:DX",
469 : "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE",
470 : "CONDENSER",
471 : "CONDENSERLOOP",
472 : "CONNECTOR:MIXER",
473 : "CONNECTOR:SPLITTER",
474 : "CONTROLLER:OUTDOORAIR",
475 : "CONTROLLER:WATERCOIL",
476 : "COOLINGTOWER:SINGLESPEED",
477 : "COOLINGTOWER:TWOSPEED",
478 : "COOLINGTOWER:VARIABLESPEED",
479 : "COOLINGTOWER:VARIABLESPEED:MERKEL",
480 : "DEHUMIDIFIER:DESICCANT:NOFANS",
481 : "DEHUMIDIFIER:DESICCANT:SYSTEM",
482 : "DISTRICTCOOLING",
483 : "DISTRICTHEATING:WATER",
484 : "DISTRICTHEATING:STEAM",
485 : "DUCT",
486 : "ELECTRICEQUIPMENT:ITE:AIRCOOLED",
487 : "EVAPORATIVECOOLER:DIRECT:CELDEKPAD",
488 : "EVAPORATIVECOOLER:DIRECT:RESEARCHSPECIAL",
489 : "EVAPORATIVECOOLER:INDIRECT:CELDEKPAD",
490 : "EVAPORATIVECOOLER:INDIRECT:RESEARCHSPECIAL",
491 : "EVAPORATIVECOOLER:INDIRECT:WETCOIL",
492 : "EVAPORATIVEFLUIDCOOLER:SINGLESPEED",
493 : "EVAPORATIVEFLUIDCOOLER:TWOSPEED",
494 : "FAN:COMPONENTMODEL",
495 : "FAN:CONSTANTVOLUME",
496 : "FAN:ONOFF",
497 : "FAN:SYSTEMMODEL",
498 : "FAN:VARIABLEVOLUME",
499 : "FAN:ZONEEXHAUST",
500 : "FLUIDCOOLER:SINGLESPEED",
501 : "FLUIDCOOLER:TWOSPEED",
502 : "GENERATOR:COMBUSTIONTURBINE",
503 : "GENERATOR:FUELCELL:AIRSUPPLY",
504 : "GENERATOR:FUELCELL:EXHAUSTGASTOWATERHEATEXCHANGER",
505 : "GENERATOR:FUELCELL:POWERMODULE",
506 : "GENERATOR:FUELCELL:STACKCOOLER",
507 : "GENERATOR:FUELCELL:WATERSUPPLY",
508 : "GENERATOR:FUELSUPPLY",
509 : "GENERATOR:INTERNALCOMBUSTIONENGINE",
510 : "GENERATOR:MICROCHP",
511 : "GENERATOR:MICROTURBINE",
512 : "GROUNDHEATEXCHANGER:HORIZONTALTRENCH",
513 : "GROUNDHEATEXCHANGER:POND",
514 : "GROUNDHEATEXCHANGER:SLINKY",
515 : "GROUNDHEATEXCHANGER:SURFACE",
516 : "GROUNDHEATEXCHANGER:SYSTEM",
517 : "HEADEREDPUMPS:CONSTANTSPEED",
518 : "HEADEREDPUMPS:VARIABLESPEED",
519 : "HEATEXCHANGER:AIRTOAIR:FLATPLATE",
520 : "HEATEXCHANGER:AIRTOAIR:SENSIBLEANDLATENT",
521 : "HEATEXCHANGER:DESICCANT:BALANCEDFLOW",
522 : "HEATEXCHANGER:FLUIDTOFLUID",
523 : "HEATPUMP:AIRTOWATER:FUELFIRED:COOLING",
524 : "HEATPUMP:AIRTOWATER:FUELFIRED:HEATING",
525 : "HEATPUMP:PLANTLOOP:EIR:COOLING",
526 : "HEATPUMP:PLANTLOOP:EIR:HEATING",
527 : "HEATPUMP:WATERTOWATER:EQUATIONFIT:COOLING",
528 : "HEATPUMP:WATERTOWATER:EQUATIONFIT:HEATING",
529 : "HEATPUMP:WATERTOWATER:PARAMETERESTIMATION:COOLING",
530 : "HEATPUMP:WATERTOWATER:PARAMETERESTIMATION:HEATING",
531 : "HUMIDIFIER:STEAM:ELECTRIC",
532 : "HUMIDIFIER:STEAM:GAS",
533 : "LIGHTS",
534 : "LOADPROFILE:PLANT",
535 : "OUTDOORAIR:MIXER",
536 : "OUTDOORAIR:NODE",
537 : "OUTDOORAIR:NODELIST",
538 : "PIPE:ADIABATIC",
539 : "PIPE:ADIABATIC:STEAM",
540 : "PIPE:INDOOR",
541 : "PIPE:OUTDOOR",
542 : "PIPE:UNDERGROUND",
543 : "PIPINGSYSTEM:UNDERGROUND:PIPECIRCUIT",
544 : "PLANTCOMPONENT:TEMPERATURESOURCE",
545 : "PLANTCOMPONENT:USERDEFINED",
546 : "PLANTEQUIPMENTOPERATION:CHILLERHEATERCHANGEOVER",
547 : "PLANTEQUIPMENTOPERATION:COMPONENTSETPOINT",
548 : "PLANTEQUIPMENTOPERATION:OUTDOORDEWPOINTDIFFERENCE",
549 : "PLANTEQUIPMENTOPERATION:OUTDOORDRYBULBDIFFERENCE",
550 : "PLANTEQUIPMENTOPERATION:OUTDOORWETBULBDIFFERENCE",
551 : "PLANTEQUIPMENTOPERATION:THERMALENERGYSTORAGE",
552 : "PLANTLOOP",
553 : "PUMP:CONSTANTSPEED",
554 : "PUMP:CONSTANTVOLUME",
555 : "PUMP:VARIABLESPEED",
556 : "PUMP:VARIABLESPEED:CONDENSATE",
557 : "REFRIGERATION:COMPRESSORRACK",
558 : "REFRIGERATION:CONDENSER:AIRCOOLED",
559 : "REFRIGERATION:CONDENSER:EVAPORATIVECOOLED",
560 : "REFRIGERATION:CONDENSER:WATERCOOLED",
561 : "REFRIGERATION:GASCOOLER:AIRCOOLED",
562 : "SETPOINTMANAGER:COLDEST",
563 : "SETPOINTMANAGER:CONDENSERENTERINGRESET",
564 : "SETPOINTMANAGER:CONDENSERENTERINGRESET:IDEAL",
565 : "SETPOINTMANAGER:FOLLOWGROUNDTEMPERATURE",
566 : "SETPOINTMANAGER:FOLLOWOUTDOORAIRTEMPERATURE",
567 : "SETPOINTMANAGER:FOLLOWSYSTEMNODETEMPERATURE",
568 : "SETPOINTMANAGER:MIXEDAIR",
569 : "SETPOINTMANAGER:MULTIZONE:COOLING:AVERAGE",
570 : "SETPOINTMANAGER:MULTIZONE:HEATING:AVERAGE",
571 : "SETPOINTMANAGER:MULTIZONE:HUMIDITY:MAXIMUM",
572 : "SETPOINTMANAGER:MULTIZONE:HUMIDITY:MINIMUM",
573 : "SETPOINTMANAGER:MULTIZONE:MAXIMUMHUMIDITY:AVERAGE",
574 : "SETPOINTMANAGER:MULTIZONE:MINIMUMHUMIDITY:AVERAGE",
575 : "SETPOINTMANAGER:OUTDOORAIRPRETREAT",
576 : "SETPOINTMANAGER:OUTDOORAIRRESET",
577 : "SETPOINTMANAGER:RETURNTEMPERATURE:CHILLEDWATER",
578 : "SETPOINTMANAGER:RETURNTEMPERATURE:HOTWATER",
579 : "SETPOINTMANAGER:SCHEDULED",
580 : "SETPOINTMANAGER:SCHEDULED:DUALSETPOINT",
581 : "SETPOINTMANAGER:SINGLEZONE:COOLING",
582 : "SETPOINTMANAGER:SINGLEZONE:HEATING",
583 : "SETPOINTMANAGER:SINGLEZONE:HUMIDITY:MAXIMUM",
584 : "SETPOINTMANAGER:SINGLEZONE:HUMIDITY:MINIMUM",
585 : "SETPOINTMANAGER:SINGLEZONE:ONESTAGECOOLING",
586 : "SETPOINTMANAGER:SINGLEZONE:ONESTAGEHEATING",
587 : "SETPOINTMANAGER:SINGLEZONE:REHEAT",
588 : "SETPOINTMANAGER:SYSTEMNODERESET:TEMPERATURE",
589 : "SETPOINTMANAGER:SYSTEMNODERESET:HUMIDITY",
590 : "SETPOINTMANAGER:WARMEST",
591 : "SETPOINTMANAGER:WARMESTTEMPERATUREFLOW",
592 : "SOLARCOLLECTOR:FLATPLATE:PHOTOVOLTAICTHERMAL",
593 : "SOLARCOLLECTOR:FLATPLATE:WATER",
594 : "SOLARCOLLECTOR:INTEGRALCOLLECTORSTORAGE",
595 : "SOLARCOLLECTOR:UNGLAZEDTRANSPIRED",
596 : "SURFACEPROPERTY:LOCALENVIRONMENT",
597 : "SWIMMINGPOOL:INDOOR",
598 : "TEMPERINGVALVE",
599 : "THERMALSTORAGE:CHILLEDWATER:MIXED",
600 : "THERMALSTORAGE:CHILLEDWATER:STRATIFIED",
601 : "THERMALSTORAGE:ICE:DETAILED",
602 : "THERMALSTORAGE:ICE:SIMPLE",
603 : "WATERHEATER:HEATPUMP",
604 : "WATERHEATER:HEATPUMP:PUMPEDCONDENSER",
605 : "WATERHEATER:HEATPUMP:WRAPPEDCONDENSER",
606 : "WATERHEATER:MIXED",
607 : "WATERHEATER:STRATIFIED",
608 : "WATERUSE:CONNECTIONS",
609 : "ZONEHVAC:AIRDISTRIBUTIONUNIT",
610 : "ZONEHVAC:BASEBOARD:CONVECTIVE:ELECTRIC",
611 : "ZONEHVAC:BASEBOARD:CONVECTIVE:WATER",
612 : "ZONEHVAC:BASEBOARD:RADIANTCONVECTIVE:ELECTRIC",
613 : "ZONEHVAC:BASEBOARD:RADIANTCONVECTIVE:STEAM",
614 : "ZONEHVAC:BASEBOARD:RADIANTCONVECTIVE:WATER",
615 : "ZONEHVAC:COOLINGPANEL:RADIANTCONVECTIVE:WATER",
616 : "ZONEHVAC:DEHUMIDIFIER:DX",
617 : "ZONEHVAC:ENERGYRECOVERYVENTILATOR",
618 : "ZONEHVAC:EQUIPMENTCONNECTIONS",
619 : "ZONEHVAC:EVAPORATIVECOOLERUNIT",
620 : "ZONEHVAC:EXHAUSTCONTROL",
621 : "ZONEHVAC:FORCEDAIR:USERDEFINED",
622 : "ZONEHVAC:FOURPIPEFANCOIL",
623 : "ZONEHVAC:HIGHTEMPERATURERADIANT",
624 : "ZONEHVAC:HYBRIDUNITARYHVAC",
625 : "ZONEHVAC:IDEALLOADSAIRSYSTEM",
626 : "ZONEHVAC:LOWTEMPERATURERADIANT:CONSTANTFLOW",
627 : "ZONEHVAC:LOWTEMPERATURERADIANT:VARIABLEFLOW",
628 : "ZONEHVAC:OUTDOORAIRUNIT",
629 : "ZONEHVAC:PACKAGEDTERMINALAIRCONDITIONER",
630 : "ZONEHVAC:PACKAGEDTERMINALHEATPUMP",
631 : "ZONEHVAC:REFRIGERATIONCHILLERSET",
632 : "ZONEHVAC:TERMINALUNIT:VARIABLEREFRIGERANTFLOW",
633 : "ZONEHVAC:UNITHEATER",
634 : "ZONEHVAC:UNITVENTILATOR",
635 : "ZONEHVAC:VENTILATEDSLAB",
636 : "ZONEHVAC:WATERTOAIRHEATPUMP",
637 : "ZONEHVAC:WINDOWAIRCONDITIONER",
638 : "ZONEPROPERTY:LOCALENVIRONMENT",
639 : "SPACEHVAC:EQUIPMENTCONNECTIONS",
640 : "SPACEHVAC:ZONEEQUIPMENTSPLITTER",
641 : "SPACEHVAC:ZONEEQUIPMENTMIXER"};
642 :
643 11020 : void RegisterNodeConnection(EnergyPlusData &state,
644 : int const NodeNumber, // Number for this Node
645 : std::string_view const NodeName, // Name of this Node
646 : DataLoopNode::ConnectionObjectType const ObjectType, // Type of object this Node is connected to (e.g. Chiller:Electric)
647 : std::string_view const ObjectName, // Name of object this Node is connected to (e.g. MyChiller)
648 : DataLoopNode::ConnectionType const ConnectionType, // Connection Type for this Node (must be valid)
649 : NodeInputManager::CompFluidStream const FluidStream, // Count on Fluid Streams
650 : bool const IsParent, // True when node is a parent node
651 : bool &errFlag, // Will be True if errors already detected or if errors found here
652 : std::string_view const InputFieldName // Input Field Name
653 : )
654 : {
655 :
656 : // SUBROUTINE INFORMATION:
657 : // AUTHOR Linda K. Lawrie
658 : // DATE WRITTEN February 2004
659 : // MODIFIED na
660 : // RE-ENGINEERED na
661 :
662 : // PURPOSE OF THIS SUBROUTINE:
663 : // This subroutine registers a node connection in the Node Connection data structure. This
664 : // structure is intended to help with HVAC diagramming as well as validation of nodes.
665 :
666 : // SUBROUTINE PARAMETER DEFINITIONS:
667 : static constexpr std::string_view RoutineName = "RegisterNodeConnection: ";
668 :
669 11020 : bool ErrorsFoundHere = false;
670 :
671 11020 : if ((ObjectType == DataLoopNode::ConnectionObjectType::Invalid) || (ObjectType == DataLoopNode::ConnectionObjectType::Num)) {
672 0 : ShowSevereError(state, "Developer Error: Invalid ObjectType");
673 0 : ShowContinueError(state, format("Occurs for Node={}, ObjectName={}", std::string{NodeName}, std::string{ObjectName}));
674 0 : ErrorsFoundHere = true;
675 : }
676 :
677 11020 : std::string_view const objTypeStr = ConnectionObjectTypeNames[static_cast<int>(ObjectType)];
678 11020 : std::string_view const conTypeStr = ConnectionTypeNames[static_cast<int>(ConnectionType)];
679 :
680 11020 : if ((ConnectionType == DataLoopNode::ConnectionType::Invalid) || (ConnectionType == DataLoopNode::ConnectionType::Num)) {
681 0 : ShowSevereError(state, format("{}{}{}", RoutineName, "Invalid ConnectionType=", ConnectionType));
682 0 : ShowContinueError(state, format("Occurs for Node={}, ObjectType={}, ObjectName={}", NodeName, objTypeStr, ObjectName));
683 0 : ErrorsFoundHere = true;
684 : }
685 :
686 11020 : bool MakeNew = true;
687 362720 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Count) {
688 351700 : if (state.dataBranchNodeConnections->NodeConnections(Count).NodeNumber != NodeNumber) {
689 342315 : continue;
690 : }
691 9385 : if (state.dataBranchNodeConnections->NodeConnections(Count).ObjectType != ObjectType) {
692 8728 : continue;
693 : }
694 657 : if (!Util::SameString(state.dataBranchNodeConnections->NodeConnections(Count).ObjectName, ObjectName)) {
695 211 : continue;
696 : }
697 446 : if (state.dataBranchNodeConnections->NodeConnections(Count).ConnectionType != ConnectionType) {
698 175 : continue;
699 : }
700 271 : if (state.dataBranchNodeConnections->NodeConnections(Count).FluidStream != FluidStream) {
701 0 : continue;
702 : }
703 542 : if ((state.dataBranchNodeConnections->NodeConnections(Count).ObjectIsParent && !IsParent) ||
704 271 : (!state.dataBranchNodeConnections->NodeConnections(Count).ObjectIsParent && IsParent)) {
705 0 : ShowSevereError(state, format("{}{}", RoutineName, "Node registered for both Parent and \"not\" Parent"));
706 0 : ShowContinueError(state, format("{}{}{}{}{}{}", "Occurs for Node=", NodeName, ", ObjectType=", ObjectType, ", ObjectName=", ObjectName));
707 0 : ErrorsFoundHere = true;
708 : }
709 271 : MakeNew = false;
710 : }
711 11020 : if (MakeNew) {
712 10749 : int constexpr NodeConnectionAlloc = 1000;
713 10749 : ++state.dataBranchNodeConnections->NumOfNodeConnections;
714 20820 : if (state.dataBranchNodeConnections->NumOfNodeConnections > 1 &&
715 10071 : state.dataBranchNodeConnections->NumOfNodeConnections > state.dataBranchNodeConnections->MaxNumOfNodeConnections) {
716 0 : state.dataBranchNodeConnections->NodeConnections.resize(state.dataBranchNodeConnections->MaxNumOfNodeConnections += NodeConnectionAlloc);
717 10749 : } else if (state.dataBranchNodeConnections->NumOfNodeConnections == 1) {
718 678 : state.dataBranchNodeConnections->NodeConnections.allocate(NodeConnectionAlloc);
719 678 : state.dataBranchNodeConnections->MaxNumOfNodeConnections = NodeConnectionAlloc;
720 : }
721 :
722 10749 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).NodeNumber = NodeNumber;
723 10749 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).NodeName = NodeName;
724 10749 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).ObjectType = ObjectType;
725 10749 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).ObjectName = ObjectName;
726 10749 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).ConnectionType = ConnectionType;
727 10749 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).FluidStream = FluidStream;
728 10749 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).ObjectIsParent = IsParent;
729 : }
730 :
731 11020 : if (has_prefixi(objTypeStr, "AirTerminal:")) {
732 389 : if (!InputFieldName.empty()) {
733 389 : ++state.dataBranchNodeConnections->NumOfAirTerminalNodes;
734 389 : int constexpr EqNodeConnectionAlloc = 100;
735 673 : if (state.dataBranchNodeConnections->NumOfAirTerminalNodes > 1 &&
736 284 : state.dataBranchNodeConnections->NumOfAirTerminalNodes > state.dataBranchNodeConnections->MaxNumOfAirTerminalNodes) {
737 0 : state.dataBranchNodeConnections->AirTerminalNodeConnections.resize(state.dataBranchNodeConnections->MaxNumOfAirTerminalNodes +=
738 : EqNodeConnectionAlloc);
739 389 : } else if (state.dataBranchNodeConnections->NumOfAirTerminalNodes == 1) {
740 105 : state.dataBranchNodeConnections->AirTerminalNodeConnections.allocate(EqNodeConnectionAlloc);
741 105 : state.dataBranchNodeConnections->MaxNumOfAirTerminalNodes = EqNodeConnectionAlloc;
742 : }
743 :
744 : // Check out AirTerminal inlet/outlet nodes
745 1167 : bool Found = Util::FindItemInList(NodeName,
746 389 : state.dataBranchNodeConnections->AirTerminalNodeConnections,
747 : &EqNodeConnectionDef::NodeName,
748 389 : state.dataBranchNodeConnections->NumOfAirTerminalNodes - 1);
749 389 : if (Found != 0) { // Nodename already used
750 0 : ShowSevereError(state, fmt::format("{}{}=\"{}\" node name duplicated", RoutineName, ObjectType, ObjectName));
751 0 : ShowContinueError(state, format("NodeName=\"{}\", entered as type={}", NodeName, conTypeStr));
752 0 : ShowContinueError(state, fmt::format("In Field={}", InputFieldName));
753 0 : ShowContinueError(state,
754 0 : format("NodeName=\"{}\", entered as type={}", NodeName, ConnectionTypeNamesUC[static_cast<int>(ConnectionType)]));
755 0 : ShowContinueError(state, format("In Field={}", InputFieldName));
756 0 : ShowContinueError(
757 : state,
758 0 : format("Already used in {}=\"{}\".", objTypeStr, state.dataBranchNodeConnections->AirTerminalNodeConnections(Found).ObjectName));
759 0 : ShowContinueError(
760 : state,
761 0 : format(" as type={}, In Field={}",
762 0 : ConnectionTypeNamesUC[static_cast<int>(state.dataBranchNodeConnections->AirTerminalNodeConnections(Found).ConnectionType)],
763 0 : state.dataBranchNodeConnections->AirTerminalNodeConnections(Found).InputFieldName));
764 0 : ErrorsFoundHere = true;
765 : } else {
766 389 : state.dataBranchNodeConnections->AirTerminalNodeConnections(state.dataBranchNodeConnections->NumOfAirTerminalNodes).NodeName =
767 389 : NodeName;
768 389 : state.dataBranchNodeConnections->AirTerminalNodeConnections(state.dataBranchNodeConnections->NumOfAirTerminalNodes).ObjectType =
769 : ObjectType;
770 389 : state.dataBranchNodeConnections->AirTerminalNodeConnections(state.dataBranchNodeConnections->NumOfAirTerminalNodes).ObjectName =
771 389 : ObjectName;
772 389 : state.dataBranchNodeConnections->AirTerminalNodeConnections(state.dataBranchNodeConnections->NumOfAirTerminalNodes).ConnectionType =
773 : ConnectionType;
774 389 : state.dataBranchNodeConnections->AirTerminalNodeConnections(state.dataBranchNodeConnections->NumOfAirTerminalNodes).InputFieldName =
775 389 : InputFieldName;
776 : }
777 : } else {
778 0 : ShowSevereError(state, fmt::format("{}{} , Developer Error: Input Field Name not included.", RoutineName, objTypeStr));
779 0 : ShowContinueError(state, "Node names not checked for duplication.");
780 : }
781 : }
782 :
783 11020 : if (ErrorsFoundHere) {
784 0 : errFlag = true;
785 : }
786 11020 : }
787 :
788 24 : void OverrideNodeConnectionType(
789 : EnergyPlusData &state,
790 : int const NodeNumber, // Number for this Node
791 : std::string const &NodeName, // Name of this Node
792 : DataLoopNode::ConnectionObjectType const ObjectType, // Type of object this Node is connected to (e.g. Chiller:Electric)
793 : std::string const &ObjectName, // Name of object this Node is connected to (e.g. MyChiller)
794 : DataLoopNode::ConnectionType const ConnectionType, // Connection Type for this Node (must be valid)
795 : NodeInputManager::CompFluidStream const FluidStream, // Count on Fluid Streams
796 : bool const IsParent, // True when node is a parent node
797 : bool &errFlag // Will be True if errors already detected or if errors found here
798 : )
799 : {
800 :
801 : // SUBROUTINE INFORMATION:
802 : // AUTHOR M. J. Witte
803 : // DATE WRITTEN June 2016
804 :
805 : // PURPOSE:
806 : // This subroutine modifies an existing node connection in the Node Connection data structure. This
807 : // structure is intended to help with HVAC diagramming as well as validation of nodes. This function
808 : // is a based on RegisterNodeConnection.
809 :
810 : static constexpr std::string_view RoutineName("ModifyNodeConnectionType: ");
811 :
812 24 : if ((ConnectionType == DataLoopNode::ConnectionType::Invalid) || (ConnectionType == DataLoopNode::ConnectionType::Num)) {
813 0 : ShowSevereError(state, format("{}{}{}", RoutineName, "Invalid ConnectionType=", ConnectionType));
814 0 : ShowContinueError(
815 : state,
816 0 : format("Occurs for Node={}, ObjectType={}, ObjectName={}", NodeName, ConnectionTypeNames[static_cast<int>(ObjectType)], ObjectName));
817 0 : errFlag = true;
818 : }
819 :
820 24 : int Found = 0;
821 342 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Count) {
822 342 : if (state.dataBranchNodeConnections->NodeConnections(Count).NodeNumber != NodeNumber) {
823 284 : continue;
824 : }
825 58 : if (state.dataBranchNodeConnections->NodeConnections(Count).ObjectType != ObjectType) {
826 12 : continue;
827 : }
828 46 : if (!Util::SameString(state.dataBranchNodeConnections->NodeConnections(Count).ObjectName, ObjectName)) {
829 22 : continue;
830 : }
831 24 : if (state.dataBranchNodeConnections->NodeConnections(Count).FluidStream != FluidStream) {
832 0 : continue;
833 : }
834 24 : if ((state.dataBranchNodeConnections->NodeConnections(Count).ObjectIsParent != IsParent)) {
835 0 : continue;
836 : }
837 24 : Found = Count;
838 24 : break;
839 : }
840 :
841 24 : if (Found > 0) {
842 24 : state.dataBranchNodeConnections->NodeConnections(Found).ConnectionType = ConnectionType;
843 : } else {
844 0 : ShowSevereError(state, format("{}{}", RoutineName, "Existing node connection not found."));
845 0 : ShowContinueError(
846 : state,
847 0 : format("Occurs for Node={}, ObjectType={}, ObjectName={}", NodeName, ConnectionTypeNames[static_cast<int>(ObjectType)], ObjectName));
848 0 : errFlag = true;
849 : }
850 24 : }
851 :
852 79 : void CheckNodeConnections(EnergyPlusData &state, bool &ErrorsFound)
853 : {
854 :
855 : // SUBROUTINE INFORMATION:
856 : // AUTHOR Linda Lawrie
857 : // DATE WRITTEN March 2004
858 : // MODIFIED na
859 : // RE-ENGINEERED na
860 :
861 : // PURPOSE OF THIS SUBROUTINE:
862 : // This subroutine processes the node connection data structure looking at:
863 : // 1. In the NodeConnections list, for any node which appears as a sensor or an
864 : // actuator, the same node must also appear in the connections list at least once
865 : // as a node type which is not sensor or actuator or outsideair.
866 : // 2. In the NodeConnections list, for any node which appears as a setpoint, the
867 : // same node must also appear in the connections list at least once as a node type
868 : // which is not a setpoint or outsideair.
869 : // 3. Every ZoneInlet must appear as an outlet from something, otherwise it will
870 : // do nothing.
871 : // 4. Every ZoneExhaust must appear as an inlet to something,
872 : // otherwise it will do nothing.
873 : // 5. Every inlet node should match either an Outlet, ZoneReturn, ZoneExhaust, ReliefAir,
874 : // or OutsideAir node.
875 : // With the current data structure, when checking inlets:
876 : // a) If an InletNode's object is AirLoopHVAC, CondenserLoop, or PlantLoop, then skip the test.
877 : // b) If an InletNode's object is not one of the above types, it is valid if the
878 : // same node name appears as an INLET to an AirLoopHVAC, CondenserLoop, or PlantLoop.
879 : // 6. Any given node can only be an inlet once in the list of Non-Parent Node Connections
880 : // 7. Any given node can only be an outlet once in the list of Non-Parent Node Connections
881 : // 8. non-parent outlet nodes -- must never be an outlet more than once
882 : // 9. nodes of type OutsideAirReference must be registered as DataLoopNode::NodeConnectionType::OutsideAir
883 : // 10. fluid streams cannot have multiple inlet/outlet nodes on same component
884 : // 11. zone nodes may not be used as anything else except as a setpoint, sensor or actuator node
885 :
886 : // METHODOLOGY EMPLOYED:
887 : // Needs description, as appropriate.
888 :
889 : // Using/Aliasing
890 :
891 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
892 : bool IsValid;
893 : bool IsInlet;
894 : bool IsOutlet;
895 : bool MatchedAtLeastOne;
896 : int ErrorCounter;
897 79 : Array1D_int FluidStreamInletCount;
898 79 : Array1D_int FluidStreamOutletCount;
899 79 : Array1D_int NodeObjects;
900 79 : Array1D_bool FluidStreamCounts;
901 :
902 79 : ErrorCounter = 0;
903 :
904 : // Check 1 -- check sensor and actuator nodes
905 2423 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
906 2344 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::Sensor) {
907 2172 : continue;
908 : }
909 172 : IsValid = false;
910 16979 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
911 16807 : if (Loop1 == Loop2) {
912 172 : continue;
913 : }
914 16635 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
915 16635 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber) {
916 15825 : continue;
917 : }
918 1620 : if ((state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Actuator) ||
919 810 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Sensor)) {
920 154 : continue;
921 : }
922 :
923 656 : IsValid = true;
924 : }
925 172 : if (!IsValid) {
926 4 : ShowSevereError(state,
927 4 : format("Node Connection Error, Node=\"{}\", Sensor node did not find a matching node of appropriate type (other than "
928 : "Actuator or Sensor).",
929 2 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
930 :
931 4 : ShowContinueError(state,
932 4 : format("Reference Object={}, Name={}",
933 2 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
934 2 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
935 2 : ++ErrorCounter;
936 2 : ErrorsFound = true;
937 : }
938 : }
939 :
940 2423 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
941 2344 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::Actuator) {
942 2296 : continue;
943 : }
944 48 : IsValid = false;
945 4652 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
946 4604 : if (Loop1 == Loop2) {
947 48 : continue;
948 : }
949 4556 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
950 4556 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber) {
951 4472 : continue;
952 : }
953 :
954 84 : if ((state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Actuator) ||
955 168 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Sensor) ||
956 84 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::OutsideAir)) {
957 20 : continue;
958 : }
959 :
960 64 : IsValid = true;
961 : }
962 48 : if (!IsValid) {
963 4 : ShowSevereError(state,
964 4 : format("Node Connection Error, Node=\"{}\", Actuator node did not find a matching node of appropriate type (other than "
965 : "Actuator, Sensor, OutsideAir).",
966 2 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
967 :
968 4 : ShowContinueError(state,
969 4 : format("Reference Object={}, Name={}",
970 2 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
971 2 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
972 2 : ++ErrorCounter;
973 2 : ErrorsFound = true;
974 : }
975 : }
976 :
977 : // Check 2 -- setpoint nodes
978 : // Check 2a -- setpoint node must also be an inlet or an outlet (CR8212)
979 2423 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
980 2344 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::SetPoint) {
981 2248 : continue;
982 : }
983 96 : IsValid = false;
984 96 : IsInlet = false;
985 96 : IsOutlet = false;
986 10889 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
987 10793 : if (Loop1 == Loop2) {
988 96 : continue;
989 : }
990 10697 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
991 10697 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber) {
992 10264 : continue;
993 : }
994 866 : if ((state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::SetPoint) ||
995 433 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::OutsideAir)) {
996 0 : continue;
997 : }
998 :
999 433 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Inlet) {
1000 71 : IsInlet = true;
1001 362 : } else if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Outlet) {
1002 181 : IsOutlet = true;
1003 : }
1004 433 : IsValid = true;
1005 : }
1006 96 : if (!IsValid) {
1007 0 : ShowSevereError(state,
1008 0 : format("Node Connection Error, Node=\"{}\", Setpoint node did not find a matching node of appropriate type (other than "
1009 : "Setpoint, OutsideAir).",
1010 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1011 :
1012 0 : ShowContinueError(state,
1013 0 : format("Reference Object={}, Name={}",
1014 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1015 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1016 0 : ++ErrorCounter;
1017 0 : ErrorsFound = true;
1018 : }
1019 96 : if (!IsInlet && !IsOutlet) {
1020 4 : ShowSevereError(state,
1021 4 : format("Node Connection Error, Node=\"{}\", Setpoint node did not find a matching node of type Inlet or Outlet.",
1022 2 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1023 4 : ShowContinueError(state, "It appears this node is not part of the HVAC system.");
1024 :
1025 4 : ShowContinueError(state,
1026 4 : format("Reference Object={}, Name={}",
1027 2 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1028 2 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1029 2 : ++ErrorCounter;
1030 : }
1031 : }
1032 :
1033 : // Check 2a -- setpoint node must also be an inlet or an outlet (CR8212)
1034 :
1035 : // Check 3 -- zone inlet nodes -- must be an outlet somewhere
1036 2423 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1037 2344 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::ZoneInlet) {
1038 2285 : continue;
1039 : }
1040 59 : IsValid = false;
1041 6423 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1042 6364 : if (Loop1 == Loop2) {
1043 59 : continue;
1044 : }
1045 6305 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
1046 6305 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber) {
1047 6180 : continue;
1048 : }
1049 125 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::Outlet) {
1050 4 : continue;
1051 : }
1052 121 : IsValid = true;
1053 : }
1054 59 : if (!IsValid) {
1055 0 : ShowSevereError(state,
1056 0 : format("Node Connection Error, Node=\"{}\", ZoneInlet node did not find an outlet node.",
1057 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1058 :
1059 0 : ShowContinueError(state,
1060 0 : format("Reference Object={}, Name={}",
1061 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1062 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1063 0 : ++ErrorCounter;
1064 : }
1065 : }
1066 :
1067 : // Check 4 -- zone exhaust nodes -- must be an inlet somewhere
1068 2423 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1069 2344 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::ZoneExhaust) {
1070 2311 : continue;
1071 : }
1072 33 : IsValid = false;
1073 3592 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1074 3559 : if (Loop1 == Loop2) {
1075 33 : continue;
1076 : }
1077 3526 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
1078 3526 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber) {
1079 3485 : continue;
1080 : }
1081 41 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::Inlet) {
1082 0 : continue;
1083 : }
1084 41 : IsValid = true;
1085 : }
1086 33 : if (!IsValid) {
1087 18 : ShowSevereError(state,
1088 18 : format("Node Connection Error, Node=\"{}\", ZoneExhaust node did not find a matching inlet node.",
1089 9 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1090 :
1091 18 : ShowContinueError(state,
1092 18 : format("Reference Object={}, Name={}",
1093 9 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1094 9 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1095 9 : ++ErrorCounter;
1096 : }
1097 : }
1098 :
1099 : // Check 5 -- return plenum induced air outlet nodes -- must be an inlet somewhere
1100 2423 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1101 2344 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::InducedAir) {
1102 2344 : continue;
1103 : }
1104 0 : IsValid = false;
1105 0 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1106 0 : if (Loop1 == Loop2) {
1107 0 : continue;
1108 : }
1109 0 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
1110 0 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber) {
1111 0 : continue;
1112 : }
1113 0 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::Inlet) {
1114 0 : continue;
1115 : }
1116 0 : IsValid = true;
1117 : }
1118 0 : if (!IsValid) {
1119 0 : ShowSevereError(state,
1120 0 : format("Node Connection Error, Node=\"{}\", Return plenum induced air outlet node did not find a matching inlet node.",
1121 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1122 :
1123 0 : ShowContinueError(state,
1124 0 : format("Reference Object={}, Name={}",
1125 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1126 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1127 0 : ++ErrorCounter;
1128 0 : ErrorsFound = true;
1129 : }
1130 : }
1131 :
1132 : // Check 6 -- every inlet should have a matching outlet, zonereturn, zoneexhaust, induced air, reliefair or outsideair
1133 : // a) If an InletNode's object is AirLoopHVAC, CondenserLoop, or PlantLoop, then skip the test.
1134 : // b) If an InletNode's object is not one of the above types, it is valid if the
1135 : // same node name appears as an INLET to an AirLoopHVAC, CondenserLoop, or PlantLoop.
1136 2423 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1137 2344 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::Inlet) {
1138 1530 : continue;
1139 : }
1140 814 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType == DataLoopNode::ConnectionObjectType::AirLoopHVAC ||
1141 1576 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType == DataLoopNode::ConnectionObjectType::CondenserLoop ||
1142 762 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType == DataLoopNode::ConnectionObjectType::PlantLoop) {
1143 74 : continue;
1144 : }
1145 740 : IsValid = false;
1146 740 : MatchedAtLeastOne = false;
1147 103870 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1148 103130 : if (Loop1 == Loop2) {
1149 740 : continue;
1150 : }
1151 102390 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
1152 102390 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber) {
1153 100796 : continue;
1154 : }
1155 :
1156 1594 : if ((state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Outlet) ||
1157 1026 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::ZoneReturn) ||
1158 987 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::ZoneExhaust) ||
1159 946 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::InducedAir) ||
1160 3562 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::ReliefAir) ||
1161 942 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::OutsideAir)) {
1162 693 : MatchedAtLeastOne = true;
1163 693 : continue;
1164 : }
1165 :
1166 1474 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Inlet &&
1167 573 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType == DataLoopNode::ConnectionObjectType::AirLoopHVAC ||
1168 476 : state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType == DataLoopNode::ConnectionObjectType::CondenserLoop ||
1169 468 : state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType == DataLoopNode::ConnectionObjectType::PlantLoop)) {
1170 149 : MatchedAtLeastOne = true;
1171 149 : continue;
1172 : }
1173 752 : IsValid = false;
1174 : }
1175 740 : if (!IsValid && !MatchedAtLeastOne) {
1176 16 : ShowSevereError(state,
1177 16 : format("{}{}{}",
1178 : "Node Connection Error, Node=\"",
1179 8 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName,
1180 : R"(", Inlet node did not find an appropriate matching "outlet" node.)"));
1181 16 : ShowContinueError(state, "If this is an outdoor air inlet node, it must be listed in an OutdoorAir:Node or OutdoorAir:NodeList object.");
1182 :
1183 16 : ShowContinueError(state,
1184 16 : format("Reference Object={}, Name={}",
1185 8 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1186 8 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1187 8 : ++ErrorCounter;
1188 : }
1189 : }
1190 :
1191 : // Check 7 -- non-parent inlet nodes -- must never be an inlet more than once
1192 2423 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1193 : // Only non-parent node connections
1194 2344 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectIsParent) {
1195 704 : continue;
1196 : }
1197 1640 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::Inlet) {
1198 1115 : continue;
1199 : }
1200 24448 : for (int Loop2 = Loop1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1201 23923 : if (Loop1 == Loop2) {
1202 525 : continue;
1203 : }
1204 23398 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectIsParent) {
1205 3304 : continue;
1206 : }
1207 20094 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::Inlet) {
1208 11095 : continue;
1209 : }
1210 8999 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber ==
1211 8999 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber) {
1212 0 : ShowSevereError(state,
1213 0 : format("Node Connection Error, Node=\"{}\", The same node appears as a non-parent Inlet node more than once.",
1214 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1215 :
1216 0 : ShowContinueError(
1217 : state,
1218 0 : format("Reference Object={}, Name={}",
1219 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1220 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1221 :
1222 0 : ShowContinueError(
1223 : state,
1224 0 : format("Reference Object={}, Name={}",
1225 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType)],
1226 0 : state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectName));
1227 0 : ++ErrorCounter;
1228 0 : break;
1229 : }
1230 : }
1231 : }
1232 :
1233 : // Check 8 -- non-parent outlet nodes -- must never be an outlet more than once
1234 2423 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1235 : // Only non-parent node connections
1236 2344 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectIsParent) {
1237 704 : continue;
1238 : }
1239 1640 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::Outlet) {
1240 1147 : continue;
1241 : }
1242 493 : IsValid = true;
1243 23925 : for (int Loop2 = Loop1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1244 23432 : if (Loop1 == Loop2) {
1245 493 : continue;
1246 : }
1247 22939 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectIsParent) {
1248 3245 : continue;
1249 : }
1250 19694 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::Outlet) {
1251 11637 : continue;
1252 : }
1253 8057 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber ==
1254 8057 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber) {
1255 : // Skip if one of the
1256 0 : ShowSevereError(state,
1257 0 : format("Node Connection Error, Node=\"{}\", The same node appears as a non-parent Outlet node more than once.",
1258 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1259 :
1260 0 : ShowContinueError(
1261 : state,
1262 0 : format("Reference Object={}, Name={}",
1263 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1264 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1265 :
1266 0 : ShowContinueError(
1267 : state,
1268 0 : format("Reference Object={}, Name={}",
1269 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType)],
1270 0 : state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectName));
1271 :
1272 0 : ++ErrorCounter;
1273 0 : break;
1274 : }
1275 : }
1276 : }
1277 :
1278 : // Check 9 -- nodes of type OutsideAirReference must be registered as DataLoopNode::NodeConnectionType::OutsideAir
1279 2423 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1280 2344 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::OutsideAirReference) {
1281 2333 : continue;
1282 : }
1283 11 : IsValid = false;
1284 193 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1285 193 : if (Loop1 == Loop2) {
1286 0 : continue;
1287 : }
1288 193 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
1289 193 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber) {
1290 182 : continue;
1291 : }
1292 11 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::OutsideAir) {
1293 0 : continue;
1294 : }
1295 11 : IsValid = true;
1296 11 : break;
1297 : }
1298 11 : if (!IsValid) {
1299 0 : ShowSevereError(state,
1300 0 : format("{}{}{}",
1301 : "Node Connection Error, Node=\"",
1302 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName,
1303 : R"(", Outdoor Air Reference did not find an appropriate "outdoor air" node.)"));
1304 0 : ShowContinueError(state, "This node must be listed in an OutdoorAir:Node or OutdoorAir:NodeList object in order to set its conditions.");
1305 :
1306 0 : ShowContinueError(state,
1307 0 : format("Reference Object={}, Name={}",
1308 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1309 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1310 :
1311 0 : ++ErrorCounter;
1312 : }
1313 : }
1314 :
1315 : // Check 10 -- fluid streams cannot have multiple inlet/outlet nodes on same component
1316 : // can have multiple inlets with one outlet or vice versa but cannot have multiple both inlet and outlet
1317 79 : if (state.dataBranchNodeConnections->NumOfNodeConnections > 0) {
1318 43 : int MaxFluidStream = static_cast<int>(maxval(state.dataBranchNodeConnections->NodeConnections, &NodeConnectionDef::FluidStream));
1319 43 : FluidStreamInletCount.allocate(MaxFluidStream);
1320 43 : FluidStreamOutletCount.allocate(MaxFluidStream);
1321 43 : FluidStreamCounts.allocate(MaxFluidStream);
1322 43 : NodeObjects.allocate(state.dataBranchNodeConnections->NumOfNodeConnections + 1);
1323 43 : FluidStreamInletCount = 0;
1324 43 : FluidStreamOutletCount = 0;
1325 43 : NodeObjects = 0;
1326 43 : FluidStreamCounts = false;
1327 : // Following code relies on node connections for single object type/name being grouped together
1328 43 : int Object = 1;
1329 43 : int EndConnect = 0;
1330 43 : int NumObjects = 2;
1331 43 : NodeObjects(1) = 1;
1332 2344 : while (Object < state.dataBranchNodeConnections->NumOfNodeConnections) {
1333 2301 : if (state.dataBranchNodeConnections->NodeConnections(Object).ObjectType !=
1334 4018 : state.dataBranchNodeConnections->NodeConnections(Object + 1).ObjectType ||
1335 1717 : state.dataBranchNodeConnections->NodeConnections(Object).ObjectName !=
1336 1717 : state.dataBranchNodeConnections->NodeConnections(Object + 1).ObjectName) {
1337 898 : EndConnect = Object + 1;
1338 898 : NodeObjects(NumObjects) = EndConnect;
1339 : // if (Object + 1 < state.dataBranchNodeConnections->NumOfNodeConnections) ++NumObjects;
1340 898 : ++NumObjects;
1341 : }
1342 2301 : ++Object;
1343 : }
1344 43 : NodeObjects(NumObjects) = state.dataBranchNodeConnections->NumOfNodeConnections + 1;
1345 : // NodeObjects now contains each consecutive object...
1346 984 : for (Object = 1; Object <= NumObjects - 1; ++Object) {
1347 941 : IsValid = true;
1348 941 : FluidStreamInletCount = 0;
1349 941 : FluidStreamOutletCount = 0;
1350 941 : FluidStreamCounts = false;
1351 941 : int Loop1 = NodeObjects(Object);
1352 941 : if (state.dataBranchNodeConnections->NumOfNodeConnections < 2) {
1353 2 : continue;
1354 : }
1355 939 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectIsParent) {
1356 322 : continue;
1357 : }
1358 617 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType == DataLoopNode::ConnectionType::Inlet) {
1359 286 : ++FluidStreamInletCount(static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).FluidStream));
1360 331 : } else if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType == DataLoopNode::ConnectionType::Outlet) {
1361 119 : ++FluidStreamOutletCount(static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).FluidStream));
1362 : }
1363 1643 : for (int Loop2 = Loop1 + 1; Loop2 <= NodeObjects(Object + 1) - 1; ++Loop2) {
1364 1026 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectIsParent) {
1365 5 : continue;
1366 : }
1367 1021 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Inlet) {
1368 239 : ++FluidStreamInletCount(static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop2).FluidStream));
1369 782 : } else if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Outlet) {
1370 374 : ++FluidStreamOutletCount(static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop2).FluidStream));
1371 : }
1372 : }
1373 2304 : for (int Loop2 = 1; Loop2 <= MaxFluidStream; ++Loop2) {
1374 1687 : if (FluidStreamInletCount(Loop2) > 1 && FluidStreamOutletCount(Loop2) > 1) {
1375 1 : IsValid = false;
1376 1 : FluidStreamCounts(Loop2) = true;
1377 : }
1378 : }
1379 617 : if (!IsValid) {
1380 :
1381 2 : ShowSevereError(
1382 : state,
1383 2 : format("(Developer) Node Connection Error, Object={}:{}",
1384 1 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1385 1 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1386 :
1387 2 : ShowContinueError(state, "Object has multiple connections on both inlet and outlet fluid streams.");
1388 2 : for (int Loop2 = 1; Loop2 <= MaxFluidStream; ++Loop2) {
1389 1 : if (FluidStreamCounts(Loop2)) {
1390 1 : ShowContinueError(state, format("...occurs in Fluid Stream [{}].", Loop2));
1391 : }
1392 : }
1393 1 : ++ErrorCounter;
1394 1 : ErrorsFound = true;
1395 : }
1396 : }
1397 43 : FluidStreamInletCount.deallocate();
1398 43 : FluidStreamOutletCount.deallocate();
1399 43 : FluidStreamCounts.deallocate();
1400 43 : NodeObjects.deallocate();
1401 : }
1402 :
1403 : // Check 11 - zone nodes may not be used as anything else except as a setpoint, sensor or actuator node
1404 2423 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1405 2344 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::ZoneNode) {
1406 2260 : continue;
1407 : }
1408 84 : IsValid = true;
1409 3978 : for (int Loop2 = Loop1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1410 3894 : if (Loop1 == Loop2) {
1411 84 : continue;
1412 : }
1413 3810 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName ==
1414 3810 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeName) {
1415 :
1416 6 : if ((state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Actuator) ||
1417 8 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Sensor) ||
1418 2 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::SetPoint)) {
1419 4 : continue;
1420 : }
1421 :
1422 4 : ShowSevereError(state,
1423 4 : format("Node Connection Error, Node Name=\"{}\", The same zone node appears more than once.",
1424 2 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1425 :
1426 4 : ShowContinueError(
1427 : state,
1428 4 : format("Reference Object={}, Object Name={}",
1429 2 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1430 2 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1431 :
1432 4 : ShowContinueError(
1433 : state,
1434 4 : format("Reference Object={}, Object Name={}",
1435 2 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType)],
1436 2 : state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectName));
1437 :
1438 2 : ++ErrorCounter;
1439 2 : ErrorsFound = true;
1440 : }
1441 : }
1442 : }
1443 :
1444 79 : state.dataBranchNodeConnections->NumNodeConnectionErrors += ErrorCounter;
1445 79 : }
1446 :
1447 734 : bool IsParentObject(EnergyPlusData &state, DataLoopNode::ConnectionObjectType const ComponentType, std::string const &ComponentName)
1448 : {
1449 :
1450 : // FUNCTION INFORMATION:
1451 : // AUTHOR Linda Lawrie
1452 : // DATE WRITTEN May 2005
1453 :
1454 : // PURPOSE OF THIS FUNCTION:
1455 : // This routine determines if a component name is a parent node.
1456 :
1457 : // METHODOLOGY EMPLOYED:
1458 : // Traverses CompSet structure.
1459 :
1460 : // Return value
1461 734 : bool IsParent = false; // True if this combination is a parent
1462 :
1463 58265 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop) {
1464 60050 : if (state.dataBranchNodeConnections->NodeConnections(Loop).ObjectType == ComponentType &&
1465 1870 : state.dataBranchNodeConnections->NodeConnections(Loop).ObjectName == ComponentName) {
1466 649 : if (state.dataBranchNodeConnections->NodeConnections(Loop).ObjectIsParent) {
1467 312 : IsParent = true;
1468 : }
1469 649 : break;
1470 : }
1471 : }
1472 734 : if (!IsParent) {
1473 422 : IsParent = IsParentObjectCompSet(state, ComponentType, ComponentName);
1474 : }
1475 :
1476 734 : return IsParent;
1477 : }
1478 :
1479 106 : int WhichParentSet(EnergyPlusData &state, DataLoopNode::ConnectionObjectType const ComponentType, std::string const &ComponentName)
1480 : {
1481 :
1482 : // FUNCTION INFORMATION:
1483 : // AUTHOR Linda Lawrie
1484 : // DATE WRITTEN May 2005
1485 :
1486 : // PURPOSE OF THIS FUNCTION:
1487 : // This routine determines which parent node list (number) for a given component name
1488 : // and type.
1489 :
1490 : // Return value
1491 106 : int WhichOne = 0;
1492 :
1493 1163 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumOfActualParents; ++Loop) {
1494 1242 : if (state.dataBranchNodeConnections->ParentNodeList(Loop).ComponentType == ComponentType &&
1495 110 : state.dataBranchNodeConnections->ParentNodeList(Loop).ComponentName == ComponentName) {
1496 75 : WhichOne = Loop;
1497 75 : break;
1498 : }
1499 : }
1500 :
1501 106 : return WhichOne;
1502 : }
1503 :
1504 106 : void GetParentData(EnergyPlusData &state,
1505 : DataLoopNode::ConnectionObjectType const ComponentType,
1506 : std::string const &ComponentName,
1507 : std::string &InletNodeName,
1508 : int &InletNodeNum,
1509 : std::string &OutletNodeName,
1510 : int &OutletNodeNum,
1511 : bool &ErrorsFound)
1512 : {
1513 :
1514 : // SUBROUTINE INFORMATION:
1515 : // AUTHOR Linda Lawrie
1516 : // DATE WRITTEN May 2005
1517 :
1518 : // PURPOSE OF THIS SUBROUTINE:
1519 : // This routine gets node data for a given Parent Component Type and Name Name.
1520 :
1521 : // METHODOLOGY EMPLOYED:
1522 : // Traverses CompSet structure.
1523 :
1524 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1525 106 : bool ErrInObject = false;
1526 :
1527 106 : InletNodeName = std::string();
1528 106 : InletNodeNum = 0;
1529 106 : OutletNodeName = std::string();
1530 106 : OutletNodeNum = 0;
1531 106 : ErrInObject = false;
1532 :
1533 106 : int Which = WhichParentSet(state, ComponentType, ComponentName);
1534 106 : if (Which != 0) {
1535 75 : InletNodeName = state.dataBranchNodeConnections->ParentNodeList(Which).InletNodeName;
1536 75 : OutletNodeName = state.dataBranchNodeConnections->ParentNodeList(Which).OutletNodeName;
1537 : // Get Node Numbers
1538 75 : InletNodeNum =
1539 75 : Util::FindItemInList(InletNodeName, state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}), state.dataLoopNodes->NumOfNodes);
1540 75 : OutletNodeNum =
1541 75 : Util::FindItemInList(OutletNodeName, state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}), state.dataLoopNodes->NumOfNodes);
1542 31 : } else if (IsParentObjectCompSet(state, ComponentType, ComponentName)) {
1543 31 : Which = WhichCompSet(state, ComponentType, ComponentName);
1544 31 : if (Which != 0) {
1545 31 : InletNodeName = state.dataBranchNodeConnections->CompSets(Which).InletNodeName;
1546 31 : OutletNodeName = state.dataBranchNodeConnections->CompSets(Which).OutletNodeName;
1547 31 : InletNodeNum = Util::FindItemInList(
1548 62 : InletNodeName, state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}), state.dataLoopNodes->NumOfNodes);
1549 31 : OutletNodeNum = Util::FindItemInList(
1550 62 : OutletNodeName, state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}), state.dataLoopNodes->NumOfNodes);
1551 : } else {
1552 0 : ErrInObject = true;
1553 0 : ShowWarningError(state,
1554 0 : format("GetParentData: Component Type={}, Component Name={} not found.",
1555 0 : ConnectionObjectTypeNames[static_cast<int>(ComponentType)],
1556 : ComponentName));
1557 : }
1558 : } else {
1559 0 : ErrInObject = true;
1560 0 : ShowWarningError(state,
1561 0 : format("GetParentData: Component Type={}, Component Name={} not found.",
1562 0 : ConnectionObjectTypeNames[static_cast<int>(ComponentType)],
1563 : ComponentName));
1564 : }
1565 :
1566 106 : if (ErrInObject) {
1567 0 : ErrorsFound = true;
1568 : }
1569 106 : }
1570 :
1571 453 : bool IsParentObjectCompSet(EnergyPlusData &state, DataLoopNode::ConnectionObjectType const ComponentType, std::string const &ComponentName)
1572 : {
1573 :
1574 : // FUNCTION INFORMATION:
1575 : // AUTHOR Linda Lawrie
1576 : // DATE WRITTEN May 2005
1577 :
1578 : // PURPOSE OF THIS FUNCTION:
1579 : // This routine determines if a component name is a parent node.
1580 :
1581 : // METHODOLOGY EMPLOYED:
1582 : // Traverses CompSet structure.
1583 :
1584 : // Return value
1585 453 : bool IsParent = false; // True if this combination is a parent
1586 :
1587 8543 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumCompSets; ++Loop) {
1588 8384 : if (state.dataBranchNodeConnections->CompSets(Loop).ParentObjectType == ComponentType &&
1589 151 : state.dataBranchNodeConnections->CompSets(Loop).ParentCName == ComponentName) {
1590 143 : IsParent = true;
1591 143 : break;
1592 : }
1593 : }
1594 :
1595 453 : return IsParent;
1596 : }
1597 :
1598 31 : int WhichCompSet(EnergyPlusData &state, DataLoopNode::ConnectionObjectType const ComponentType, std::string const &ComponentName)
1599 : {
1600 :
1601 : // FUNCTION INFORMATION:
1602 : // AUTHOR Linda Lawrie
1603 : // DATE WRITTEN May 2005
1604 :
1605 : // PURPOSE OF THIS FUNCTION:
1606 : // This routine determines which comp set (number) for a given component name
1607 : // and type.
1608 :
1609 : // METHODOLOGY EMPLOYED:
1610 : // Traverses CompSet structure.
1611 :
1612 : // Return value
1613 31 : int WhichOne = 0;
1614 :
1615 46 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumCompSets; ++Loop) {
1616 77 : if (state.dataBranchNodeConnections->CompSets(Loop).ComponentObjectType == ComponentType &&
1617 31 : state.dataBranchNodeConnections->CompSets(Loop).CName == ComponentName) {
1618 31 : WhichOne = Loop;
1619 31 : break;
1620 : }
1621 : }
1622 :
1623 31 : return WhichOne;
1624 : }
1625 :
1626 212 : int GetNumChildren(EnergyPlusData &state, DataLoopNode::ConnectionObjectType const ComponentType, std::string const &ComponentName)
1627 : {
1628 :
1629 : // FUNCTION INFORMATION:
1630 : // AUTHOR Linda Lawrie
1631 : // DATE WRITTEN May 2005
1632 : // MODIFIED na
1633 : // RE-ENGINEERED na
1634 :
1635 : // PURPOSE OF THIS FUNCTION:
1636 : // This routine counts the number of children for a parent Component Set.
1637 :
1638 : // METHODOLOGY EMPLOYED:
1639 : // Traverses CompSet structure.
1640 :
1641 : // Return value
1642 : int NumChildren;
1643 :
1644 212 : NumChildren = 0;
1645 212 : if (IsParentObject(state, ComponentType, ComponentName)) {
1646 3540 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumCompSets; ++Loop) {
1647 3982 : if (state.dataBranchNodeConnections->CompSets(Loop).ParentObjectType == ComponentType &&
1648 654 : state.dataBranchNodeConnections->CompSets(Loop).ParentCName == ComponentName) {
1649 366 : ++NumChildren;
1650 : }
1651 : }
1652 : }
1653 :
1654 212 : return NumChildren;
1655 : }
1656 :
1657 67 : void GetComponentData(EnergyPlusData &state,
1658 : DataLoopNode::ConnectionObjectType const ComponentType,
1659 : std::string const &ComponentName,
1660 : bool &IsParent, // true or false
1661 : int &NumInlets,
1662 : Array1D_string &InletNodeNames,
1663 : Array1D_int &InletNodeNums,
1664 : Array1D<NodeInputManager::CompFluidStream> &InletFluidStreams,
1665 : int &NumOutlets,
1666 : Array1D_string &OutletNodeNames,
1667 : Array1D_int &OutletNodeNums,
1668 : Array1D<NodeInputManager::CompFluidStream> &OutletFluidStreams)
1669 : {
1670 :
1671 : // SUBROUTINE INFORMATION:
1672 : // AUTHOR Linda Lawrie
1673 : // DATE WRITTEN May 2005
1674 :
1675 : // PURPOSE OF THIS SUBROUTINE:
1676 : // This routine gets data for a given Component Type and Name Name.
1677 :
1678 : // METHODOLOGY EMPLOYED:
1679 : // Traverses CompSet structure.
1680 :
1681 67 : if (allocated(InletNodeNames)) {
1682 3 : InletNodeNames.deallocate();
1683 : }
1684 67 : if (allocated(InletNodeNums)) {
1685 3 : InletNodeNums.deallocate();
1686 : }
1687 67 : if (allocated(InletFluidStreams)) {
1688 26 : InletFluidStreams.deallocate();
1689 : }
1690 67 : if (allocated(OutletNodeNames)) {
1691 3 : OutletNodeNames.deallocate();
1692 : }
1693 67 : if (allocated(OutletNodeNums)) {
1694 3 : OutletNodeNums.deallocate();
1695 : }
1696 67 : if (allocated(OutletFluidStreams)) {
1697 26 : OutletFluidStreams.deallocate();
1698 : }
1699 :
1700 67 : NumInlets = 0;
1701 67 : NumOutlets = 0;
1702 :
1703 67 : IsParent = false;
1704 6870 : for (int Which = 1; Which <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Which) {
1705 7017 : if (state.dataBranchNodeConnections->NodeConnections(Which).ObjectType != ComponentType ||
1706 214 : state.dataBranchNodeConnections->NodeConnections(Which).ObjectName != ComponentName) {
1707 6711 : continue;
1708 : }
1709 92 : if (state.dataBranchNodeConnections->NodeConnections(Which).ObjectIsParent) {
1710 61 : IsParent = true;
1711 : }
1712 92 : if (state.dataBranchNodeConnections->NodeConnections(Which).ConnectionType == DataLoopNode::ConnectionType::Inlet) {
1713 25 : ++NumInlets;
1714 67 : } else if (state.dataBranchNodeConnections->NodeConnections(Which).ConnectionType == DataLoopNode::ConnectionType::Outlet) {
1715 65 : ++NumOutlets;
1716 : }
1717 : }
1718 :
1719 67 : InletNodeNames.allocate(NumInlets);
1720 67 : InletNodeNums.allocate(NumInlets);
1721 67 : InletFluidStreams.allocate(NumInlets);
1722 67 : OutletNodeNames.allocate(NumOutlets);
1723 67 : OutletNodeNums.allocate(NumOutlets);
1724 67 : OutletFluidStreams.allocate(NumOutlets);
1725 :
1726 67 : InletNodeNames = std::string();
1727 67 : InletNodeNums = 0;
1728 67 : InletFluidStreams = NodeInputManager::CompFluidStream::Invalid;
1729 67 : OutletNodeNames = std::string();
1730 67 : OutletNodeNums = 0;
1731 67 : OutletFluidStreams = NodeInputManager::CompFluidStream::Invalid;
1732 67 : NumInlets = 0;
1733 67 : NumOutlets = 0;
1734 :
1735 6870 : for (int Which = 1; Which <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Which) {
1736 7017 : if (state.dataBranchNodeConnections->NodeConnections(Which).ObjectType != ComponentType ||
1737 214 : state.dataBranchNodeConnections->NodeConnections(Which).ObjectName != ComponentName) {
1738 6711 : continue;
1739 : }
1740 92 : if (state.dataBranchNodeConnections->NodeConnections(Which).ConnectionType == DataLoopNode::ConnectionType::Inlet) {
1741 25 : ++NumInlets;
1742 25 : InletNodeNames(NumInlets) = state.dataBranchNodeConnections->NodeConnections(Which).NodeName;
1743 25 : InletNodeNums(NumInlets) = state.dataBranchNodeConnections->NodeConnections(Which).NodeNumber;
1744 25 : InletFluidStreams(NumInlets) = state.dataBranchNodeConnections->NodeConnections(Which).FluidStream;
1745 67 : } else if (state.dataBranchNodeConnections->NodeConnections(Which).ConnectionType == DataLoopNode::ConnectionType::Outlet) {
1746 65 : ++NumOutlets;
1747 65 : OutletNodeNames(NumOutlets) = state.dataBranchNodeConnections->NodeConnections(Which).NodeName;
1748 65 : OutletNodeNums(NumOutlets) = state.dataBranchNodeConnections->NodeConnections(Which).NodeNumber;
1749 65 : OutletFluidStreams(NumOutlets) = state.dataBranchNodeConnections->NodeConnections(Which).FluidStream;
1750 : }
1751 : }
1752 67 : }
1753 :
1754 106 : void GetChildrenData(EnergyPlusData &state,
1755 : DataLoopNode::ConnectionObjectType const ComponentType,
1756 : std::string const &ComponentName,
1757 : int &NumChildren,
1758 : EPVector<DataLoopNode::ConnectionObjectType> &ChildrenCType,
1759 : Array1D_string &ChildrenCName,
1760 : Array1D_string &InletNodeName,
1761 : Array1D_int &InletNodeNum,
1762 : Array1D_string &OutletNodeName,
1763 : Array1D_int &OutletNodeNum,
1764 : bool &ErrorsFound)
1765 : {
1766 :
1767 : // SUBROUTINE INFORMATION:
1768 : // AUTHOR Linda Lawrie
1769 : // DATE WRITTEN May 2005
1770 :
1771 : // PURPOSE OF THIS SUBROUTINE:
1772 : // This routine gets children data for given parent node.
1773 :
1774 : // METHODOLOGY EMPLOYED:
1775 : // Traverses CompSet structure.
1776 :
1777 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1778 106 : EPVector<DataLoopNode::ConnectionObjectType> ChildCType;
1779 106 : Array1D_string ChildCName;
1780 106 : Array1D_string ChildInNodeName;
1781 106 : Array1D_string ChildOutNodeName;
1782 106 : Array1D_int ChildInNodeNum;
1783 106 : Array1D_int ChildOutNodeNum;
1784 : bool ErrInObject;
1785 :
1786 106 : std::fill(ChildrenCType.begin(), ChildrenCType.end(), DataLoopNode::ConnectionObjectType::Invalid);
1787 106 : ChildrenCName = std::string();
1788 106 : InletNodeName = std::string();
1789 106 : InletNodeNum = 0;
1790 106 : OutletNodeName = std::string();
1791 106 : OutletNodeNum = 0;
1792 106 : ErrInObject = false;
1793 :
1794 106 : if (IsParentObject(state, ComponentType, ComponentName)) {
1795 106 : NumChildren = GetNumChildren(state, ComponentType, ComponentName);
1796 106 : if (NumChildren == 0) {
1797 0 : ShowWarningError(state,
1798 0 : format("GetChildrenData: Parent Node has no children, node={}:{}.",
1799 0 : ConnectionObjectTypeNames[static_cast<int>(ComponentType)],
1800 : ComponentName));
1801 : } else {
1802 : int ParentInletNodeNum;
1803 : int ParentOutletNodeNum;
1804 106 : std::string ParentInletNodeName;
1805 106 : std::string ParentOutletNodeName;
1806 106 : GetParentData(
1807 : state, ComponentType, ComponentName, ParentInletNodeName, ParentInletNodeNum, ParentOutletNodeName, ParentOutletNodeNum, ErrInObject);
1808 106 : ChildCType.clear();
1809 106 : ChildCType.allocate(NumChildren);
1810 106 : ChildCName.allocate(NumChildren);
1811 106 : ChildInNodeName.allocate(NumChildren);
1812 106 : ChildOutNodeName.allocate(NumChildren);
1813 106 : ChildInNodeNum.allocate(NumChildren);
1814 106 : ChildOutNodeNum.allocate(NumChildren);
1815 106 : ChildCName = std::string();
1816 106 : ChildInNodeName = std::string();
1817 106 : ChildOutNodeName = std::string();
1818 106 : ChildInNodeNum = 0;
1819 106 : ChildOutNodeNum = 0;
1820 106 : int CountNum = 0;
1821 1770 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumCompSets; ++Loop) {
1822 1991 : if (state.dataBranchNodeConnections->CompSets(Loop).ParentObjectType == ComponentType &&
1823 327 : state.dataBranchNodeConnections->CompSets(Loop).ParentCName == ComponentName) {
1824 183 : ++CountNum;
1825 183 : ChildCType(CountNum) = state.dataBranchNodeConnections->CompSets(Loop).ComponentObjectType;
1826 183 : ChildCName(CountNum) = state.dataBranchNodeConnections->CompSets(Loop).CName;
1827 183 : ChildInNodeName(CountNum) = state.dataBranchNodeConnections->CompSets(Loop).InletNodeName;
1828 183 : ChildOutNodeName(CountNum) = state.dataBranchNodeConnections->CompSets(Loop).OutletNodeName;
1829 : // Get Node Numbers
1830 183 : ChildInNodeNum(CountNum) = Util::FindItemInList(ChildInNodeName(CountNum),
1831 366 : state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}),
1832 183 : state.dataLoopNodes->NumOfNodes);
1833 183 : ChildOutNodeNum(CountNum) = Util::FindItemInList(ChildOutNodeName(CountNum),
1834 366 : state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}),
1835 183 : state.dataLoopNodes->NumOfNodes);
1836 : }
1837 : }
1838 106 : if (CountNum != NumChildren) {
1839 0 : ShowSevereError(state, "GetChildrenData: Counted nodes not equal to GetNumChildren count");
1840 0 : ErrInObject = true;
1841 : } else {
1842 : // Children arrays built. Now "sort" for flow connection order(?)
1843 106 : std::string MatchNodeName = ParentInletNodeName;
1844 106 : CountNum = 0;
1845 106 : int CountMatchLoop = 0;
1846 289 : while (CountMatchLoop < NumChildren) {
1847 183 : ++CountMatchLoop;
1848 : // Matched=.FALSE.
1849 501 : for (int Loop = 1; Loop <= NumChildren; ++Loop) {
1850 385 : if (ChildInNodeName(Loop) == MatchNodeName) {
1851 67 : ++CountNum;
1852 67 : ChildrenCType(CountNum) = ChildCType(Loop);
1853 67 : ChildrenCName(CountNum) = ChildCName(Loop);
1854 67 : InletNodeName(CountNum) = ChildInNodeName(Loop);
1855 67 : InletNodeNum(CountNum) = ChildInNodeNum(Loop);
1856 67 : OutletNodeName(CountNum) = ChildOutNodeName(Loop);
1857 67 : OutletNodeNum(CountNum) = ChildOutNodeNum(Loop);
1858 67 : ChildInNodeName(Loop).clear(); // So it won't match anymore
1859 : // Matched=.TRUE.
1860 67 : MatchNodeName = ChildOutNodeName(Loop);
1861 67 : break;
1862 : }
1863 : }
1864 : }
1865 106 : if (MatchNodeName != ParentOutletNodeName) {
1866 76 : for (int Loop = 1; Loop <= NumChildren; ++Loop) {
1867 76 : if (ChildInNodeName(Loop).empty()) {
1868 0 : continue;
1869 : }
1870 76 : if (ChildOutNodeName(Loop) == ParentOutletNodeName) {
1871 60 : break;
1872 : }
1873 16 : break;
1874 : }
1875 : }
1876 289 : for (int Loop = 1; Loop <= NumChildren; ++Loop) {
1877 183 : if (ChildInNodeName(Loop).empty()) {
1878 67 : continue;
1879 : }
1880 116 : ++CountNum;
1881 116 : ChildrenCType(CountNum) = ChildCType(Loop);
1882 116 : ChildrenCName(CountNum) = ChildCName(Loop);
1883 116 : InletNodeName(CountNum) = ChildInNodeName(Loop);
1884 116 : InletNodeNum(CountNum) = ChildInNodeNum(Loop);
1885 116 : OutletNodeName(CountNum) = ChildOutNodeName(Loop);
1886 116 : OutletNodeNum(CountNum) = ChildOutNodeNum(Loop);
1887 : }
1888 106 : ChildCType.deallocate();
1889 106 : ChildCName.deallocate();
1890 106 : ChildInNodeName.deallocate();
1891 106 : ChildOutNodeName.deallocate();
1892 106 : ChildInNodeNum.deallocate();
1893 106 : ChildOutNodeNum.deallocate();
1894 106 : }
1895 106 : }
1896 : } else {
1897 0 : ShowWarningError(state,
1898 0 : format("GetChildrenData: Requested Children Data for non Parent Node={}:{}.",
1899 0 : ConnectionObjectTypeNames[static_cast<int>(ComponentType)],
1900 : ComponentName));
1901 0 : ErrInObject = true;
1902 : }
1903 :
1904 106 : if (ErrInObject) {
1905 0 : ErrorsFound = true;
1906 : }
1907 106 : }
1908 :
1909 3015 : void SetUpCompSets(EnergyPlusData &state,
1910 : std::string_view ParentType, // Parent Object Type
1911 : std::string_view ParentName, // Parent Object Name
1912 : std::string_view CompType, // Component Type
1913 : std::string_view CompName, // Component Name
1914 : std::string_view InletNode, // Inlet Node Name
1915 : std::string_view OutletNode, // Outlet Node Name
1916 : std::string_view const Description // Description
1917 : )
1918 : {
1919 :
1920 : // SUBROUTINE INFORMATION:
1921 : // AUTHOR Linda Lawrie
1922 : // DATE WRITTEN November 2001
1923 :
1924 : // PURPOSE OF THIS SUBROUTINE:
1925 : // This subroutine sets up "Component Sets" as input in the branch
1926 : // lists. These can be used later to verify that the proper names and
1927 : // inlet/outlet nodes have been input. This routine assumes that identical
1928 : // "CompSets" cannot be used in multiple places and issues a warning if they are.
1929 :
1930 3015 : std::string ParentTypeUC = Util::makeUPPER(ParentType);
1931 3015 : std::string CompTypeUC = Util::makeUPPER(CompType);
1932 : // TODO: Refactor this away by passing in enums
1933 : DataLoopNode::ConnectionObjectType ParentTypeEnum =
1934 3015 : static_cast<DataLoopNode::ConnectionObjectType>(getEnumValue(ConnectionObjectTypeNamesUC, ParentTypeUC));
1935 3015 : assert(ParentTypeEnum != DataLoopNode::ConnectionObjectType::Invalid);
1936 :
1937 : DataLoopNode::ConnectionObjectType ComponentTypeEnum =
1938 3015 : static_cast<DataLoopNode::ConnectionObjectType>(getEnumValue(ConnectionObjectTypeNamesUC, CompTypeUC));
1939 3015 : assert(ComponentTypeEnum != DataLoopNode::ConnectionObjectType::Invalid);
1940 :
1941 3015 : int Found = 0;
1942 :
1943 : // See if Component-Nodes set is already there - should be unique
1944 : // Try to fill in blanks (passed in as undefined
1945 17283 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
1946 14956 : if (CompName != state.dataBranchNodeConnections->CompSets(Count).CName) {
1947 13861 : continue;
1948 : }
1949 1095 : if (ComponentTypeEnum != DataLoopNode::ConnectionObjectType::Undefined) {
1950 1044 : if (ComponentTypeEnum != state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType) {
1951 4 : continue;
1952 : }
1953 : }
1954 : // Component name matches, component type matches or is undefined
1955 1091 : if (InletNode != undefined) {
1956 924 : if (state.dataBranchNodeConnections->CompSets(Count).InletNodeName != undefined) {
1957 913 : if (InletNode != state.dataBranchNodeConnections->CompSets(Count).InletNodeName) {
1958 344 : continue;
1959 : }
1960 : } else {
1961 11 : state.dataBranchNodeConnections->CompSets(Count).InletNodeName = InletNode;
1962 : }
1963 : }
1964 747 : if (OutletNode != undefined) {
1965 638 : if (state.dataBranchNodeConnections->CompSets(Count).OutletNodeName != undefined) {
1966 627 : if (OutletNode != state.dataBranchNodeConnections->CompSets(Count).OutletNodeName) {
1967 25 : continue;
1968 : }
1969 : } else {
1970 11 : state.dataBranchNodeConnections->CompSets(Count).OutletNodeName = OutletNode;
1971 : }
1972 : }
1973 : // See if something undefined and set here
1974 1410 : if (state.dataBranchNodeConnections->CompSets(Count).ParentObjectType == DataLoopNode::ConnectionObjectType::Undefined &&
1975 688 : state.dataBranchNodeConnections->CompSets(Count).ParentCName == undefined) {
1976 : // Assume this is a further definition for this compset
1977 688 : state.dataBranchNodeConnections->CompSets(Count).ParentObjectType = ParentTypeEnum;
1978 688 : state.dataBranchNodeConnections->CompSets(Count).ParentCName = ParentName;
1979 688 : if (!Description.empty()) {
1980 18 : state.dataBranchNodeConnections->CompSets(Count).Description = Description;
1981 : }
1982 688 : Found = Count;
1983 688 : break;
1984 : }
1985 : }
1986 3015 : if (Found == 0) {
1987 12994 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
1988 10693 : Found = 0;
1989 : // Test if inlet node has been used before as an inlet node
1990 : // If the matching node name does not belong to the parent object, then error
1991 : // For example a fan may share the same inlet node as the furnace object which is its parent
1992 10693 : if (InletNode != state.dataBranchNodeConnections->CompSets(Count).InletNodeName) {
1993 10287 : continue;
1994 : // If parent type is undefined then no error
1995 700 : } else if ((ParentTypeEnum == DataLoopNode::ConnectionObjectType::Undefined) ||
1996 294 : (state.dataBranchNodeConnections->CompSets(Count).ParentObjectType == DataLoopNode::ConnectionObjectType::Undefined)) {
1997 : // If node name is undefined then no error
1998 224 : } else if (InletNode != undefined) {
1999 : // If the matching node name does not belong to the parent or child object, then error
2000 : // For example a fan may share the same inlet node as the furnace object which is its parent
2001 8 : if ((ParentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType) &&
2002 3 : (ParentName == state.dataBranchNodeConnections->CompSets(Count).CName)) {
2003 : // OK - The duplicate inlet node belongs to this component's parent
2004 2 : } else if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ParentObjectType) &&
2005 0 : (CompName == state.dataBranchNodeConnections->CompSets(Count).ParentCName)) {
2006 : // OK - The duplicate inlet node belongs to a child of this component
2007 : } else {
2008 : // Due to possibility of grandparents or more, if the matching node name
2009 : // belongs to a component that appears as a parent, then OK
2010 2 : int Found2 = 0;
2011 8 : for (int Count2 = 1; Count2 <= state.dataBranchNodeConnections->NumCompSets; ++Count2) {
2012 6 : if ((state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType ==
2013 6 : state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
2014 0 : (state.dataBranchNodeConnections->CompSets(Count).CName ==
2015 0 : state.dataBranchNodeConnections->CompSets(Count2).ParentCName)) {
2016 0 : Found2 = 1;
2017 : }
2018 6 : if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
2019 0 : (CompName == state.dataBranchNodeConnections->CompSets(Count2).ParentCName)) {
2020 0 : Found2 = 1;
2021 : }
2022 : }
2023 2 : if (Found2 == 0) {
2024 2 : ShowWarningError(state, format("Node used as an inlet more than once: {}", InletNode));
2025 4 : ShowContinueError(
2026 : state,
2027 4 : format(" Used by: {}, name={}",
2028 2 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType)],
2029 2 : state.dataBranchNodeConnections->CompSets(Count).ParentCName));
2030 4 : ShowContinueError(
2031 : state,
2032 4 : format(" as inlet for: {}, name={}",
2033 2 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
2034 2 : state.dataBranchNodeConnections->CompSets(Count).CName));
2035 2 : ShowContinueError(state, format("{}{}{}", " and by : ", ParentTypeUC + ", name=", ParentName));
2036 2 : ShowContinueError(state, format("{}{}{}", " as inlet for: ", CompTypeUC + ", name=", CompName));
2037 : }
2038 : }
2039 : }
2040 : // Test if outlet node has been used before as an outlet node
2041 : // If the matching node name does not belong to the parent or child object, then error
2042 : // For example a fan may share the same outlet node as the furnace object which is its parent
2043 406 : if (OutletNode != state.dataBranchNodeConnections->CompSets(Count).OutletNodeName) {
2044 100 : continue;
2045 : // If parent type is undefined then no error
2046 511 : } else if ((ParentTypeEnum == DataLoopNode::ConnectionObjectType::Undefined) ||
2047 205 : (state.dataBranchNodeConnections->CompSets(Count).ParentObjectType == DataLoopNode::ConnectionObjectType::Undefined)) {
2048 : // If node name is undefined then no error
2049 137 : } else if (OutletNode != undefined) {
2050 33 : if ((ParentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType) &&
2051 3 : (ParentName == state.dataBranchNodeConnections->CompSets(Count).CName)) {
2052 : // OK - The duplicate outlet node belongs to this component's parent
2053 27 : } else if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ParentObjectType) &&
2054 0 : (CompName == state.dataBranchNodeConnections->CompSets(Count).ParentCName)) {
2055 : // OK - The duplicate outlet node belongs to a child of this component
2056 : } else {
2057 : // Due to possibility of grandparents or more, if the matching node name
2058 : // belongs to a component that appears as a parent, then OK
2059 27 : int Found2 = 0;
2060 141 : for (int Count2 = 1; Count2 <= state.dataBranchNodeConnections->NumCompSets; ++Count2) {
2061 114 : if ((state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType ==
2062 114 : state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
2063 0 : (state.dataBranchNodeConnections->CompSets(Count).CName ==
2064 0 : state.dataBranchNodeConnections->CompSets(Count2).ParentCName)) {
2065 0 : Found2 = 1;
2066 : }
2067 114 : if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
2068 0 : (CompName == state.dataBranchNodeConnections->CompSets(Count2).ParentCName)) {
2069 0 : Found2 = 1;
2070 : }
2071 : }
2072 : // This rule is violated by dual duct units, so let it pass
2073 27 : if (Found2 == 0) {
2074 : std::string_view const CType =
2075 27 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)];
2076 27 : if ((!has_prefixi(CType, "AirTerminal:DualDuct:")) && (!has_prefixi(CompTypeUC, "AirTerminal:DualDuct:"))) {
2077 25 : ShowWarningError(state, format("Node used as an outlet more than once: {}", OutletNode));
2078 50 : ShowContinueError(
2079 : state,
2080 50 : format(" Used by: {}, name={}",
2081 25 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType)],
2082 25 : state.dataBranchNodeConnections->CompSets(Count).ParentCName));
2083 50 : ShowContinueError(
2084 : state,
2085 50 : format(
2086 : " as outlet for: {}, name={}",
2087 25 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
2088 25 : state.dataBranchNodeConnections->CompSets(Count).CName));
2089 25 : ShowContinueError(state, format("{}{}{}", " and by : ", ParentTypeUC + ", name=", ParentName));
2090 25 : ShowContinueError(state, format("{}{}{}", " as outlet for: ", CompTypeUC + ", name=", CompName));
2091 : }
2092 : }
2093 : }
2094 : }
2095 306 : if (ComponentTypeEnum != state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType &&
2096 : ComponentTypeEnum != DataLoopNode::ConnectionObjectType::Undefined) {
2097 223 : continue;
2098 : }
2099 83 : if (CompName != state.dataBranchNodeConnections->CompSets(Count).CName) {
2100 57 : continue;
2101 : }
2102 26 : Found = Count;
2103 26 : break;
2104 : }
2105 : }
2106 3015 : if (Found == 0) {
2107 2301 : state.dataBranchNodeConnections->CompSets.resize(++state.dataBranchNodeConnections->NumCompSets);
2108 2301 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).ParentObjectType = ParentTypeEnum;
2109 :
2110 2301 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).ParentCName = ParentName;
2111 2301 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).ComponentObjectType = ComponentTypeEnum;
2112 2301 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).CName = CompName;
2113 2301 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).InletNodeName =
2114 :
2115 4602 : Util::makeUPPER(InletNode); // TODO: Fix this....
2116 2301 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).OutletNodeName =
2117 4602 : Util::makeUPPER(OutletNode); // TODO: Fix this....
2118 :
2119 2301 : if (!Description.empty()) {
2120 1313 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).Description = Description;
2121 : } else {
2122 988 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).Description = undefined;
2123 : }
2124 : }
2125 3015 : }
2126 :
2127 86 : void TestInletOutletNodes(EnergyPlusData &state)
2128 : {
2129 :
2130 : // SUBROUTINE INFORMATION:
2131 : // AUTHOR Linda Lawrie
2132 : // DATE WRITTEN November 2001
2133 :
2134 : // PURPOSE OF THIS SUBROUTINE:
2135 : // This subroutine tests the branches to see if a duplicate inlet node
2136 : // exists under a different name in the sequence; likewise for outlet.
2137 :
2138 86 : Array1D_bool AlreadyNoted;
2139 :
2140 : // Test component sets created by branches
2141 86 : AlreadyNoted.dimension(state.dataBranchNodeConnections->NumCompSets, false);
2142 813 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
2143 10610 : for (int Other = 1; Other <= state.dataBranchNodeConnections->NumCompSets; ++Other) {
2144 9883 : if (Count == Other) {
2145 727 : continue;
2146 : }
2147 9156 : if (state.dataBranchNodeConnections->CompSets(Count).InletNodeName != state.dataBranchNodeConnections->CompSets(Other).InletNodeName) {
2148 9134 : continue;
2149 : }
2150 22 : if (AlreadyNoted(Count)) {
2151 17 : continue;
2152 : }
2153 : // All other values must match
2154 5 : if (state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType !=
2155 8 : state.dataBranchNodeConnections->CompSets(Other).ComponentObjectType ||
2156 8 : state.dataBranchNodeConnections->CompSets(Count).CName != state.dataBranchNodeConnections->CompSets(Other).CName ||
2157 0 : state.dataBranchNodeConnections->CompSets(Count).OutletNodeName != state.dataBranchNodeConnections->CompSets(Other).OutletNodeName) {
2158 5 : AlreadyNoted(Other) = true;
2159 10 : ShowWarningError(state,
2160 10 : format("Node used as an inlet more than once: {}", state.dataBranchNodeConnections->CompSets(Count).InletNodeName));
2161 10 : ShowContinueError(
2162 : state,
2163 10 : format(" Used by: {}, name={}",
2164 5 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType)],
2165 5 : state.dataBranchNodeConnections->CompSets(Count).ParentCName));
2166 10 : ShowContinueError(
2167 : state,
2168 10 : format(" as inlet for: {}, name={}",
2169 5 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Other).ComponentObjectType)],
2170 5 : state.dataBranchNodeConnections->CompSets(Other).CName));
2171 10 : ShowContinueError(
2172 : state,
2173 10 : format(" and by: {}, name={}",
2174 5 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Other).ParentObjectType)],
2175 5 : state.dataBranchNodeConnections->CompSets(Other).ParentCName));
2176 10 : ShowContinueError(
2177 : state,
2178 10 : format(" as inlet for: {}, name={}",
2179 5 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
2180 5 : state.dataBranchNodeConnections->CompSets(Count).CName));
2181 : }
2182 : }
2183 : }
2184 :
2185 86 : AlreadyNoted = false;
2186 813 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
2187 10610 : for (int Other = 1; Other <= state.dataBranchNodeConnections->NumCompSets; ++Other) {
2188 9883 : if (Count == Other) {
2189 727 : continue;
2190 : }
2191 9156 : if (state.dataBranchNodeConnections->CompSets(Count).OutletNodeName != state.dataBranchNodeConnections->CompSets(Other).OutletNodeName) {
2192 9146 : continue;
2193 : }
2194 10 : if (AlreadyNoted(Count)) {
2195 5 : continue;
2196 : }
2197 : // All other values must match
2198 5 : if (state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType !=
2199 5 : state.dataBranchNodeConnections->CompSets(Other).ComponentObjectType ||
2200 5 : state.dataBranchNodeConnections->CompSets(Count).CName != state.dataBranchNodeConnections->CompSets(Other).CName ||
2201 0 : state.dataBranchNodeConnections->CompSets(Count).InletNodeName != state.dataBranchNodeConnections->CompSets(Other).InletNodeName) {
2202 5 : AlreadyNoted(Other) = true;
2203 10 : ShowWarningError(
2204 10 : state, format("Node used as an outlet more than once: {}", state.dataBranchNodeConnections->CompSets(Count).OutletNodeName));
2205 10 : ShowContinueError(
2206 : state,
2207 10 : format(" Used by: {}, name={}",
2208 5 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType)],
2209 5 : state.dataBranchNodeConnections->CompSets(Count).ParentCName));
2210 10 : ShowContinueError(
2211 : state,
2212 10 : format(" as outlet for: {}, name={}",
2213 5 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Other).ComponentObjectType)],
2214 5 : state.dataBranchNodeConnections->CompSets(Other).CName));
2215 10 : ShowContinueError(
2216 : state,
2217 10 : format(" and by: {}, name={}",
2218 5 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Other).ParentObjectType)],
2219 5 : state.dataBranchNodeConnections->CompSets(Other).ParentCName));
2220 10 : ShowContinueError(
2221 : state,
2222 10 : format(" as outlet for: {}, name={}",
2223 5 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
2224 5 : state.dataBranchNodeConnections->CompSets(Count).CName));
2225 : }
2226 : }
2227 : }
2228 :
2229 86 : AlreadyNoted.deallocate();
2230 86 : }
2231 :
2232 2178 : void TestCompSet(EnergyPlusData &state,
2233 : std::string_view const CompType, // Component Type
2234 : std::string_view CompName, // Component Name
2235 : std::string const &InletNode, // Inlet Node Name
2236 : std::string const &OutletNode, // Outlet Node Name
2237 : std::string const &Description // Description of Node Pair (for warning message)
2238 : )
2239 : {
2240 :
2241 : // SUBROUTINE INFORMATION:
2242 : // AUTHOR Linda K. Lawrie
2243 : // DATE WRITTEN November 2001
2244 :
2245 : // PURPOSE OF THIS SUBROUTINE:
2246 : // Register a child component in the CompSets data structure.
2247 : // NOTE: This function was originally designed to test the stored "Component Sets" to
2248 : // see if there was one of this combination in there. Thus the name "TestCompSet".
2249 : // However, this was based on a false assumption that input would always be gotten
2250 : // first for the parent object, then for the child object. But this is often not the
2251 : // case. Ultimately, the name of this function should be changed or it should be merged
2252 : // into SetUpCompSets.
2253 : // Until then, this function does the following:
2254 : // a) Search CompSets for this combination of component type, component name,
2255 : // inlet node and outlet node. If component type/name match and the existing
2256 : // node names are UNDEFINED, this compset is assumed to be a match.
2257 : // b) If found, fill in any missing data such as node names or node description
2258 : // c) If not found, call SetUpCompSets (with parent type and name UNDEFINED)
2259 : // to add a new item in the CompSets array
2260 :
2261 2178 : std::string CompTypeUC = Util::makeUPPER(CompType);
2262 :
2263 : // TODO: Refactor this away by passing in enums
2264 : DataLoopNode::ConnectionObjectType ComponentTypeEnum =
2265 2178 : static_cast<DataLoopNode::ConnectionObjectType>(getEnumValue(ConnectionObjectTypeNamesUC, CompTypeUC));
2266 2178 : assert(ComponentTypeEnum != DataLoopNode::ConnectionObjectType::Invalid);
2267 :
2268 : // See if Already there
2269 2178 : int Found = 0;
2270 12422 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
2271 19491 : if ((ComponentTypeEnum != state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType) &&
2272 8367 : (state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType != DataLoopNode::ConnectionObjectType::Undefined)) {
2273 8367 : continue;
2274 : }
2275 2757 : if (CompName != state.dataBranchNodeConnections->CompSets(Count).CName) {
2276 1613 : continue;
2277 : }
2278 1693 : if ((InletNode != state.dataBranchNodeConnections->CompSets(Count).InletNodeName) &&
2279 1693 : (state.dataBranchNodeConnections->CompSets(Count).InletNodeName != undefined) && (InletNode != undefined)) {
2280 264 : continue;
2281 : }
2282 1022 : if ((OutletNode != state.dataBranchNodeConnections->CompSets(Count).OutletNodeName) &&
2283 1022 : (state.dataBranchNodeConnections->CompSets(Count).OutletNodeName != undefined) && (OutletNode != undefined)) {
2284 0 : continue;
2285 : }
2286 :
2287 880 : Found = Count;
2288 880 : break;
2289 : }
2290 :
2291 2178 : if (Found == 0) {
2292 1298 : SetUpCompSets(state, undefined, undefined, CompType, CompName, InletNode, OutletNode, Description);
2293 : } else {
2294 : // Fill in node names and component type for previously undefined values:
2295 : // If the parent object did not specify a component type or inlet or outlet node, then that value
2296 : // is UNDEFINED in CompSets. When a component calls TestCompSet, the comp type and inlet and
2297 : // outlet nodes are known, so they can be filled in for future reference.
2298 880 : if (state.dataBranchNodeConnections->CompSets(Found).ComponentObjectType == DataLoopNode::ConnectionObjectType::Undefined) {
2299 0 : state.dataBranchNodeConnections->CompSets(Found).ComponentObjectType = ComponentTypeEnum;
2300 : }
2301 880 : if (state.dataBranchNodeConnections->CompSets(Found).InletNodeName == undefined) {
2302 241 : state.dataBranchNodeConnections->CompSets(Found).InletNodeName = InletNode;
2303 : }
2304 880 : if (state.dataBranchNodeConnections->CompSets(Found).OutletNodeName == undefined) {
2305 98 : state.dataBranchNodeConnections->CompSets(Found).OutletNodeName = OutletNode;
2306 : }
2307 880 : if (state.dataBranchNodeConnections->CompSets(Found).Description == undefined) {
2308 863 : state.dataBranchNodeConnections->CompSets(Found).Description = Description;
2309 : }
2310 : }
2311 2178 : }
2312 :
2313 73 : void TestCompSetInletOutletNodes(EnergyPlusData &state, bool &ErrorsFound)
2314 : {
2315 :
2316 : // SUBROUTINE INFORMATION:
2317 : // AUTHOR Linda Lawrie
2318 : // DATE WRITTEN March 2008
2319 : // MODIFIED na
2320 : // RE-ENGINEERED na
2321 :
2322 : // PURPOSE OF THIS SUBROUTINE:
2323 : // This subroutine tests the comp sets to see if a duplicate comp name
2324 : // exists under a different set of inlet/outlet nodes.
2325 :
2326 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2327 73 : Array1D_bool AlreadyNoted;
2328 :
2329 : // Test component sets created by branches
2330 73 : AlreadyNoted.dimension(state.dataBranchNodeConnections->NumCompSets, false);
2331 420 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
2332 7924 : for (int Other = 1; Other <= state.dataBranchNodeConnections->NumCompSets; ++Other) {
2333 7577 : if (Count == Other) {
2334 347 : continue;
2335 : }
2336 7230 : if (state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType ==
2337 : DataLoopNode::ConnectionObjectType ::SolarCollectorUnglazedTranspired) {
2338 0 : continue;
2339 : }
2340 7230 : if (state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType !=
2341 8274 : state.dataBranchNodeConnections->CompSets(Other).ComponentObjectType ||
2342 1044 : state.dataBranchNodeConnections->CompSets(Count).CName != state.dataBranchNodeConnections->CompSets(Other).CName) {
2343 7180 : continue;
2344 : }
2345 50 : if (state.dataBranchNodeConnections->CompSets(Count).Description != state.dataBranchNodeConnections->CompSets(Other).Description) {
2346 100 : if (state.dataBranchNodeConnections->CompSets(Count).Description != undefined &&
2347 50 : state.dataBranchNodeConnections->CompSets(Other).Description != undefined) {
2348 50 : continue;
2349 : }
2350 : }
2351 0 : if (state.dataBranchNodeConnections->CompSets(Count).InletNodeName == state.dataBranchNodeConnections->CompSets(Other).InletNodeName) {
2352 0 : continue;
2353 : }
2354 0 : if (state.dataBranchNodeConnections->CompSets(Count).OutletNodeName == state.dataBranchNodeConnections->CompSets(Other).OutletNodeName) {
2355 0 : continue;
2356 : }
2357 0 : if (AlreadyNoted(Count)) {
2358 0 : continue;
2359 : }
2360 : // All other values must match
2361 0 : AlreadyNoted(Other) = true;
2362 0 : ShowSevereError(state, "Same component name and type has differing Node Names.");
2363 0 : ShowContinueError(
2364 : state,
2365 0 : format(" Component: {}, name={}",
2366 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
2367 0 : state.dataBranchNodeConnections->CompSets(Count).CName));
2368 0 : ShowContinueError(state,
2369 0 : format(" Nodes, inlet: {}, outlet: {}",
2370 0 : state.dataBranchNodeConnections->CompSets(Count).InletNodeName,
2371 0 : state.dataBranchNodeConnections->CompSets(Count).OutletNodeName));
2372 0 : ShowContinueError(state,
2373 0 : format(" & Nodes, inlet: {}, outlet: {}",
2374 0 : state.dataBranchNodeConnections->CompSets(Other).InletNodeName,
2375 0 : state.dataBranchNodeConnections->CompSets(Other).OutletNodeName));
2376 0 : ShowContinueError(state,
2377 0 : format(" Node Types: {} & {}",
2378 0 : state.dataBranchNodeConnections->CompSets(Count).Description,
2379 0 : state.dataBranchNodeConnections->CompSets(Other).Description));
2380 0 : ErrorsFound = true;
2381 : }
2382 : }
2383 :
2384 73 : AlreadyNoted.deallocate();
2385 73 : }
2386 :
2387 53 : void GetNodeConnectionType(EnergyPlusData &state, int const NodeNumber, EPVector<DataLoopNode::ConnectionType> &NodeConnectType, bool &errFlag)
2388 : {
2389 :
2390 : // FUNCTION INFORMATION:
2391 : // AUTHOR Lixing Gu
2392 : // DATE WRITTEN Jan 2007
2393 :
2394 : // PURPOSE OF THIS FUNCTION:
2395 : // This function provides a connection type with given node number
2396 :
2397 53 : Array1D_int ListArray;
2398 53 : Array1D_string ConnectionTypes(15);
2399 :
2400 848 : for (int nodetype = 1; nodetype < static_cast<int>(ConnectionType::Num); ++nodetype) {
2401 795 : ConnectionTypes(nodetype) = ConnectionTypeNames[nodetype];
2402 : }
2403 :
2404 53 : if (allocated(NodeConnectType)) {
2405 40 : NodeConnectType.deallocate();
2406 : }
2407 :
2408 : int NumInList;
2409 106 : FindAllNodeNumbersInList(
2410 53 : NodeNumber, state.dataBranchNodeConnections->NodeConnections, state.dataBranchNodeConnections->NumOfNodeConnections, NumInList, ListArray);
2411 :
2412 53 : NodeConnectType.allocate(NumInList);
2413 :
2414 53 : if (NumInList > 0) {
2415 80 : for (int NodeConnectIndex = 1; NodeConnectIndex <= NumInList; ++NodeConnectIndex) {
2416 41 : NodeConnectType(NodeConnectIndex) = state.dataBranchNodeConnections->NodeConnections(ListArray(NodeConnectIndex)).ConnectionType;
2417 : }
2418 : } else {
2419 14 : if (NodeNumber > 0) {
2420 14 : ShowWarningError(state, format("Node not found = {}.", state.dataLoopNodes->NodeID(NodeNumber)));
2421 : } else {
2422 0 : ShowWarningError(state, "Invalid node number passed = 0.");
2423 : }
2424 14 : errFlag = true;
2425 : }
2426 53 : }
2427 :
2428 53 : void FindAllNodeNumbersInList(int const WhichNumber,
2429 : EPVector<DataBranchNodeConnections::NodeConnectionDef> const &NodeConnections,
2430 : int const NumItems,
2431 : int &CountOfItems, // Number of items found
2432 : Array1D_int &AllNumbersInList // Index array to all numbers found
2433 : )
2434 : {
2435 :
2436 : // FUNCTION INFORMATION:
2437 : // AUTHOR R. Raustad
2438 : // DATE WRITTEN January 2007
2439 :
2440 : // PURPOSE OF THIS FUNCTION:
2441 : // This function looks up a number(integer) in a similar list of
2442 : // items and returns the index of the item in the list, if
2443 : // found.
2444 :
2445 53 : CountOfItems = 0;
2446 :
2447 53 : if (allocated(AllNumbersInList)) {
2448 0 : AllNumbersInList.deallocate();
2449 : }
2450 :
2451 332 : for (int Count = 1; Count <= NumItems; ++Count) {
2452 279 : if (WhichNumber == NodeConnections(Count).NodeNumber) {
2453 41 : ++CountOfItems;
2454 : }
2455 : }
2456 :
2457 53 : if (CountOfItems > 0) {
2458 :
2459 39 : AllNumbersInList.dimension(CountOfItems, 0);
2460 39 : CountOfItems = 0;
2461 :
2462 276 : for (int Count = 1; Count <= NumItems; ++Count) {
2463 237 : if (WhichNumber == NodeConnections(Count).NodeNumber) {
2464 41 : ++CountOfItems;
2465 41 : AllNumbersInList(CountOfItems) = Count;
2466 : }
2467 : }
2468 : }
2469 53 : }
2470 :
2471 : } // namespace EnergyPlus::BranchNodeConnections
|