Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <string>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 : #include <ObjexxFCL/Fmath.hh>
54 : #include <ObjexxFCL/string.functions.hh>
55 :
56 : // EnergyPlus Headers
57 : #include <EnergyPlus/BranchInputManager.hh>
58 : #include <EnergyPlus/BranchNodeConnections.hh>
59 : #include <EnergyPlus/CurveManager.hh>
60 : #include <EnergyPlus/Data/EnergyPlusData.hh>
61 : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
62 : #include <EnergyPlus/DataErrorTracking.hh>
63 : #include <EnergyPlus/GeneralRoutines.hh>
64 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
65 : #include <EnergyPlus/NodeInputManager.hh>
66 : #include <EnergyPlus/UtilityRoutines.hh>
67 :
68 : namespace EnergyPlus {
69 :
70 : namespace BranchInputManager {
71 :
72 : // Module containing the routines dealing with the BRANCH and CONNECTOR
73 : // lists input.
74 :
75 : // MODULE INFORMATION:
76 : // AUTHOR Linda Lawrie
77 : // DATE WRITTEN October 1999
78 : // MODIFIED na
79 : // RE-ENGINEERED na
80 :
81 : // PURPOSE OF THIS MODULE:
82 : // To Get the IDD objects "BranchList", "Branch", "ConnectorList",
83 : // "Connector:Splitter", and "Connector:Mixer". Also, to supply other modules/routines with
84 : // information about these objects.
85 :
86 : // Using/Aliasing
87 : using namespace DataLoopNode;
88 : using namespace DataBranchAirLoopPlant;
89 : using namespace NodeInputManager;
90 : using namespace BranchNodeConnections;
91 :
92 : // MODULE PARAMETER DEFINITIONS
93 : const char *cMIXER("Connector:Mixer");
94 : const char *cSPLITTER("Connector:Splitter");
95 :
96 105 : void ManageBranchInput(EnergyPlusData &state)
97 : {
98 :
99 : // SUBROUTINE INFORMATION:
100 : // AUTHOR Linda Lawrie
101 : // DATE WRITTEN Nov 2004
102 : // MODIFIED na
103 : // RE-ENGINEERED na
104 :
105 : // PURPOSE OF THIS SUBROUTINE:
106 : // This subroutine is called from HVACManager to make sure that branch input is
107 : // gathered prior to need.
108 :
109 105 : if (state.dataBranchInputManager->GetBranchInputFlag) {
110 105 : GetBranchInput(state);
111 105 : if (state.dataBranchInputManager->GetBranchListInputFlag) {
112 105 : state.dataBranchInputManager->GetBranchListInputFlag = false;
113 105 : GetBranchListInput(state);
114 : }
115 105 : AuditBranches(state, false);
116 105 : state.dataBranchInputManager->GetBranchInputFlag = false;
117 : }
118 105 : }
119 :
120 : //==================================================================================
121 : // Routines that "get" data from internal branch management structure
122 : //==================================================================================
123 :
124 184 : void GetBranchList(EnergyPlusData &state,
125 : std::string const &LoopName, // Name of Loop Branch List is on
126 : std::string const &BranchListName, // Branch List Name from Input
127 : int &NumBranchNames, // Number of Branches for this Branch List
128 : Array1D_string &BranchNames, // Names of Branches on this Branch List
129 : std::string const &LoopType // Type of Loop Branch list is on
130 : )
131 : {
132 :
133 : // SUBROUTINE INFORMATION:
134 : // AUTHOR Linda K. Lawrie
135 : // DATE WRITTEN October 1999
136 : // MODIFIED October 2001, Automatic Extensibility
137 : // RE-ENGINEERED na
138 :
139 : // PURPOSE OF THIS SUBROUTINE:
140 : // This subroutine "gets" the branch list specified in a Plant or Condenser loop and
141 : // returns number and names to the outside calling routine.
142 :
143 : // Using/Aliasing
144 :
145 : int Found; // Points to correct Branch List/Branch
146 : bool ErrFound; // True when error has occurred (cannot find Branch List)
147 :
148 184 : ErrFound = false;
149 :
150 184 : if (state.dataBranchInputManager->GetBranchListInputFlag) {
151 0 : state.dataBranchInputManager->GetBranchListInputFlag = false;
152 0 : GetBranchListInput(state);
153 : }
154 :
155 : // Find this BranchList in the master BranchList Names
156 184 : Found = Util::FindItemInList(BranchListName, state.dataBranchInputManager->BranchList);
157 184 : if (Found == 0) {
158 0 : ShowFatalError(state, format("GetBranchList: BranchList Name not found={}", BranchListName));
159 : }
160 :
161 : // Set data
162 184 : if (state.dataBranchInputManager->BranchList(Found).LoopName.empty()) {
163 184 : state.dataBranchInputManager->BranchList(Found).LoopName = LoopName;
164 184 : state.dataBranchInputManager->BranchList(Found).LoopType = LoopType;
165 0 : } else if (state.dataBranchInputManager->BranchList(Found).LoopName != LoopName) {
166 0 : ShowSevereError(state, "GetBranchList: BranchList Loop Name already assigned");
167 0 : ShowContinueError(state,
168 0 : format("BranchList={}, already assigned to loop={}",
169 0 : state.dataBranchInputManager->BranchList(Found).Name,
170 0 : state.dataBranchInputManager->BranchList(Found).LoopName));
171 0 : ShowContinueError(state, format("Now requesting assignment to Loop={}", LoopName));
172 0 : ErrFound = true;
173 : }
174 :
175 : // Return data
176 184 : NumBranchNames = state.dataBranchInputManager->BranchList(Found).NumOfBranchNames;
177 184 : if (isize(BranchNames) < NumBranchNames) {
178 0 : ShowSevereError(state, "GetBranchList: Branch Names array not big enough to hold Branch Names");
179 0 : ShowContinueError(state, format("Input BranchListName={}, in Loop={}", BranchListName, LoopName));
180 0 : ShowContinueError(state, fmt::format("BranchName Array size={}, but input size={}", size(BranchNames), (NumBranchNames)));
181 0 : ErrFound = true;
182 : } else {
183 184 : BranchNames = "";
184 184 : BranchNames({1, NumBranchNames}) = state.dataBranchInputManager->BranchList(Found).BranchNames({1, NumBranchNames});
185 : }
186 :
187 184 : if (ErrFound) {
188 0 : ShowFatalError(state, "GetBranchList: preceding condition(s) causes program termination.");
189 : }
190 184 : }
191 :
192 184 : int NumBranchesInBranchList(EnergyPlusData &state, std::string const &BranchListName)
193 : {
194 :
195 : // FUNCTION INFORMATION:
196 : // AUTHOR Linda K. Lawrie
197 : // DATE WRITTEN July 2003
198 : // MODIFIED na
199 : // RE-ENGINEERED na
200 :
201 : // PURPOSE OF THIS FUNCTION:
202 : // This function returns the number of branches in a branch list so that the calling
203 : // routine can allocate arrays before calling GetBranchList.
204 :
205 : // Return value
206 : int NumBranchesInBranchList;
207 :
208 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
209 : int Found;
210 :
211 184 : if (state.dataBranchInputManager->GetBranchListInputFlag) {
212 16 : state.dataBranchInputManager->GetBranchListInputFlag = false;
213 16 : GetBranchListInput(state);
214 : }
215 :
216 : // Find this BranchList in the master BranchList Names
217 184 : Found = Util::FindItemInList(BranchListName, state.dataBranchInputManager->BranchList);
218 184 : if (Found == 0) {
219 0 : ShowFatalError(state, format("NumBranchesInBranchList: BranchList Name not found={}", BranchListName));
220 : }
221 :
222 184 : NumBranchesInBranchList = state.dataBranchInputManager->BranchList(Found).NumOfBranchNames;
223 :
224 184 : return NumBranchesInBranchList;
225 : }
226 :
227 549 : void GetBranchData(EnergyPlusData &state,
228 : std::string const &LoopName, // Loop Name of this Branch
229 : std::string const &BranchName, // Requested Branch Name
230 : DataBranchAirLoopPlant::PressureCurveType &PressCurveType, // Index of a pressure curve object
231 : int &PressCurveIndex, // Index of a pressure curve object
232 : int &NumComps, // Number of Components on Branch
233 : Array1D_string &CompType, // Component Type for each item on Branch
234 : Array1D_string &CompName, // Component Name for each item on Branch
235 : Array1D_string &CompInletNodeNames, // Component Inlet Node IDs for each item on Branch
236 : Array1D_int &CompInletNodeNums, // Component Inlet Node Numbers for each item on Branch
237 : Array1D_string &CompOutletNodeNames, // Component Outlet Node IDs for each item on Branch
238 : Array1D_int &CompOutletNodeNums, // Component Outlet Node Numbers for each item on Branch
239 : bool &ErrorsFound)
240 : {
241 :
242 : // SUBROUTINE INFORMATION:
243 : // AUTHOR Linda K. Lawrie
244 : // DATE WRITTEN October 1999
245 : // MODIFIED October 2001, Automatic Extensibility
246 : // September 2012, B. Griffith, removed component control types
247 : // RE-ENGINEERED na
248 :
249 : // PURPOSE OF THIS SUBROUTINE:
250 : // This routine gets the Branch Data (internal structure) for the requested
251 : // Branch Name and returns it in "list structure" to the calling routine.
252 :
253 : // Using/Aliasing
254 :
255 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
256 : int Count; // Loop Counter
257 : int MinCompsAllowed;
258 :
259 : // NumComps now defined on input
260 :
261 549 : state.dataBranchInputManager->BComponents.allocate(NumComps);
262 :
263 549 : GetInternalBranchData(
264 549 : state, LoopName, BranchName, PressCurveType, PressCurveIndex, NumComps, state.dataBranchInputManager->BComponents, ErrorsFound);
265 :
266 3843 : MinCompsAllowed = min(
267 1098 : size(CompType), size(CompName), size(CompInletNodeNames), size(CompInletNodeNums), size(CompOutletNodeNames), size(CompOutletNodeNums));
268 549 : if (MinCompsAllowed < NumComps) {
269 0 : ShowSevereError(state, "GetBranchData: Component List arrays not big enough to hold Number of Components");
270 0 : ShowContinueError(state, format("Input BranchName={}, in Loop={}", BranchName, LoopName));
271 0 : ShowContinueError(state, fmt::format("Max Component Array size={}, but input size={}", MinCompsAllowed, NumComps));
272 0 : ShowFatalError(state, "Program terminates due to preceding conditions.");
273 : }
274 :
275 1226 : for (Count = 1; Count <= NumComps; ++Count) {
276 677 : CompType(Count) = state.dataBranchInputManager->BComponents(Count).CType;
277 677 : CompName(Count) = state.dataBranchInputManager->BComponents(Count).Name;
278 677 : CompInletNodeNames(Count) = state.dataBranchInputManager->BComponents(Count).InletNodeName;
279 677 : CompInletNodeNums(Count) = state.dataBranchInputManager->BComponents(Count).InletNode;
280 677 : CompOutletNodeNames(Count) = state.dataBranchInputManager->BComponents(Count).OutletNodeName;
281 677 : CompOutletNodeNums(Count) = state.dataBranchInputManager->BComponents(Count).OutletNode;
282 : }
283 549 : state.dataBranchInputManager->BComponents.deallocate();
284 549 : }
285 :
286 549 : int NumCompsInBranch(EnergyPlusData &state, std::string const &BranchName)
287 : {
288 :
289 : // FUNCTION INFORMATION:
290 : // AUTHOR Linda K. Lawrie
291 : // DATE WRITTEN July 2003
292 : // MODIFIED na
293 : // RE-ENGINEERED na
294 :
295 : // PURPOSE OF THIS FUNCTION:
296 : // This function returns the number of components in a branch so that the calling
297 : // routine can allocate arrays before calling GetBranchData.
298 :
299 : // Return value
300 : int NumCompsInBranch;
301 :
302 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
303 : int Found;
304 :
305 549 : if (state.dataBranchInputManager->GetBranchInputFlag) {
306 30 : state.dataBranchInputManager->GetBranchInputFlag = false;
307 30 : GetBranchInput(state);
308 : }
309 :
310 549 : Found = Util::FindItemInList(BranchName, state.dataBranchInputManager->Branch);
311 549 : if (Found == 0) {
312 0 : ShowSevereError(state, format("NumCompsInBranch: Branch not found={}", BranchName));
313 0 : NumCompsInBranch = 0;
314 : } else {
315 549 : NumCompsInBranch = state.dataBranchInputManager->Branch(Found).NumOfComponents;
316 : }
317 :
318 549 : return NumCompsInBranch;
319 : }
320 :
321 3 : int GetAirBranchIndex(EnergyPlusData &state, std::string const &CompType, std::string_view CompName)
322 : {
323 :
324 : // FUNCTION INFORMATION:
325 : // AUTHOR Richard Raustad, FSEC
326 : // DATE WRITTEN April 2013
327 : // MODIFIED na
328 : // RE-ENGINEERED na
329 :
330 : // PURPOSE OF THIS FUNCTION:
331 : // This function returns the branch index so that the calling
332 : // routine can search for a fan on this branch or use branch flow for sizing.
333 :
334 : // Return value
335 3 : int GetAirBranchIndex(0);
336 :
337 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
338 : int BranchNum;
339 : int CompNum;
340 : int NumBranches;
341 :
342 3 : if (state.dataBranchInputManager->GetBranchInputFlag) {
343 1 : state.dataBranchInputManager->GetBranchInputFlag = false;
344 1 : GetBranchInput(state);
345 : }
346 :
347 3 : NumBranches = size(state.dataBranchInputManager->Branch);
348 :
349 3 : if (NumBranches == 0) {
350 0 : ShowSevereError(state, format("GetAirBranchIndex: Branch not found with component = {} \"{}\"", CompType, CompName));
351 : } else {
352 6 : for (BranchNum = 1; BranchNum <= NumBranches; ++BranchNum) {
353 14 : for (CompNum = 1; CompNum <= state.dataBranchInputManager->Branch(BranchNum).NumOfComponents; ++CompNum) {
354 14 : if (Util::SameString(CompType, state.dataBranchInputManager->Branch(BranchNum).Component(CompNum).CType) &&
355 3 : Util::SameString(CompName, state.dataBranchInputManager->Branch(BranchNum).Component(CompNum).Name)) {
356 2 : GetAirBranchIndex = BranchNum;
357 2 : goto BranchLoop_exit;
358 : }
359 : }
360 : }
361 3 : BranchLoop_exit:;
362 : }
363 :
364 3 : return GetAirBranchIndex;
365 : }
366 :
367 0 : void GetBranchFanTypeName(EnergyPlusData &state,
368 : int const BranchNum,
369 : std::string &FanType,
370 : std::string &FanName,
371 : bool &ErrFound // Set to true if error found, false otherwise
372 : )
373 : {
374 :
375 : // FUNCTION INFORMATION:
376 : // AUTHOR Richard Raustad, FSEC
377 : // DATE WRITTEN April 2013
378 : // MODIFIED na
379 : // RE-ENGINEERED na
380 :
381 : // PURPOSE OF THIS FUNCTION:
382 : // This function returns the branch fan flow rate so that the calling
383 : // routine can either use this flow or use then branch flow for sizing.
384 :
385 : // Using/Aliasing
386 :
387 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
388 : int CompNum;
389 : int NumBranches;
390 :
391 0 : if (state.dataBranchInputManager->GetBranchInputFlag) {
392 0 : state.dataBranchInputManager->GetBranchInputFlag = false;
393 0 : GetBranchInput(state);
394 : }
395 :
396 0 : ErrFound = false;
397 0 : NumBranches = size(state.dataBranchInputManager->Branch);
398 :
399 0 : FanType = std::string();
400 0 : FanName = std::string();
401 :
402 0 : if (NumBranches == 0) {
403 0 : ShowSevereError(state, fmt::format("GetBranchFanTypeName: Branch index not found = {}", BranchNum));
404 0 : ErrFound = true;
405 : } else {
406 0 : if (BranchNum > 0 && BranchNum <= NumBranches) {
407 0 : for (CompNum = 1; CompNum <= state.dataBranchInputManager->Branch(BranchNum).NumOfComponents; ++CompNum) {
408 0 : if (Util::SameString("Fan:OnOff", state.dataBranchInputManager->Branch(BranchNum).Component(CompNum).CType) ||
409 0 : Util::SameString("Fan:ConstantVolume", state.dataBranchInputManager->Branch(BranchNum).Component(CompNum).CType) ||
410 0 : Util::SameString("Fan:VariableVolume", state.dataBranchInputManager->Branch(BranchNum).Component(CompNum).CType) ||
411 0 : Util::SameString("Fan:SystemModel", state.dataBranchInputManager->Branch(BranchNum).Component(CompNum).CType)) {
412 0 : FanType = state.dataBranchInputManager->Branch(BranchNum).Component(CompNum).CType;
413 0 : FanName = state.dataBranchInputManager->Branch(BranchNum).Component(CompNum).Name;
414 0 : break;
415 : }
416 : }
417 0 : if (FanType.empty()) ErrFound = true;
418 : } else {
419 0 : ShowSevereError(state, fmt::format("GetBranchFanTypeName: Branch index not found = {}", BranchNum));
420 0 : ErrFound = true;
421 : }
422 : }
423 0 : }
424 :
425 1277 : void GetInternalBranchData(EnergyPlusData &state,
426 : std::string const &LoopName, // Loop Name for Branch
427 : std::string const &BranchName, // Requested Branch Name
428 : DataBranchAirLoopPlant::PressureCurveType &PressCurveType, // Index of pressure curve object
429 : int &PressCurveIndex, // Index of pressure curve object
430 : int &NumComps, // Number of Components on Branch
431 : Array1D<ComponentData> const &BComponents, // Component data returned
432 : bool &ErrorsFound // True when Loop Name is already assigned and this not same loop
433 : )
434 : {
435 :
436 : // SUBROUTINE INFORMATION:
437 : // AUTHOR Linda K. Lawrie
438 : // DATE WRITTEN October 1999
439 : // MODIFIED na
440 : // RE-ENGINEERED na
441 :
442 : // PURPOSE OF THIS SUBROUTINE:
443 : // This routine gets the Branch Data (internal structure) for the requested
444 : // Branch Name and returns it to the calling routine. This is used internally
445 : // in the module.
446 :
447 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
448 : int Found; // Pointer to requested Branch Name
449 :
450 1277 : if (state.dataBranchInputManager->GetBranchInputFlag) {
451 0 : GetBranchInput(state);
452 0 : state.dataBranchInputManager->GetBranchInputFlag = false;
453 : }
454 :
455 1277 : Found = Util::FindItemInList(BranchName, state.dataBranchInputManager->Branch);
456 1277 : if (Found == 0) {
457 0 : ShowSevereError(state, format("GetInternalBranchData: Branch not found={}", BranchName));
458 0 : ErrorsFound = true;
459 0 : NumComps = 0;
460 : } else {
461 1277 : if (state.dataBranchInputManager->Branch(Found).AssignedLoopName.empty()) {
462 549 : state.dataBranchInputManager->Branch(Found).AssignedLoopName = LoopName;
463 549 : PressCurveType = state.dataBranchInputManager->Branch(Found).PressureCurveType;
464 549 : PressCurveIndex = state.dataBranchInputManager->Branch(Found).PressureCurveIndex;
465 549 : NumComps = state.dataBranchInputManager->Branch(Found).NumOfComponents;
466 549 : BComponents({1, NumComps}) = state.dataBranchInputManager->Branch(Found).Component({1, NumComps});
467 728 : } else if (state.dataBranchInputManager->Branch(Found).AssignedLoopName != LoopName) {
468 0 : ShowSevereError(state, format("Attempt to assign branch to two different loops, Branch={}", BranchName));
469 0 : ShowContinueError(state, format("Branch already assigned to loop={}", state.dataBranchInputManager->Branch(Found).AssignedLoopName));
470 0 : ShowContinueError(state, format("New attempt to assign to loop={}", LoopName));
471 0 : ErrorsFound = true;
472 0 : NumComps = 0;
473 : } else {
474 728 : PressCurveType = state.dataBranchInputManager->Branch(Found).PressureCurveType;
475 728 : PressCurveIndex = state.dataBranchInputManager->Branch(Found).PressureCurveIndex;
476 728 : NumComps = state.dataBranchInputManager->Branch(Found).NumOfComponents;
477 728 : BComponents({1, NumComps}) = state.dataBranchInputManager->Branch(Found).Component({1, NumComps});
478 : }
479 : }
480 1277 : }
481 :
482 122 : void GetNumSplitterMixerInConntrList(EnergyPlusData &state,
483 : std::string const &LoopName, // Loop Name for this Splitter (used in error message)
484 : std::string const &ConnectorListName, // Requested Connector List Name
485 : int &numSplitters, // Number of splitters in the loop
486 : int &numMixers, // Number of mixers in the loop
487 : bool &ErrorsFound // if no connector list
488 : )
489 : {
490 :
491 : // SUBROUTINE INFORMATION:
492 : // AUTHOR Sankaranarayanan K P
493 : // DATE WRITTEN April 2005
494 : // MODIFIED Linda Lawrie - September 2005
495 : // RE-ENGINEERED na
496 :
497 : // PURPOSE OF THIS SUBROUTINE:
498 : // This subroutine returns the number of splitter and mixers in a connector list item
499 : // The data is filled from the idd object 'ConnectorList'
500 :
501 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
502 : int ConnNum;
503 :
504 122 : if (state.dataBranchInputManager->GetConnectorListInputFlag) {
505 43 : GetConnectorListInput(state);
506 43 : state.dataBranchInputManager->GetConnectorListInputFlag = false;
507 : }
508 :
509 122 : numSplitters = 0;
510 122 : numMixers = 0;
511 122 : ConnNum = Util::FindItemInList(ConnectorListName, state.dataBranchInputManager->ConnectorLists);
512 :
513 122 : if (ConnNum > 0) {
514 122 : numSplitters = state.dataBranchInputManager->ConnectorLists(ConnNum).NumOfSplitters;
515 122 : numMixers = state.dataBranchInputManager->ConnectorLists(ConnNum).NumOfMixers;
516 : } else {
517 0 : ShowSevereError(state, format("Ref: Loop={}, Connector List not found={}", LoopName, ConnectorListName));
518 0 : ErrorsFound = true;
519 : }
520 122 : }
521 :
522 366 : void GetConnectorList(EnergyPlusData &state,
523 : std::string const &ConnectorListName, // Requested Connector List
524 : ConnectorData &Connectoid, // Returned Connector Data
525 : ObjexxFCL::Optional_int_const NumInList // Number of the current connector in the list of connectors
526 : )
527 : {
528 :
529 : // SUBROUTINE INFORMATION:
530 : // AUTHOR Linda K. Lawrie
531 : // DATE WRITTEN October 1999
532 :
533 : // PURPOSE OF THIS SUBROUTINE:
534 : // Obtains connector data for requested connector list. Also,
535 : // this subroutine gets the input for the following IDD structure:
536 : // ConnectorList,
537 : // \memo only two connectors allowed per loop
538 : // \memo if two entered, one must be Connector:Splitter and one must be Connector:Mixer
539 : // A1, \field Name
540 : // \required-field
541 : // \reference ConnectorLists
542 : // A2, \field Connector 1 Object Type
543 : // \required-field
544 : // \key Connector:Splitter
545 : // \key Connector:Mixer
546 : // A3, \field Connector 1 Name
547 : // \required-field
548 : // A4, \field Connector 2 Object Type
549 : // \key Connector:Splitter
550 : // \key Connector:Mixer
551 : // A5; \field Connector 2 Name
552 :
553 366 : if (state.dataBranchInputManager->GetConnectorListInputFlag) {
554 0 : GetConnectorListInput(state);
555 0 : state.dataBranchInputManager->GetConnectorListInputFlag = false;
556 : }
557 :
558 366 : if (not_blank(ConnectorListName)) {
559 366 : int Count = Util::FindItemInList(ConnectorListName, state.dataBranchInputManager->ConnectorLists);
560 366 : if (Count == 0) {
561 0 : ShowFatalError(state, format("GetConnectorList: Connector List not found={}", ConnectorListName));
562 : }
563 366 : Connectoid = state.dataBranchInputManager->ConnectorLists(Count);
564 366 : if (present(NumInList)) {
565 366 : Connectoid.ConnectorType(1) = state.dataBranchInputManager->ConnectorLists(Count).ConnectorType(NumInList);
566 366 : Connectoid.ConnectorName(1) = state.dataBranchInputManager->ConnectorLists(Count).ConnectorName(NumInList);
567 366 : Connectoid.ConnectorType(2) = "";
568 366 : Connectoid.ConnectorName(2) = "";
569 : }
570 : } else {
571 0 : Connectoid.Name = "";
572 0 : Connectoid.NumOfConnectors = 0;
573 0 : Connectoid.ConnectorType(1) = "";
574 0 : Connectoid.ConnectorType(2) = "";
575 0 : Connectoid.ConnectorName(1) = "";
576 0 : Connectoid.ConnectorName(2) = "";
577 : }
578 366 : }
579 :
580 244 : void GetLoopMixer(EnergyPlusData &state,
581 : std::string const &LoopName, // Loop Name for Mixer
582 : std::string const &ConnectorListName, // Requested Connector List Name
583 : std::string &MixerName, // Name of Mixer
584 : bool &IsMixer, // True when Mixer is on this connector, false otherwise
585 : std::string &OutletNodeName, // Outlet Node ID
586 : int &OutletNodeNum, // Outlet Node Number
587 : int &NumInletNodes, // Number of Inlet Nodes
588 : Array1D_string &InletNodeNames, // Inlet Node IDs
589 : Array1D_int &InletNodeNums, // Inlet Node Numbers
590 : bool &ErrorsFound,
591 : ObjexxFCL::Optional_int_const ConnectorNumber, // number of the current item in connector list
592 : ObjexxFCL::Optional_int MixerNumber // Mixer number for this specific splitter
593 : )
594 : {
595 :
596 : // SUBROUTINE INFORMATION:
597 : // AUTHOR Linda K. Lawrie
598 : // DATE WRITTEN October 1999
599 : // MODIFIED October 2001, Automatic Extensibility
600 :
601 : // PURPOSE OF THIS SUBROUTINE:
602 : // This routine gets the data for the requested Connector List and returns values indicating
603 : // if this connector list name is a mixer or not.
604 :
605 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
606 : int Count; // Loop Counter
607 : DataBranchAirLoopPlant::PressureCurveType PressCurveType;
608 :
609 : // Object Data
610 244 : ConnectorData Connectoid; // Connector Data
611 244 : Array1D<ComponentData> BComponents; // Branch Component Data
612 :
613 244 : if (state.dataBranchInputManager->GetMixerInputFlag) {
614 0 : GetMixerInput(state);
615 0 : state.dataBranchInputManager->GetMixerInputFlag = false;
616 : }
617 :
618 244 : GetConnectorList(state, ConnectorListName, Connectoid, ConnectorNumber);
619 244 : if (Util::SameString(Connectoid.ConnectorType(1), cMIXER)) {
620 122 : Count = Util::FindItemInList(Connectoid.ConnectorName(1), state.dataBranchInputManager->Mixers);
621 122 : if (present(MixerNumber)) ++MixerNumber;
622 122 : if (Count == 0) {
623 0 : ShowFatalError(state, format("GetLoopMixer: No Mixer Found={}", Connectoid.ConnectorName(1)));
624 : }
625 122 : } else if (Util::SameString(Connectoid.ConnectorType(2), cMIXER)) {
626 0 : Count = Util::FindItemInList(Connectoid.ConnectorName(2), state.dataBranchInputManager->Mixers);
627 0 : if (Count == 0) {
628 0 : ShowFatalError(state, format("GetLoopMixer: No Mixer Found={}", Connectoid.ConnectorName(2)));
629 : }
630 : } else {
631 122 : Count = 0;
632 : }
633 :
634 : // Set defaults for later error potential
635 244 : IsMixer = false;
636 244 : MixerName = std::string();
637 244 : OutletNodeName = std::string();
638 244 : OutletNodeNum = 0;
639 244 : NumInletNodes = 0;
640 244 : InletNodeNames = "";
641 244 : InletNodeNums = 0;
642 :
643 244 : if (Count != 0) { // Build up Output list(s). For each component(?)
644 :
645 : int NumParams;
646 : int NumAlphas;
647 : int NumNumbers;
648 : // The inlet nodes for the mixer will be the last "outlet" node of
649 : // each corresponding inlet branch. The outlet node for the mixer
650 : // will be the first "inlet" node of the outlet branch since that
651 : // would be the first node on the branch.
652 122 : MixerName = state.dataBranchInputManager->Mixers(Count).Name;
653 122 : IsMixer = true;
654 : // The number of "components" on a Mixer is the number of branches. This is the number of alpha arguments -1.
655 122 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Branch", NumParams, NumAlphas, NumNumbers);
656 122 : BComponents.allocate(NumAlphas - 1);
657 122 : bool errFlag = false;
658 : int PressCurveIndex;
659 : int NumComps; // Number of Components on this Branch
660 122 : GetInternalBranchData(state,
661 : LoopName,
662 122 : state.dataBranchInputManager->Mixers(Count).OutletBranchName,
663 : PressCurveType,
664 : PressCurveIndex,
665 : NumComps,
666 : BComponents,
667 : errFlag);
668 122 : if (errFlag) {
669 0 : ShowContinueError(state, format("..occurs for Connector:Mixer Name={}", state.dataBranchInputManager->Mixers(Count).Name));
670 0 : ErrorsFound = true;
671 : }
672 122 : if (NumComps > 0) {
673 122 : OutletNodeName = BComponents(1).InletNodeName;
674 122 : OutletNodeNum = BComponents(1).InletNode;
675 122 : NumInletNodes = state.dataBranchInputManager->Mixers(Count).NumInletBranches;
676 : // Register this node connection because the mixer gets node information indirectly from the branch
677 122 : errFlag = false;
678 244 : RegisterNodeConnection(state,
679 : OutletNodeNum,
680 122 : state.dataLoopNodes->NodeID(OutletNodeNum),
681 : DataLoopNode::ConnectionObjectType::ConnectorMixer,
682 : MixerName,
683 : DataLoopNode::ConnectionType::Outlet,
684 : NodeInputManager::CompFluidStream::Primary,
685 : ObjectIsNotParent,
686 : errFlag);
687 :
688 122 : if (NumInletNodes > isize(InletNodeNames) || NumInletNodes > isize(InletNodeNums)) {
689 0 : ShowSevereError(state, format("GetLoopMixer: Connector:Mixer={} contains too many inlets for size of Inlet Array.", MixerName));
690 0 : ShowContinueError(state, fmt::format("Max array size={}, Mixer statement inlets={}", size(InletNodeNames), NumInletNodes));
691 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
692 : }
693 122 : InletNodeNums = 0;
694 122 : InletNodeNames = "";
695 :
696 364 : for (int Loop = 1; Loop <= state.dataBranchInputManager->Mixers(Count).NumInletBranches; ++Loop) {
697 242 : GetInternalBranchData(state,
698 : LoopName,
699 242 : state.dataBranchInputManager->Mixers(Count).InletBranchNames(Loop),
700 : PressCurveType,
701 : PressCurveIndex,
702 : NumComps,
703 : BComponents,
704 : ErrorsFound);
705 242 : if (NumComps > 0) {
706 242 : InletNodeNames(Loop) = BComponents(NumComps).OutletNodeName;
707 242 : InletNodeNums(Loop) = BComponents(NumComps).OutletNode;
708 : // Register this node connection because the mixer gets node information indirectly from the branch
709 242 : errFlag = false;
710 484 : RegisterNodeConnection(state,
711 242 : InletNodeNums(Loop),
712 242 : state.dataLoopNodes->NodeID(InletNodeNums(Loop)),
713 : DataLoopNode::ConnectionObjectType::ConnectorMixer,
714 : MixerName,
715 : DataLoopNode::ConnectionType::Inlet,
716 : NodeInputManager::CompFluidStream::Primary,
717 : ObjectIsNotParent,
718 : errFlag);
719 : }
720 : }
721 : } else {
722 : // Set so cascading errors don't happen?
723 0 : IsMixer = false;
724 : }
725 122 : BComponents.deallocate();
726 : }
727 244 : }
728 :
729 122 : void GetLoopSplitter(EnergyPlusData &state,
730 : std::string const &LoopName, // Loop Name for this Splitter
731 : std::string const &ConnectorListName, // Requested Connector List Name
732 : std::string &SplitterName, // Name of Splitter
733 : bool &IsSplitter, // True if splitter on this connector list, false otherwise
734 : std::string &InletNodeName, // Inlet Node ID
735 : int &InletNodeNum, // Inlet Node Number
736 : int &NumOutletNodes, // Number of Outlet Nodes
737 : Array1D_string &OutletNodeNames, // Outlet Node IDs
738 : Array1D_int &OutletNodeNums, // Outlet Node Numbers
739 : bool &ErrorsFound,
740 : ObjexxFCL::Optional_int_const ConnectorNumber, // number of the current item in connector list
741 : ObjexxFCL::Optional_int SplitterNumber // splitter number for this specific splitter
742 : )
743 : {
744 :
745 : // SUBROUTINE INFORMATION:
746 : // AUTHOR Linda K. Lawrie
747 : // DATE WRITTEN October 1999
748 : // MODIFIED October 2001, Automatic Extensibility
749 :
750 : // PURPOSE OF THIS SUBROUTINE:
751 : // This routine gets the data for the requested Connector List and returns values indicating
752 : // if this connector list name is a splitter or not.
753 :
754 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
755 : int Count; // Loop Counter
756 : DataBranchAirLoopPlant::PressureCurveType PressCurveType;
757 :
758 : // Object Data
759 122 : ConnectorData Connectoid; // Connector Data
760 122 : Array1D<ComponentData> BComponents; // Branch Component Data
761 :
762 122 : if (state.dataBranchInputManager->GetSplitterInputFlag) {
763 0 : GetSplitterInput(state);
764 0 : state.dataBranchInputManager->GetSplitterInputFlag = false;
765 : }
766 :
767 122 : if (ConnectorListName.empty()) {
768 0 : ShowSevereError(state, format("GetLoopSplitter: ConnectorListName is blank. LoopName={}", LoopName));
769 0 : ShowFatalError(state, "Program terminates due to previous condition.");
770 : }
771 122 : GetConnectorList(state, ConnectorListName, Connectoid, ConnectorNumber);
772 122 : if (Util::SameString(Connectoid.ConnectorType(1), cSPLITTER)) {
773 122 : Count = Util::FindItemInList(Connectoid.ConnectorName(1), state.dataBranchInputManager->Splitters);
774 122 : if (present(SplitterNumber)) ++SplitterNumber;
775 122 : if (Count == 0) {
776 0 : ShowFatalError(state, format("GetLoopSplitter: No Splitter Found={}", Connectoid.ConnectorName(1)));
777 : }
778 0 : } else if (Util::SameString(Connectoid.ConnectorType(2), cSPLITTER)) {
779 0 : Count = Util::FindItemInList(Connectoid.ConnectorName(2), state.dataBranchInputManager->Splitters);
780 0 : if (Count == 0) {
781 0 : ShowFatalError(state, format("GetLoopSplitter: No Splitter Found={}", Connectoid.ConnectorName(2)));
782 : }
783 : } else {
784 0 : Count = 0;
785 : }
786 :
787 : // Default for any errors
788 122 : SplitterName = std::string();
789 122 : IsSplitter = false;
790 122 : InletNodeName = std::string();
791 122 : InletNodeNum = 0;
792 122 : NumOutletNodes = 0;
793 122 : OutletNodeNames = "";
794 122 : OutletNodeNums = 0;
795 :
796 122 : if (Count != 0) { // Build up Output list(s). For each component(?)
797 :
798 : int NumComps; // Number of Components on this Branch
799 : int NumParams;
800 : int NumAlphas;
801 : int NumNumbers;
802 : int PressCurveIndex;
803 :
804 : // The inlet node for the splitter will be the last "outlet" node of the inlet
805 : // branch. The outlet nodes for the splitter will be the first "inlet" node of
806 : // each corresponding outlet branch since that would be the first node on the branch.
807 :
808 122 : SplitterName = state.dataBranchInputManager->Splitters(Count).Name;
809 122 : IsSplitter = true;
810 : // The number of "components" on a Splitter is the number of branches. This is the number of alpha arguments -1.
811 122 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Branch", NumParams, NumAlphas, NumNumbers);
812 122 : BComponents.allocate(NumAlphas - 1);
813 122 : bool errFlag = false;
814 122 : GetInternalBranchData(state,
815 : LoopName,
816 122 : state.dataBranchInputManager->Splitters(Count).InletBranchName,
817 : PressCurveType,
818 : PressCurveIndex,
819 : NumComps,
820 : BComponents,
821 : errFlag);
822 122 : if (errFlag) {
823 0 : ShowContinueError(state, format("..occurs for Splitter Name={}", state.dataBranchInputManager->Splitters(Count).Name));
824 0 : ErrorsFound = true;
825 : }
826 122 : if (NumComps > 0) {
827 122 : InletNodeName = BComponents(NumComps).OutletNodeName;
828 122 : InletNodeNum = BComponents(NumComps).OutletNode;
829 122 : NumOutletNodes = state.dataBranchInputManager->Splitters(Count).NumOutletBranches;
830 : // Register this node connection because the splitter gets node information indirectly from the branch
831 122 : errFlag = false;
832 244 : RegisterNodeConnection(state,
833 : InletNodeNum,
834 122 : state.dataLoopNodes->NodeID(InletNodeNum),
835 : DataLoopNode::ConnectionObjectType::ConnectorSplitter,
836 : SplitterName,
837 : DataLoopNode::ConnectionType::Inlet,
838 : NodeInputManager::CompFluidStream::Primary,
839 : ObjectIsNotParent,
840 : errFlag);
841 :
842 122 : if (NumOutletNodes > isize(OutletNodeNames) || NumOutletNodes > isize(OutletNodeNums)) {
843 0 : ShowSevereError(
844 0 : state, format("GetLoopSplitter: Connector:Splitter={} contains too many outlets for size of Outlet Array.", SplitterName));
845 0 : ShowContinueError(state, fmt::format("Max array size={}, Splitter statement outlets={}", size(OutletNodeNames), NumOutletNodes));
846 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
847 : }
848 122 : OutletNodeNums = 0;
849 122 : OutletNodeNames = "";
850 :
851 364 : for (int Loop = 1; Loop <= state.dataBranchInputManager->Splitters(Count).NumOutletBranches; ++Loop) {
852 242 : GetInternalBranchData(state,
853 : LoopName,
854 242 : state.dataBranchInputManager->Splitters(Count).OutletBranchNames(Loop),
855 : PressCurveType,
856 : PressCurveIndex,
857 : NumComps,
858 : BComponents,
859 : ErrorsFound);
860 242 : if (NumComps > 0) {
861 242 : OutletNodeNames(Loop) = BComponents(1).InletNodeName;
862 242 : OutletNodeNums(Loop) = BComponents(1).InletNode;
863 : // Register this node connection because the splitter gets node information indirectly from the branch
864 242 : errFlag = false;
865 484 : RegisterNodeConnection(state,
866 242 : OutletNodeNums(Loop),
867 242 : state.dataLoopNodes->NodeID(OutletNodeNums(Loop)),
868 : DataLoopNode::ConnectionObjectType::ConnectorSplitter,
869 : SplitterName,
870 : DataLoopNode::ConnectionType::Outlet,
871 : NodeInputManager::CompFluidStream::Primary,
872 : ObjectIsNotParent,
873 : errFlag);
874 : }
875 : }
876 : } else {
877 : // Set so cascading errors don't happen
878 0 : IsSplitter = false;
879 : }
880 122 : BComponents.deallocate();
881 : }
882 122 : }
883 :
884 124 : std::string GetFirstBranchInletNodeName(EnergyPlusData &state, std::string const &BranchListName) // Branch List name to search
885 : {
886 :
887 : // FUNCTION INFORMATION:
888 : // AUTHOR Linda K. Lawrie
889 : // DATE WRITTEN November 2004
890 :
891 : // PURPOSE OF THIS FUNCTION:
892 : // This function uses the branch structure to obtain the inlet node
893 : // of the first branch from referenced Branch List.
894 :
895 : // Return value
896 124 : std::string InletNodeName; // Inlet node name of first branch in branch list
897 :
898 124 : if (state.dataBranchInputManager->GetBranchListInputFlag) {
899 15 : state.dataBranchInputManager->GetBranchListInputFlag = false;
900 15 : GetBranchListInput(state);
901 : }
902 :
903 124 : int Found1 = Util::FindItemInList(BranchListName, state.dataBranchInputManager->BranchList);
904 124 : if (Found1 == 0) {
905 0 : ShowSevereError(state, format("GetFirstBranchInletNodeName: BranchList=\"{}\", not a valid BranchList Name", BranchListName));
906 0 : InletNodeName = "Invalid Node Name";
907 : } else {
908 124 : int Found2 = Util::FindItemInList(state.dataBranchInputManager->BranchList(Found1).BranchNames(1), state.dataBranchInputManager->Branch);
909 124 : if (Found2 == 0) {
910 0 : ShowSevereError(state,
911 0 : format("GetFirstBranchInletNodeName: BranchList=\"{}\", Branch=\"{}\" not a valid Branch Name",
912 : BranchListName,
913 0 : state.dataBranchInputManager->BranchList(Found1).BranchNames(1)));
914 0 : InletNodeName = "Invalid Node Name";
915 : } else {
916 124 : InletNodeName = state.dataBranchInputManager->Branch(Found2).Component(1).InletNodeName;
917 : }
918 : }
919 :
920 124 : return InletNodeName;
921 0 : }
922 :
923 124 : std::string GetLastBranchOutletNodeName(EnergyPlusData &state, std::string const &BranchListName) // Branch List name to search
924 : {
925 :
926 : // FUNCTION INFORMATION:
927 : // AUTHOR Linda K. Lawrie
928 : // DATE WRITTEN August 2003
929 :
930 : // PURPOSE OF THIS FUNCTION:
931 : // This function uses the branch structure to obtain the outlet node
932 : // of the last branch from referenced Branch List.
933 :
934 : // Return value
935 124 : std::string OutletNodeName; // Outlet node name of last branch in branch list
936 :
937 124 : if (state.dataBranchInputManager->GetBranchListInputFlag) {
938 0 : state.dataBranchInputManager->GetBranchListInputFlag = false;
939 0 : GetBranchListInput(state);
940 : }
941 :
942 124 : int Found1 = Util::FindItemInList(BranchListName, state.dataBranchInputManager->BranchList);
943 124 : if (Found1 == 0) {
944 0 : ShowSevereError(state, format("GetLastBranchOutletNodeName: BranchList=\"{}\", not a valid BranchList Name", BranchListName));
945 0 : OutletNodeName = "Invalid Node Name";
946 : } else {
947 124 : int Found2 = Util::FindItemInList(
948 124 : state.dataBranchInputManager->BranchList(Found1).BranchNames(state.dataBranchInputManager->BranchList(Found1).NumOfBranchNames),
949 124 : state.dataBranchInputManager->Branch);
950 124 : if (Found2 == 0) {
951 0 : ShowSevereError(state,
952 0 : format("GetLastBranchOutletNodeName: BranchList=\"{}\", Branch=\"{}\" not a valid Branch Name",
953 : BranchListName,
954 0 : state.dataBranchInputManager->BranchList(Found1).BranchNames(
955 0 : state.dataBranchInputManager->BranchList(Found1).NumOfBranchNames)));
956 0 : OutletNodeName = "Invalid Node Name";
957 : } else {
958 124 : OutletNodeName = state.dataBranchInputManager->Branch(Found2)
959 124 : .Component(state.dataBranchInputManager->Branch(Found2).NumOfComponents)
960 124 : .OutletNodeName;
961 : }
962 : }
963 :
964 124 : return OutletNodeName;
965 0 : }
966 :
967 : //==================================================================================
968 : // Routines that get the input for the internal branch management structure
969 : //==================================================================================
970 :
971 253 : void GetBranchInput(EnergyPlusData &state)
972 : {
973 :
974 : // SUBROUTINE INFORMATION:
975 : // AUTHOR Linda K. Lawrie
976 : // DATE WRITTEN October 1999
977 : // MODIFIED October 2001, Automatic Extensibility
978 :
979 : // PURPOSE OF THIS SUBROUTINE:
980 : // This subroutine gets the input for the following IDD structure:
981 : // Branch,
982 : // \extensible:4 Just duplicate last 4 fields and \ comments (changing numbering, please)
983 : // \memo List components on the branch in simulation and connection order
984 : // \memo Note: this should NOT include splitters or mixers which define
985 : // \memo endpoints of branches
986 : // A1, \field Name
987 : // \required-field
988 : // \reference Branches
989 : // N1, \field Maximum Flow Rate
990 : // \default 0
991 : // \units m3/s
992 : // \minimum 0
993 : // \autosizable
994 : // A2, \field Pressure Curve Name
995 : // \type object-list
996 : // \reference AllCurves
997 : // A3, \field Component 1 Object Type
998 : // \required-field
999 : // A4, \field Component 1 Name
1000 : // \required-field
1001 : // A5, \field Component 1 Inlet Node Name
1002 : // \required-field
1003 : // A6, \field Component 1 Outlet Node Name
1004 : // \required-field
1005 :
1006 : // SUBROUTINE PARAMETER DEFINITIONS:
1007 : static constexpr std::string_view RoutineName("GetBranchInput: ");
1008 :
1009 : // INTERFACE BLOCK SPECIFICATIONS
1010 : // na
1011 :
1012 253 : Array1D_string Alphas; // Used to retrieve names from IDF
1013 253 : Array1D_int NodeNums; // Possible Array of Node Numbers (only 1 allowed)
1014 253 : Array1D<Real64> Numbers; // Used to retrieve numbers from IDF
1015 253 : Array1D_string cAlphaFields;
1016 253 : Array1D_string cNumericFields;
1017 253 : Array1D_bool lNumericBlanks;
1018 253 : Array1D_bool lAlphaBlanks;
1019 :
1020 253 : if (state.dataBranchInputManager->GetBranchInputOneTimeFlag) {
1021 137 : std::string CurrentModuleObject = "Branch";
1022 137 : int NumOfBranches = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
1023 :
1024 137 : if (NumOfBranches > 0) {
1025 86 : state.dataBranchInputManager->Branch.allocate(NumOfBranches);
1026 : int NumNumbers; // Used to retrieve numbers from IDF
1027 : int NumAlphas; // Used to retrieve names from IDF
1028 : int NumParams;
1029 86 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "NodeList", NumParams, NumAlphas, NumNumbers);
1030 86 : NodeNums.dimension(NumParams, 0);
1031 86 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNumbers);
1032 86 : Alphas.allocate(NumAlphas);
1033 86 : Numbers.dimension(NumNumbers, 0.0);
1034 86 : cAlphaFields.allocate(NumAlphas);
1035 86 : cNumericFields.allocate(NumNumbers);
1036 86 : lAlphaBlanks.dimension(NumAlphas, true);
1037 86 : lNumericBlanks.dimension(NumNumbers, true);
1038 86 : int BCount = 0; // Actual Num of Branches
1039 : int IOStat; // Could be used in the Get Routines, not currently checked
1040 643 : for (int Count = 1; Count <= NumOfBranches; ++Count) {
1041 557 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1042 : CurrentModuleObject,
1043 : Count,
1044 : Alphas,
1045 : NumAlphas,
1046 : Numbers,
1047 : NumNumbers,
1048 : IOStat,
1049 : lNumericBlanks,
1050 : lAlphaBlanks,
1051 : cAlphaFields,
1052 : cNumericFields);
1053 557 : ++BCount;
1054 557 : GetSingleBranchInput(state, RoutineName, BCount, Alphas, cAlphaFields, NumAlphas, NodeNums, lAlphaBlanks);
1055 : }
1056 :
1057 86 : NumOfBranches = BCount;
1058 86 : NodeNums.deallocate();
1059 86 : Alphas.deallocate();
1060 86 : Numbers.deallocate();
1061 86 : cAlphaFields.deallocate();
1062 86 : cNumericFields.deallocate();
1063 86 : lAlphaBlanks.deallocate();
1064 86 : lNumericBlanks.deallocate();
1065 86 : TestInletOutletNodes(state);
1066 86 : state.dataBranchInputManager->GetBranchInputOneTimeFlag = false;
1067 : }
1068 137 : }
1069 253 : }
1070 :
1071 559 : void GetSingleBranchInput(EnergyPlusData &state,
1072 : std::string_view const RoutineName,
1073 : int const BCount,
1074 : Array1D_string const &Alphas,
1075 : Array1D_string const &cAlphaFields,
1076 : int const NumAlphas,
1077 : Array1D_int &NodeNums,
1078 : Array1D_bool const &lAlphaBlanks)
1079 : {
1080 : // Locals
1081 : PressureCurveType pressureCurveType;
1082 : int PressureCurveIndex;
1083 : bool ErrFound; // Flag for error detection
1084 : int Comp; // Loop Counter
1085 : bool IsNotOK; // Flag to verify name
1086 : int NumInComps; // Number of components actually verified (no SPLITTER or MIXER allowed)
1087 : DataLoopNode::ConnectionType ConnectionType; // Used to pass variable node connection type to GetNodeNums
1088 : int NumNodes; // Number of Nodes from NodeInputManager
1089 :
1090 559 : std::string CurrentModuleObject = "Branch";
1091 :
1092 559 : state.dataBranchInputManager->Branch(BCount).Name = Alphas(1);
1093 559 : Curve::GetPressureCurveTypeAndIndex(state, Alphas(2), pressureCurveType, PressureCurveIndex);
1094 559 : if (pressureCurveType == DataBranchAirLoopPlant::PressureCurveType::Invalid) {
1095 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid data.", RoutineName, CurrentModuleObject, Alphas(1)));
1096 0 : ShowContinueError(state, format("..Invalid {}=\"{}\".", cAlphaFields(2), Alphas(2)));
1097 0 : ShowContinueError(state, "This curve could not be found in the input deck. Ensure that this curve has been entered");
1098 0 : ShowContinueError(state, " as either a Curve:Functional:PressureDrop or one of Curve:{Linear,Quadratic,Cubic,Exponent}");
1099 0 : ShowContinueError(state, "This error could be caused by a misspelled curve name");
1100 0 : ErrFound = true;
1101 : }
1102 559 : state.dataBranchInputManager->Branch(BCount).PressureCurveType = pressureCurveType;
1103 559 : state.dataBranchInputManager->Branch(BCount).PressureCurveIndex = PressureCurveIndex;
1104 559 : state.dataBranchInputManager->Branch(BCount).NumOfComponents = (NumAlphas - 2) / 4;
1105 559 : if (state.dataBranchInputManager->Branch(BCount).NumOfComponents * 4 != (NumAlphas - 2))
1106 0 : ++state.dataBranchInputManager->Branch(BCount).NumOfComponents;
1107 559 : NumInComps = state.dataBranchInputManager->Branch(BCount).NumOfComponents;
1108 559 : state.dataBranchInputManager->Branch(BCount).Component.allocate(state.dataBranchInputManager->Branch(BCount).NumOfComponents);
1109 559 : Comp = 1;
1110 1255 : for (int Loop = 3; Loop <= NumAlphas; Loop += 4) {
1111 696 : if (Util::SameString(Alphas(Loop), cSPLITTER) || Util::SameString(Alphas(Loop), cMIXER)) {
1112 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid data.", RoutineName, CurrentModuleObject, Alphas(1)));
1113 0 : ShowContinueError(state, format("Connector:Splitter/Connector:Mixer not allowed in object {}", CurrentModuleObject));
1114 0 : ErrFound = true;
1115 0 : continue;
1116 : }
1117 696 : if (Comp > NumInComps) {
1118 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid data.", RoutineName, CurrentModuleObject, Alphas(1)));
1119 0 : ShowContinueError(state, fmt::format("...Number of Arguments indicate [{}], but count of fields indicates [{}]", NumInComps, Comp));
1120 0 : ShowContinueError(state, format("...examine {} carefully.", CurrentModuleObject));
1121 0 : continue;
1122 : }
1123 696 : state.dataBranchInputManager->Branch(BCount).Component(Comp).CType = Alphas(Loop);
1124 696 : state.dataBranchInputManager->Branch(BCount).Component(Comp).Name = Alphas(Loop + 1);
1125 696 : ValidateComponent(state, Alphas(Loop), Alphas(Loop + 1), IsNotOK, CurrentModuleObject);
1126 696 : if (IsNotOK) {
1127 27 : ShowContinueError(state, format("Occurs on {}={}", CurrentModuleObject, Alphas(1)));
1128 27 : ErrFound = true;
1129 : }
1130 696 : state.dataBranchInputManager->Branch(BCount).Component(Comp).InletNodeName = Alphas(Loop + 2);
1131 : // If first component on branch, then inlet node is inlet to branch, otherwise node is internal
1132 696 : if (Loop == 3) {
1133 559 : ConnectionType = DataLoopNode::ConnectionType::Inlet;
1134 : } else {
1135 137 : ConnectionType = DataLoopNode::ConnectionType::Internal;
1136 : }
1137 696 : if (!lAlphaBlanks(Loop + 2)) {
1138 1392 : GetNodeNums(state,
1139 696 : state.dataBranchInputManager->Branch(BCount).Component(Comp).InletNodeName,
1140 : NumNodes,
1141 : NodeNums,
1142 : ErrFound,
1143 : DataLoopNode::NodeFluidType::Blank,
1144 : DataLoopNode::ConnectionObjectType::Branch,
1145 696 : state.dataBranchInputManager->Branch(BCount).Name,
1146 : ConnectionType,
1147 : NodeInputManager::CompFluidStream::Primary,
1148 : ObjectIsParent,
1149 : false,
1150 696 : cAlphaFields(Loop + 2));
1151 696 : if (NumNodes > 1) {
1152 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid data.", RoutineName, CurrentModuleObject, Alphas(1)));
1153 0 : ShowContinueError(state,
1154 0 : format("..invalid {}=\"{}\" must be a single node - appears to be a list.",
1155 : cAlphaFields(Loop + 2),
1156 0 : state.dataBranchInputManager->Branch(BCount).Component(Comp).InletNodeName));
1157 0 : ShowContinueError(
1158 0 : state, format("Occurs on {}=\"{}\", {}=\"{}\".", cAlphaFields(Loop), Alphas(Loop), cAlphaFields(Loop + 1), Alphas(Loop + 1)));
1159 0 : ErrFound = true;
1160 : } else {
1161 696 : state.dataBranchInputManager->Branch(BCount).Component(Comp).InletNode = NodeNums(1);
1162 : }
1163 : } else {
1164 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid data.", RoutineName, CurrentModuleObject, Alphas(1)));
1165 0 : ShowContinueError(state, format("blank required field: {}", cAlphaFields(Loop + 2)));
1166 0 : ShowContinueError(
1167 0 : state, format("Occurs on {}=\"{}\", {}=\"{}\".", cAlphaFields(Loop), Alphas(Loop), cAlphaFields(Loop + 1), Alphas(Loop + 1)));
1168 0 : ErrFound = true;
1169 : }
1170 696 : state.dataBranchInputManager->Branch(BCount).Component(Comp).OutletNodeName = Alphas(Loop + 3);
1171 : // If last component on branch, then outlet node is outlet from branch, otherwise node is internal
1172 696 : if (Loop == NumAlphas - 3) {
1173 559 : ConnectionType = DataLoopNode::ConnectionType::Outlet;
1174 : } else {
1175 137 : ConnectionType = DataLoopNode::ConnectionType::Internal;
1176 : }
1177 696 : if (!lAlphaBlanks(Loop + 3)) {
1178 1392 : GetNodeNums(state,
1179 696 : state.dataBranchInputManager->Branch(BCount).Component(Comp).OutletNodeName,
1180 : NumNodes,
1181 : NodeNums,
1182 : ErrFound,
1183 : DataLoopNode::NodeFluidType::Blank,
1184 : DataLoopNode::ConnectionObjectType::Branch,
1185 696 : state.dataBranchInputManager->Branch(BCount).Name,
1186 : ConnectionType,
1187 : NodeInputManager::CompFluidStream::Primary,
1188 : ObjectIsParent,
1189 : false,
1190 696 : cAlphaFields(Loop + 3));
1191 696 : if (NumNodes > 1) {
1192 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid data.", RoutineName, CurrentModuleObject, Alphas(1)));
1193 0 : ShowContinueError(state,
1194 0 : format("..invalid {}=\"{}\" must be a single node - appears to be a list.",
1195 : cAlphaFields(Loop + 2),
1196 0 : state.dataBranchInputManager->Branch(BCount).Component(Comp).InletNodeName));
1197 0 : ShowContinueError(
1198 0 : state, format("Occurs on {}=\"{}\", {}=\"{}\".", cAlphaFields(Loop), Alphas(Loop), cAlphaFields(Loop + 1), Alphas(Loop + 1)));
1199 0 : ErrFound = true;
1200 : } else {
1201 696 : state.dataBranchInputManager->Branch(BCount).Component(Comp).OutletNode = NodeNums(1);
1202 : }
1203 : } else {
1204 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid data.", RoutineName, CurrentModuleObject, Alphas(1)));
1205 0 : ShowContinueError(state, format("blank required field: {}", cAlphaFields(Loop + 3)));
1206 0 : ShowContinueError(
1207 0 : state, format("Occurs on {}=\"{}\", {}=\"{}\".", cAlphaFields(Loop), Alphas(Loop), cAlphaFields(Loop + 1), Alphas(Loop + 1)));
1208 0 : ErrFound = true;
1209 : }
1210 :
1211 696 : if (!lAlphaBlanks(Loop) && !lAlphaBlanks(Loop + 1) && !lAlphaBlanks(Loop + 2) && !lAlphaBlanks(Loop + 3))
1212 1392 : SetUpCompSets(state,
1213 : CurrentModuleObject,
1214 696 : state.dataBranchInputManager->Branch(BCount).Name,
1215 696 : Alphas(Loop),
1216 696 : Alphas(Loop + 1),
1217 696 : Alphas(Loop + 2),
1218 696 : Alphas(Loop + 3)); // no blanks in required field set
1219 :
1220 696 : ++Comp;
1221 : }
1222 559 : state.dataBranchInputManager->Branch(BCount).NumOfComponents = NumInComps;
1223 559 : }
1224 :
1225 136 : void GetBranchListInput(EnergyPlusData &state)
1226 : {
1227 :
1228 : // SUBROUTINE INFORMATION:
1229 : // AUTHOR Linda K. Lawrie
1230 : // DATE WRITTEN July 2003
1231 :
1232 : // PURPOSE OF THIS SUBROUTINE:
1233 : // This subroutine gets the branch list input and fills up the structures for
1234 : // branch lists.
1235 : // This subroutine gets the input for the following IDD structure:
1236 : // BRANCH LIST,
1237 : // \extensible:1 Just duplicate last field and \ comments (changing numbering, please)
1238 : // \memo Branches MUST be listed in flow order: inlet branch, then parallel branches, then outlet branch.
1239 : // \memo Branches are simulated in the order listed. Branch names cannot be duplicated within a single branch list.
1240 : // A1, \field Branch List Name
1241 : // \required-field
1242 : // \reference BranchLists
1243 : // A2, \field Branch Name 1
1244 : // \required-field
1245 : // \type object-list
1246 : // \object-list Branches
1247 : // A3, \field Branch Name 2
1248 : // \type object-list
1249 : // \object-list Branches
1250 :
1251 : // Using/Aliasing
1252 :
1253 : // SUBROUTINE PARAMETER DEFINITIONS:
1254 : static constexpr std::string_view RoutineName("GetBranchListInput: ");
1255 :
1256 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1257 : int Count; // Loop Counter
1258 : int BCount; // Actual Branch List Count
1259 : int Loop; // Loop Counter
1260 : int Found; // Points to correct Branch List/Branch
1261 : bool ErrFound; // True when error has occurred (cannot find Branch List)
1262 : // Following are needed because routine calls GetBranchInput
1263 : // which would overwrite the module Alphas and NumAlphas
1264 : int NumAlphas; // Used to retrieve Branch list from IDF
1265 136 : Array1D_string Alphas; // Used to retrieve names from IDF
1266 : int NumNumbers;
1267 136 : Array1D<Real64> Numbers; // Not used in this object
1268 136 : Array1D_string cAlphaFields;
1269 136 : Array1D_string cNumericFields;
1270 136 : Array1D_bool lNumericBlanks;
1271 136 : Array1D_bool lAlphaBlanks;
1272 : int IOStat; // Could be used in the Get Routines, not currently checked
1273 : int NumParams;
1274 136 : std::string TestName;
1275 :
1276 136 : ErrFound = false;
1277 136 : std::string CurrentModuleObject = "BranchList";
1278 136 : int NumOfBranchLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
1279 136 : state.dataBranchInputManager->BranchList.allocate(NumOfBranchLists);
1280 136 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNumbers);
1281 136 : Alphas.allocate(NumAlphas);
1282 136 : Numbers.dimension(NumNumbers, 0.0);
1283 136 : cAlphaFields.allocate(NumAlphas);
1284 136 : cNumericFields.allocate(NumNumbers);
1285 136 : lAlphaBlanks.dimension(NumAlphas, true);
1286 136 : lNumericBlanks.dimension(NumNumbers, true);
1287 :
1288 136 : if (NumNumbers > 0) {
1289 0 : ShowSevereError(state,
1290 0 : format("{}{} Object definition contains numbers, cannot be decoded by GetBranchListInput routine.",
1291 : RoutineName,
1292 : CurrentModuleObject));
1293 0 : ErrFound = true;
1294 : }
1295 136 : BCount = 0;
1296 324 : for (Count = 1; Count <= NumOfBranchLists; ++Count) {
1297 188 : CurrentModuleObject = "BranchList";
1298 188 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1299 : CurrentModuleObject,
1300 : Count,
1301 : Alphas,
1302 : NumAlphas,
1303 : Numbers,
1304 : NumNumbers,
1305 : IOStat,
1306 : lNumericBlanks,
1307 : lAlphaBlanks,
1308 : cAlphaFields,
1309 : cNumericFields);
1310 :
1311 188 : ++BCount;
1312 188 : state.dataBranchInputManager->BranchList(BCount).Name = Alphas(1);
1313 188 : state.dataBranchInputManager->BranchList(BCount).NumOfBranchNames = NumAlphas - 1;
1314 188 : state.dataBranchInputManager->BranchList(BCount).BranchNames.allocate(NumAlphas - 1);
1315 188 : if (state.dataBranchInputManager->BranchList(BCount).NumOfBranchNames == 0) {
1316 0 : ShowSevereError(state,
1317 0 : format("{}{}=\"{}\", No branch names entered.",
1318 : RoutineName,
1319 : CurrentModuleObject,
1320 0 : state.dataBranchInputManager->BranchList(BCount).Name));
1321 0 : ErrFound = true;
1322 : } else {
1323 188 : state.dataBranchInputManager->BranchList(BCount).BranchNames({1, NumAlphas - 1}) = Alphas({2, NumAlphas});
1324 747 : for (Loop = 1; Loop <= state.dataBranchInputManager->BranchList(BCount).NumOfBranchNames; ++Loop) {
1325 : // If NumOfBranches = 0 then Branches haven't been read yet.
1326 559 : if ((int)state.dataBranchInputManager->Branch.size() == 0) {
1327 31 : GetBranchInput(state);
1328 : }
1329 559 : if (!state.dataBranchInputManager->BranchList(BCount).BranchNames(Loop).empty()) {
1330 559 : Found = Util::FindItemInList(state.dataBranchInputManager->BranchList(BCount).BranchNames(Loop),
1331 559 : state.dataBranchInputManager->Branch);
1332 559 : if (Found == 0) {
1333 8 : ShowSevereError(state,
1334 8 : format("{}{}=\"{}\", invalid data.",
1335 : RoutineName,
1336 : CurrentModuleObject,
1337 4 : state.dataBranchInputManager->BranchList(BCount).Name));
1338 8 : ShowContinueError(state,
1339 8 : format("..invalid Branch Name not found=\"{}\".",
1340 4 : state.dataBranchInputManager->BranchList(BCount).BranchNames(Loop)));
1341 4 : ErrFound = true;
1342 : }
1343 : }
1344 : }
1345 : }
1346 : }
1347 :
1348 : // Check for duplicate names specified in Branch Lists
1349 324 : for (Count = 1; Count <= NumOfBranchLists; ++Count) {
1350 188 : if (state.dataBranchInputManager->BranchList(Count).NumOfBranchNames == 0) continue;
1351 188 : TestName = state.dataBranchInputManager->BranchList(Count).BranchNames(1);
1352 559 : for (Loop = 2; Loop <= state.dataBranchInputManager->BranchList(Count).NumOfBranchNames; ++Loop) {
1353 371 : if (TestName != state.dataBranchInputManager->BranchList(Count).BranchNames(Loop)) continue;
1354 0 : ShowSevereError(
1355 : state,
1356 0 : format("{}{}=\"{}\", invalid data.", RoutineName, CurrentModuleObject, state.dataBranchInputManager->BranchList(BCount).Name));
1357 0 : ShowContinueError(state, "..invalid: duplicate branch name specified in the list.");
1358 0 : ShowContinueError(state, format("..Branch Name={}", TestName));
1359 0 : ShowContinueError(state, fmt::format("..Branch Name #{} is duplicate.", Loop));
1360 0 : ErrFound = true;
1361 : }
1362 : }
1363 :
1364 136 : if (ErrFound) {
1365 1 : ShowSevereError(state, format("{} Invalid Input -- preceding condition(s) will likely cause termination.", RoutineName));
1366 : }
1367 136 : NumOfBranchLists = BCount;
1368 136 : Alphas.deallocate();
1369 136 : Numbers.deallocate();
1370 136 : cAlphaFields.deallocate();
1371 136 : cNumericFields.deallocate();
1372 136 : lAlphaBlanks.deallocate();
1373 136 : lNumericBlanks.deallocate();
1374 136 : }
1375 :
1376 43 : void GetConnectorListInput(EnergyPlusData &state)
1377 : {
1378 :
1379 : // SUBROUTINE INFORMATION:
1380 : // AUTHOR Linda K. Lawrie
1381 : // DATE WRITTEN October 1999
1382 :
1383 : // PURPOSE OF THIS SUBROUTINE:
1384 : // Obtains connector list input from IDF.
1385 : // ConnectorList,
1386 : // \memo only two connectors allowed per loop
1387 : // \memo if two entered, one must be Connector:Splitter and one must be Connector:Mixer
1388 : // A1, \field Name
1389 : // \required-field
1390 : // \reference ConnectorLists
1391 : // A2, \field Connector 1 Object Type
1392 : // \required-field
1393 : // \key Connector:Splitter
1394 : // \key Connector:Mixer
1395 : // A3, \field Connector 1 Name
1396 : // \required-field
1397 : // A4, \field Connector 2 Object Type
1398 : // \key Connector:Splitter
1399 : // \key Connector:Mixer
1400 : // A5; \field Connector 2 Name
1401 : // This is in the process of possibly being extended, thus the code herein.
1402 :
1403 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1404 : int Count; // Loop Counter
1405 : int NumAlphas; // Used to retrieve names from IDF
1406 43 : Array1D_string Alphas; // Used to retrieve names from IDF
1407 : int NumNumbers; // Used to retrieve numbers from IDF
1408 43 : Array1D<Real64> Numbers; // Used to retrieve numbers from IDF
1409 43 : Array1D_string cAlphaFields;
1410 43 : Array1D_string cNumericFields;
1411 43 : Array1D_bool lNumericBlanks;
1412 43 : Array1D_bool lAlphaBlanks;
1413 : int IOStat; // Could be used in the Get Routines, not currently checked
1414 : int NumParams;
1415 : int Arg;
1416 : int SplitNum;
1417 : int MixerNum;
1418 43 : Array1D_string BranchNames;
1419 : int NumBranchNames;
1420 : bool ErrorsFound;
1421 : int Loop;
1422 : int Loop1;
1423 : int Loop2;
1424 : bool CurMixer;
1425 : bool CurSplitter;
1426 : int TestNum;
1427 : bool MatchFound;
1428 :
1429 43 : if (!state.dataBranchInputManager->GetConnectorListInputFlag) return;
1430 43 : ErrorsFound = false;
1431 43 : std::string CurrentModuleObject = "ConnectorList";
1432 43 : int NumOfConnectorLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
1433 43 : state.dataBranchInputManager->ConnectorLists.allocate(NumOfConnectorLists);
1434 43 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNumbers);
1435 43 : if (NumAlphas != 5 || NumNumbers != 0) {
1436 0 : ShowWarningError(state,
1437 0 : format("GetConnectorList: Illegal \"extension\" to {} object. Internal code does not support > 2 connectors "
1438 : "(Connector:Splitter and Connector:Mixer)",
1439 : CurrentModuleObject));
1440 : }
1441 43 : Alphas.allocate(NumAlphas);
1442 43 : Numbers.dimension(NumNumbers, 0.0);
1443 43 : cAlphaFields.allocate(NumAlphas);
1444 43 : cNumericFields.allocate(NumNumbers);
1445 43 : lAlphaBlanks.dimension(NumAlphas, true);
1446 43 : lNumericBlanks.dimension(NumNumbers, true);
1447 165 : for (Count = 1; Count <= NumOfConnectorLists; ++Count) {
1448 122 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1449 : CurrentModuleObject,
1450 : Count,
1451 : Alphas,
1452 : NumAlphas,
1453 : Numbers,
1454 : NumNumbers,
1455 : IOStat,
1456 : lNumericBlanks,
1457 : lAlphaBlanks,
1458 : cAlphaFields,
1459 : cNumericFields);
1460 122 : state.dataBranchInputManager->ConnectorLists(Count).Name = Alphas(1);
1461 122 : int NumConnectors = (NumAlphas - 1) / 2; // potential problem if puts in type but not name
1462 122 : if (mod(NumAlphas - 1, 2) != 0) ++NumConnectors;
1463 122 : state.dataBranchInputManager->ConnectorLists(Count).NumOfConnectors = NumConnectors;
1464 122 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorType.allocate(NumConnectors);
1465 122 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorName.allocate(NumConnectors);
1466 122 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorMatchNo.allocate(NumConnectors);
1467 244 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorType = "UNKNOWN";
1468 122 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorName = "UNKNOWN";
1469 122 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorMatchNo = 0;
1470 122 : state.dataBranchInputManager->ConnectorLists(Count).NumOfSplitters = 0;
1471 122 : state.dataBranchInputManager->ConnectorLists(Count).NumOfMixers = 0;
1472 :
1473 122 : int CCount = 0;
1474 366 : for (Arg = 2; Arg <= NumAlphas; Arg += 2) {
1475 244 : ++CCount;
1476 244 : if (Util::SameString(Alphas(Arg), cSPLITTER)) {
1477 122 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorType(CCount) = Alphas(Arg).substr(0, 30);
1478 122 : ++state.dataBranchInputManager->ConnectorLists(Count).NumOfSplitters;
1479 122 : } else if (Util::SameString(Alphas(Arg), cMIXER)) {
1480 122 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorType(CCount) = Alphas(Arg).substr(0, 30);
1481 122 : ++state.dataBranchInputManager->ConnectorLists(Count).NumOfMixers;
1482 : } else {
1483 0 : ShowWarningError(
1484 : state,
1485 0 : format("GetConnectorListInput: Invalid {}={} in {}={}", cAlphaFields(Arg), Alphas(Arg), CurrentModuleObject, Alphas(1)));
1486 : }
1487 244 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorName(CCount) = Alphas(Arg + 1);
1488 : }
1489 : }
1490 43 : state.dataBranchInputManager->GetConnectorListInputFlag = false;
1491 43 : Alphas.deallocate();
1492 43 : Numbers.deallocate();
1493 43 : cAlphaFields.deallocate();
1494 43 : cNumericFields.deallocate();
1495 43 : lAlphaBlanks.deallocate();
1496 43 : lNumericBlanks.deallocate();
1497 :
1498 : // Validity checks on Connector Lists
1499 43 : if (state.dataBranchInputManager->GetSplitterInputFlag) {
1500 43 : GetSplitterInput(state);
1501 43 : state.dataBranchInputManager->GetSplitterInputFlag = false;
1502 : }
1503 43 : if (state.dataBranchInputManager->GetMixerInputFlag) {
1504 43 : GetMixerInput(state);
1505 43 : state.dataBranchInputManager->GetMixerInputFlag = false;
1506 : }
1507 :
1508 43 : SplitNum = 0;
1509 43 : MixerNum = 0;
1510 165 : for (Count = 1; Count <= NumOfConnectorLists; ++Count) {
1511 122 : if (state.dataBranchInputManager->ConnectorLists(Count).NumOfConnectors <= 1) continue; // Air Loop only has one.
1512 122 : if (state.dataBranchInputManager->ConnectorLists(Count).NumOfConnectors > 2) continue; // Rules not clear for this case
1513 366 : for (Loop = 1; Loop <= state.dataBranchInputManager->ConnectorLists(Count).NumOfConnectors; ++Loop) {
1514 244 : if (state.dataBranchInputManager->ConnectorLists(Count).ConnectorMatchNo(Loop) != 0) continue;
1515 122 : if (Util::SameString(state.dataBranchInputManager->ConnectorLists(Count).ConnectorType(Loop), cSPLITTER)) {
1516 122 : CurSplitter = true;
1517 122 : CurMixer = false;
1518 122 : SplitNum = Util::FindItemInList(state.dataBranchInputManager->ConnectorLists(Count).ConnectorName(Loop),
1519 122 : state.dataBranchInputManager->Splitters);
1520 : // Following code sets up branch names to be matched from Splitter/Mixer data structure
1521 122 : if (SplitNum == 0) {
1522 0 : ShowSevereError(state,
1523 0 : format("Invalid Connector:Splitter(none)={}, referenced by {}={}",
1524 0 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorName(Loop),
1525 : CurrentModuleObject,
1526 0 : state.dataBranchInputManager->ConnectorLists(Count).Name));
1527 0 : ErrorsFound = true;
1528 0 : continue;
1529 : }
1530 122 : NumBranchNames = state.dataBranchInputManager->Splitters(SplitNum).NumOutletBranches;
1531 122 : BranchNames = state.dataBranchInputManager->Splitters(SplitNum).OutletBranchNames;
1532 0 : } else if (Util::SameString(state.dataBranchInputManager->ConnectorLists(Count).ConnectorType(Loop), cMIXER)) {
1533 0 : CurSplitter = true;
1534 0 : CurMixer = false;
1535 0 : MixerNum = Util::FindItemInList(state.dataBranchInputManager->ConnectorLists(Count).ConnectorName(Loop),
1536 0 : state.dataBranchInputManager->Mixers);
1537 0 : if (MixerNum == 0) {
1538 0 : ShowSevereError(state,
1539 0 : format("Invalid Connector:Mixer(none)={}, referenced by {}={}",
1540 0 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorName(Loop),
1541 : CurrentModuleObject,
1542 0 : state.dataBranchInputManager->ConnectorLists(Count).Name));
1543 0 : ErrorsFound = true;
1544 0 : continue;
1545 : }
1546 0 : NumBranchNames = state.dataBranchInputManager->Mixers(MixerNum).NumInletBranches;
1547 0 : BranchNames = state.dataBranchInputManager->Mixers(MixerNum).InletBranchNames;
1548 : } else {
1549 0 : continue;
1550 : }
1551 : // Try to match mixer to splitter
1552 244 : for (Loop1 = Loop + 1; Loop1 <= state.dataBranchInputManager->ConnectorLists(Count).NumOfConnectors; ++Loop1) {
1553 122 : if (CurMixer && !Util::SameString(state.dataBranchInputManager->ConnectorLists(Count).ConnectorType(Loop1), cSPLITTER)) continue;
1554 122 : if (CurSplitter && !Util::SameString(state.dataBranchInputManager->ConnectorLists(Count).ConnectorType(Loop1), cMIXER)) continue;
1555 122 : if (state.dataBranchInputManager->ConnectorLists(Count).ConnectorMatchNo(Loop1) != 0) continue;
1556 : {
1557 122 : if (CurSplitter) {
1558 : // Current "item" is a splitter, candidate is a mixer.
1559 122 : MixerNum = Util::FindItemInList(state.dataBranchInputManager->ConnectorLists(Count).ConnectorName(Loop1),
1560 122 : state.dataBranchInputManager->Mixers);
1561 122 : if (MixerNum == 0) continue;
1562 122 : if (state.dataBranchInputManager->Mixers(MixerNum).NumInletBranches != NumBranchNames) continue;
1563 122 : MatchFound = true;
1564 364 : for (Loop2 = 1; Loop2 <= state.dataBranchInputManager->Mixers(MixerNum).NumInletBranches; ++Loop2) {
1565 242 : TestNum = Util::FindItemInList(
1566 242 : state.dataBranchInputManager->Mixers(MixerNum).InletBranchNames(Loop2), BranchNames, NumBranchNames);
1567 242 : if (TestNum == 0) {
1568 0 : MatchFound = false;
1569 0 : break;
1570 : }
1571 : }
1572 122 : if (MatchFound) {
1573 122 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorMatchNo(Loop1) = MixerNum;
1574 122 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorMatchNo(Loop) = SplitNum;
1575 : }
1576 : } else {
1577 : // Current "item" is a splitter, candidate is a mixer.
1578 0 : SplitNum = Util::FindItemInList(state.dataBranchInputManager->ConnectorLists(Count).ConnectorName(Loop1),
1579 0 : state.dataBranchInputManager->Splitters);
1580 0 : if (SplitNum == 0) continue;
1581 0 : if (state.dataBranchInputManager->Splitters(SplitNum).NumOutletBranches != NumBranchNames) continue;
1582 0 : MatchFound = true;
1583 0 : for (Loop2 = 1; Loop2 <= state.dataBranchInputManager->Splitters(SplitNum).NumOutletBranches; ++Loop2) {
1584 0 : TestNum = Util::FindItemInList(
1585 0 : state.dataBranchInputManager->Splitters(SplitNum).OutletBranchNames(Loop2), BranchNames, NumBranchNames);
1586 0 : if (TestNum == 0) {
1587 0 : MatchFound = false;
1588 0 : break;
1589 : }
1590 : }
1591 0 : if (MatchFound) {
1592 0 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorMatchNo(Loop1) = SplitNum;
1593 0 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorMatchNo(Loop) = MixerNum;
1594 : }
1595 : }
1596 : }
1597 : }
1598 122 : BranchNames.deallocate();
1599 : }
1600 : }
1601 :
1602 165 : for (Count = 1; Count <= NumOfConnectorLists; ++Count) {
1603 122 : if (state.dataBranchInputManager->ConnectorLists(Count).NumOfConnectors <= 1) continue; // Air Loop only has one.
1604 122 : if (state.dataBranchInputManager->ConnectorLists(Count).NumOfConnectors > 2) continue; // Rules not clear
1605 366 : for (Loop = 1; Loop <= state.dataBranchInputManager->ConnectorLists(Count).NumOfConnectors; ++Loop) {
1606 244 : if (state.dataBranchInputManager->ConnectorLists(Count).ConnectorMatchNo(Loop) != 0) continue;
1607 : // = 0, not matched.
1608 0 : ShowSevereError(state, format("For {}={}", CurrentModuleObject, state.dataBranchInputManager->ConnectorLists(Count).Name));
1609 0 : ShowContinueError(state,
1610 0 : format("...Item={}, Type={} was not matched.",
1611 0 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorName(Loop),
1612 0 : state.dataBranchInputManager->ConnectorLists(Count).ConnectorType(Loop)));
1613 0 : if (Util::SameString(state.dataBranchInputManager->ConnectorLists(Count).ConnectorType(Loop), "Connector:Splitter")) {
1614 0 : ShowContinueError(
1615 : state, "The BranchList for this Connector:Splitter does not match the BranchList for its corresponding Connector:Mixer.");
1616 : } else {
1617 0 : ShowContinueError(
1618 : state, "The BranchList for this Connector:Mixer does not match the BranchList for its corresponding Connector:Splitter.");
1619 : }
1620 0 : ErrorsFound = true;
1621 : }
1622 : }
1623 :
1624 43 : if (ErrorsFound) {
1625 0 : ShowFatalError(state, "GetConnectorListInput: Program terminates for preceding conditions.");
1626 : }
1627 43 : }
1628 :
1629 43 : void GetSplitterInput(EnergyPlusData &state)
1630 : {
1631 :
1632 : // SUBROUTINE INFORMATION:
1633 : // AUTHOR Linda Lawrie
1634 : // DATE WRITTEN Sept 2005 (moved from GetLoopSplitter)
1635 :
1636 : // PURPOSE OF THIS SUBROUTINE:
1637 : // Gets the Splitter data that is used in Loops.
1638 : // IDD structure:
1639 : // Connector:Splitter,
1640 : // \min-fields 3
1641 : // \extensible:1 Just duplicate last field and \ comments (changing numbering, please)
1642 : // \memo Split one air/water stream into N outlet streams. Branch names cannot be duplicated
1643 : // \memo within a single Splitter list.
1644 : // A1, \field Name
1645 : // \required-field
1646 : // A2, \field Inlet Branch Name
1647 : // \required-field
1648 : // \type object-list
1649 : // \object-list Branches
1650 : // A3, \field Outlet Branch 1 Name
1651 : // \required-field
1652 : // \type object-list
1653 : // \object-list Branches
1654 : // A4, \field Outlet Branch 2 Name
1655 : // \type object-list
1656 : // \object-list Branches
1657 :
1658 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1659 : int NumAlphas; // Used to retrieve names from IDF
1660 43 : Array1D_string Alphas; // Used to retrieve names from IDF
1661 : int NumNumbers; // Used to retrieve numbers from IDF
1662 43 : Array1D<Real64> Numbers; // Used to retrieve numbers from IDF
1663 43 : Array1D_string cAlphaFields;
1664 43 : Array1D_string cNumericFields;
1665 43 : Array1D_bool lNumericBlanks;
1666 43 : Array1D_bool lAlphaBlanks;
1667 : int IOStat; // Could be used in the Get Routines, not currently checked
1668 : int NumParams;
1669 : int Loop;
1670 : int Loop1;
1671 : int Count;
1672 43 : bool ErrorsFound(false);
1673 43 : std::string TestName;
1674 43 : std::string FoundSupplyDemandAir;
1675 43 : std::string SaveSupplyDemandAir;
1676 43 : std::string FoundLoop;
1677 43 : std::string SaveLoop;
1678 : bool MatchedLoop;
1679 :
1680 43 : if (!state.dataBranchInputManager->GetSplitterInputFlag) return;
1681 43 : std::string CurrentModuleObject = cSPLITTER;
1682 43 : int NumSplitters = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
1683 43 : state.dataBranchInputManager->Splitters.allocate(NumSplitters);
1684 43 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNumbers);
1685 43 : Alphas.allocate(NumAlphas);
1686 43 : Numbers.dimension(NumNumbers, 0.0);
1687 43 : cAlphaFields.allocate(NumAlphas);
1688 43 : cNumericFields.allocate(NumNumbers);
1689 43 : lAlphaBlanks.dimension(NumAlphas, true);
1690 43 : lNumericBlanks.dimension(NumNumbers, true);
1691 165 : for (Count = 1; Count <= NumSplitters; ++Count) {
1692 122 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1693 : CurrentModuleObject,
1694 : Count,
1695 : Alphas,
1696 : NumAlphas,
1697 : Numbers,
1698 : NumNumbers,
1699 : IOStat,
1700 : lNumericBlanks,
1701 : lAlphaBlanks,
1702 : cAlphaFields,
1703 : cNumericFields);
1704 122 : state.dataBranchInputManager->Splitters(Count).Name = Alphas(1);
1705 122 : state.dataBranchInputManager->Splitters(Count).InletBranchName = Alphas(2);
1706 122 : state.dataBranchInputManager->Splitters(Count).NumOutletBranches = NumAlphas - 2;
1707 244 : state.dataBranchInputManager->Splitters(Count).OutletBranchNames.allocate(
1708 122 : state.dataBranchInputManager->Splitters(Count).NumOutletBranches);
1709 364 : for (Loop = 1; Loop <= state.dataBranchInputManager->Splitters(Count).NumOutletBranches; ++Loop) {
1710 242 : state.dataBranchInputManager->Splitters(Count).OutletBranchNames(Loop) = Alphas(2 + Loop);
1711 : }
1712 : }
1713 43 : state.dataBranchInputManager->GetSplitterInputFlag = false;
1714 43 : Alphas.deallocate();
1715 43 : Numbers.deallocate();
1716 43 : cAlphaFields.deallocate();
1717 43 : cNumericFields.deallocate();
1718 43 : lAlphaBlanks.deallocate();
1719 43 : lNumericBlanks.deallocate();
1720 :
1721 : // More validity -- check splitter "names" against branches.
1722 43 : if (!state.dataBranchInputManager->GetBranchInputFlag) {
1723 43 : GetBranchInput(state);
1724 43 : state.dataBranchInputManager->GetBranchInputFlag = false;
1725 : }
1726 165 : for (Count = 1; Count <= NumSplitters; ++Count) {
1727 122 : int Found = Util::FindItemInList(state.dataBranchInputManager->Splitters(Count).InletBranchName, state.dataBranchInputManager->Branch);
1728 122 : if (Found == 0) {
1729 0 : ShowSevereError(state,
1730 0 : format("GetSplitterInput: Invalid Branch={}, referenced as Inlet Branch to {}={}",
1731 0 : state.dataBranchInputManager->Splitters(Count).InletBranchName,
1732 : CurrentModuleObject,
1733 0 : state.dataBranchInputManager->Splitters(Count).Name));
1734 0 : ErrorsFound = true;
1735 : }
1736 364 : for (Loop = 1; Loop <= state.dataBranchInputManager->Splitters(Count).NumOutletBranches; ++Loop) {
1737 242 : Found = Util::FindItemInList(state.dataBranchInputManager->Splitters(Count).OutletBranchNames(Loop),
1738 242 : state.dataBranchInputManager->Branch);
1739 242 : if (Found == 0) {
1740 0 : ShowSevereError(state,
1741 0 : fmt::format("GetSplitterInput: Invalid Branch={}, referenced as Outlet Branch # {} to {}={}",
1742 0 : state.dataBranchInputManager->Splitters(Count).OutletBranchNames(Loop),
1743 : Loop,
1744 : CurrentModuleObject,
1745 0 : state.dataBranchInputManager->Splitters(Count).Name));
1746 0 : ErrorsFound = true;
1747 : }
1748 : }
1749 : }
1750 :
1751 : // Check for duplicate names specified in Splitters
1752 165 : for (Count = 1; Count <= NumSplitters; ++Count) {
1753 122 : TestName = state.dataBranchInputManager->Splitters(Count).InletBranchName;
1754 364 : for (Loop = 1; Loop <= state.dataBranchInputManager->Splitters(Count).NumOutletBranches; ++Loop) {
1755 242 : if (TestName != state.dataBranchInputManager->Splitters(Count).OutletBranchNames(Loop)) continue;
1756 0 : ShowSevereError(state,
1757 0 : format("{}={} specifies an outlet node name the same as the inlet node.",
1758 : CurrentModuleObject,
1759 0 : state.dataBranchInputManager->Splitters(Count).Name));
1760 0 : ShowContinueError(state, format("..Inlet Node={}", TestName));
1761 0 : ShowContinueError(state, fmt::format("..Outlet Node #{} is duplicate.", Loop));
1762 0 : ErrorsFound = true;
1763 : }
1764 364 : for (Loop = 1; Loop <= state.dataBranchInputManager->Splitters(Count).NumOutletBranches; ++Loop) {
1765 417 : for (Loop1 = Loop + 1; Loop1 <= state.dataBranchInputManager->Splitters(Count).NumOutletBranches; ++Loop1) {
1766 175 : if (state.dataBranchInputManager->Splitters(Count).OutletBranchNames(Loop) !=
1767 175 : state.dataBranchInputManager->Splitters(Count).OutletBranchNames(Loop1))
1768 175 : continue;
1769 0 : ShowSevereError(state,
1770 0 : format("{}={} specifies duplicate outlet nodes in its outlet node list.",
1771 : CurrentModuleObject,
1772 0 : state.dataBranchInputManager->Splitters(Count).Name));
1773 0 : ShowContinueError(
1774 : state,
1775 0 : fmt::format("..Outlet Node #{} Name={}", Loop, state.dataBranchInputManager->Splitters(Count).OutletBranchNames(Loop)));
1776 0 : ShowContinueError(state, fmt::format("..Outlet Node #{} is duplicate.", Loop));
1777 0 : ErrorsFound = true;
1778 : }
1779 : }
1780 : }
1781 :
1782 43 : if (ErrorsFound) {
1783 0 : ShowFatalError(state, format("GetSplitterInput: Fatal Errors Found in {}, program terminates.", CurrentModuleObject));
1784 : }
1785 :
1786 : // Everything supposed to be good. Now make sure all branches in Splitter on same side of loop.
1787 43 : SaveSupplyDemandAir = std::string();
1788 165 : for (Count = 1; Count <= NumSplitters; ++Count) {
1789 : // 2. Find the branch name in branchlist
1790 122 : TestName = state.dataBranchInputManager->Splitters(Count).InletBranchName;
1791 122 : std::string BranchListName = std::string();
1792 327 : for (Loop1 = 1; Loop1 <= (int)state.dataBranchInputManager->BranchList.size(); ++Loop1) {
1793 327 : if (any_eq(state.dataBranchInputManager->BranchList(Loop1).BranchNames, TestName)) {
1794 122 : BranchListName = state.dataBranchInputManager->BranchList(Loop1).Name;
1795 122 : break;
1796 : }
1797 : }
1798 :
1799 122 : if (!BranchListName.empty()) {
1800 122 : FoundSupplyDemandAir = std::string();
1801 122 : FoundLoop = std::string();
1802 122 : MatchedLoop = false;
1803 : // 3. Find the loop and type
1804 122 : FindAirPlantCondenserLoopFromBranchList(state, BranchListName, FoundLoop, FoundSupplyDemandAir, MatchedLoop);
1805 122 : if (MatchedLoop) {
1806 122 : SaveSupplyDemandAir = FoundSupplyDemandAir;
1807 122 : SaveLoop = FoundLoop;
1808 : } else {
1809 0 : ShowSevereError(
1810 : state,
1811 0 : format("GetSplitterInput: Inlet Splitter Branch=\"{}\" and BranchList=\"{}\" not matched to a Air/Plant/Condenser Loop",
1812 : TestName,
1813 : BranchListName));
1814 0 : ShowContinueError(state, "...and therefore, not a valid Loop Splitter.");
1815 0 : ShowContinueError(state, format("...{}={}", CurrentModuleObject, state.dataBranchInputManager->Splitters(Count).Name));
1816 0 : ErrorsFound = true;
1817 : }
1818 : } else {
1819 0 : ShowSevereError(state, format("GetSplitterInput: Inlet Splitter Branch=\"{}\" not on BranchList", TestName));
1820 0 : ShowContinueError(state, "...and therefore, not a valid Loop Splitter.");
1821 0 : ShowContinueError(state, format("...{}={}", CurrentModuleObject, state.dataBranchInputManager->Splitters(Count).Name));
1822 0 : ErrorsFound = true;
1823 : }
1824 364 : for (Loop = 1; Loop <= state.dataBranchInputManager->Splitters(Count).NumOutletBranches; ++Loop) {
1825 242 : TestName = state.dataBranchInputManager->Splitters(Count).OutletBranchNames(Loop);
1826 242 : BranchListName = std::string();
1827 659 : for (Loop1 = 1; Loop1 <= (int)state.dataBranchInputManager->BranchList.size(); ++Loop1) {
1828 659 : if (any_eq(state.dataBranchInputManager->BranchList(Loop1).BranchNames, TestName)) {
1829 242 : BranchListName = state.dataBranchInputManager->BranchList(Loop1).Name;
1830 242 : break;
1831 : }
1832 : }
1833 :
1834 242 : if (!BranchListName.empty()) {
1835 242 : FoundSupplyDemandAir = std::string();
1836 242 : FoundLoop = std::string();
1837 242 : MatchedLoop = false;
1838 : // 3. Find the loop and type
1839 242 : FindAirPlantCondenserLoopFromBranchList(state, BranchListName, FoundLoop, FoundSupplyDemandAir, MatchedLoop);
1840 242 : if (MatchedLoop) {
1841 242 : if (SaveSupplyDemandAir != FoundSupplyDemandAir || SaveLoop != FoundLoop) {
1842 0 : ShowSevereError(
1843 0 : state, format("GetSplitterInput: Outlet Splitter Branch=\"{}\" does not match types of Inlet Branch.", TestName));
1844 0 : ShowContinueError(state, format("...Inlet Branch is on \"{}\" on \"{}\" side.", SaveLoop, SaveSupplyDemandAir));
1845 0 : ShowContinueError(state, format("...Outlet Branch is on \"{}\" on \"{}\" side.", FoundLoop, FoundSupplyDemandAir));
1846 0 : ShowContinueError(state, "...All branches in Loop Splitter must be on same kind of loop and supply/demand side.");
1847 0 : ShowContinueError(state, format("...{}={}", CurrentModuleObject, state.dataBranchInputManager->Splitters(Count).Name));
1848 0 : ErrorsFound = true;
1849 : }
1850 : } else {
1851 0 : ShowSevereError(
1852 : state,
1853 0 : format("GetSplitterInput: Outlet Splitter Branch=\"{}\" and BranchList=\"{}\" not matched to a Air/Plant/Condenser Loop",
1854 : TestName,
1855 : BranchListName));
1856 0 : ShowContinueError(state, "...and therefore, not a valid Loop Splitter.");
1857 0 : ShowContinueError(state, format("...{}={}", CurrentModuleObject, state.dataBranchInputManager->Splitters(Count).Name));
1858 0 : ErrorsFound = true;
1859 : }
1860 : } else {
1861 0 : ShowSevereError(state, format("GetSplitterInput: Outlet Splitter Branch=\"{}\" not on BranchList", TestName));
1862 0 : ShowContinueError(state, "...and therefore, not a valid Loop Splitter");
1863 0 : ShowContinueError(state, format("...{}={}", CurrentModuleObject, state.dataBranchInputManager->Splitters(Count).Name));
1864 0 : ErrorsFound = true;
1865 : }
1866 : }
1867 122 : }
1868 :
1869 43 : if (ErrorsFound) {
1870 0 : ShowFatalError(state, format("GetSplitterInput: Fatal Errors Found in {}, program terminates.", CurrentModuleObject));
1871 : }
1872 43 : }
1873 :
1874 46 : void GetMixerInput(EnergyPlusData &state)
1875 : {
1876 :
1877 : // SUBROUTINE INFORMATION:
1878 : // AUTHOR Linda Lawrie
1879 : // DATE WRITTEN Sept 2005 (moved from GetLoopMixer)
1880 :
1881 : // PURPOSE OF THIS SUBROUTINE:
1882 : // Gets the Mixer data that is used in Loops.
1883 : // IDD Structure:
1884 : // Connector:Mixer,
1885 : // \min-fields 3
1886 : // \extensible:1 Just duplicate last field and \ comments (changing numbering, please)
1887 : // \memo Mix N inlet air/water streams into one. Branch names cannot be duplicated within
1888 : // \memo a single mixer list.
1889 : // A1 , \field Name
1890 : // \required-field
1891 : // A2 , \field Outlet Branch Name
1892 : // \required-field
1893 : // \type object-list
1894 : // \object-list Branches
1895 : // A3 , \field Inlet Branch 1 Name
1896 : // \required-field
1897 : // \type object-list
1898 : // \object-list Branches
1899 : // A4 , \field Inlet Branch 2 Name
1900 : // \type object-list
1901 : // \object-list Branches
1902 :
1903 : // Using/Aliasing
1904 :
1905 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1906 : int NumAlphas; // Used to retrieve names from IDF
1907 46 : Array1D_string Alphas; // Used to retrieve names from IDF
1908 : int NumNumbers; // Used to retrieve numbers from IDF
1909 46 : Array1D<Real64> Numbers; // Used to retrieve numbers from IDF
1910 46 : Array1D_string cAlphaFields;
1911 46 : Array1D_string cNumericFields;
1912 46 : Array1D_bool lNumericBlanks;
1913 46 : Array1D_bool lAlphaBlanks;
1914 : int IOStat; // Could be used in the Get Routines, not currently checked
1915 : int NumParams;
1916 : int Loop;
1917 : int Loop1;
1918 : int Count;
1919 46 : bool ErrorsFound(false);
1920 46 : std::string TestName;
1921 46 : std::string FoundSupplyDemandAir;
1922 46 : std::string SaveSupplyDemandAir;
1923 46 : std::string FoundLoop;
1924 46 : std::string SaveLoop;
1925 : bool MatchedLoop;
1926 :
1927 46 : if (!state.dataBranchInputManager->GetMixerInputFlag) return;
1928 :
1929 46 : std::string CurrentModuleObject = cMIXER;
1930 :
1931 46 : int NumMixers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
1932 46 : state.dataBranchInputManager->Mixers.allocate(NumMixers);
1933 46 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNumbers);
1934 46 : Alphas.allocate(NumAlphas);
1935 46 : Numbers.dimension(NumNumbers, 0.0);
1936 46 : cAlphaFields.allocate(NumAlphas);
1937 46 : cNumericFields.allocate(NumNumbers);
1938 46 : lAlphaBlanks.dimension(NumAlphas, true);
1939 46 : lNumericBlanks.dimension(NumNumbers, true);
1940 168 : for (Count = 1; Count <= NumMixers; ++Count) {
1941 122 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1942 : CurrentModuleObject,
1943 : Count,
1944 : Alphas,
1945 : NumAlphas,
1946 : Numbers,
1947 : NumNumbers,
1948 : IOStat,
1949 : lNumericBlanks,
1950 : lAlphaBlanks,
1951 : cAlphaFields,
1952 : cNumericFields);
1953 122 : state.dataBranchInputManager->Mixers(Count).Name = Alphas(1);
1954 122 : state.dataBranchInputManager->Mixers(Count).OutletBranchName = Alphas(2);
1955 122 : state.dataBranchInputManager->Mixers(Count).NumInletBranches = NumAlphas - 2;
1956 122 : state.dataBranchInputManager->Mixers(Count).InletBranchNames.allocate(state.dataBranchInputManager->Mixers(Count).NumInletBranches);
1957 364 : for (Loop = 1; Loop <= state.dataBranchInputManager->Mixers(Count).NumInletBranches; ++Loop) {
1958 242 : state.dataBranchInputManager->Mixers(Count).InletBranchNames(Loop) = Alphas(2 + Loop);
1959 : }
1960 : }
1961 46 : state.dataBranchInputManager->GetMixerInputFlag = false;
1962 46 : Alphas.deallocate();
1963 46 : Numbers.deallocate();
1964 46 : cAlphaFields.deallocate();
1965 46 : cNumericFields.deallocate();
1966 46 : lAlphaBlanks.deallocate();
1967 46 : lNumericBlanks.deallocate();
1968 :
1969 : // More validity -- check mixer "names" against branches.
1970 46 : if (!state.dataBranchInputManager->GetBranchInputFlag) {
1971 43 : GetBranchInput(state);
1972 43 : state.dataBranchInputManager->GetBranchInputFlag = false;
1973 : }
1974 168 : for (Count = 1; Count <= NumMixers; ++Count) {
1975 122 : int Found = Util::FindItemInList(state.dataBranchInputManager->Mixers(Count).OutletBranchName, state.dataBranchInputManager->Branch);
1976 122 : if (Found == 0) {
1977 0 : ShowSevereError(state,
1978 0 : format("GetMixerInput: Invalid Branch={}, referenced as Outlet Branch in {}={}",
1979 0 : state.dataBranchInputManager->Mixers(Count).OutletBranchName,
1980 : CurrentModuleObject,
1981 0 : state.dataBranchInputManager->Mixers(Count).Name));
1982 0 : ErrorsFound = true;
1983 : }
1984 364 : for (Loop = 1; Loop <= state.dataBranchInputManager->Mixers(Count).NumInletBranches; ++Loop) {
1985 : Found =
1986 242 : Util::FindItemInList(state.dataBranchInputManager->Mixers(Count).InletBranchNames(Loop), state.dataBranchInputManager->Branch);
1987 242 : if (Found == 0) {
1988 0 : ShowSevereError(state,
1989 0 : format("GetMixerInput: Invalid Branch={}, referenced as Inlet Branch # {} in {}={}",
1990 0 : state.dataBranchInputManager->Mixers(Count).InletBranchNames(Loop),
1991 : Loop,
1992 : CurrentModuleObject,
1993 0 : state.dataBranchInputManager->Mixers(Count).Name));
1994 0 : ErrorsFound = true;
1995 : }
1996 : }
1997 : }
1998 :
1999 : // Check for duplicate names specified in Mixer
2000 168 : for (Count = 1; Count <= NumMixers; ++Count) {
2001 122 : TestName = state.dataBranchInputManager->Mixers(Count).OutletBranchName;
2002 364 : for (Loop = 1; Loop <= state.dataBranchInputManager->Mixers(Count).NumInletBranches; ++Loop) {
2003 242 : if (TestName != state.dataBranchInputManager->Mixers(Count).InletBranchNames(Loop)) continue;
2004 0 : ShowSevereError(state,
2005 0 : format("{}={} specifies an inlet node name the same as the outlet node.",
2006 : CurrentModuleObject,
2007 0 : state.dataBranchInputManager->Mixers(Count).Name));
2008 0 : ShowContinueError(state, format("..Outlet Node={}", TestName));
2009 0 : ShowContinueError(state, format("..Inlet Node #{} is duplicate.", Loop));
2010 0 : ErrorsFound = true;
2011 : }
2012 364 : for (Loop = 1; Loop <= state.dataBranchInputManager->Mixers(Count).NumInletBranches; ++Loop) {
2013 417 : for (Loop1 = Loop + 1; Loop1 <= state.dataBranchInputManager->Mixers(Count).NumInletBranches; ++Loop1) {
2014 175 : if (state.dataBranchInputManager->Mixers(Count).InletBranchNames(Loop) !=
2015 175 : state.dataBranchInputManager->Mixers(Count).InletBranchNames(Loop1))
2016 175 : continue;
2017 0 : ShowSevereError(state,
2018 0 : format("{}={} specifies duplicate inlet nodes in its inlet node list.",
2019 : CurrentModuleObject,
2020 0 : state.dataBranchInputManager->Mixers(Count).Name));
2021 0 : ShowContinueError(
2022 0 : state, fmt::format("..Inlet Node #{} Name={}", Loop, state.dataBranchInputManager->Mixers(Count).InletBranchNames(Loop)));
2023 0 : ShowContinueError(state, fmt::format("..Inlet Node #{} is duplicate.", Loop));
2024 0 : ErrorsFound = true;
2025 : }
2026 : }
2027 : }
2028 :
2029 46 : if (ErrorsFound) {
2030 0 : ShowFatalError(state, format("GetMixerInput: Fatal Errors Found in {}, program terminates.", CurrentModuleObject));
2031 : }
2032 :
2033 : // Everything supposed to be good. Now make sure all branches in Splitter on same side of loop.
2034 46 : SaveSupplyDemandAir = std::string();
2035 168 : for (Count = 1; Count <= NumMixers; ++Count) {
2036 : // 2. Find the branch name in branchlist
2037 122 : TestName = state.dataBranchInputManager->Mixers(Count).OutletBranchName;
2038 122 : std::string BranchListName = std::string();
2039 327 : for (Loop1 = 1; Loop1 <= (int)state.dataBranchInputManager->BranchList.size(); ++Loop1) {
2040 327 : if (any_eq(state.dataBranchInputManager->BranchList(Loop1).BranchNames, TestName)) {
2041 122 : BranchListName = state.dataBranchInputManager->BranchList(Loop1).Name;
2042 122 : break;
2043 : }
2044 : }
2045 :
2046 122 : if (!BranchListName.empty()) {
2047 122 : FoundSupplyDemandAir = std::string();
2048 122 : FoundLoop = std::string();
2049 122 : MatchedLoop = false;
2050 : // 3. Find the loop and type
2051 122 : FindAirPlantCondenserLoopFromBranchList(state, BranchListName, FoundLoop, FoundSupplyDemandAir, MatchedLoop);
2052 122 : if (MatchedLoop) {
2053 122 : SaveSupplyDemandAir = FoundSupplyDemandAir;
2054 122 : SaveLoop = FoundLoop;
2055 : } else {
2056 0 : ShowSevereError(
2057 : state,
2058 0 : format("GetMixerInput: Outlet Mixer Branch=\"{}\" and BranchList=\"{}\" not matched to a Air/Plant/Condenser Loop",
2059 : TestName,
2060 : BranchListName));
2061 0 : ShowContinueError(state, "...and therefore, not a valid Loop Mixer.");
2062 0 : ShowContinueError(state, format("...{}={}", CurrentModuleObject, state.dataBranchInputManager->Mixers(Count).Name));
2063 0 : ErrorsFound = true;
2064 : }
2065 : } else {
2066 0 : ShowSevereError(state, format("GetMixerInput: Outlet Mixer Branch=\"{}\" not on BranchList", TestName));
2067 0 : ShowContinueError(state, "...and therefore, not a valid Loop Mixer.");
2068 0 : ShowContinueError(state, format("...{}={}", CurrentModuleObject, state.dataBranchInputManager->Mixers(Count).Name));
2069 0 : ErrorsFound = true;
2070 : }
2071 364 : for (Loop = 1; Loop <= state.dataBranchInputManager->Mixers(Count).NumInletBranches; ++Loop) {
2072 242 : TestName = state.dataBranchInputManager->Mixers(Count).InletBranchNames(Loop);
2073 242 : BranchListName = std::string();
2074 659 : for (Loop1 = 1; Loop1 <= (int)state.dataBranchInputManager->BranchList.size(); ++Loop1) {
2075 659 : if (any_eq(state.dataBranchInputManager->BranchList(Loop1).BranchNames, TestName)) {
2076 242 : BranchListName = state.dataBranchInputManager->BranchList(Loop1).Name;
2077 242 : break;
2078 : }
2079 : }
2080 :
2081 242 : if (!BranchListName.empty()) {
2082 242 : FoundSupplyDemandAir = std::string();
2083 242 : FoundLoop = std::string();
2084 242 : MatchedLoop = false;
2085 : // 3. Find the plant loop and type
2086 242 : FindAirPlantCondenserLoopFromBranchList(state, BranchListName, FoundLoop, FoundSupplyDemandAir, MatchedLoop);
2087 242 : if (MatchedLoop) {
2088 242 : if (SaveSupplyDemandAir != FoundSupplyDemandAir || SaveLoop != FoundLoop) {
2089 0 : ShowSevereError(state,
2090 0 : format("GetMixerInput: Outlet Mixer Branch=\"{}\" does not match types of Inlet Branch.", TestName));
2091 0 : ShowContinueError(state, format("...Outlet Branch is on \"{}\" on \"{}\" side.", SaveLoop, SaveSupplyDemandAir));
2092 0 : ShowContinueError(state, format("...Inlet Branch is on \"{}\" on \"{}\" side.", FoundLoop, FoundSupplyDemandAir));
2093 0 : ShowContinueError(state, "...All branches in Loop Mixer must be on same kind of loop and supply/demand side.");
2094 0 : ShowContinueError(state, format("...{}={}", CurrentModuleObject, state.dataBranchInputManager->Mixers(Count).Name));
2095 0 : ErrorsFound = true;
2096 : }
2097 : } else {
2098 0 : ShowSevereError(
2099 : state,
2100 0 : format("GetMixerInput: Inlet Mixer Branch=\"{}\" and BranchList=\"{}\" not matched to a Air/Plant/Condenser Loop",
2101 : TestName,
2102 : BranchListName));
2103 0 : ShowContinueError(state, "...and therefore, not a valid Loop Mixer.");
2104 0 : ShowContinueError(state, format("...{}={}", CurrentModuleObject, state.dataBranchInputManager->Mixers(Count).Name));
2105 0 : ErrorsFound = true;
2106 : }
2107 : } else {
2108 0 : ShowSevereError(state, format("GetMixerInput: Inlet Mixer Branch=\"{}\" not on BranchList", TestName));
2109 0 : ShowContinueError(state, "...and therefore, not a valid Loop Mixer");
2110 0 : ShowContinueError(state, format("...{}={}", CurrentModuleObject, state.dataBranchInputManager->Mixers(Count).Name));
2111 0 : ErrorsFound = true;
2112 : }
2113 : }
2114 122 : }
2115 :
2116 46 : if (ErrorsFound) {
2117 0 : ShowFatalError(state, format("GetMixerInput: Fatal Errors Found in {}, program terminates.", CurrentModuleObject));
2118 : }
2119 46 : }
2120 :
2121 728 : void FindPlantLoopBranchConnection(EnergyPlusData &state,
2122 : std::string const &BranchListName,
2123 : std::string &FoundPlantLoopName,
2124 : int &FoundPlantLoopNum,
2125 : std::string &FoundSupplyDemand,
2126 : Real64 &FoundVolFlowRate,
2127 : bool &MatchedPlantLoop)
2128 : {
2129 :
2130 : // SUBROUTINE INFORMATION:
2131 : // AUTHOR Linda Lawrie
2132 : // DATE WRITTEN October 2007
2133 :
2134 : // PURPOSE OF THIS SUBROUTINE:
2135 : // An auxiliary routine locate a plant loop and type from a BranchListName
2136 :
2137 : // METHODOLOGY EMPLOYED:
2138 : // Calls GetObject for PLANT LOOP
2139 :
2140 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2141 : int Num;
2142 : int NumPlantLoops;
2143 : int NumParams;
2144 728 : Array1D_string Alphas;
2145 : int NumAlphas;
2146 728 : Array1D<Real64> Numbers;
2147 : int NumNumbers;
2148 : int IOStat;
2149 :
2150 : // Get Inputs
2151 728 : std::string CurrentModuleObject = "PlantLoop";
2152 :
2153 728 : NumPlantLoops = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
2154 728 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNumbers);
2155 728 : Alphas.allocate(NumAlphas);
2156 728 : Numbers.allocate(NumNumbers);
2157 :
2158 1034 : for (Num = 1; Num <= NumPlantLoops; ++Num) {
2159 932 : state.dataInputProcessing->inputProcessor->getObjectItem(state, CurrentModuleObject, Num, Alphas, NumAlphas, Numbers, NumNumbers, IOStat);
2160 : // Only looking for BranchList here.
2161 932 : if (Alphas(8) == BranchListName) {
2162 270 : FoundPlantLoopName = Alphas(1);
2163 270 : FoundSupplyDemand = "Supply";
2164 270 : FoundVolFlowRate = Numbers(3);
2165 270 : FoundPlantLoopNum = Num;
2166 270 : MatchedPlantLoop = true;
2167 270 : break;
2168 662 : } else if (Alphas(12) == BranchListName) {
2169 356 : FoundPlantLoopName = Alphas(1);
2170 356 : FoundSupplyDemand = "Demand";
2171 356 : FoundVolFlowRate = Numbers(3);
2172 356 : FoundPlantLoopNum = Num;
2173 356 : MatchedPlantLoop = true;
2174 356 : break;
2175 : }
2176 : }
2177 :
2178 728 : Alphas.deallocate();
2179 728 : Numbers.deallocate();
2180 728 : }
2181 :
2182 102 : void FindCondenserLoopBranchConnection(EnergyPlusData &state,
2183 : std::string const &BranchListName,
2184 : std::string &FoundCondLoopName,
2185 : int &FoundCondLoopNum,
2186 : std::string &FoundSupplyDemand,
2187 : Real64 &FoundVolFlowRate,
2188 : bool &MatchedCondLoop)
2189 : {
2190 :
2191 : // SUBROUTINE INFORMATION:
2192 : // AUTHOR Linda Lawrie
2193 : // DATE WRITTEN February 2008
2194 :
2195 : // PURPOSE OF THIS SUBROUTINE:
2196 : // An auxiliary routine locate a condenser loop and type from a BranchListName
2197 :
2198 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2199 : int Num;
2200 : int NumCondLoops;
2201 : int NumParams;
2202 102 : Array1D_string Alphas;
2203 : int NumAlphas;
2204 102 : Array1D<Real64> Numbers;
2205 : int NumNumbers;
2206 : int IOStat;
2207 :
2208 : // Get Inputs
2209 102 : std::string CurrentModuleObject = "CondenserLoop";
2210 :
2211 102 : NumCondLoops = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
2212 102 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNumbers);
2213 102 : Alphas.allocate(NumAlphas);
2214 102 : Numbers.allocate(NumNumbers);
2215 :
2216 102 : for (Num = 1; Num <= NumCondLoops; ++Num) {
2217 102 : state.dataInputProcessing->inputProcessor->getObjectItem(state, CurrentModuleObject, Num, Alphas, NumAlphas, Numbers, NumNumbers, IOStat);
2218 : // Only looking for BranchList here.
2219 102 : if (Alphas(8) == BranchListName) {
2220 48 : FoundCondLoopName = Alphas(1);
2221 48 : FoundSupplyDemand = "Supply";
2222 48 : FoundVolFlowRate = Numbers(3);
2223 48 : FoundCondLoopNum = Num;
2224 48 : MatchedCondLoop = true;
2225 48 : break;
2226 54 : } else if (Alphas(12) == BranchListName) {
2227 54 : FoundCondLoopName = Alphas(1);
2228 54 : FoundSupplyDemand = "Demand";
2229 54 : FoundVolFlowRate = Numbers(3);
2230 54 : FoundCondLoopNum = Num;
2231 54 : MatchedCondLoop = true;
2232 54 : break;
2233 : }
2234 : }
2235 :
2236 102 : Alphas.deallocate();
2237 102 : Numbers.deallocate();
2238 102 : }
2239 :
2240 3 : void FindAirLoopBranchConnection(EnergyPlusData &state,
2241 : std::string const &BranchListName,
2242 : std::string &FoundAirLoopName,
2243 : int &FoundAirLoopNum,
2244 : std::string &FoundAir,
2245 : Real64 &FoundVolFlowRate,
2246 : bool &MatchedAirLoop)
2247 : {
2248 :
2249 : // SUBROUTINE INFORMATION:
2250 : // AUTHOR Linda Lawrie
2251 : // DATE WRITTEN February 2008
2252 :
2253 : // PURPOSE OF THIS SUBROUTINE:
2254 : // An auxiliary routine to locate a Air condenser loop and type from a BranchListName
2255 :
2256 : // METHODOLOGY EMPLOYED:
2257 : // calls GetObject for PRIMARY AIR LOOP
2258 :
2259 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2260 : int Num;
2261 : int NumAirLoops;
2262 : int NumParams;
2263 3 : Array1D_string Alphas;
2264 : int NumAlphas;
2265 3 : Array1D<Real64> Numbers;
2266 : int NumNumbers;
2267 : int IOStat;
2268 :
2269 : // Get Inputs
2270 3 : std::string CurrentModuleObject = "AirLoopHVAC";
2271 3 : NumAirLoops = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
2272 3 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNumbers);
2273 3 : Alphas.allocate(NumAlphas);
2274 3 : Numbers.allocate(NumNumbers);
2275 :
2276 6 : for (Num = 1; Num <= NumAirLoops; ++Num) {
2277 5 : state.dataInputProcessing->inputProcessor->getObjectItem(state, CurrentModuleObject, Num, Alphas, NumAlphas, Numbers, NumNumbers, IOStat);
2278 : // Only looking for BranchList here.
2279 5 : if (Alphas(4) == BranchListName) {
2280 2 : FoundAirLoopName = Alphas(1);
2281 2 : FoundAir = "Air";
2282 2 : FoundVolFlowRate = Numbers(1);
2283 2 : FoundAirLoopNum = Num;
2284 2 : MatchedAirLoop = true;
2285 2 : break;
2286 : }
2287 : }
2288 :
2289 3 : Alphas.deallocate();
2290 3 : Numbers.deallocate();
2291 3 : }
2292 :
2293 728 : void FindAirPlantCondenserLoopFromBranchList(EnergyPlusData &state,
2294 : std::string const &BranchListName, // Branch List Name
2295 : std::string &LoopType, // LoopType (if found, Plant,Condenser or Air)
2296 : std::string &LoopSupplyDemandAir, // Supply if "Supply" or Demand if "Demand" or Air if "Air"
2297 : bool &MatchedLoop // true if found
2298 : )
2299 : {
2300 :
2301 : // SUBROUTINE INFORMATION:
2302 : // AUTHOR Linda Lawrie
2303 : // DATE WRITTEN February 2008
2304 :
2305 : // PURPOSE OF THIS SUBROUTINE:
2306 : // Assist in validating Loop Splitter/Mixer connections.
2307 :
2308 : // METHODOLOGY EMPLOYED:
2309 : // Call two previously written subroutines that match a Branch List Name to
2310 : // Plant or Condenser Loop
2311 :
2312 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2313 728 : std::string FoundLoopName;
2314 : int FoundLoopNum;
2315 : Real64 FoundLoopVolFlowRate;
2316 :
2317 728 : LoopSupplyDemandAir = std::string();
2318 728 : FoundLoopName = std::string();
2319 728 : FoundLoopNum = 0;
2320 728 : FoundLoopVolFlowRate = 0.0;
2321 728 : MatchedLoop = false;
2322 728 : LoopType = std::string();
2323 :
2324 : // Try Plant first
2325 728 : FindPlantLoopBranchConnection(state, BranchListName, FoundLoopName, FoundLoopNum, LoopSupplyDemandAir, FoundLoopVolFlowRate, MatchedLoop);
2326 :
2327 728 : if (MatchedLoop) LoopType = "Plant";
2328 728 : if (!MatchedLoop) { // Try Condenser Loop
2329 102 : LoopSupplyDemandAir = std::string();
2330 102 : FoundLoopName = std::string();
2331 102 : FoundLoopNum = 0;
2332 102 : FoundLoopVolFlowRate = 0.0;
2333 102 : MatchedLoop = false;
2334 :
2335 : // Try Condenser
2336 102 : FindCondenserLoopBranchConnection(
2337 : state, BranchListName, FoundLoopName, FoundLoopNum, LoopSupplyDemandAir, FoundLoopVolFlowRate, MatchedLoop);
2338 102 : if (MatchedLoop) LoopType = "Condenser";
2339 : }
2340 :
2341 728 : if (!MatchedLoop) { // Try Air Loop
2342 0 : LoopSupplyDemandAir = std::string();
2343 0 : FoundLoopName = std::string();
2344 0 : FoundLoopNum = 0;
2345 0 : FoundLoopVolFlowRate = 0.0;
2346 0 : MatchedLoop = false;
2347 :
2348 : // Try Air
2349 0 : FindAirLoopBranchConnection(state, BranchListName, FoundLoopName, FoundLoopNum, LoopSupplyDemandAir, FoundLoopVolFlowRate, MatchedLoop);
2350 0 : if (MatchedLoop) LoopType = "Air";
2351 : }
2352 728 : }
2353 :
2354 : //==================================================================================
2355 : // Routines that test branch integrity
2356 : //==================================================================================
2357 :
2358 110 : void AuditBranches(EnergyPlusData &state,
2359 : bool const mustprint, // true if the warning should be printed.
2360 : ObjexxFCL::Optional_string_const CompType, // when mustprint (ScanPlantLoop) use CompType in error message and scan
2361 : ObjexxFCL::Optional_string_const CompName // when mustprint (ScanPlantLoop) use CompName in error message and scan
2362 : )
2363 : {
2364 :
2365 : // SUBROUTINE INFORMATION:
2366 : // AUTHOR Linda Lawrie
2367 : // DATE WRITTEN November 2011
2368 :
2369 : // PURPOSE OF THIS SUBROUTINE:
2370 : // This routine will point out any "dangling branches" that are not included on a BranchList.
2371 : // Warnings are produced as the user might clutter up the input file with unused branches.
2372 :
2373 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2374 : int NumDanglingCount; // when mustprint not true, count and report
2375 : int BlNum; // Branch List Counter
2376 : int BrN; // Branch Counter
2377 : int CpN; // Components on Branch
2378 : bool NeverFound;
2379 :
2380 110 : NumDanglingCount = 0;
2381 110 : NeverFound = true;
2382 499 : for (BrN = 1; BrN <= (int)state.dataBranchInputManager->Branch.size(); ++BrN) {
2383 389 : int Found = 0;
2384 389 : std::string FoundBranchName = "";
2385 389 : if (present(CompType) && present(CompName)) {
2386 0 : for (CpN = 1; CpN <= state.dataBranchInputManager->Branch(BrN).NumOfComponents; ++CpN) {
2387 0 : if (!Util::SameString(CompType(), state.dataBranchInputManager->Branch(BrN).Component(CpN).CType) ||
2388 0 : !Util::SameString(CompName(), state.dataBranchInputManager->Branch(BrN).Component(CpN).Name))
2389 0 : continue;
2390 0 : FoundBranchName = state.dataBranchInputManager->Branch(BrN).Name;
2391 0 : NeverFound = false;
2392 : }
2393 : }
2394 1094 : for (BlNum = 1; BlNum <= (int)state.dataBranchInputManager->BranchList.size(); ++BlNum) {
2395 1094 : Found = Util::FindItemInList(state.dataBranchInputManager->Branch(BrN).Name,
2396 1094 : state.dataBranchInputManager->BranchList(BlNum).BranchNames,
2397 1094 : state.dataBranchInputManager->BranchList(BlNum).NumOfBranchNames);
2398 1094 : if (Found != 0) break;
2399 : }
2400 389 : if (Found != 0) continue;
2401 0 : ++NumDanglingCount;
2402 0 : if (state.dataGlobal->DisplayExtraWarnings || mustprint) {
2403 0 : if (mustprint) {
2404 0 : ShowContinueError(
2405 0 : state, format("AuditBranches: Branch=\"{}\" not found on any BranchLists.", state.dataBranchInputManager->Branch(BrN).Name));
2406 0 : if (!FoundBranchName.empty()) {
2407 0 : ShowContinueError(state, format("Branch contains component, type=\"{}\", name=\"{}\"", CompType, CompName));
2408 : }
2409 : } else {
2410 0 : ShowSevereMessage(
2411 0 : state, format("AuditBranches: Branch=\"{}\" not found on any BranchLists.", state.dataBranchInputManager->Branch(BrN).Name));
2412 0 : ++state.dataErrTracking->TotalSevereErrors;
2413 : }
2414 : }
2415 389 : }
2416 110 : if (mustprint && NeverFound) { // this may be caught during branch input, not sure
2417 5 : ShowContinueError(state, format("Component, type=\"{}\", name=\"{}\" was not found on any Branch.", CompType, CompName));
2418 15 : ShowContinueError(state, "Look for mistyped branch or component names/types.");
2419 : }
2420 110 : if (!mustprint && NumDanglingCount > 0) {
2421 0 : ShowSevereMessage(state, fmt::format("AuditBranches: There are {} branch(es) that do not appear on any BranchList.", NumDanglingCount));
2422 0 : state.dataErrTracking->TotalSevereErrors += NumDanglingCount;
2423 0 : ShowContinueError(state, "Use Output:Diagnostics,DisplayExtraWarnings; for detail of each branch not on a branch list.");
2424 : }
2425 110 : }
2426 :
2427 73 : void TestBranchIntegrity(EnergyPlusData &state, bool &ErrFound)
2428 : {
2429 :
2430 : // SUBROUTINE INFORMATION:
2431 : // AUTHOR Linda Lawrie
2432 : // DATE WRITTEN November 2001
2433 :
2434 : // PURPOSE OF THIS SUBROUTINE:
2435 : // This subroutine tests branch integrity and displays the loop for each branch.
2436 : // Also, input and output nodes.
2437 :
2438 : // Using/Aliasing
2439 :
2440 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2441 : int Loop;
2442 : int Count;
2443 : int MatchNode; // Node Number for match
2444 73 : std::string MatchNodeName; // Name for error message if not matched
2445 73 : std::string BranchInletNodeName; // Branch Inlet Node Name
2446 73 : std::string BranchOutletNodeName; // Branch Outlet Node Name
2447 73 : std::string BranchLoopName; // Loop Name which Branch is part of
2448 73 : std::string BranchLoopType; // Loop Type which Branch is part of
2449 : int NumErr; // Error Counter
2450 73 : Array1D_bool BranchReported;
2451 : int BCount;
2452 : int Found;
2453 : // LOGICAL UniqueNodeError
2454 : int Loop2;
2455 : NodeFluidType BranchFluidType;
2456 : int InitialBranchFluidNode;
2457 73 : Array1D_int BranchFluidNodes;
2458 73 : Array1D_int FoundBranches;
2459 73 : Array1D_int BranchPtrs;
2460 73 : std::string cBranchFluidType;
2461 : int Ptr;
2462 : int EndPtr;
2463 :
2464 : struct BranchUniqueNodes
2465 : {
2466 : int NumNodes{0};
2467 : Array1D_string UniqueNodeNames;
2468 : };
2469 :
2470 : // Object Data
2471 73 : Array1D<BranchUniqueNodes> BranchNodes;
2472 :
2473 : // Formats
2474 :
2475 73 : BranchReported.dimension((int)state.dataBranchInputManager->Branch.size(), false);
2476 :
2477 : // Do by Branch Lists
2478 146 : ShowMessage(state, "Testing Individual Branch Integrity");
2479 73 : ErrFound = false;
2480 :
2481 73 : BranchNodes.allocate((int)state.dataBranchInputManager->Branch.size());
2482 :
2483 73 : print(state.files.bnd, "{}\n", "! ===============================================================");
2484 : static constexpr std::string_view Format_700("! <#Branch Lists>,<Number of Branch Lists>");
2485 73 : print(state.files.bnd, "{}\n", Format_700);
2486 73 : print(state.files.bnd, " #Branch Lists,{}\n", (int)state.dataBranchInputManager->BranchList.size());
2487 : static constexpr std::string_view Format_702(
2488 : "! <Branch List>,<Branch List Count>,<Branch List Name>,<Loop Name>,<Loop Type>,<Number of Branches>");
2489 73 : print(state.files.bnd, "{}\n", Format_702);
2490 : static constexpr std::string_view Format_704(
2491 : "! <Branch>,<Branch Count>,<Branch Name>,<Loop Name>,<Loop Type>,<Branch Inlet Node Name>,<Branch Outlet Node Name>");
2492 73 : print(state.files.bnd, "{}\n", Format_704);
2493 :
2494 121 : for (BCount = 1; BCount <= (int)state.dataBranchInputManager->BranchList.size(); ++BCount) {
2495 48 : print(state.files.bnd,
2496 : " Branch List,{},{},{},{},{}\n",
2497 : BCount,
2498 48 : state.dataBranchInputManager->BranchList(BCount).Name,
2499 48 : state.dataBranchInputManager->BranchList(BCount).LoopName,
2500 48 : state.dataBranchInputManager->BranchList(BCount).LoopType,
2501 48 : state.dataBranchInputManager->BranchList(BCount).NumOfBranchNames);
2502 :
2503 48 : BranchFluidType = NodeFluidType::Blank;
2504 48 : bool MixedFluidTypesOnBranchList = false;
2505 48 : int NumNodesOnBranchList = 0;
2506 48 : FoundBranches.allocate(state.dataBranchInputManager->BranchList(BCount).NumOfBranchNames);
2507 48 : FoundBranches = 0;
2508 48 : BranchPtrs.allocate(state.dataBranchInputManager->BranchList(BCount).NumOfBranchNames + 2);
2509 48 : BranchPtrs = 0;
2510 188 : for (Count = 1; Count <= state.dataBranchInputManager->BranchList(BCount).NumOfBranchNames; ++Count) {
2511 : Found =
2512 140 : Util::FindItemInList(state.dataBranchInputManager->BranchList(BCount).BranchNames(Count), state.dataBranchInputManager->Branch);
2513 140 : if (Found > 0) {
2514 140 : NumNodesOnBranchList += state.dataBranchInputManager->Branch(Found).NumOfComponents * 2;
2515 140 : FoundBranches(Count) = Found;
2516 140 : BranchPtrs(Count) = NumNodesOnBranchList;
2517 : } else {
2518 0 : ShowSevereError(state, format("Branch not found={}", state.dataBranchInputManager->BranchList(BCount).BranchNames(Count)));
2519 0 : ErrFound = true;
2520 : }
2521 : }
2522 48 : BranchPtrs(state.dataBranchInputManager->BranchList(BCount).NumOfBranchNames + 1) =
2523 48 : BranchPtrs(state.dataBranchInputManager->BranchList(BCount).NumOfBranchNames) + 1;
2524 48 : BranchFluidNodes.dimension(NumNodesOnBranchList, 0);
2525 48 : std::string OriginalBranchFluidType = std::string();
2526 48 : int NumFluidNodes = 0;
2527 188 : for (Count = 1; Count <= state.dataBranchInputManager->BranchList(BCount).NumOfBranchNames; ++Count) {
2528 140 : Found = FoundBranches(Count);
2529 140 : if (Found == 0) {
2530 0 : print(state.files.bnd,
2531 : " Branch,{},{},(not found),**Unknown**,**Unknown**,**Unknown**,**Unknown**\n",
2532 : Count,
2533 0 : state.dataBranchInputManager->BranchList(BCount).BranchNames(Count));
2534 0 : continue;
2535 : }
2536 140 : BranchReported(Found) = true;
2537 : // Check Branch for connections
2538 :
2539 140 : MatchNode = 0;
2540 140 : InitialBranchFluidNode = 0;
2541 140 : if (state.dataBranchInputManager->Branch(Found).NumOfComponents > 0) {
2542 140 : MatchNode = state.dataBranchInputManager->Branch(Found).Component(1).InletNode;
2543 140 : MatchNodeName = state.dataBranchInputManager->Branch(Found).Component(1).InletNodeName;
2544 140 : BranchInletNodeName = state.dataBranchInputManager->Branch(Found).Component(1).InletNodeName;
2545 : } else {
2546 0 : ShowWarningError(state, format("Branch has no components={}", state.dataBranchInputManager->Branch(Found).Name));
2547 : }
2548 140 : NumErr = 0;
2549 332 : for (Loop = 1; Loop <= state.dataBranchInputManager->Branch(Found).NumOfComponents; ++Loop) {
2550 192 : if (BranchFluidType == DataLoopNode::NodeFluidType::Blank) {
2551 48 : ++NumFluidNodes;
2552 48 : BranchFluidNodes(NumFluidNodes) = state.dataBranchInputManager->Branch(Found).Component(Loop).InletNode;
2553 48 : BranchFluidType = state.dataLoopNodes->Node(state.dataBranchInputManager->Branch(Found).Component(Loop).InletNode).FluidType;
2554 48 : InitialBranchFluidNode = state.dataBranchInputManager->Branch(Found).Component(Loop).InletNode;
2555 48 : OriginalBranchFluidType = DataLoopNode::NodeFluidTypeNames[static_cast<int>(DataLoopNode::NodeFluidType::Blank)];
2556 144 : } else if (BranchFluidType !=
2557 144 : state.dataLoopNodes->Node(state.dataBranchInputManager->Branch(Found).Component(Loop).InletNode).FluidType &&
2558 0 : state.dataLoopNodes->Node(state.dataBranchInputManager->Branch(Found).Component(Loop).InletNode).FluidType !=
2559 : DataLoopNode::NodeFluidType::Blank) {
2560 0 : ++NumFluidNodes;
2561 0 : BranchFluidNodes(NumFluidNodes) = state.dataBranchInputManager->Branch(Found).Component(Loop).InletNode;
2562 0 : MixedFluidTypesOnBranchList = true;
2563 : } else {
2564 144 : ++NumFluidNodes;
2565 144 : BranchFluidNodes(NumFluidNodes) = state.dataBranchInputManager->Branch(Found).Component(Loop).InletNode;
2566 : }
2567 192 : if (BranchFluidType == DataLoopNode::NodeFluidType::Blank) {
2568 0 : ++NumFluidNodes;
2569 0 : BranchFluidNodes(NumFluidNodes) = state.dataBranchInputManager->Branch(Found).Component(Loop).InletNode;
2570 0 : BranchFluidType = state.dataLoopNodes->Node(state.dataBranchInputManager->Branch(Found).Component(Loop).OutletNode).FluidType;
2571 0 : InitialBranchFluidNode = state.dataBranchInputManager->Branch(Found).Component(Loop).OutletNode;
2572 0 : OriginalBranchFluidType = DataLoopNode::NodeFluidTypeNames[static_cast<int>(BranchFluidType)];
2573 192 : } else if (BranchFluidType !=
2574 192 : state.dataLoopNodes->Node(state.dataBranchInputManager->Branch(Found).Component(Loop).OutletNode).FluidType &&
2575 0 : state.dataLoopNodes->Node(state.dataBranchInputManager->Branch(Found).Component(Loop).OutletNode).FluidType !=
2576 : DataLoopNode::NodeFluidType::Blank) {
2577 0 : ++NumFluidNodes;
2578 0 : BranchFluidNodes(NumFluidNodes) = state.dataBranchInputManager->Branch(Found).Component(Loop).OutletNode;
2579 0 : MixedFluidTypesOnBranchList = true;
2580 : } else {
2581 192 : ++NumFluidNodes;
2582 192 : BranchFluidNodes(NumFluidNodes) = state.dataBranchInputManager->Branch(Found).Component(Loop).OutletNode;
2583 : }
2584 192 : if (state.dataBranchInputManager->Branch(Found).Component(Loop).InletNode != MatchNode) {
2585 0 : ShowSevereError(state, format("Error Detected in BranchList={}", state.dataBranchInputManager->BranchList(BCount).Name));
2586 0 : ShowContinueError(state, format("Actual Error occurs in Branch={}", state.dataBranchInputManager->Branch(Found).Name));
2587 0 : ShowContinueError(state, format("Branch Outlet does not match Inlet, Outlet={}", MatchNodeName));
2588 0 : ShowContinueError(state, format("Inlet Name={}", state.dataBranchInputManager->Branch(Found).Component(Loop).InletNodeName));
2589 0 : ErrFound = true;
2590 0 : ++NumErr;
2591 : } else {
2592 192 : MatchNode = state.dataBranchInputManager->Branch(Found).Component(Loop).OutletNode;
2593 192 : MatchNodeName = state.dataBranchInputManager->Branch(Found).Component(Loop).OutletNodeName;
2594 : }
2595 : }
2596 140 : state.dataBranchInputManager->Branch(Found).FluidType = BranchFluidType;
2597 140 : BranchOutletNodeName = MatchNodeName;
2598 140 : if (state.dataBranchInputManager->Branch(Found).AssignedLoopName.empty()) {
2599 0 : BranchLoopName = "**Unknown**";
2600 0 : BranchLoopType = "**Unknown**";
2601 140 : } else if (state.dataBranchInputManager->Branch(Found).AssignedLoopName ==
2602 140 : state.dataBranchInputManager->BranchList(BCount).LoopName) {
2603 140 : BranchLoopName = state.dataBranchInputManager->BranchList(BCount).LoopName;
2604 140 : BranchLoopType = state.dataBranchInputManager->BranchList(BCount).LoopType;
2605 : } else {
2606 0 : BranchLoopName = state.dataBranchInputManager->Branch(Found).AssignedLoopName;
2607 0 : BranchLoopType = "**Unknown**";
2608 : }
2609 140 : print(state.files.bnd,
2610 : " Branch,{},{},{},{},{},{}\n",
2611 : Count,
2612 140 : state.dataBranchInputManager->Branch(Found).Name,
2613 : BranchLoopName,
2614 : BranchLoopType,
2615 : BranchInletNodeName,
2616 : BranchOutletNodeName);
2617 : }
2618 48 : if (MixedFluidTypesOnBranchList) {
2619 0 : ShowSevereError(state,
2620 0 : format("BranchList={} has mixed fluid types in its nodes.", state.dataBranchInputManager->BranchList(BCount).Name));
2621 0 : ErrFound = true;
2622 0 : if (OriginalBranchFluidType.empty()) OriginalBranchFluidType = "**Unknown**";
2623 0 : ShowContinueError(
2624 0 : state, format("Initial Node={}, Fluid Type={}", state.dataLoopNodes->NodeID(InitialBranchFluidNode), OriginalBranchFluidType));
2625 0 : ShowContinueError(state, "BranchList Topology - Note nodes which do not match that fluid type:");
2626 0 : Ptr = 1;
2627 0 : EndPtr = BranchPtrs(1);
2628 0 : for (Loop = 1; Loop <= state.dataBranchInputManager->BranchList(BCount).NumOfBranchNames; ++Loop) {
2629 0 : if (FoundBranches(Loop) != 0) {
2630 0 : ShowContinueError(state, format("..Branch={}", state.dataBranchInputManager->Branch(FoundBranches(Loop)).Name));
2631 : } else {
2632 0 : ShowContinueError(state, format("..Illegal Branch={}", state.dataBranchInputManager->BranchList(BCount).BranchNames(Loop)));
2633 0 : continue;
2634 : }
2635 0 : for (Loop2 = Ptr; Loop2 <= EndPtr; ++Loop2) {
2636 : cBranchFluidType =
2637 0 : DataLoopNode::NodeFluidTypeNames[static_cast<int>(state.dataLoopNodes->Node(BranchFluidNodes(Loop2)).FluidType)];
2638 0 : if (cBranchFluidType.empty()) cBranchFluidType = "**Unknown**";
2639 0 : ShowContinueError(
2640 0 : state, format("....Node={}, Fluid Type={}", state.dataLoopNodes->NodeID(BranchFluidNodes(Loop2)), cBranchFluidType));
2641 : }
2642 0 : Ptr = EndPtr + 1;
2643 0 : EndPtr = BranchPtrs(Loop + 1);
2644 : }
2645 : }
2646 48 : BranchFluidNodes.deallocate();
2647 48 : BranchPtrs.deallocate();
2648 48 : FoundBranches.deallocate();
2649 48 : }
2650 :
2651 : // Build node names in branches
2652 213 : for (Count = 1; Count <= (int)state.dataBranchInputManager->Branch.size(); ++Count) {
2653 140 : BranchNodes(Count).UniqueNodeNames.allocate(state.dataBranchInputManager->Branch(Count).NumOfComponents * 2);
2654 140 : int NodeNum = 0;
2655 332 : for (Loop = 1; Loop <= state.dataBranchInputManager->Branch(Count).NumOfComponents; ++Loop) {
2656 192 : Found = Util::FindItemInList(
2657 192 : state.dataBranchInputManager->Branch(Count).Component(Loop).InletNodeName, BranchNodes(Count).UniqueNodeNames, NodeNum);
2658 192 : if (Found == 0) {
2659 140 : ++NodeNum;
2660 140 : BranchNodes(Count).UniqueNodeNames(NodeNum) = state.dataBranchInputManager->Branch(Count).Component(Loop).InletNodeName;
2661 : }
2662 192 : Found = Util::FindItemInList(
2663 192 : state.dataBranchInputManager->Branch(Count).Component(Loop).OutletNodeName, BranchNodes(Count).UniqueNodeNames, NodeNum);
2664 192 : if (Found == 0) {
2665 192 : ++NodeNum;
2666 192 : BranchNodes(Count).UniqueNodeNames(NodeNum) = state.dataBranchInputManager->Branch(Count).Component(Loop).OutletNodeName;
2667 : }
2668 : }
2669 140 : BranchNodes(Count).NumNodes = NodeNum;
2670 : }
2671 : // Check Uniqueness branch to branch
2672 213 : for (Count = 1; Count <= (int)state.dataBranchInputManager->Branch.size(); ++Count) {
2673 1295 : for (Loop = Count + 1; Loop <= (int)state.dataBranchInputManager->Branch.size(); ++Loop) {
2674 3624 : for (Loop2 = 1; Loop2 <= BranchNodes(Count).NumNodes; ++Loop2) {
2675 2469 : Found = Util::FindItemInList(
2676 2469 : BranchNodes(Count).UniqueNodeNames(Loop2), BranchNodes(Loop).UniqueNodeNames, BranchNodes(Loop).NumNodes);
2677 2469 : if (Found != 0) {
2678 0 : ShowSevereError(state, format("Non-unique node name found, name={}", BranchNodes(Count).UniqueNodeNames(Loop2)));
2679 0 : ShowContinueError(state, format("..1st occurrence in Branch={}", state.dataBranchInputManager->Branch(Count).Name));
2680 0 : ShowContinueError(state, format("..duplicate occurrence in Branch={}", state.dataBranchInputManager->Branch(Loop).Name));
2681 0 : ErrFound = true;
2682 : }
2683 : }
2684 : }
2685 : }
2686 213 : for (Count = 1; Count <= (int)state.dataBranchInputManager->Branch.size(); ++Count) {
2687 140 : BranchNodes(Count).UniqueNodeNames.deallocate();
2688 : }
2689 73 : BranchNodes.deallocate();
2690 :
2691 73 : BCount = 0;
2692 213 : for (Count = 1; Count <= (int)state.dataBranchInputManager->Branch.size(); ++Count) {
2693 140 : if (BranchReported(Count)) continue;
2694 0 : ++BCount;
2695 : }
2696 73 : if (BCount > 0) {
2697 : static constexpr std::string_view Format_706("! <# Orphaned Branches>,<Number of Branches not on Branch Lists>");
2698 0 : print(state.files.bnd, "{}\n", Format_706);
2699 0 : print(state.files.bnd, " #Orphaned Branches,{}\n", BCount);
2700 0 : ShowWarningError(state, "There are orphaned Branches in input. See .bnd file for details.");
2701 :
2702 0 : BCount = 0;
2703 :
2704 0 : for (Count = 1; Count <= (int)state.dataBranchInputManager->Branch.size(); ++Count) {
2705 0 : if (BranchReported(Count)) continue;
2706 0 : ++BCount;
2707 0 : ShowWarningError(state, format("Orphan Branch=\"{}\".", state.dataBranchInputManager->Branch(Count).Name));
2708 :
2709 0 : if (state.dataBranchInputManager->Branch(Count).NumOfComponents > 0) {
2710 0 : MatchNode = state.dataBranchInputManager->Branch(Count).Component(1).InletNode;
2711 0 : MatchNodeName = state.dataBranchInputManager->Branch(Count).Component(1).InletNodeName;
2712 0 : BranchInletNodeName = state.dataBranchInputManager->Branch(Count).Component(1).InletNodeName;
2713 : } else {
2714 0 : ShowWarningError(state, format("Branch has no components={}", state.dataBranchInputManager->Branch(Count).Name));
2715 : }
2716 0 : NumErr = 0;
2717 0 : for (Loop = 1; Loop <= state.dataBranchInputManager->Branch(Count).NumOfComponents; ++Loop) {
2718 0 : if (state.dataBranchInputManager->Branch(Count).Component(Loop).InletNode != MatchNode) {
2719 0 : ShowSevereError(state, format("Error Detected in Branch={}", state.dataBranchInputManager->Branch(Count).Name));
2720 0 : ShowContinueError(state, format("Branch Outlet does not match Inlet, Outlet={}", MatchNodeName));
2721 0 : ShowContinueError(state, format("Inlet Name={}", state.dataBranchInputManager->Branch(Count).Component(Loop).InletNodeName));
2722 0 : ErrFound = true;
2723 0 : ++NumErr;
2724 : } else {
2725 0 : MatchNode = state.dataBranchInputManager->Branch(Count).Component(Loop).OutletNode;
2726 0 : MatchNodeName = state.dataBranchInputManager->Branch(Count).Component(Loop).OutletNodeName;
2727 : }
2728 : }
2729 0 : BranchOutletNodeName = MatchNodeName;
2730 0 : if (state.dataBranchInputManager->Branch(Count).AssignedLoopName.empty()) {
2731 0 : BranchLoopName = "**Unknown**";
2732 0 : BranchLoopType = "**Unknown**";
2733 : } else {
2734 0 : BranchLoopName = state.dataBranchInputManager->Branch(Count).AssignedLoopName;
2735 0 : BranchLoopType = "**Unknown**";
2736 : }
2737 0 : print(state.files.bnd,
2738 : " Branch,{},{},{},{},{},{}\n",
2739 : BCount,
2740 0 : state.dataBranchInputManager->Branch(Count).Name,
2741 : BranchLoopName,
2742 : BranchLoopType,
2743 : BranchInletNodeName,
2744 : BranchOutletNodeName);
2745 : }
2746 : }
2747 :
2748 73 : if (ErrFound) {
2749 0 : ShowSevereError(state, "Branch(es) did not pass integrity testing");
2750 : } else {
2751 219 : ShowMessage(state, "All Branches passed integrity testing");
2752 : }
2753 73 : }
2754 :
2755 : } // namespace BranchInputManager
2756 :
2757 : } // namespace EnergyPlus
|