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