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