Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, 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 297884 : 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 297884 : bool ErrorsFoundHere = false;
670 :
671 297884 : 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 297884 : std::string_view const objTypeStr = ConnectionObjectTypeNames[static_cast<int>(ObjectType)];
678 297884 : std::string_view const conTypeStr = ConnectionTypeNames[static_cast<int>(ConnectionType)];
679 :
680 297884 : 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 297884 : bool MakeNew = true;
687 93477593 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Count) {
688 93179709 : if (state.dataBranchNodeConnections->NodeConnections(Count).NodeNumber != NodeNumber) continue;
689 336689 : if (state.dataBranchNodeConnections->NodeConnections(Count).ObjectType != ObjectType) continue;
690 129137 : if (!Util::SameString(state.dataBranchNodeConnections->NodeConnections(Count).ObjectName, ObjectName)) continue;
691 120765 : if (state.dataBranchNodeConnections->NodeConnections(Count).ConnectionType != ConnectionType) continue;
692 118328 : if (state.dataBranchNodeConnections->NodeConnections(Count).FluidStream != FluidStream) continue;
693 236654 : if ((state.dataBranchNodeConnections->NodeConnections(Count).ObjectIsParent && !IsParent) ||
694 118327 : (!state.dataBranchNodeConnections->NodeConnections(Count).ObjectIsParent && IsParent)) {
695 0 : ShowSevereError(state, format("{}{}", RoutineName, "Node registered for both Parent and \"not\" Parent"));
696 0 : ShowContinueError(state, format("{}{}{}{}{}{}", "Occurs for Node=", NodeName, ", ObjectType=", ObjectType, ", ObjectName=", ObjectName));
697 0 : ErrorsFoundHere = true;
698 : }
699 118327 : MakeNew = false;
700 : }
701 297884 : if (MakeNew) {
702 179557 : int constexpr NodeConnectionAlloc = 1000;
703 179557 : ++state.dataBranchNodeConnections->NumOfNodeConnections;
704 358386 : if (state.dataBranchNodeConnections->NumOfNodeConnections > 1 &&
705 178829 : state.dataBranchNodeConnections->NumOfNodeConnections > state.dataBranchNodeConnections->MaxNumOfNodeConnections) {
706 31 : state.dataBranchNodeConnections->NodeConnections.resize(state.dataBranchNodeConnections->MaxNumOfNodeConnections += NodeConnectionAlloc);
707 179526 : } else if (state.dataBranchNodeConnections->NumOfNodeConnections == 1) {
708 728 : state.dataBranchNodeConnections->NodeConnections.allocate(NodeConnectionAlloc);
709 728 : state.dataBranchNodeConnections->MaxNumOfNodeConnections = NodeConnectionAlloc;
710 : }
711 :
712 179557 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).NodeNumber = NodeNumber;
713 179557 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).NodeName = NodeName;
714 179557 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).ObjectType = ObjectType;
715 179557 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).ObjectName = ObjectName;
716 179557 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).ConnectionType = ConnectionType;
717 179557 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).FluidStream = FluidStream;
718 179557 : state.dataBranchNodeConnections->NodeConnections(state.dataBranchNodeConnections->NumOfNodeConnections).ObjectIsParent = IsParent;
719 : }
720 :
721 297884 : if (has_prefixi(objTypeStr, "AirTerminal:")) {
722 9910 : if (!InputFieldName.empty()) {
723 9910 : ++state.dataBranchNodeConnections->NumOfAirTerminalNodes;
724 9910 : int constexpr EqNodeConnectionAlloc = 100;
725 19278 : if (state.dataBranchNodeConnections->NumOfAirTerminalNodes > 1 &&
726 9368 : state.dataBranchNodeConnections->NumOfAirTerminalNodes > state.dataBranchNodeConnections->MaxNumOfAirTerminalNodes) {
727 19 : state.dataBranchNodeConnections->AirTerminalNodeConnections.resize(state.dataBranchNodeConnections->MaxNumOfAirTerminalNodes +=
728 : EqNodeConnectionAlloc);
729 9891 : } else if (state.dataBranchNodeConnections->NumOfAirTerminalNodes == 1) {
730 542 : state.dataBranchNodeConnections->AirTerminalNodeConnections.allocate(EqNodeConnectionAlloc);
731 542 : state.dataBranchNodeConnections->MaxNumOfAirTerminalNodes = EqNodeConnectionAlloc;
732 : }
733 :
734 : // Check out AirTerminal inlet/outlet nodes
735 29730 : bool Found = Util::FindItemInList(NodeName,
736 9910 : state.dataBranchNodeConnections->AirTerminalNodeConnections,
737 : &EqNodeConnectionDef::NodeName,
738 9910 : state.dataBranchNodeConnections->NumOfAirTerminalNodes - 1);
739 9910 : if (Found != 0) { // Nodename already used
740 0 : ShowSevereError(state, fmt::format("{}{}=\"{}\" node name duplicated", RoutineName, ObjectType, ObjectName));
741 0 : ShowContinueError(state, format("NodeName=\"{}\", entered as type={}", NodeName, conTypeStr));
742 0 : ShowContinueError(state, fmt::format("In Field={}", InputFieldName));
743 0 : ShowContinueError(state,
744 0 : format("NodeName=\"{}\", entered as type={}", NodeName, ConnectionTypeNamesUC[static_cast<int>(ConnectionType)]));
745 0 : ShowContinueError(state, format("In Field={}", InputFieldName));
746 0 : ShowContinueError(
747 : state,
748 0 : format("Already used in {}=\"{}\".", objTypeStr, state.dataBranchNodeConnections->AirTerminalNodeConnections(Found).ObjectName));
749 0 : ShowContinueError(
750 : state,
751 0 : format(" as type={}, In Field={}",
752 0 : ConnectionTypeNamesUC[static_cast<int>(state.dataBranchNodeConnections->AirTerminalNodeConnections(Found).ConnectionType)],
753 0 : state.dataBranchNodeConnections->AirTerminalNodeConnections(Found).InputFieldName));
754 0 : ErrorsFoundHere = true;
755 : } else {
756 9910 : state.dataBranchNodeConnections->AirTerminalNodeConnections(state.dataBranchNodeConnections->NumOfAirTerminalNodes).NodeName =
757 9910 : NodeName;
758 9910 : state.dataBranchNodeConnections->AirTerminalNodeConnections(state.dataBranchNodeConnections->NumOfAirTerminalNodes).ObjectType =
759 : ObjectType;
760 9910 : state.dataBranchNodeConnections->AirTerminalNodeConnections(state.dataBranchNodeConnections->NumOfAirTerminalNodes).ObjectName =
761 9910 : ObjectName;
762 9910 : state.dataBranchNodeConnections->AirTerminalNodeConnections(state.dataBranchNodeConnections->NumOfAirTerminalNodes).ConnectionType =
763 : ConnectionType;
764 9910 : state.dataBranchNodeConnections->AirTerminalNodeConnections(state.dataBranchNodeConnections->NumOfAirTerminalNodes).InputFieldName =
765 9910 : InputFieldName;
766 : }
767 : } else {
768 0 : ShowSevereError(state, fmt::format("{}{} , Developer Error: Input Field Name not included.", RoutineName, objTypeStr));
769 0 : ShowContinueError(state, "Node names not checked for duplication.");
770 : }
771 : }
772 :
773 297884 : if (ErrorsFoundHere) {
774 0 : errFlag = true;
775 : }
776 297884 : }
777 :
778 24 : void OverrideNodeConnectionType(
779 : EnergyPlusData &state,
780 : int const NodeNumber, // Number for this Node
781 : std::string const &NodeName, // Name of this Node
782 : DataLoopNode::ConnectionObjectType const ObjectType, // Type of object this Node is connected to (e.g. Chiller:Electric)
783 : std::string const &ObjectName, // Name of object this Node is connected to (e.g. MyChiller)
784 : DataLoopNode::ConnectionType const ConnectionType, // Connection Type for this Node (must be valid)
785 : NodeInputManager::CompFluidStream const FluidStream, // Count on Fluid Streams
786 : bool const IsParent, // True when node is a parent node
787 : bool &errFlag // Will be True if errors already detected or if errors found here
788 : )
789 : {
790 :
791 : // SUBROUTINE INFORMATION:
792 : // AUTHOR M. J. Witte
793 : // DATE WRITTEN June 2016
794 :
795 : // PURPOSE:
796 : // This subroutine modifies an existing node connection in the Node Connection data structure. This
797 : // structure is intended to help with HVAC diagramming as well as validation of nodes. This function
798 : // is a based on RegisterNodeConnection.
799 :
800 : static constexpr std::string_view RoutineName("ModifyNodeConnectionType: ");
801 :
802 24 : if ((ConnectionType == DataLoopNode::ConnectionType::Invalid) || (ConnectionType == DataLoopNode::ConnectionType::Num)) {
803 0 : ShowSevereError(state, format("{}{}{}", RoutineName, "Invalid ConnectionType=", ConnectionType));
804 0 : ShowContinueError(
805 : state,
806 0 : format("Occurs for Node={}, ObjectType={}, ObjectName={}", NodeName, ConnectionTypeNames[static_cast<int>(ObjectType)], ObjectName));
807 0 : errFlag = true;
808 : }
809 :
810 24 : int Found = 0;
811 1572 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Count) {
812 1572 : if (state.dataBranchNodeConnections->NodeConnections(Count).NodeNumber != NodeNumber) continue;
813 65 : if (state.dataBranchNodeConnections->NodeConnections(Count).ObjectType != ObjectType) continue;
814 46 : if (!Util::SameString(state.dataBranchNodeConnections->NodeConnections(Count).ObjectName, ObjectName)) continue;
815 24 : if (state.dataBranchNodeConnections->NodeConnections(Count).FluidStream != FluidStream) continue;
816 24 : if ((state.dataBranchNodeConnections->NodeConnections(Count).ObjectIsParent != IsParent)) continue;
817 24 : Found = Count;
818 24 : break;
819 : }
820 :
821 24 : if (Found > 0) {
822 24 : state.dataBranchNodeConnections->NodeConnections(Found).ConnectionType = ConnectionType;
823 : } else {
824 0 : ShowSevereError(state, format("{}{}", RoutineName, "Existing node connection not found."));
825 0 : ShowContinueError(
826 : state,
827 0 : format("Occurs for Node={}, ObjectType={}, ObjectName={}", NodeName, ConnectionTypeNames[static_cast<int>(ObjectType)], ObjectName));
828 0 : errFlag = true;
829 : }
830 24 : }
831 :
832 795 : void CheckNodeConnections(EnergyPlusData &state, bool &ErrorsFound)
833 : {
834 :
835 : // SUBROUTINE INFORMATION:
836 : // AUTHOR Linda Lawrie
837 : // DATE WRITTEN March 2004
838 : // MODIFIED na
839 : // RE-ENGINEERED na
840 :
841 : // PURPOSE OF THIS SUBROUTINE:
842 : // This subroutine processes the node connection data structure looking at:
843 : // 1. In the NodeConnections list, for any node which appears as a sensor or an
844 : // actuator, the same node must also appear in the connections list at least once
845 : // as a node type which is not sensor or actuator or outsideair.
846 : // 2. In the NodeConnections list, for any node which appears as a setpoint, the
847 : // same node must also appear in the connections list at least once as a node type
848 : // which is not a setpoint or outsideair.
849 : // 3. Every ZoneInlet must appear as an outlet from something, otherwise it will
850 : // do nothing.
851 : // 4. Every ZoneExhaust must appear as an inlet to something,
852 : // otherwise it will do nothing.
853 : // 5. Every inlet node should match either an Outlet, ZoneReturn, ZoneExhaust, ReliefAir,
854 : // or OutsideAir node.
855 : // With the current data structure, when checking inlets:
856 : // a) If an InletNode's object is AirLoopHVAC, CondenserLoop, or PlantLoop, then skip the test.
857 : // b) If an InletNode's object is not one of the above types, it is valid if the
858 : // same node name appears as an INLET to an AirLoopHVAC, CondenserLoop, or PlantLoop.
859 : // 6. Any given node can only be an inlet once in the list of Non-Parent Node Connections
860 : // 7. Any given node can only be an outlet once in the list of Non-Parent Node Connections
861 : // 8. non-parent outlet nodes -- must never be an outlet more than once
862 : // 9. nodes of type OutsideAirReference must be registered as DataLoopNode::NodeConnectionType::OutsideAir
863 : // 10. fluid streams cannot have multiple inlet/outlet nodes on same component
864 : // 11. zone nodes may not be used as anything else except as a setpoint, sensor or actuator node
865 :
866 : // METHODOLOGY EMPLOYED:
867 : // Needs description, as appropriate.
868 :
869 : // Using/Aliasing
870 :
871 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
872 : bool IsValid;
873 : bool IsInlet;
874 : bool IsOutlet;
875 : bool MatchedAtLeastOne;
876 : int ErrorCounter;
877 795 : Array1D_int FluidStreamInletCount;
878 795 : Array1D_int FluidStreamOutletCount;
879 795 : Array1D_int NodeObjects;
880 795 : Array1D_bool FluidStreamCounts;
881 :
882 795 : ErrorCounter = 0;
883 :
884 : // Check 1 -- check sensor and actuator nodes
885 180109 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
886 179314 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::Sensor) continue;
887 9890 : IsValid = false;
888 7712975 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
889 7703085 : if (Loop1 == Loop2) continue;
890 7693195 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
891 7693195 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber)
892 7646586 : continue;
893 93177 : if ((state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Actuator) ||
894 46568 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Sensor)) {
895 10287 : continue;
896 : }
897 :
898 36322 : IsValid = true;
899 : }
900 9890 : if (!IsValid) {
901 0 : ShowSevereError(state,
902 0 : format("Node Connection Error, Node=\"{}\", Sensor node did not find a matching node of appropriate type (other than "
903 : "Actuator or Sensor).",
904 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
905 :
906 0 : ShowContinueError(state,
907 0 : format("Reference Object={}, Name={}",
908 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
909 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
910 0 : ++ErrorCounter;
911 0 : ErrorsFound = true;
912 : }
913 : }
914 :
915 180109 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
916 179314 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::Actuator) continue;
917 2986 : IsValid = false;
918 2767053 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
919 2764067 : if (Loop1 == Loop2) continue;
920 2761081 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
921 2761081 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber)
922 2755150 : continue;
923 :
924 5931 : if ((state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Actuator) ||
925 11821 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Sensor) ||
926 5890 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::OutsideAir)) {
927 1096 : continue;
928 : }
929 :
930 4835 : IsValid = true;
931 : }
932 2986 : if (!IsValid) {
933 0 : ShowSevereError(state,
934 0 : format("Node Connection Error, Node=\"{}\", Actuator node did not find a matching node of appropriate type (other than "
935 : "Actuator, Sensor, OutsideAir).",
936 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
937 :
938 0 : ShowContinueError(state,
939 0 : format("Reference Object={}, Name={}",
940 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
941 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
942 0 : ++ErrorCounter;
943 0 : ErrorsFound = true;
944 : }
945 : }
946 :
947 : // Check 2 -- setpoint nodes
948 : // Check 2a -- setpoint node must also be an inlet or an outlet (CR8212)
949 180109 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
950 179314 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::SetPoint) continue;
951 5066 : IsValid = false;
952 5066 : IsInlet = false;
953 5066 : IsOutlet = false;
954 3002736 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
955 2997670 : if (Loop1 == Loop2) continue;
956 2992604 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
957 2992604 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber)
958 2969393 : continue;
959 46238 : if ((state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::SetPoint) ||
960 23027 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::OutsideAir)) {
961 184 : continue;
962 : }
963 :
964 23027 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Inlet) {
965 3547 : IsInlet = true;
966 19480 : } else if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Outlet) {
967 10391 : IsOutlet = true;
968 : }
969 23027 : IsValid = true;
970 : }
971 5066 : if (!IsValid) {
972 0 : ShowSevereError(state,
973 0 : format("Node Connection Error, Node=\"{}\", Setpoint node did not find a matching node of appropriate type (other than "
974 : "Setpoint, OutsideAir).",
975 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
976 :
977 0 : ShowContinueError(state,
978 0 : format("Reference Object={}, Name={}",
979 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
980 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
981 0 : ++ErrorCounter;
982 0 : ErrorsFound = true;
983 : }
984 5066 : if (!IsInlet && !IsOutlet) {
985 0 : ShowSevereError(state,
986 0 : format("Node Connection Error, Node=\"{}\", Setpoint node did not find a matching node of type Inlet or Outlet.",
987 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
988 0 : ShowContinueError(state, "It appears this node is not part of the HVAC system.");
989 :
990 0 : ShowContinueError(state,
991 0 : format("Reference Object={}, Name={}",
992 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
993 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
994 0 : ++ErrorCounter;
995 : }
996 : }
997 :
998 : // Check 2a -- setpoint node must also be an inlet or an outlet (CR8212)
999 :
1000 : // Check 3 -- zone inlet nodes -- must be an outlet somewhere
1001 180109 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1002 179314 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::ZoneInlet) continue;
1003 4471 : IsValid = false;
1004 4357357 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1005 4352886 : if (Loop1 == Loop2) continue;
1006 4348415 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
1007 4348415 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber)
1008 4336510 : continue;
1009 11905 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::Outlet) continue;
1010 11280 : IsValid = true;
1011 : }
1012 4471 : if (!IsValid) {
1013 0 : ShowSevereError(state,
1014 0 : format("Node Connection Error, Node=\"{}\", ZoneInlet node did not find an outlet node.",
1015 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1016 :
1017 0 : ShowContinueError(state,
1018 0 : format("Reference Object={}, Name={}",
1019 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1020 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1021 0 : ++ErrorCounter;
1022 : }
1023 : }
1024 :
1025 : // Check 4 -- zone exhaust nodes -- must be an inlet somewhere
1026 180109 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1027 179314 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::ZoneExhaust) continue;
1028 849 : IsValid = false;
1029 1099045 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1030 1098196 : if (Loop1 == Loop2) continue;
1031 1097347 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
1032 1097347 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber)
1033 1095877 : continue;
1034 1470 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::Inlet) continue;
1035 1456 : IsValid = true;
1036 : }
1037 849 : if (!IsValid) {
1038 0 : ShowSevereError(state,
1039 0 : format("Node Connection Error, Node=\"{}\", ZoneExhaust node did not find a matching inlet node.",
1040 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1041 :
1042 0 : ShowContinueError(state,
1043 0 : format("Reference Object={}, Name={}",
1044 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1045 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1046 0 : ++ErrorCounter;
1047 : }
1048 : }
1049 :
1050 : // Check 5 -- return plenum induced air outlet nodes -- must be an inlet somewhere
1051 180109 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1052 179314 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::InducedAir) continue;
1053 26 : IsValid = false;
1054 17817 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1055 17791 : if (Loop1 == Loop2) continue;
1056 17765 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
1057 17765 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber)
1058 17718 : continue;
1059 47 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::Inlet) continue;
1060 47 : IsValid = true;
1061 : }
1062 26 : if (!IsValid) {
1063 0 : ShowSevereError(state,
1064 0 : format("Node Connection Error, Node=\"{}\", Return plenum induced air outlet node did not find a matching inlet node.",
1065 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1066 :
1067 0 : ShowContinueError(state,
1068 0 : format("Reference Object={}, Name={}",
1069 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1070 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1071 0 : ++ErrorCounter;
1072 0 : ErrorsFound = true;
1073 : }
1074 : }
1075 :
1076 : // Check 6 -- every inlet should have a matching outlet, zonereturn, zoneexhaust, induced air, reliefair or outsideair
1077 : // a) If an InletNode's object is AirLoopHVAC, CondenserLoop, or PlantLoop, then skip the test.
1078 : // b) If an InletNode's object is not one of the above types, it is valid if the
1079 : // same node name appears as an INLET to an AirLoopHVAC, CondenserLoop, or PlantLoop.
1080 180109 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1081 179314 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::Inlet) continue;
1082 67692 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType == DataLoopNode::ConnectionObjectType::AirLoopHVAC ||
1083 132446 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType == DataLoopNode::ConnectionObjectType::CondenserLoop ||
1084 64754 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType == DataLoopNode::ConnectionObjectType::PlantLoop)
1085 4716 : continue;
1086 62976 : IsValid = false;
1087 62976 : MatchedAtLeastOne = false;
1088 53753362 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1089 53690386 : if (Loop1 == Loop2) continue;
1090 53627410 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
1091 53627410 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber)
1092 53499468 : continue;
1093 :
1094 127942 : if ((state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Outlet) ||
1095 69835 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::ZoneReturn) ||
1096 66202 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::ZoneExhaust) ||
1097 64746 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::InducedAir) ||
1098 262429 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::ReliefAir) ||
1099 64652 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::OutsideAir)) {
1100 65151 : MatchedAtLeastOne = true;
1101 65151 : continue;
1102 : }
1103 :
1104 108091 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Inlet &&
1105 45300 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType == DataLoopNode::ConnectionObjectType::AirLoopHVAC ||
1106 40402 : state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType == DataLoopNode::ConnectionObjectType::CondenserLoop ||
1107 39370 : state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType == DataLoopNode::ConnectionObjectType::PlantLoop)) {
1108 9486 : MatchedAtLeastOne = true;
1109 9486 : continue;
1110 : }
1111 53305 : IsValid = false;
1112 : }
1113 62976 : if (!IsValid && !MatchedAtLeastOne) {
1114 4 : ShowSevereError(state,
1115 4 : format("{}{}{}",
1116 : "Node Connection Error, Node=\"",
1117 2 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName,
1118 : R"(", Inlet node did not find an appropriate matching "outlet" node.)"));
1119 2 : ShowContinueError(state, "If this is an outdoor air inlet node, it must be listed in an OutdoorAir:Node or OutdoorAir:NodeList object.");
1120 :
1121 4 : ShowContinueError(state,
1122 4 : format("Reference Object={}, Name={}",
1123 2 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1124 2 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1125 2 : ++ErrorCounter;
1126 : }
1127 : }
1128 :
1129 : // Check 7 -- non-parent inlet nodes -- must never be an inlet more than once
1130 180109 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1131 : // Only non-parent node connections
1132 179314 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectIsParent) continue;
1133 123895 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::Inlet) continue;
1134 14101799 : for (int Loop2 = Loop1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1135 14056791 : if (Loop1 == Loop2) continue;
1136 14011780 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectIsParent) continue;
1137 11453202 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::Inlet) continue;
1138 5158077 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber ==
1139 5158077 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber) {
1140 6 : ShowSevereError(state,
1141 6 : format("Node Connection Error, Node=\"{}\", The same node appears as a non-parent Inlet node more than once.",
1142 3 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1143 :
1144 6 : ShowContinueError(
1145 : state,
1146 6 : format("Reference Object={}, Name={}",
1147 3 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1148 3 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1149 :
1150 6 : ShowContinueError(
1151 : state,
1152 6 : format("Reference Object={}, Name={}",
1153 3 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType)],
1154 3 : state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectName));
1155 3 : ++ErrorCounter;
1156 3 : break;
1157 : }
1158 : }
1159 : }
1160 :
1161 : // Check 8 -- non-parent outlet nodes -- must never be an outlet more than once
1162 180109 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1163 : // Only non-parent node connections
1164 179314 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectIsParent) continue;
1165 123895 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::Outlet) continue;
1166 43796 : IsValid = true;
1167 14748259 : for (int Loop2 = Loop1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1168 14704464 : if (Loop1 == Loop2) continue;
1169 14660668 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectIsParent) continue;
1170 12021389 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::Outlet) continue;
1171 4852368 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber ==
1172 4852368 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber) {
1173 : // Skip if one of the
1174 2 : ShowSevereError(state,
1175 2 : format("Node Connection Error, Node=\"{}\", The same node appears as a non-parent Outlet node more than once.",
1176 1 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1177 :
1178 2 : ShowContinueError(
1179 : state,
1180 2 : format("Reference Object={}, Name={}",
1181 1 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1182 1 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1183 :
1184 2 : ShowContinueError(
1185 : state,
1186 2 : format("Reference Object={}, Name={}",
1187 1 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType)],
1188 1 : state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectName));
1189 :
1190 1 : ++ErrorCounter;
1191 1 : break;
1192 : }
1193 : }
1194 : }
1195 :
1196 : // Check 9 -- nodes of type OutsideAirReference must be registered as DataLoopNode::NodeConnectionType::OutsideAir
1197 180109 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1198 179314 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::OutsideAirReference) continue;
1199 544 : IsValid = false;
1200 158686 : for (int Loop2 = 1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1201 158686 : if (Loop1 == Loop2) continue;
1202 158648 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeNumber !=
1203 158648 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeNumber)
1204 158094 : continue;
1205 554 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType != DataLoopNode::ConnectionType::OutsideAir) continue;
1206 544 : IsValid = true;
1207 544 : break;
1208 : }
1209 544 : if (!IsValid) {
1210 0 : ShowSevereError(state,
1211 0 : format("{}{}{}",
1212 : "Node Connection Error, Node=\"",
1213 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName,
1214 : R"(", Outdoor Air Reference did not find an appropriate "outdoor air" node.)"));
1215 0 : ShowContinueError(state, "This node must be listed in an OutdoorAir:Node or OutdoorAir:NodeList object in order to set its conditions.");
1216 :
1217 0 : ShowContinueError(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 : ++ErrorCounter;
1223 : }
1224 : }
1225 :
1226 : // Check 10 -- fluid streams cannot have multiple inlet/outlet nodes on same component
1227 : // can have multiple inlets with one outlet or vice versa but cannot have multiple both inlet and outlet
1228 795 : if (state.dataBranchNodeConnections->NumOfNodeConnections > 0) {
1229 727 : int MaxFluidStream = static_cast<int>(maxval(state.dataBranchNodeConnections->NodeConnections, &NodeConnectionDef::FluidStream));
1230 727 : FluidStreamInletCount.allocate(MaxFluidStream);
1231 727 : FluidStreamOutletCount.allocate(MaxFluidStream);
1232 727 : FluidStreamCounts.allocate(MaxFluidStream);
1233 727 : NodeObjects.allocate(state.dataBranchNodeConnections->NumOfNodeConnections + 1);
1234 727 : FluidStreamInletCount = 0;
1235 727 : FluidStreamOutletCount = 0;
1236 727 : NodeObjects = 0;
1237 727 : FluidStreamCounts = false;
1238 : // Following code relies on node connections for single object type/name being grouped together
1239 727 : int Object = 1;
1240 727 : int EndConnect = 0;
1241 727 : int NumObjects = 2;
1242 727 : NodeObjects(1) = 1;
1243 179314 : while (Object < state.dataBranchNodeConnections->NumOfNodeConnections) {
1244 178587 : if (state.dataBranchNodeConnections->NodeConnections(Object).ObjectType !=
1245 337865 : state.dataBranchNodeConnections->NodeConnections(Object + 1).ObjectType ||
1246 159278 : state.dataBranchNodeConnections->NodeConnections(Object).ObjectName !=
1247 159278 : state.dataBranchNodeConnections->NodeConnections(Object + 1).ObjectName) {
1248 66709 : EndConnect = Object + 1;
1249 66709 : NodeObjects(NumObjects) = EndConnect;
1250 : // if (Object + 1 < state.dataBranchNodeConnections->NumOfNodeConnections) ++NumObjects;
1251 66709 : ++NumObjects;
1252 : }
1253 178587 : ++Object;
1254 : }
1255 727 : NodeObjects(NumObjects) = state.dataBranchNodeConnections->NumOfNodeConnections + 1;
1256 : // NodeObjects now contains each consecutive object...
1257 68163 : for (Object = 1; Object <= NumObjects - 1; ++Object) {
1258 67436 : IsValid = true;
1259 67436 : FluidStreamInletCount = 0;
1260 67436 : FluidStreamOutletCount = 0;
1261 67436 : FluidStreamCounts = false;
1262 67436 : int Loop1 = NodeObjects(Object);
1263 67436 : if (state.dataBranchNodeConnections->NumOfNodeConnections < 2) continue;
1264 67436 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectIsParent) continue;
1265 41941 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType == DataLoopNode::ConnectionType::Inlet) {
1266 22419 : ++FluidStreamInletCount(static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).FluidStream));
1267 19522 : } else if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType == DataLoopNode::ConnectionType::Outlet) {
1268 7383 : ++FluidStreamOutletCount(static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).FluidStream));
1269 : }
1270 125922 : for (int Loop2 = Loop1 + 1; Loop2 <= NodeObjects(Object + 1) - 1; ++Loop2) {
1271 83981 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectIsParent) continue;
1272 81798 : if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Inlet) {
1273 22588 : ++FluidStreamInletCount(static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop2).FluidStream));
1274 59210 : } else if (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Outlet) {
1275 36413 : ++FluidStreamOutletCount(static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop2).FluidStream));
1276 : }
1277 : }
1278 534402 : for (int Loop2 = 1; Loop2 <= MaxFluidStream; ++Loop2) {
1279 492461 : if (FluidStreamInletCount(Loop2) > 1 && FluidStreamOutletCount(Loop2) > 1) {
1280 0 : IsValid = false;
1281 0 : FluidStreamCounts(Loop2) = true;
1282 : }
1283 : }
1284 41941 : if (!IsValid) {
1285 :
1286 0 : ShowSevereError(
1287 : state,
1288 0 : format("(Developer) Node Connection Error, Object={}:{}",
1289 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1290 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1291 :
1292 0 : ShowContinueError(state, "Object has multiple connections on both inlet and outlet fluid streams.");
1293 0 : for (int Loop2 = 1; Loop2 <= MaxFluidStream; ++Loop2) {
1294 0 : if (FluidStreamCounts(Loop2)) ShowContinueError(state, format("...occurs in Fluid Stream [{}].", Loop2));
1295 : }
1296 0 : ++ErrorCounter;
1297 0 : ErrorsFound = true;
1298 : }
1299 : }
1300 727 : FluidStreamInletCount.deallocate();
1301 727 : FluidStreamOutletCount.deallocate();
1302 727 : FluidStreamCounts.deallocate();
1303 727 : NodeObjects.deallocate();
1304 : }
1305 :
1306 : // Check 11 - zone nodes may not be used as anything else except as a setpoint, sensor or actuator node
1307 180109 : for (int Loop1 = 1; Loop1 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop1) {
1308 179314 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).ConnectionType != DataLoopNode::ConnectionType::ZoneNode) continue;
1309 4620 : IsValid = true;
1310 3008244 : for (int Loop2 = Loop1; Loop2 <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop2) {
1311 3003624 : if (Loop1 == Loop2) continue;
1312 2999004 : if (state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName ==
1313 2999004 : state.dataBranchNodeConnections->NodeConnections(Loop2).NodeName) {
1314 :
1315 659 : if ((state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Actuator) ||
1316 659 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::Sensor) ||
1317 0 : (state.dataBranchNodeConnections->NodeConnections(Loop2).ConnectionType == DataLoopNode::ConnectionType::SetPoint)) {
1318 659 : continue;
1319 : }
1320 :
1321 0 : ShowSevereError(state,
1322 0 : format("Node Connection Error, Node Name=\"{}\", The same zone node appears more than once.",
1323 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).NodeName));
1324 :
1325 0 : ShowContinueError(
1326 : state,
1327 0 : format("Reference Object={}, Object Name={}",
1328 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectType)],
1329 0 : state.dataBranchNodeConnections->NodeConnections(Loop1).ObjectName));
1330 :
1331 0 : ShowContinueError(
1332 : state,
1333 0 : format("Reference Object={}, Object Name={}",
1334 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectType)],
1335 0 : state.dataBranchNodeConnections->NodeConnections(Loop2).ObjectName));
1336 :
1337 0 : ++ErrorCounter;
1338 0 : ErrorsFound = true;
1339 : }
1340 : }
1341 : }
1342 :
1343 795 : state.dataBranchNodeConnections->NumNodeConnectionErrors += ErrorCounter;
1344 795 : }
1345 :
1346 60149 : bool IsParentObject(EnergyPlusData &state, DataLoopNode::ConnectionObjectType const ComponentType, std::string const &ComponentName)
1347 : {
1348 :
1349 : // FUNCTION INFORMATION:
1350 : // AUTHOR Linda Lawrie
1351 : // DATE WRITTEN May 2005
1352 :
1353 : // PURPOSE OF THIS FUNCTION:
1354 : // This routine determines if a component name is a parent node.
1355 :
1356 : // METHODOLOGY EMPLOYED:
1357 : // Traverses CompSet structure.
1358 :
1359 : // Return value
1360 60149 : bool IsParent = false; // True if this combination is a parent
1361 :
1362 38304123 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Loop) {
1363 39789552 : if (state.dataBranchNodeConnections->NodeConnections(Loop).ObjectType == ComponentType &&
1364 1490537 : state.dataBranchNodeConnections->NodeConnections(Loop).ObjectName == ComponentName) {
1365 55041 : if (state.dataBranchNodeConnections->NodeConnections(Loop).ObjectIsParent) {
1366 22780 : IsParent = true;
1367 : }
1368 55041 : break;
1369 : }
1370 : }
1371 60149 : if (!IsParent) {
1372 37369 : IsParent = IsParentObjectCompSet(state, ComponentType, ComponentName);
1373 : }
1374 :
1375 60149 : return IsParent;
1376 : }
1377 :
1378 9185 : int WhichParentSet(EnergyPlusData &state, DataLoopNode::ConnectionObjectType const ComponentType, std::string const &ComponentName)
1379 : {
1380 :
1381 : // FUNCTION INFORMATION:
1382 : // AUTHOR Linda Lawrie
1383 : // DATE WRITTEN May 2005
1384 :
1385 : // PURPOSE OF THIS FUNCTION:
1386 : // This routine determines which parent node list (number) for a given component name
1387 : // and type.
1388 :
1389 : // Return value
1390 9185 : int WhichOne = 0;
1391 :
1392 1044444 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumOfActualParents; ++Loop) {
1393 1154855 : if (state.dataBranchNodeConnections->ParentNodeList(Loop).ComponentType == ComponentType &&
1394 111917 : state.dataBranchNodeConnections->ParentNodeList(Loop).ComponentName == ComponentName) {
1395 7679 : WhichOne = Loop;
1396 7679 : break;
1397 : }
1398 : }
1399 :
1400 9185 : return WhichOne;
1401 : }
1402 :
1403 9185 : void GetParentData(EnergyPlusData &state,
1404 : DataLoopNode::ConnectionObjectType const ComponentType,
1405 : std::string const &ComponentName,
1406 : std::string &InletNodeName,
1407 : int &InletNodeNum,
1408 : std::string &OutletNodeName,
1409 : int &OutletNodeNum,
1410 : bool &ErrorsFound)
1411 : {
1412 :
1413 : // SUBROUTINE INFORMATION:
1414 : // AUTHOR Linda Lawrie
1415 : // DATE WRITTEN May 2005
1416 :
1417 : // PURPOSE OF THIS SUBROUTINE:
1418 : // This routine gets node data for a given Parent Component Type and Name Name.
1419 :
1420 : // METHODOLOGY EMPLOYED:
1421 : // Traverses CompSet structure.
1422 :
1423 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1424 9185 : bool ErrInObject = false;
1425 :
1426 9185 : InletNodeName = std::string();
1427 9185 : InletNodeNum = 0;
1428 9185 : OutletNodeName = std::string();
1429 9185 : OutletNodeNum = 0;
1430 9185 : ErrInObject = false;
1431 :
1432 9185 : int Which = WhichParentSet(state, ComponentType, ComponentName);
1433 9185 : if (Which != 0) {
1434 7679 : InletNodeName = state.dataBranchNodeConnections->ParentNodeList(Which).InletNodeName;
1435 7679 : OutletNodeName = state.dataBranchNodeConnections->ParentNodeList(Which).OutletNodeName;
1436 : // Get Node Numbers
1437 7679 : InletNodeNum =
1438 7679 : Util::FindItemInList(InletNodeName, state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}), state.dataLoopNodes->NumOfNodes);
1439 7679 : OutletNodeNum =
1440 7679 : Util::FindItemInList(OutletNodeName, state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}), state.dataLoopNodes->NumOfNodes);
1441 1506 : } else if (IsParentObjectCompSet(state, ComponentType, ComponentName)) {
1442 1506 : Which = WhichCompSet(state, ComponentType, ComponentName);
1443 1506 : if (Which != 0) {
1444 1506 : InletNodeName = state.dataBranchNodeConnections->CompSets(Which).InletNodeName;
1445 1506 : OutletNodeName = state.dataBranchNodeConnections->CompSets(Which).OutletNodeName;
1446 1506 : InletNodeNum = Util::FindItemInList(
1447 3012 : InletNodeName, state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}), state.dataLoopNodes->NumOfNodes);
1448 1506 : OutletNodeNum = Util::FindItemInList(
1449 3012 : OutletNodeName, state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}), state.dataLoopNodes->NumOfNodes);
1450 : } else {
1451 0 : ErrInObject = true;
1452 0 : ShowWarningError(state,
1453 0 : format("GetParentData: Component Type={}, Component Name={} not found.",
1454 0 : ConnectionObjectTypeNames[static_cast<int>(ComponentType)],
1455 : ComponentName));
1456 : }
1457 : } else {
1458 0 : ErrInObject = true;
1459 0 : ShowWarningError(state,
1460 0 : format("GetParentData: Component Type={}, Component Name={} not found.",
1461 0 : ConnectionObjectTypeNames[static_cast<int>(ComponentType)],
1462 : ComponentName));
1463 : }
1464 :
1465 9185 : if (ErrInObject) ErrorsFound = true;
1466 9185 : }
1467 :
1468 38875 : bool IsParentObjectCompSet(EnergyPlusData &state, DataLoopNode::ConnectionObjectType const ComponentType, std::string const &ComponentName)
1469 : {
1470 :
1471 : // FUNCTION INFORMATION:
1472 : // AUTHOR Linda Lawrie
1473 : // DATE WRITTEN May 2005
1474 :
1475 : // PURPOSE OF THIS FUNCTION:
1476 : // This routine determines if a component name is a parent node.
1477 :
1478 : // METHODOLOGY EMPLOYED:
1479 : // Traverses CompSet structure.
1480 :
1481 : // Return value
1482 38875 : bool IsParent = false; // True if this combination is a parent
1483 :
1484 5434591 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumCompSets; ++Loop) {
1485 5622742 : if (state.dataBranchNodeConnections->CompSets(Loop).ParentObjectType == ComponentType &&
1486 211560 : state.dataBranchNodeConnections->CompSets(Loop).ParentCName == ComponentName) {
1487 15466 : IsParent = true;
1488 15466 : break;
1489 : }
1490 : }
1491 :
1492 38875 : return IsParent;
1493 : }
1494 :
1495 1506 : int WhichCompSet(EnergyPlusData &state, DataLoopNode::ConnectionObjectType const ComponentType, std::string const &ComponentName)
1496 : {
1497 :
1498 : // FUNCTION INFORMATION:
1499 : // AUTHOR Linda Lawrie
1500 : // DATE WRITTEN May 2005
1501 :
1502 : // PURPOSE OF THIS FUNCTION:
1503 : // This routine determines which comp set (number) for a given component name
1504 : // and type.
1505 :
1506 : // METHODOLOGY EMPLOYED:
1507 : // Traverses CompSet structure.
1508 :
1509 : // Return value
1510 1506 : int WhichOne = 0;
1511 :
1512 24528 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumCompSets; ++Loop) {
1513 31356 : if (state.dataBranchNodeConnections->CompSets(Loop).ComponentObjectType == ComponentType &&
1514 6828 : state.dataBranchNodeConnections->CompSets(Loop).CName == ComponentName) {
1515 1506 : WhichOne = Loop;
1516 1506 : break;
1517 : }
1518 : }
1519 :
1520 1506 : return WhichOne;
1521 : }
1522 :
1523 18403 : int GetNumChildren(EnergyPlusData &state, DataLoopNode::ConnectionObjectType const ComponentType, std::string const &ComponentName)
1524 : {
1525 :
1526 : // FUNCTION INFORMATION:
1527 : // AUTHOR Linda Lawrie
1528 : // DATE WRITTEN May 2005
1529 : // MODIFIED na
1530 : // RE-ENGINEERED na
1531 :
1532 : // PURPOSE OF THIS FUNCTION:
1533 : // This routine counts the number of children for a parent Component Set.
1534 :
1535 : // METHODOLOGY EMPLOYED:
1536 : // Traverses CompSet structure.
1537 :
1538 : // Return value
1539 : int NumChildren;
1540 :
1541 18403 : NumChildren = 0;
1542 18403 : if (IsParentObject(state, ComponentType, ComponentName)) {
1543 3019072 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumCompSets; ++Loop) {
1544 3572694 : if (state.dataBranchNodeConnections->CompSets(Loop).ParentObjectType == ComponentType &&
1545 571992 : state.dataBranchNodeConnections->CompSets(Loop).ParentCName == ComponentName) {
1546 25100 : ++NumChildren;
1547 : }
1548 : }
1549 : }
1550 :
1551 18403 : return NumChildren;
1552 : }
1553 :
1554 4893 : void GetComponentData(EnergyPlusData &state,
1555 : DataLoopNode::ConnectionObjectType const ComponentType,
1556 : std::string const &ComponentName,
1557 : bool &IsParent, // true or false
1558 : int &NumInlets,
1559 : Array1D_string &InletNodeNames,
1560 : Array1D_int &InletNodeNums,
1561 : Array1D<NodeInputManager::CompFluidStream> &InletFluidStreams,
1562 : int &NumOutlets,
1563 : Array1D_string &OutletNodeNames,
1564 : Array1D_int &OutletNodeNums,
1565 : Array1D<NodeInputManager::CompFluidStream> &OutletFluidStreams)
1566 : {
1567 :
1568 : // SUBROUTINE INFORMATION:
1569 : // AUTHOR Linda Lawrie
1570 : // DATE WRITTEN May 2005
1571 :
1572 : // PURPOSE OF THIS SUBROUTINE:
1573 : // This routine gets data for a given Component Type and Name Name.
1574 :
1575 : // METHODOLOGY EMPLOYED:
1576 : // Traverses CompSet structure.
1577 :
1578 4893 : if (allocated(InletNodeNames)) InletNodeNames.deallocate();
1579 4893 : if (allocated(InletNodeNums)) InletNodeNums.deallocate();
1580 4893 : if (allocated(InletFluidStreams)) InletFluidStreams.deallocate();
1581 4893 : if (allocated(OutletNodeNames)) OutletNodeNames.deallocate();
1582 4893 : if (allocated(OutletNodeNums)) OutletNodeNums.deallocate();
1583 4893 : if (allocated(OutletFluidStreams)) OutletFluidStreams.deallocate();
1584 :
1585 4893 : NumInlets = 0;
1586 4893 : NumOutlets = 0;
1587 :
1588 4893 : IsParent = false;
1589 4652614 : for (int Which = 1; Which <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Which) {
1590 4798362 : if (state.dataBranchNodeConnections->NodeConnections(Which).ObjectType != ComponentType ||
1591 150641 : state.dataBranchNodeConnections->NodeConnections(Which).ObjectName != ComponentName)
1592 4641497 : continue;
1593 6224 : if (state.dataBranchNodeConnections->NodeConnections(Which).ObjectIsParent) IsParent = true;
1594 6224 : if (state.dataBranchNodeConnections->NodeConnections(Which).ConnectionType == DataLoopNode::ConnectionType::Inlet) {
1595 1140 : ++NumInlets;
1596 5084 : } else if (state.dataBranchNodeConnections->NodeConnections(Which).ConnectionType == DataLoopNode::ConnectionType::Outlet) {
1597 4890 : ++NumOutlets;
1598 : }
1599 : }
1600 :
1601 4893 : InletNodeNames.allocate(NumInlets);
1602 4893 : InletNodeNums.allocate(NumInlets);
1603 4893 : InletFluidStreams.allocate(NumInlets);
1604 4893 : OutletNodeNames.allocate(NumOutlets);
1605 4893 : OutletNodeNums.allocate(NumOutlets);
1606 4893 : OutletFluidStreams.allocate(NumOutlets);
1607 :
1608 4893 : InletNodeNames = std::string();
1609 4893 : InletNodeNums = 0;
1610 4893 : InletFluidStreams = NodeInputManager::CompFluidStream::Invalid;
1611 4893 : OutletNodeNames = std::string();
1612 4893 : OutletNodeNums = 0;
1613 4893 : OutletFluidStreams = NodeInputManager::CompFluidStream::Invalid;
1614 4893 : NumInlets = 0;
1615 4893 : NumOutlets = 0;
1616 :
1617 4652614 : for (int Which = 1; Which <= state.dataBranchNodeConnections->NumOfNodeConnections; ++Which) {
1618 4798362 : if (state.dataBranchNodeConnections->NodeConnections(Which).ObjectType != ComponentType ||
1619 150641 : state.dataBranchNodeConnections->NodeConnections(Which).ObjectName != ComponentName)
1620 4641497 : continue;
1621 6224 : if (state.dataBranchNodeConnections->NodeConnections(Which).ConnectionType == DataLoopNode::ConnectionType::Inlet) {
1622 1140 : ++NumInlets;
1623 1140 : InletNodeNames(NumInlets) = state.dataBranchNodeConnections->NodeConnections(Which).NodeName;
1624 1140 : InletNodeNums(NumInlets) = state.dataBranchNodeConnections->NodeConnections(Which).NodeNumber;
1625 1140 : InletFluidStreams(NumInlets) = state.dataBranchNodeConnections->NodeConnections(Which).FluidStream;
1626 5084 : } else if (state.dataBranchNodeConnections->NodeConnections(Which).ConnectionType == DataLoopNode::ConnectionType::Outlet) {
1627 4890 : ++NumOutlets;
1628 4890 : OutletNodeNames(NumOutlets) = state.dataBranchNodeConnections->NodeConnections(Which).NodeName;
1629 4890 : OutletNodeNums(NumOutlets) = state.dataBranchNodeConnections->NodeConnections(Which).NodeNumber;
1630 4890 : OutletFluidStreams(NumOutlets) = state.dataBranchNodeConnections->NodeConnections(Which).FluidStream;
1631 : }
1632 : }
1633 4893 : }
1634 :
1635 9185 : void GetChildrenData(EnergyPlusData &state,
1636 : DataLoopNode::ConnectionObjectType const ComponentType,
1637 : std::string const &ComponentName,
1638 : int &NumChildren,
1639 : EPVector<DataLoopNode::ConnectionObjectType> &ChildrenCType,
1640 : Array1D_string &ChildrenCName,
1641 : Array1D_string &InletNodeName,
1642 : Array1D_int &InletNodeNum,
1643 : Array1D_string &OutletNodeName,
1644 : Array1D_int &OutletNodeNum,
1645 : bool &ErrorsFound)
1646 : {
1647 :
1648 : // SUBROUTINE INFORMATION:
1649 : // AUTHOR Linda Lawrie
1650 : // DATE WRITTEN May 2005
1651 :
1652 : // PURPOSE OF THIS SUBROUTINE:
1653 : // This routine gets children data for given parent node.
1654 :
1655 : // METHODOLOGY EMPLOYED:
1656 : // Traverses CompSet structure.
1657 :
1658 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1659 9185 : EPVector<DataLoopNode::ConnectionObjectType> ChildCType;
1660 9185 : Array1D_string ChildCName;
1661 9185 : Array1D_string ChildInNodeName;
1662 9185 : Array1D_string ChildOutNodeName;
1663 9185 : Array1D_int ChildInNodeNum;
1664 9185 : Array1D_int ChildOutNodeNum;
1665 : bool ErrInObject;
1666 :
1667 9185 : std::fill(ChildrenCType.begin(), ChildrenCType.end(), DataLoopNode::ConnectionObjectType::Invalid);
1668 9185 : ChildrenCName = std::string();
1669 9185 : InletNodeName = std::string();
1670 9185 : InletNodeNum = 0;
1671 9185 : OutletNodeName = std::string();
1672 9185 : OutletNodeNum = 0;
1673 9185 : ErrInObject = false;
1674 :
1675 9185 : if (IsParentObject(state, ComponentType, ComponentName)) {
1676 9185 : NumChildren = GetNumChildren(state, ComponentType, ComponentName);
1677 9185 : if (NumChildren == 0) {
1678 0 : ShowWarningError(state,
1679 0 : format("GetChildrenData: Parent Node has no children, node={}:{}.",
1680 0 : ConnectionObjectTypeNames[static_cast<int>(ComponentType)],
1681 : ComponentName));
1682 : } else {
1683 : int ParentInletNodeNum;
1684 : int ParentOutletNodeNum;
1685 9185 : std::string ParentInletNodeName;
1686 9185 : std::string ParentOutletNodeName;
1687 9185 : GetParentData(
1688 : state, ComponentType, ComponentName, ParentInletNodeName, ParentInletNodeNum, ParentOutletNodeName, ParentOutletNodeNum, ErrInObject);
1689 9185 : ChildCType.clear();
1690 9185 : ChildCType.allocate(NumChildren);
1691 9185 : ChildCName.allocate(NumChildren);
1692 9185 : ChildInNodeName.allocate(NumChildren);
1693 9185 : ChildOutNodeName.allocate(NumChildren);
1694 9185 : ChildInNodeNum.allocate(NumChildren);
1695 9185 : ChildOutNodeNum.allocate(NumChildren);
1696 9185 : ChildCName = std::string();
1697 9185 : ChildInNodeName = std::string();
1698 9185 : ChildOutNodeName = std::string();
1699 9185 : ChildInNodeNum = 0;
1700 9185 : ChildOutNodeNum = 0;
1701 9185 : int CountNum = 0;
1702 1509536 : for (int Loop = 1; Loop <= state.dataBranchNodeConnections->NumCompSets; ++Loop) {
1703 1786347 : if (state.dataBranchNodeConnections->CompSets(Loop).ParentObjectType == ComponentType &&
1704 285996 : state.dataBranchNodeConnections->CompSets(Loop).ParentCName == ComponentName) {
1705 12550 : ++CountNum;
1706 12550 : ChildCType(CountNum) = state.dataBranchNodeConnections->CompSets(Loop).ComponentObjectType;
1707 12550 : ChildCName(CountNum) = state.dataBranchNodeConnections->CompSets(Loop).CName;
1708 12550 : ChildInNodeName(CountNum) = state.dataBranchNodeConnections->CompSets(Loop).InletNodeName;
1709 12550 : ChildOutNodeName(CountNum) = state.dataBranchNodeConnections->CompSets(Loop).OutletNodeName;
1710 : // Get Node Numbers
1711 12550 : ChildInNodeNum(CountNum) = Util::FindItemInList(ChildInNodeName(CountNum),
1712 25100 : state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}),
1713 12550 : state.dataLoopNodes->NumOfNodes);
1714 12550 : ChildOutNodeNum(CountNum) = Util::FindItemInList(ChildOutNodeName(CountNum),
1715 25100 : state.dataLoopNodes->NodeID({1, state.dataLoopNodes->NumOfNodes}),
1716 12550 : state.dataLoopNodes->NumOfNodes);
1717 : }
1718 : }
1719 9185 : if (CountNum != NumChildren) {
1720 0 : ShowSevereError(state, "GetChildrenData: Counted nodes not equal to GetNumChildren count");
1721 0 : ErrInObject = true;
1722 : } else {
1723 : // Children arrays built. Now "sort" for flow connection order(?)
1724 9185 : std::string MatchNodeName = ParentInletNodeName;
1725 9185 : CountNum = 0;
1726 9185 : int CountMatchLoop = 0;
1727 21735 : while (CountMatchLoop < NumChildren) {
1728 12550 : ++CountMatchLoop;
1729 : // Matched=.FALSE.
1730 30730 : for (int Loop = 1; Loop <= NumChildren; ++Loop) {
1731 21463 : if (ChildInNodeName(Loop) == MatchNodeName) {
1732 3283 : ++CountNum;
1733 3283 : ChildrenCType(CountNum) = ChildCType(Loop);
1734 3283 : ChildrenCName(CountNum) = ChildCName(Loop);
1735 3283 : InletNodeName(CountNum) = ChildInNodeName(Loop);
1736 3283 : InletNodeNum(CountNum) = ChildInNodeNum(Loop);
1737 3283 : OutletNodeName(CountNum) = ChildOutNodeName(Loop);
1738 3283 : OutletNodeNum(CountNum) = ChildOutNodeNum(Loop);
1739 3283 : ChildInNodeName(Loop).clear(); // So it won't match anymore
1740 : // Matched=.TRUE.
1741 3283 : MatchNodeName = ChildOutNodeName(Loop);
1742 3283 : break;
1743 : }
1744 : }
1745 : }
1746 9185 : if (MatchNodeName != ParentOutletNodeName) {
1747 7713 : for (int Loop = 1; Loop <= NumChildren; ++Loop) {
1748 7709 : if (ChildInNodeName(Loop).empty()) continue;
1749 7697 : if (ChildOutNodeName(Loop) == ParentOutletNodeName) break;
1750 526 : break;
1751 : }
1752 : }
1753 21735 : for (int Loop = 1; Loop <= NumChildren; ++Loop) {
1754 12550 : if (ChildInNodeName(Loop).empty()) continue;
1755 9267 : ++CountNum;
1756 9267 : ChildrenCType(CountNum) = ChildCType(Loop);
1757 9267 : ChildrenCName(CountNum) = ChildCName(Loop);
1758 9267 : InletNodeName(CountNum) = ChildInNodeName(Loop);
1759 9267 : InletNodeNum(CountNum) = ChildInNodeNum(Loop);
1760 9267 : OutletNodeName(CountNum) = ChildOutNodeName(Loop);
1761 9267 : OutletNodeNum(CountNum) = ChildOutNodeNum(Loop);
1762 : }
1763 9185 : ChildCType.deallocate();
1764 9185 : ChildCName.deallocate();
1765 9185 : ChildInNodeName.deallocate();
1766 9185 : ChildOutNodeName.deallocate();
1767 9185 : ChildInNodeNum.deallocate();
1768 9185 : ChildOutNodeNum.deallocate();
1769 9185 : }
1770 9185 : }
1771 : } else {
1772 0 : ShowWarningError(state,
1773 0 : format("GetChildrenData: Requested Children Data for non Parent Node={}:{}.",
1774 0 : ConnectionObjectTypeNames[static_cast<int>(ComponentType)],
1775 : ComponentName));
1776 0 : ErrInObject = true;
1777 : }
1778 :
1779 9185 : if (ErrInObject) ErrorsFound = true;
1780 9185 : }
1781 :
1782 35816 : void SetUpCompSets(EnergyPlusData &state,
1783 : std::string_view ParentType, // Parent Object Type
1784 : std::string_view ParentName, // Parent Object Name
1785 : std::string_view CompType, // Component Type
1786 : std::string_view CompName, // Component Name
1787 : std::string_view InletNode, // Inlet Node Name
1788 : std::string_view OutletNode, // Outlet Node Name
1789 : std::string_view const Description // Description
1790 : )
1791 : {
1792 :
1793 : // SUBROUTINE INFORMATION:
1794 : // AUTHOR Linda Lawrie
1795 : // DATE WRITTEN November 2001
1796 :
1797 : // PURPOSE OF THIS SUBROUTINE:
1798 : // This subroutine sets up "Component Sets" as input in the branch
1799 : // lists. These can be used later to verify that the proper names and
1800 : // inlet/outlet nodes have been input. This routine assumes that identical
1801 : // "CompSets" cannot be used in multiple places and issues a warning if they are.
1802 :
1803 35816 : std::string ParentTypeUC = Util::makeUPPER(ParentType);
1804 35816 : std::string CompTypeUC = Util::makeUPPER(CompType);
1805 : // TODO: Refactor this away by passing in enums
1806 : DataLoopNode::ConnectionObjectType ParentTypeEnum =
1807 35816 : static_cast<DataLoopNode::ConnectionObjectType>(getEnumValue(ConnectionObjectTypeNamesUC, ParentTypeUC));
1808 35816 : assert(ParentTypeEnum != DataLoopNode::ConnectionObjectType::Invalid);
1809 :
1810 : DataLoopNode::ConnectionObjectType ComponentTypeEnum =
1811 35816 : static_cast<DataLoopNode::ConnectionObjectType>(getEnumValue(ConnectionObjectTypeNamesUC, CompTypeUC));
1812 35816 : assert(ComponentTypeEnum != DataLoopNode::ConnectionObjectType::Invalid);
1813 :
1814 35816 : int Found = 0;
1815 :
1816 : // See if Component-Nodes set is already there - should be unique
1817 : // Try to fill in blanks (passed in as undefined
1818 3231688 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
1819 3202545 : if (CompName != state.dataBranchNodeConnections->CompSets(Count).CName) continue;
1820 14048 : if (ComponentTypeEnum != DataLoopNode::ConnectionObjectType::Undefined) {
1821 13588 : if (ComponentTypeEnum != state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType) continue;
1822 : }
1823 : // Component name matches, component type matches or is undefined
1824 14019 : if (InletNode != undefined) {
1825 12009 : if (state.dataBranchNodeConnections->CompSets(Count).InletNodeName != undefined) {
1826 12008 : if (InletNode != state.dataBranchNodeConnections->CompSets(Count).InletNodeName) continue;
1827 : } else {
1828 1 : state.dataBranchNodeConnections->CompSets(Count).InletNodeName = InletNode;
1829 : }
1830 : }
1831 7284 : if (OutletNode != undefined) {
1832 5727 : if (state.dataBranchNodeConnections->CompSets(Count).OutletNodeName != undefined) {
1833 5726 : if (OutletNode != state.dataBranchNodeConnections->CompSets(Count).OutletNodeName) continue;
1834 : } else {
1835 1 : state.dataBranchNodeConnections->CompSets(Count).OutletNodeName = OutletNode;
1836 : }
1837 : }
1838 : // See if something undefined and set here
1839 13790 : if (state.dataBranchNodeConnections->CompSets(Count).ParentObjectType == DataLoopNode::ConnectionObjectType::Undefined &&
1840 6673 : state.dataBranchNodeConnections->CompSets(Count).ParentCName == undefined) {
1841 : // Assume this is a further definition for this compset
1842 6673 : state.dataBranchNodeConnections->CompSets(Count).ParentObjectType = ParentTypeEnum;
1843 6673 : state.dataBranchNodeConnections->CompSets(Count).ParentCName = ParentName;
1844 6673 : if (!Description.empty()) {
1845 43 : state.dataBranchNodeConnections->CompSets(Count).Description = Description;
1846 : }
1847 6673 : Found = Count;
1848 6673 : break;
1849 : }
1850 : }
1851 35816 : if (Found == 0) {
1852 2204362 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
1853 2175219 : Found = 0;
1854 : // Test if inlet node has been used before as an inlet node
1855 : // If the matching node name does not belong to the parent object, then error
1856 : // For example a fan may share the same inlet node as the furnace object which is its parent
1857 2175219 : if (InletNode != state.dataBranchNodeConnections->CompSets(Count).InletNodeName) {
1858 2118842 : continue;
1859 : // If parent type is undefined then no error
1860 111946 : } else if ((ParentTypeEnum == DataLoopNode::ConnectionObjectType::Undefined) ||
1861 55569 : (state.dataBranchNodeConnections->CompSets(Count).ParentObjectType == DataLoopNode::ConnectionObjectType::Undefined)) {
1862 : // If node name is undefined then no error
1863 55561 : } else if (InletNode != undefined) {
1864 : // If the matching node name does not belong to the parent or child object, then error
1865 : // For example a fan may share the same inlet node as the furnace object which is its parent
1866 84 : if ((ParentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType) &&
1867 42 : (ParentName == state.dataBranchNodeConnections->CompSets(Count).CName)) {
1868 : // OK - The duplicate inlet node belongs to this component's parent
1869 0 : } else if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ParentObjectType) &&
1870 0 : (CompName == state.dataBranchNodeConnections->CompSets(Count).ParentCName)) {
1871 : // OK - The duplicate inlet node belongs to a child of this component
1872 : } else {
1873 : // Due to possibility of grandparents or more, if the matching node name
1874 : // belongs to a component that appears as a parent, then OK
1875 0 : int Found2 = 0;
1876 0 : for (int Count2 = 1; Count2 <= state.dataBranchNodeConnections->NumCompSets; ++Count2) {
1877 0 : if ((state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType ==
1878 0 : state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
1879 0 : (state.dataBranchNodeConnections->CompSets(Count).CName == state.dataBranchNodeConnections->CompSets(Count2).ParentCName))
1880 0 : Found2 = 1;
1881 0 : if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
1882 0 : (CompName == state.dataBranchNodeConnections->CompSets(Count2).ParentCName))
1883 0 : Found2 = 1;
1884 : }
1885 0 : if (Found2 == 0) {
1886 0 : ShowWarningError(state, format("Node used as an inlet more than once: {}", InletNode));
1887 0 : ShowContinueError(
1888 : state,
1889 0 : format(" Used by: {}, name={}",
1890 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType)],
1891 0 : state.dataBranchNodeConnections->CompSets(Count).ParentCName));
1892 0 : ShowContinueError(
1893 : state,
1894 0 : format(" as inlet for: {}, name={}",
1895 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
1896 0 : state.dataBranchNodeConnections->CompSets(Count).CName));
1897 0 : ShowContinueError(state, format("{}{}{}", " and by : ", ParentTypeUC + ", name=", ParentName));
1898 0 : ShowContinueError(state, format("{}{}{}", " as inlet for: ", CompTypeUC + ", name=", CompName));
1899 : }
1900 : }
1901 : }
1902 : // Test if outlet node has been used before as an outlet node
1903 : // If the matching node name does not belong to the parent or child object, then error
1904 : // For example a fan may share the same outlet node as the furnace object which is its parent
1905 56377 : if (OutletNode != state.dataBranchNodeConnections->CompSets(Count).OutletNodeName) {
1906 50615 : continue;
1907 : // If parent type is undefined then no error
1908 11200 : } else if ((ParentTypeEnum == DataLoopNode::ConnectionObjectType::Undefined) ||
1909 5438 : (state.dataBranchNodeConnections->CompSets(Count).ParentObjectType == DataLoopNode::ConnectionObjectType::Undefined)) {
1910 : // If node name is undefined then no error
1911 5435 : } else if (OutletNode != undefined) {
1912 113 : if ((ParentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType) &&
1913 42 : (ParentName == state.dataBranchNodeConnections->CompSets(Count).CName)) {
1914 : // OK - The duplicate outlet node belongs to this component's parent
1915 29 : } else if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ParentObjectType) &&
1916 0 : (CompName == state.dataBranchNodeConnections->CompSets(Count).ParentCName)) {
1917 : // OK - The duplicate outlet node belongs to a child of this component
1918 : } else {
1919 : // Due to possibility of grandparents or more, if the matching node name
1920 : // belongs to a component that appears as a parent, then OK
1921 29 : int Found2 = 0;
1922 1160 : for (int Count2 = 1; Count2 <= state.dataBranchNodeConnections->NumCompSets; ++Count2) {
1923 1131 : if ((state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType ==
1924 1131 : state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
1925 0 : (state.dataBranchNodeConnections->CompSets(Count).CName == state.dataBranchNodeConnections->CompSets(Count2).ParentCName))
1926 0 : Found2 = 1;
1927 1131 : if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
1928 0 : (CompName == state.dataBranchNodeConnections->CompSets(Count2).ParentCName))
1929 0 : Found2 = 1;
1930 : }
1931 : // This rule is violated by dual duct units, so let it pass
1932 29 : if (Found2 == 0) {
1933 : std::string_view const CType =
1934 29 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)];
1935 29 : if ((!has_prefixi(CType, "AirTerminal:DualDuct:")) && (!has_prefixi(CompTypeUC, "AirTerminal:DualDuct:"))) {
1936 0 : ShowWarningError(state, format("Node used as an outlet more than once: {}", OutletNode));
1937 0 : ShowContinueError(
1938 : state,
1939 0 : format(" Used by: {}, name={}",
1940 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType)],
1941 0 : state.dataBranchNodeConnections->CompSets(Count).ParentCName));
1942 0 : ShowContinueError(
1943 : state,
1944 0 : format(
1945 : " as outlet for: {}, name={}",
1946 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
1947 0 : state.dataBranchNodeConnections->CompSets(Count).CName));
1948 0 : ShowContinueError(state, format("{}{}{}", " and by : ", ParentTypeUC + ", name=", ParentName));
1949 0 : ShowContinueError(state, format("{}{}{}", " as outlet for: ", CompTypeUC + ", name=", CompName));
1950 : }
1951 : }
1952 : }
1953 : }
1954 5762 : if (ComponentTypeEnum != state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType &&
1955 : ComponentTypeEnum != DataLoopNode::ConnectionObjectType::Undefined)
1956 562 : continue;
1957 5200 : if (CompName != state.dataBranchNodeConnections->CompSets(Count).CName) continue;
1958 0 : Found = Count;
1959 0 : break;
1960 : }
1961 : }
1962 35816 : if (Found == 0) {
1963 29143 : state.dataBranchNodeConnections->CompSets.resize(++state.dataBranchNodeConnections->NumCompSets);
1964 29143 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).ParentObjectType = ParentTypeEnum;
1965 :
1966 29143 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).ParentCName = ParentName;
1967 29143 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).ComponentObjectType = ComponentTypeEnum;
1968 29143 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).CName = CompName;
1969 29143 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).InletNodeName =
1970 :
1971 58286 : Util::makeUPPER(InletNode); // TODO: Fix this....
1972 29143 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).OutletNodeName =
1973 58286 : Util::makeUPPER(OutletNode); // TODO: Fix this....
1974 :
1975 29143 : if (!Description.empty()) {
1976 6708 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).Description = Description;
1977 : } else {
1978 22435 : state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).Description = undefined;
1979 : }
1980 : }
1981 35816 : }
1982 :
1983 632 : void TestInletOutletNodes(EnergyPlusData &state)
1984 : {
1985 :
1986 : // SUBROUTINE INFORMATION:
1987 : // AUTHOR Linda Lawrie
1988 : // DATE WRITTEN November 2001
1989 :
1990 : // PURPOSE OF THIS SUBROUTINE:
1991 : // This subroutine tests the branches to see if a duplicate inlet node
1992 : // exists under a different name in the sequence; likewise for outlet.
1993 :
1994 632 : Array1D_bool AlreadyNoted;
1995 :
1996 : // Test component sets created by branches
1997 632 : AlreadyNoted.dimension(state.dataBranchNodeConnections->NumCompSets, false);
1998 17912 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
1999 1224340 : for (int Other = 1; Other <= state.dataBranchNodeConnections->NumCompSets; ++Other) {
2000 1207060 : if (Count == Other) continue;
2001 1189780 : if (state.dataBranchNodeConnections->CompSets(Count).InletNodeName != state.dataBranchNodeConnections->CompSets(Other).InletNodeName)
2002 1189780 : continue;
2003 0 : if (AlreadyNoted(Count)) continue;
2004 : // All other values must match
2005 0 : if (state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType !=
2006 0 : state.dataBranchNodeConnections->CompSets(Other).ComponentObjectType ||
2007 0 : state.dataBranchNodeConnections->CompSets(Count).CName != state.dataBranchNodeConnections->CompSets(Other).CName ||
2008 0 : state.dataBranchNodeConnections->CompSets(Count).OutletNodeName != state.dataBranchNodeConnections->CompSets(Other).OutletNodeName) {
2009 0 : AlreadyNoted(Other) = true;
2010 0 : ShowWarningError(state,
2011 0 : format("Node used as an inlet more than once: {}", state.dataBranchNodeConnections->CompSets(Count).InletNodeName));
2012 0 : ShowContinueError(
2013 : state,
2014 0 : format(" Used by: {}, name={}",
2015 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType)],
2016 0 : state.dataBranchNodeConnections->CompSets(Count).ParentCName));
2017 0 : ShowContinueError(
2018 : state,
2019 0 : format(" as inlet for: {}, name={}",
2020 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Other).ComponentObjectType)],
2021 0 : state.dataBranchNodeConnections->CompSets(Other).CName));
2022 0 : ShowContinueError(
2023 : state,
2024 0 : format(" and by: {}, name={}",
2025 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Other).ParentObjectType)],
2026 0 : state.dataBranchNodeConnections->CompSets(Other).ParentCName));
2027 0 : ShowContinueError(
2028 : state,
2029 0 : format(" as inlet for: {}, name={}",
2030 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
2031 0 : state.dataBranchNodeConnections->CompSets(Count).CName));
2032 : }
2033 : }
2034 : }
2035 :
2036 632 : AlreadyNoted = false;
2037 17912 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
2038 1224340 : for (int Other = 1; Other <= state.dataBranchNodeConnections->NumCompSets; ++Other) {
2039 1207060 : if (Count == Other) continue;
2040 1189780 : if (state.dataBranchNodeConnections->CompSets(Count).OutletNodeName != state.dataBranchNodeConnections->CompSets(Other).OutletNodeName)
2041 1189780 : continue;
2042 0 : if (AlreadyNoted(Count)) continue;
2043 : // All other values must match
2044 0 : if (state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType !=
2045 0 : state.dataBranchNodeConnections->CompSets(Other).ComponentObjectType ||
2046 0 : state.dataBranchNodeConnections->CompSets(Count).CName != state.dataBranchNodeConnections->CompSets(Other).CName ||
2047 0 : state.dataBranchNodeConnections->CompSets(Count).InletNodeName != state.dataBranchNodeConnections->CompSets(Other).InletNodeName) {
2048 0 : AlreadyNoted(Other) = true;
2049 0 : ShowWarningError(
2050 0 : state, format("Node used as an outlet more than once: {}", state.dataBranchNodeConnections->CompSets(Count).OutletNodeName));
2051 0 : ShowContinueError(
2052 : state,
2053 0 : format(" Used by: {}, name={}",
2054 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType)],
2055 0 : state.dataBranchNodeConnections->CompSets(Count).ParentCName));
2056 0 : ShowContinueError(
2057 : state,
2058 0 : format(" as outlet for: {}, name={}",
2059 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Other).ComponentObjectType)],
2060 0 : state.dataBranchNodeConnections->CompSets(Other).CName));
2061 0 : ShowContinueError(
2062 : state,
2063 0 : format(" and by: {}, name={}",
2064 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Other).ParentObjectType)],
2065 0 : state.dataBranchNodeConnections->CompSets(Other).ParentCName));
2066 0 : ShowContinueError(
2067 : state,
2068 0 : format(" as outlet for: {}, name={}",
2069 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
2070 0 : state.dataBranchNodeConnections->CompSets(Count).CName));
2071 : }
2072 : }
2073 : }
2074 :
2075 632 : AlreadyNoted.deallocate();
2076 632 : }
2077 :
2078 29116 : void TestCompSet(EnergyPlusData &state,
2079 : std::string_view const CompType, // Component Type
2080 : std::string_view CompName, // Component Name
2081 : std::string const &InletNode, // Inlet Node Name
2082 : std::string const &OutletNode, // Outlet Node Name
2083 : std::string const &Description // Description of Node Pair (for warning message)
2084 : )
2085 : {
2086 :
2087 : // SUBROUTINE INFORMATION:
2088 : // AUTHOR Linda K. Lawrie
2089 : // DATE WRITTEN November 2001
2090 :
2091 : // PURPOSE OF THIS SUBROUTINE:
2092 : // Register a child component in the CompSets data structure.
2093 : // NOTE: This function was originally designed to test the stored "Component Sets" to
2094 : // see if there was one of this combination in there. Thus the name "TestCompSet".
2095 : // However, this was based on a false assumption that input would always be gotten
2096 : // first for the parent object, then for the child object. But this is often not the
2097 : // case. Ultimately, the name of this function should be changed or it should be merged
2098 : // into SetUpCompSets.
2099 : // Until then, this function does the following:
2100 : // a) Search CompSets for this combination of component type, component name,
2101 : // inlet node and outlet node. If component type/name match and the existing
2102 : // node names are UNDEFINED, this compset is assumed to be a match.
2103 : // b) If found, fill in any missing data such as node names or node description
2104 : // c) If not found, call SetUpCompSets (with parent type and name UNDEFINED)
2105 : // to add a new item in the CompSets array
2106 :
2107 29116 : std::string CompTypeUC = Util::makeUPPER(CompType);
2108 :
2109 : // TODO: Refactor this away by passing in enums
2110 : DataLoopNode::ConnectionObjectType ComponentTypeEnum =
2111 29116 : static_cast<DataLoopNode::ConnectionObjectType>(getEnumValue(ConnectionObjectTypeNamesUC, CompTypeUC));
2112 29116 : assert(ComponentTypeEnum != DataLoopNode::ConnectionObjectType::Invalid);
2113 :
2114 : // See if Already there
2115 29116 : int Found = 0;
2116 2203870 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
2117 3960554 : if ((ComponentTypeEnum != state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType) &&
2118 1763359 : (state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType != DataLoopNode::ConnectionObjectType::Undefined))
2119 1763359 : continue;
2120 433836 : if (CompName != state.dataBranchNodeConnections->CompSets(Count).CName) continue;
2121 36976 : if ((InletNode != state.dataBranchNodeConnections->CompSets(Count).InletNodeName) &&
2122 36976 : (state.dataBranchNodeConnections->CompSets(Count).InletNodeName != undefined) && (InletNode != undefined))
2123 4363 : continue;
2124 24593 : if ((OutletNode != state.dataBranchNodeConnections->CompSets(Count).OutletNodeName) &&
2125 24593 : (state.dataBranchNodeConnections->CompSets(Count).OutletNodeName != undefined) && (OutletNode != undefined))
2126 0 : continue;
2127 :
2128 22441 : Found = Count;
2129 22441 : break;
2130 : }
2131 :
2132 29116 : if (Found == 0) {
2133 6675 : SetUpCompSets(state, undefined, undefined, CompType, CompName, InletNode, OutletNode, Description);
2134 : } else {
2135 : // Fill in node names and component type for previously undefined values:
2136 : // If the parent object did not specify a component type or inlet or outlet node, then that value
2137 : // is UNDEFINED in CompSets. When a component calls TestCompSet, the comp type and inlet and
2138 : // outlet nodes are known, so they can be filled in for future reference.
2139 22441 : if (state.dataBranchNodeConnections->CompSets(Found).ComponentObjectType == DataLoopNode::ConnectionObjectType::Undefined) {
2140 0 : state.dataBranchNodeConnections->CompSets(Found).ComponentObjectType = ComponentTypeEnum;
2141 : }
2142 22441 : if (state.dataBranchNodeConnections->CompSets(Found).InletNodeName == undefined)
2143 4749 : state.dataBranchNodeConnections->CompSets(Found).InletNodeName = InletNode;
2144 22441 : if (state.dataBranchNodeConnections->CompSets(Found).OutletNodeName == undefined)
2145 1092 : state.dataBranchNodeConnections->CompSets(Found).OutletNodeName = OutletNode;
2146 22441 : if (state.dataBranchNodeConnections->CompSets(Found).Description == undefined)
2147 22418 : state.dataBranchNodeConnections->CompSets(Found).Description = Description;
2148 : }
2149 29116 : }
2150 :
2151 795 : void TestCompSetInletOutletNodes(EnergyPlusData &state, bool &ErrorsFound)
2152 : {
2153 :
2154 : // SUBROUTINE INFORMATION:
2155 : // AUTHOR Linda Lawrie
2156 : // DATE WRITTEN March 2008
2157 : // MODIFIED na
2158 : // RE-ENGINEERED na
2159 :
2160 : // PURPOSE OF THIS SUBROUTINE:
2161 : // This subroutine tests the comp sets to see if a duplicate comp name
2162 : // exists under a different set of inlet/outlet nodes.
2163 :
2164 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2165 795 : Array1D_bool AlreadyNoted;
2166 :
2167 : // Test component sets created by branches
2168 795 : AlreadyNoted.dimension(state.dataBranchNodeConnections->NumCompSets, false);
2169 29900 : for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
2170 4407242 : for (int Other = 1; Other <= state.dataBranchNodeConnections->NumCompSets; ++Other) {
2171 4378137 : if (Count == Other) continue;
2172 4349032 : if (state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType ==
2173 : DataLoopNode::ConnectionObjectType ::SolarCollectorUnglazedTranspired)
2174 558 : continue;
2175 4348474 : if (state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType !=
2176 5171132 : state.dataBranchNodeConnections->CompSets(Other).ComponentObjectType ||
2177 822658 : state.dataBranchNodeConnections->CompSets(Count).CName != state.dataBranchNodeConnections->CompSets(Other).CName)
2178 4339748 : continue;
2179 8726 : if (state.dataBranchNodeConnections->CompSets(Count).Description != state.dataBranchNodeConnections->CompSets(Other).Description) {
2180 17452 : if (state.dataBranchNodeConnections->CompSets(Count).Description != undefined &&
2181 8726 : state.dataBranchNodeConnections->CompSets(Other).Description != undefined)
2182 8726 : continue;
2183 : }
2184 0 : if (state.dataBranchNodeConnections->CompSets(Count).InletNodeName == state.dataBranchNodeConnections->CompSets(Other).InletNodeName)
2185 0 : continue;
2186 0 : if (state.dataBranchNodeConnections->CompSets(Count).OutletNodeName == state.dataBranchNodeConnections->CompSets(Other).OutletNodeName)
2187 0 : continue;
2188 0 : if (AlreadyNoted(Count)) continue;
2189 : // All other values must match
2190 0 : AlreadyNoted(Other) = true;
2191 0 : ShowSevereError(state, "Same component name and type has differing Node Names.");
2192 0 : ShowContinueError(
2193 : state,
2194 0 : format(" Component: {}, name={}",
2195 0 : ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
2196 0 : state.dataBranchNodeConnections->CompSets(Count).CName));
2197 0 : ShowContinueError(state,
2198 0 : format(" Nodes, inlet: {}, outlet: {}",
2199 0 : state.dataBranchNodeConnections->CompSets(Count).InletNodeName,
2200 0 : state.dataBranchNodeConnections->CompSets(Count).OutletNodeName));
2201 0 : ShowContinueError(state,
2202 0 : format(" & Nodes, inlet: {}, outlet: {}",
2203 0 : state.dataBranchNodeConnections->CompSets(Other).InletNodeName,
2204 0 : state.dataBranchNodeConnections->CompSets(Other).OutletNodeName));
2205 0 : ShowContinueError(state,
2206 0 : format(" Node Types: {} & {}",
2207 0 : state.dataBranchNodeConnections->CompSets(Count).Description,
2208 0 : state.dataBranchNodeConnections->CompSets(Other).Description));
2209 0 : ErrorsFound = true;
2210 : }
2211 : }
2212 :
2213 795 : AlreadyNoted.deallocate();
2214 795 : }
2215 :
2216 79 : void GetNodeConnectionType(EnergyPlusData &state, int const NodeNumber, EPVector<DataLoopNode::ConnectionType> &NodeConnectType, bool &errFlag)
2217 : {
2218 :
2219 : // FUNCTION INFORMATION:
2220 : // AUTHOR Lixing Gu
2221 : // DATE WRITTEN Jan 2007
2222 :
2223 : // PURPOSE OF THIS FUNCTION:
2224 : // This function provides a connection type with given node number
2225 :
2226 79 : Array1D_int ListArray;
2227 79 : Array1D_string ConnectionTypes(15);
2228 :
2229 1264 : for (int nodetype = 1; nodetype < static_cast<int>(ConnectionType::Num); ++nodetype) {
2230 1185 : ConnectionTypes(nodetype) = ConnectionTypeNames[nodetype];
2231 : }
2232 :
2233 79 : if (allocated(NodeConnectType)) NodeConnectType.deallocate();
2234 :
2235 : int NumInList;
2236 158 : FindAllNodeNumbersInList(
2237 79 : NodeNumber, state.dataBranchNodeConnections->NodeConnections, state.dataBranchNodeConnections->NumOfNodeConnections, NumInList, ListArray);
2238 :
2239 79 : NodeConnectType.allocate(NumInList);
2240 :
2241 79 : if (NumInList > 0) {
2242 212 : for (int NodeConnectIndex = 1; NodeConnectIndex <= NumInList; ++NodeConnectIndex) {
2243 133 : NodeConnectType(NodeConnectIndex) = state.dataBranchNodeConnections->NodeConnections(ListArray(NodeConnectIndex)).ConnectionType;
2244 : }
2245 : } else {
2246 0 : if (NodeNumber > 0) {
2247 0 : ShowWarningError(state, format("Node not found = {}.", state.dataLoopNodes->NodeID(NodeNumber)));
2248 : } else {
2249 0 : ShowWarningError(state, "Invalid node number passed = 0.");
2250 : }
2251 0 : errFlag = true;
2252 : }
2253 79 : }
2254 :
2255 79 : void FindAllNodeNumbersInList(int const WhichNumber,
2256 : EPVector<DataBranchNodeConnections::NodeConnectionDef> const &NodeConnections,
2257 : int const NumItems,
2258 : int &CountOfItems, // Number of items found
2259 : Array1D_int &AllNumbersInList // Index array to all numbers found
2260 : )
2261 : {
2262 :
2263 : // FUNCTION INFORMATION:
2264 : // AUTHOR R. Raustad
2265 : // DATE WRITTEN January 2007
2266 :
2267 : // PURPOSE OF THIS FUNCTION:
2268 : // This function looks up a number(integer) in a similar list of
2269 : // items and returns the index of the item in the list, if
2270 : // found.
2271 :
2272 79 : CountOfItems = 0;
2273 :
2274 79 : if (allocated(AllNumbersInList)) AllNumbersInList.deallocate();
2275 :
2276 6215 : for (int Count = 1; Count <= NumItems; ++Count) {
2277 6136 : if (WhichNumber == NodeConnections(Count).NodeNumber) {
2278 133 : ++CountOfItems;
2279 : }
2280 : }
2281 :
2282 79 : if (CountOfItems > 0) {
2283 :
2284 79 : AllNumbersInList.dimension(CountOfItems, 0);
2285 79 : CountOfItems = 0;
2286 :
2287 6215 : for (int Count = 1; Count <= NumItems; ++Count) {
2288 6136 : if (WhichNumber == NodeConnections(Count).NodeNumber) {
2289 133 : ++CountOfItems;
2290 133 : AllNumbersInList(CountOfItems) = Count;
2291 : }
2292 : }
2293 : }
2294 79 : }
2295 :
2296 : } // namespace EnergyPlus::BranchNodeConnections
|