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