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