Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // EnergyPlus Headers
49 : #include <EnergyPlus/BranchNodeConnections.hh>
50 : #include <EnergyPlus/Data/EnergyPlusData.hh>
51 : #include <EnergyPlus/DataContaminantBalance.hh>
52 : #include <EnergyPlus/DataIPShortCuts.hh>
53 : #include <EnergyPlus/DataLoopNode.hh>
54 : #include <EnergyPlus/HVACDuct.hh>
55 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
56 : #include <EnergyPlus/NodeInputManager.hh>
57 : #include <EnergyPlus/UtilityRoutines.hh>
58 :
59 : namespace EnergyPlus {
60 :
61 : namespace HVACDuct {
62 :
63 : // Module containing the routines dealing with the Duct component
64 : // in forced air air conditioning systems
65 :
66 : // MODULE INFORMATION:
67 : // AUTHOR Fred Buhl
68 : // DATE WRITTEN 17May2005
69 : // MODIFIED na
70 : // RE-ENGINEERED na
71 :
72 : // PURPOSE OF THIS MODULE:
73 : // To encapsulate the data and routines required to model duct
74 : // components in the EnergyPlus HVAC simulation
75 :
76 : // METHODOLOGY EMPLOYED:
77 : // At this point ducts are passive elements in the loop that just pass inlet node
78 : // conditions to the outlet node. The function of a duct component is to allow the
79 : // definition of a bypass branch: a branch must contain at least 1 component.
80 :
81 : // REFERENCES:
82 : // na
83 :
84 : // OTHER NOTES:
85 : // na
86 :
87 : // USE STATEMENTS:
88 : // <use statements for data only modules>
89 : // Using/Aliasing
90 : using namespace DataLoopNode;
91 :
92 : // <use statements for access to subroutines in other modules>
93 :
94 : // Data
95 : // MODULE PARAMETER DEFINITIONS:
96 : // na
97 :
98 : // DERIVED TYPE DEFINITIONS:
99 :
100 : // MODULE VARIABLE DECLARATIONS:
101 :
102 : // SUBROUTINE SPECIFICATIONS FOR MODULE HVACDuct:
103 :
104 : // <name Public routines, optionally name Private routines within this module>
105 :
106 : // Object Data
107 :
108 : // Functions
109 :
110 92527 : void SimDuct(EnergyPlusData &state,
111 : std::string_view CompName, // name of the duct component
112 : [[maybe_unused]] bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep !unused1208
113 : int &CompIndex // index of duct component
114 : )
115 : {
116 :
117 : // SUBROUTINE INFORMATION:
118 : // AUTHOR Fred Buhl
119 : // DATE WRITTEN 17May2005
120 : // MODIFIED na
121 : // RE-ENGINEERED na
122 :
123 : // PURPOSE OF THIS SUBROUTINE:
124 : // Manage the simulation of a duct component
125 :
126 : // Using/Aliasing
127 :
128 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
129 : int DuctNum; // index of duct being simulated
130 :
131 92527 : if (state.dataHVACDuct->GetInputFlag) {
132 2 : GetDuctInput(state);
133 2 : state.dataHVACDuct->GetInputFlag = false;
134 : }
135 :
136 : // Get the duct component index
137 92527 : if (CompIndex == 0) {
138 3 : DuctNum = UtilityRoutines::FindItemInList(CompName, state.dataHVACDuct->Duct);
139 3 : if (DuctNum == 0) {
140 0 : ShowFatalError(state, "SimDuct: Component not found=" + std::string{CompName});
141 : }
142 3 : CompIndex = DuctNum;
143 : } else {
144 92524 : DuctNum = CompIndex;
145 92524 : if (DuctNum > state.dataHVACDuct->NumDucts || DuctNum < 1) {
146 0 : ShowFatalError(state,
147 0 : format("SimDuct: Invalid CompIndex passed={}, Number of Components={}, Entered Component name={}",
148 : DuctNum,
149 0 : state.dataHVACDuct->NumDucts,
150 0 : CompName));
151 : }
152 92524 : if (state.dataHVACDuct->CheckEquipName(DuctNum)) {
153 3 : if (CompName != state.dataHVACDuct->Duct(DuctNum).Name) {
154 0 : ShowFatalError(state,
155 0 : format("SimDuct: Invalid CompIndex passed={}, Component name={}, stored Component Name for that index={}",
156 : DuctNum,
157 : CompName,
158 0 : state.dataHVACDuct->Duct(DuctNum).Name));
159 : }
160 3 : state.dataHVACDuct->CheckEquipName(DuctNum) = false;
161 : }
162 : }
163 :
164 92527 : InitDuct(state, DuctNum);
165 :
166 92527 : CalcDuct(DuctNum);
167 :
168 92527 : UpdateDuct(state, DuctNum);
169 :
170 92527 : ReportDuct(DuctNum);
171 92527 : }
172 :
173 2 : void GetDuctInput(EnergyPlusData &state)
174 : {
175 :
176 : // SUBROUTINE INFORMATION:
177 : // AUTHOR Fred Buhl
178 : // DATE WRITTEN 17May2005
179 : // MODIFIED na
180 : // RE-ENGINEERED na
181 :
182 : // PURPOSE OF THIS SUBROUTINE:
183 : // Obtains input data for ducts and stores it in duct data structures.
184 :
185 : // METHODOLOGY EMPLOYED:
186 : // Uses InputProcessor "Get" routines to obtain data.
187 :
188 : // Using/Aliasing
189 : using BranchNodeConnections::TestCompSet;
190 : using NodeInputManager::GetOnlySingleNode;
191 :
192 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
193 : int DuctNum; // duct index
194 : static constexpr std::string_view RoutineName("GetDuctInput:");
195 : int NumAlphas; // Number of Alphas for each GetObjectItem call
196 : int NumNumbers; // Number of Numbers for each GetObjectItem call
197 : int IOStatus; // Used in GetObjectItem
198 2 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
199 2 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
200 2 : cCurrentModuleObject = "Duct";
201 2 : state.dataHVACDuct->NumDucts = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
202 2 : state.dataHVACDuct->Duct.allocate(state.dataHVACDuct->NumDucts);
203 2 : state.dataHVACDuct->CheckEquipName.dimension(state.dataHVACDuct->NumDucts, true);
204 :
205 5 : for (DuctNum = 1; DuctNum <= state.dataHVACDuct->NumDucts; ++DuctNum) {
206 21 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
207 : cCurrentModuleObject,
208 : DuctNum,
209 3 : state.dataIPShortCut->cAlphaArgs,
210 : NumAlphas,
211 3 : state.dataIPShortCut->rNumericArgs,
212 : NumNumbers,
213 : IOStatus,
214 3 : state.dataIPShortCut->lNumericFieldBlanks,
215 3 : state.dataIPShortCut->lAlphaFieldBlanks,
216 3 : state.dataIPShortCut->cAlphaFieldNames,
217 3 : state.dataIPShortCut->cNumericFieldNames);
218 3 : UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
219 :
220 3 : state.dataHVACDuct->Duct(DuctNum).Name = state.dataIPShortCut->cAlphaArgs(1);
221 3 : state.dataHVACDuct->Duct(DuctNum).InletNodeNum = GetOnlySingleNode(state,
222 3 : state.dataIPShortCut->cAlphaArgs(2),
223 : ErrorsFound,
224 : DataLoopNode::ConnectionObjectType::Duct,
225 3 : state.dataIPShortCut->cAlphaArgs(1),
226 : DataLoopNode::NodeFluidType::Air,
227 : DataLoopNode::ConnectionType::Inlet,
228 : NodeInputManager::CompFluidStream::Primary,
229 3 : ObjectIsNotParent);
230 3 : state.dataHVACDuct->Duct(DuctNum).OutletNodeNum = GetOnlySingleNode(state,
231 3 : state.dataIPShortCut->cAlphaArgs(3),
232 : ErrorsFound,
233 : DataLoopNode::ConnectionObjectType::Duct,
234 3 : state.dataIPShortCut->cAlphaArgs(1),
235 : DataLoopNode::NodeFluidType::Air,
236 : DataLoopNode::ConnectionType::Outlet,
237 : NodeInputManager::CompFluidStream::Primary,
238 3 : ObjectIsNotParent);
239 6 : TestCompSet(state,
240 : cCurrentModuleObject,
241 3 : state.dataIPShortCut->cAlphaArgs(1),
242 3 : state.dataIPShortCut->cAlphaArgs(2),
243 3 : state.dataIPShortCut->cAlphaArgs(3),
244 : "Air Nodes");
245 : }
246 :
247 : // No output variables
248 :
249 2 : if (ErrorsFound) {
250 0 : ShowFatalError(state, std::string{RoutineName} + " Errors found in input");
251 : }
252 2 : }
253 :
254 92527 : void InitDuct(EnergyPlusData &state, int const DuctNum) // number of the current duct being simulated
255 : {
256 :
257 : // SUBROUTINE INFORMATION:
258 : // AUTHOR Fred Buhl
259 : // DATE WRITTEN 17May2005
260 : // MODIFIED na
261 : // RE-ENGINEERED na
262 :
263 : // PURPOSE OF THIS SUBROUTINE:
264 : // This subroutine is for initializations of the Duct Components
265 :
266 : // METHODOLOGY EMPLOYED:
267 : // Uses the status flags to trigger initializations
268 :
269 : // REFERENCES:
270 : // na
271 :
272 : // USE STATEMENTS:
273 : // na
274 :
275 : // Locals
276 : // SUBROUTINE ARGUMENT DEFINITIONS:
277 :
278 : // SUBROUTINE PARAMETER DEFINITIONS:
279 : // na
280 :
281 : // INTERFACE BLOCK SPECIFICATIONS
282 : // na
283 :
284 : // DERIVED TYPE DEFINITIONS
285 : // na
286 :
287 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
288 92527 : bool MyOneTimeFlag(true);
289 185054 : Array1D_bool MyEnvrnFlag;
290 :
291 : // do one time initializations
292 92527 : if (MyOneTimeFlag) {
293 : // initialize the environment and sizing flags
294 92527 : MyEnvrnFlag.dimension(state.dataHVACDuct->NumDucts, true);
295 :
296 92527 : MyOneTimeFlag = false;
297 : }
298 :
299 : // Do the Begin Environment initializations
300 92527 : if (state.dataGlobal->BeginEnvrnFlag && MyEnvrnFlag(DuctNum)) {
301 : }
302 :
303 92527 : if (!state.dataGlobal->BeginEnvrnFlag) {
304 91600 : MyEnvrnFlag(DuctNum) = true;
305 : }
306 :
307 : // do these initializations every HVAC time step
308 92527 : }
309 :
310 92527 : void CalcDuct([[maybe_unused]] int const DuctNum) // number of the current duct being simulated !unused1208
311 : {
312 :
313 : // SUBROUTINE INFORMATION:
314 : // AUTHOR Fred Buhl
315 : // DATE WRITTEN 17May2005
316 : // MODIFIED na
317 : // RE-ENGINEERED na
318 :
319 : // PURPOSE OF THIS SUBROUTINE:
320 : // na
321 :
322 : // METHODOLOGY EMPLOYED:
323 : // na
324 :
325 : // REFERENCES:
326 : // na
327 :
328 : // USE STATEMENTS:
329 : // na
330 :
331 : // Locals
332 : // SUBROUTINE ARGUMENT DEFINITIONS:
333 :
334 : // SUBROUTINE PARAMETER DEFINITIONS:
335 : // na
336 :
337 : // INTERFACE BLOCK SPECIFICATIONS:
338 : // na
339 :
340 : // DERIVED TYPE DEFINITIONS:
341 : // na
342 :
343 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
344 : // na
345 92527 : }
346 :
347 92527 : void UpdateDuct(EnergyPlusData &state, int const DuctNum) // number of the current duct being simulated
348 : {
349 :
350 : // SUBROUTINE INFORMATION:
351 : // AUTHOR Fred Buhl
352 : // DATE WRITTEN 17May2005
353 : // MODIFIED na
354 : // RE-ENGINEERED na
355 :
356 : // PURPOSE OF THIS SUBROUTINE:
357 : // Moves duct output to the outlet nodes
358 :
359 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
360 : int InNode; // inlet node number
361 : int OutNode; // outlet node number
362 :
363 92527 : InNode = state.dataHVACDuct->Duct(DuctNum).InletNodeNum;
364 92527 : OutNode = state.dataHVACDuct->Duct(DuctNum).OutletNodeNum;
365 : // Set the outlet air node conditions of the duct
366 92527 : state.dataLoopNodes->Node(OutNode).MassFlowRate = state.dataLoopNodes->Node(InNode).MassFlowRate;
367 92527 : state.dataLoopNodes->Node(OutNode).Temp = state.dataLoopNodes->Node(InNode).Temp;
368 92527 : state.dataLoopNodes->Node(OutNode).HumRat = state.dataLoopNodes->Node(InNode).HumRat;
369 92527 : state.dataLoopNodes->Node(OutNode).Enthalpy = state.dataLoopNodes->Node(InNode).Enthalpy;
370 92527 : state.dataLoopNodes->Node(OutNode).Quality = state.dataLoopNodes->Node(InNode).Quality;
371 92527 : state.dataLoopNodes->Node(OutNode).Press = state.dataLoopNodes->Node(InNode).Press;
372 92527 : state.dataLoopNodes->Node(OutNode).MassFlowRateMin = state.dataLoopNodes->Node(InNode).MassFlowRateMin;
373 92527 : state.dataLoopNodes->Node(OutNode).MassFlowRateMax = state.dataLoopNodes->Node(InNode).MassFlowRateMax;
374 92527 : state.dataLoopNodes->Node(OutNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail;
375 92527 : state.dataLoopNodes->Node(OutNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail;
376 :
377 92527 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
378 0 : state.dataLoopNodes->Node(OutNode).CO2 = state.dataLoopNodes->Node(InNode).CO2;
379 : }
380 :
381 92527 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
382 0 : state.dataLoopNodes->Node(OutNode).GenContam = state.dataLoopNodes->Node(InNode).GenContam;
383 : }
384 92527 : }
385 :
386 92527 : void ReportDuct([[maybe_unused]] int const DuctNum) // number of the current duct being simulated !unused1208
387 : {
388 :
389 : // SUBROUTINE INFORMATION:
390 : // AUTHOR Fred Buhl
391 : // DATE WRITTEN 17May2005
392 : // MODIFIED na
393 : // RE-ENGINEERED na
394 :
395 : // PURPOSE OF THIS SUBROUTINE:
396 : // Fill remaining report variables
397 :
398 : // METHODOLOGY EMPLOYED:
399 : // na
400 :
401 : // REFERENCES:
402 : // na
403 :
404 : // USE STATEMENTS:
405 : // na
406 :
407 : // Locals
408 : // SUBROUTINE ARGUMENT DEFINITIONS:
409 :
410 : // SUBROUTINE PARAMETER DEFINITIONS:
411 : // na
412 :
413 : // INTERFACE BLOCK SPECIFICATIONS:
414 : // na
415 :
416 : // DERIVED TYPE DEFINITIONS:
417 : // na
418 :
419 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
420 : // na
421 92527 : }
422 :
423 : } // namespace HVACDuct
424 :
425 2313 : } // namespace EnergyPlus
|