Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cmath>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 : #include <ObjexxFCL/Fmath.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <EnergyPlus/Autosizing/Base.hh>
57 : #include <EnergyPlus/BranchNodeConnections.hh>
58 : #include <EnergyPlus/Data/EnergyPlusData.hh>
59 : #include <EnergyPlus/DataContaminantBalance.hh>
60 : #include <EnergyPlus/DataDefineEquip.hh>
61 : #include <EnergyPlus/DataEnvironment.hh>
62 : #include <EnergyPlus/DataHVACGlobals.hh>
63 : #include <EnergyPlus/DataLoopNode.hh>
64 : #include <EnergyPlus/DataSizing.hh>
65 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
66 : #include <EnergyPlus/DataZoneEquipment.hh>
67 : #include <EnergyPlus/FluidProperties.hh>
68 : #include <EnergyPlus/General.hh>
69 : #include <EnergyPlus/GeneralRoutines.hh>
70 : #include <EnergyPlus/HVACCooledBeam.hh>
71 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
72 : #include <EnergyPlus/NodeInputManager.hh>
73 : #include <EnergyPlus/OutputProcessor.hh>
74 : #include <EnergyPlus/OutputReportPredefined.hh>
75 : #include <EnergyPlus/Plant/DataPlant.hh>
76 : #include <EnergyPlus/PlantUtilities.hh>
77 : #include <EnergyPlus/Psychrometrics.hh>
78 : #include <EnergyPlus/ScheduleManager.hh>
79 : #include <EnergyPlus/UtilityRoutines.hh>
80 : #include <EnergyPlus/WaterCoils.hh>
81 :
82 : namespace EnergyPlus {
83 :
84 : namespace HVACCooledBeam {
85 :
86 : // Module containing routines dealing with cooled beam units
87 :
88 : // MODULE INFORMATION:
89 : // AUTHOR Fred Buhl
90 : // DATE WRITTEN February 2, 2008
91 : // MODIFIED na
92 : // RE-ENGINEERED na
93 :
94 : // PURPOSE OF THIS MODULE:
95 : // To encapsulate the data and algorithms needed to simulate cooled beam units
96 :
97 : // METHODOLOGY EMPLOYED:
98 : // Cooled beam units are treated as terminal units. There is a fixed amount of supply air delivered
99 : // either directly through a diffuser or through the cooled beam units. Thermodynamically the
100 : // situation is similar to 4 pipe induction terminal units. The detailed methodology follows the
101 : // method in DOE-2.1E.
102 :
103 : // Using/Aliasing
104 : using namespace DataLoopNode;
105 : using HVAC::SmallAirVolFlow;
106 : using HVAC::SmallLoad;
107 : using HVAC::SmallMassFlow;
108 : using HVAC::SmallWaterVolFlow;
109 : using Psychrometrics::PsyCpAirFnW;
110 : using Psychrometrics::PsyHFnTdbW;
111 : using Psychrometrics::PsyRhoAirFnPbTdbW;
112 :
113 36725 : void SimCoolBeam(EnergyPlusData &state,
114 : std::string_view CompName, // name of the cooled beam unit
115 : bool const FirstHVACIteration, // TRUE if first HVAC iteration in time step
116 : int const ZoneNum, // index of zone served by the unit
117 : int const ZoneNodeNum, // zone node number of zone served by the unit
118 : int &CompIndex, // which cooled beam unit in data structure
119 : Real64 &NonAirSysOutput // convective cooling by the beam system [W]
120 : )
121 : {
122 :
123 : // SUBROUTINE INFORMATION:
124 : // AUTHOR Fred Buhl
125 : // DATE WRITTEN Feb 3, 2009
126 : // MODIFIED na
127 : // RE-ENGINEERED na
128 :
129 : // PURPOSE OF THIS SUBROUTINE:
130 : // Manages the simulation of a cooled beam unit.
131 : // Called from SimZoneAirLoopEquipment in module ZoneAirLoopEquipmentManager.
132 :
133 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
134 : int CBNum; // index of cooled beam unit being simulated
135 :
136 : // First time SimIndUnit is called, get the input for all the cooled beam units
137 36725 : if (state.dataHVACCooledBeam->GetInputFlag) {
138 1 : GetCoolBeams(state);
139 1 : state.dataHVACCooledBeam->GetInputFlag = false;
140 : }
141 :
142 : // Get the unit index
143 36725 : if (CompIndex == 0) {
144 5 : CBNum = Util::FindItemInList(CompName, state.dataHVACCooledBeam->CoolBeam);
145 5 : if (CBNum == 0) {
146 0 : ShowFatalError(state, format("SimCoolBeam: Cool Beam Unit not found={}", CompName));
147 : }
148 5 : CompIndex = CBNum;
149 : } else {
150 36720 : CBNum = CompIndex;
151 36720 : if (CBNum > state.dataHVACCooledBeam->NumCB || CBNum < 1) {
152 0 : ShowFatalError(state,
153 0 : format("SimCoolBeam: Invalid CompIndex passed={}, Number of Cool Beam Units={}, System name={}",
154 : CompIndex,
155 0 : state.dataHVACCooledBeam->NumCB,
156 : CompName));
157 : }
158 36720 : if (state.dataHVACCooledBeam->CheckEquipName(CBNum)) {
159 5 : if (CompName != state.dataHVACCooledBeam->CoolBeam(CBNum).Name) {
160 0 : ShowFatalError(state,
161 0 : format("SimCoolBeam: Invalid CompIndex passed={}, Cool Beam Unit name={}, stored Cool Beam Unit for that index={}",
162 : CompIndex,
163 : CompName,
164 0 : state.dataHVACCooledBeam->CoolBeam(CBNum).Name));
165 : }
166 5 : state.dataHVACCooledBeam->CheckEquipName(CBNum) = false;
167 : }
168 : }
169 36725 : if (CBNum == 0) {
170 0 : ShowFatalError(state, format("Cool Beam Unit not found = {}", CompName));
171 : }
172 :
173 73450 : state.dataSize->CurTermUnitSizingNum =
174 36725 : state.dataDefineEquipment->AirDistUnit(state.dataHVACCooledBeam->CoolBeam(CBNum).ADUNum).TermUnitSizingNum;
175 : // initialize the unit
176 36725 : InitCoolBeam(state, CBNum, FirstHVACIteration);
177 :
178 36725 : ControlCoolBeam(state, CBNum, ZoneNum, ZoneNodeNum, FirstHVACIteration, NonAirSysOutput);
179 :
180 : // Update the current unit's outlet nodes. No update needed
181 36725 : UpdateCoolBeam(state, CBNum);
182 :
183 : // Fill the report variables. There are no report variables
184 36725 : ReportCoolBeam(state, CBNum);
185 36725 : }
186 :
187 1 : void GetCoolBeams(EnergyPlusData &state)
188 : {
189 :
190 : // SUBROUTINE INFORMATION:
191 : // AUTHOR Fred Buhl
192 : // DATE WRITTEN Feb 3, 2009
193 : // MODIFIED na
194 : // RE-ENGINEERED na
195 :
196 : // PURPOSE OF THIS SUBROUTINE:
197 : // Obtains input data for cool beam units and stores it in the
198 : // cool beam unit data structures
199 :
200 : // METHODOLOGY EMPLOYED:
201 : // Uses "Get" routines to read in data.
202 :
203 : // Using/Aliasing
204 : using BranchNodeConnections::TestCompSet;
205 : using NodeInputManager::GetOnlySingleNode;
206 : using namespace DataSizing;
207 : using WaterCoils::GetCoilWaterInletNode;
208 :
209 : // SUBROUTINE PARAMETER DEFINITIONS:
210 : static constexpr std::string_view RoutineName("GetCoolBeams "); // include trailing blank space
211 : static constexpr std::string_view routineName = "GetCoolBeams";
212 :
213 : int CBIndex; // loop index
214 1 : std::string CurrentModuleObject; // for ease in getting objects
215 1 : Array1D_string Alphas; // Alpha input items for object
216 1 : Array1D_string cAlphaFields; // Alpha field names
217 1 : Array1D_string cNumericFields; // Numeric field names
218 1 : Array1D<Real64> Numbers; // Numeric input items for object
219 1 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
220 1 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
221 1 : int NumAlphas(0); // Number of Alphas for each GetObjectItem call
222 1 : int NumNumbers(0); // Number of Numbers for each GetObjectItem call
223 1 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
224 : // certain object in the input file
225 : int IOStatus; // Used in GetObjectItem
226 1 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
227 : int CtrlZone; // controlled zome do loop index
228 : int SupAirIn; // controlled zone supply air inlet index
229 : bool AirNodeFound;
230 : int ADUNum;
231 :
232 1 : auto &CoolBeam = state.dataHVACCooledBeam->CoolBeam;
233 1 : auto &CheckEquipName = state.dataHVACCooledBeam->CheckEquipName;
234 :
235 : // find the number of cooled beam units
236 1 : CurrentModuleObject = "AirTerminal:SingleDuct:ConstantVolume:CooledBeam";
237 : // Update Num in state and make local convenience copy
238 1 : int NumCB = state.dataHVACCooledBeam->NumCB = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
239 : // allocate the data structures
240 1 : CoolBeam.allocate(NumCB);
241 1 : CheckEquipName.dimension(NumCB, true);
242 :
243 1 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
244 1 : NumAlphas = 7;
245 1 : NumNumbers = 16;
246 1 : TotalArgs = 23;
247 :
248 1 : Alphas.allocate(NumAlphas);
249 1 : cAlphaFields.allocate(NumAlphas);
250 1 : cNumericFields.allocate(NumNumbers);
251 1 : Numbers.dimension(NumNumbers, 0.0);
252 1 : lAlphaBlanks.dimension(NumAlphas, true);
253 1 : lNumericBlanks.dimension(NumNumbers, true);
254 :
255 : // loop over cooled beam units; get and load the input data
256 6 : for (CBIndex = 1; CBIndex <= NumCB; ++CBIndex) {
257 :
258 5 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
259 : CurrentModuleObject,
260 : CBIndex,
261 : Alphas,
262 : NumAlphas,
263 : Numbers,
264 : NumNumbers,
265 : IOStatus,
266 : lNumericBlanks,
267 : lAlphaBlanks,
268 : cAlphaFields,
269 : cNumericFields);
270 :
271 5 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
272 5 : int CBNum = CBIndex;
273 :
274 5 : CoolBeam(CBNum).Name = Alphas(1);
275 5 : CoolBeam(CBNum).UnitType = CurrentModuleObject;
276 5 : CoolBeam(CBNum).UnitType_Num = 1;
277 5 : CoolBeam(CBNum).CBTypeString = Alphas(3);
278 5 : if (Util::SameString(CoolBeam(CBNum).CBTypeString, "Passive")) {
279 1 : CoolBeam(CBNum).CBType = CooledBeamType::Passive;
280 4 : } else if (Util::SameString(CoolBeam(CBNum).CBTypeString, "Active")) {
281 4 : CoolBeam(CBNum).CBType = CooledBeamType::Active;
282 : } else {
283 0 : ShowSevereError(state, format("Illegal {} = {}.", cAlphaFields(3), CoolBeam(CBNum).CBTypeString));
284 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, CoolBeam(CBNum).Name));
285 0 : ErrorsFound = true;
286 : }
287 :
288 5 : if (lAlphaBlanks(2)) {
289 0 : CoolBeam(CBNum).availSched = Sched::GetScheduleAlwaysOn(state);
290 5 : } else if ((CoolBeam(CBNum).availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) { // convert schedule name to pointer
291 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
292 0 : ErrorsFound = true;
293 : }
294 5 : CoolBeam(CBNum).AirInNode = GetOnlySingleNode(state,
295 5 : Alphas(4),
296 : ErrorsFound,
297 : DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeCooledBeam,
298 5 : Alphas(1),
299 : DataLoopNode::NodeFluidType::Air,
300 : DataLoopNode::ConnectionType::Inlet,
301 : NodeInputManager::CompFluidStream::Primary,
302 : ObjectIsNotParent,
303 5 : cAlphaFields(4));
304 5 : CoolBeam(CBNum).AirOutNode = GetOnlySingleNode(state,
305 5 : Alphas(5),
306 : ErrorsFound,
307 : DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeCooledBeam,
308 5 : Alphas(1),
309 : DataLoopNode::NodeFluidType::Air,
310 : DataLoopNode::ConnectionType::Outlet,
311 : NodeInputManager::CompFluidStream::Primary,
312 : ObjectIsNotParent,
313 5 : cAlphaFields(5));
314 5 : CoolBeam(CBNum).CWInNode = GetOnlySingleNode(state,
315 5 : Alphas(6),
316 : ErrorsFound,
317 : DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeCooledBeam,
318 5 : Alphas(1),
319 : DataLoopNode::NodeFluidType::Water,
320 : DataLoopNode::ConnectionType::Inlet,
321 : NodeInputManager::CompFluidStream::Secondary,
322 : ObjectIsNotParent,
323 5 : cAlphaFields(6));
324 5 : CoolBeam(CBNum).CWOutNode = GetOnlySingleNode(state,
325 5 : Alphas(7),
326 : ErrorsFound,
327 : DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeCooledBeam,
328 5 : Alphas(1),
329 : DataLoopNode::NodeFluidType::Water,
330 : DataLoopNode::ConnectionType::Outlet,
331 : NodeInputManager::CompFluidStream::Secondary,
332 : ObjectIsNotParent,
333 5 : cAlphaFields(7));
334 5 : CoolBeam(CBNum).MaxAirVolFlow = Numbers(1);
335 5 : CoolBeam(CBNum).MaxCoolWaterVolFlow = Numbers(2);
336 5 : CoolBeam(CBNum).NumBeams = Numbers(3);
337 5 : CoolBeam(CBNum).BeamLength = Numbers(4);
338 5 : CoolBeam(CBNum).DesInletWaterTemp = Numbers(5);
339 5 : CoolBeam(CBNum).DesOutletWaterTemp = Numbers(6);
340 5 : CoolBeam(CBNum).CoilArea = Numbers(7);
341 5 : CoolBeam(CBNum).a = Numbers(8);
342 5 : CoolBeam(CBNum).n1 = Numbers(9);
343 5 : CoolBeam(CBNum).n2 = Numbers(10);
344 5 : CoolBeam(CBNum).n3 = Numbers(11);
345 5 : CoolBeam(CBNum).a0 = Numbers(12);
346 5 : CoolBeam(CBNum).K1 = Numbers(13);
347 5 : CoolBeam(CBNum).n = Numbers(14);
348 5 : CoolBeam(CBNum).Kin = Numbers(15);
349 5 : CoolBeam(CBNum).InDiam = Numbers(16);
350 :
351 : // Register component set data
352 15 : TestCompSet(state,
353 : CurrentModuleObject,
354 5 : CoolBeam(CBNum).Name,
355 5 : state.dataLoopNodes->NodeID(CoolBeam(CBNum).AirInNode),
356 5 : state.dataLoopNodes->NodeID(CoolBeam(CBNum).AirOutNode),
357 : "Air Nodes");
358 10 : TestCompSet(state,
359 : CurrentModuleObject,
360 5 : CoolBeam(CBNum).Name,
361 5 : state.dataLoopNodes->NodeID(CoolBeam(CBNum).CWInNode),
362 5 : state.dataLoopNodes->NodeID(CoolBeam(CBNum).CWOutNode),
363 : "Water Nodes");
364 :
365 : // Setup the Cooled Beam reporting variables
366 : // CurrentModuleObject = "AirTerminal:SingleDuct:ConstantVolume:CooledBeam"
367 10 : SetupOutputVariable(state,
368 : "Zone Air Terminal Beam Sensible Cooling Energy",
369 : Constant::Units::J,
370 5 : CoolBeam(CBNum).BeamCoolingEnergy,
371 : OutputProcessor::TimeStepType::System,
372 : OutputProcessor::StoreType::Sum,
373 5 : CoolBeam(CBNum).Name,
374 : Constant::eResource::EnergyTransfer,
375 : OutputProcessor::Group::HVAC,
376 : OutputProcessor::EndUseCat::CoolingCoils);
377 10 : SetupOutputVariable(state,
378 : "Zone Air Terminal Beam Chilled Water Energy",
379 : Constant::Units::J,
380 5 : CoolBeam(CBNum).BeamCoolingEnergy,
381 : OutputProcessor::TimeStepType::System,
382 : OutputProcessor::StoreType::Sum,
383 5 : CoolBeam(CBNum).Name,
384 : Constant::eResource::PlantLoopCoolingDemand,
385 : OutputProcessor::Group::HVAC,
386 : OutputProcessor::EndUseCat::CoolingCoils);
387 10 : SetupOutputVariable(state,
388 : "Zone Air Terminal Beam Sensible Cooling Rate",
389 : Constant::Units::W,
390 5 : CoolBeam(CBNum).BeamCoolingRate,
391 : OutputProcessor::TimeStepType::System,
392 : OutputProcessor::StoreType::Average,
393 5 : CoolBeam(CBNum).Name);
394 10 : SetupOutputVariable(state,
395 : "Zone Air Terminal Supply Air Sensible Cooling Energy",
396 : Constant::Units::J,
397 5 : CoolBeam(CBNum).SupAirCoolingEnergy,
398 : OutputProcessor::TimeStepType::System,
399 : OutputProcessor::StoreType::Sum,
400 5 : CoolBeam(CBNum).Name);
401 10 : SetupOutputVariable(state,
402 : "Zone Air Terminal Supply Air Sensible Cooling Rate",
403 : Constant::Units::W,
404 5 : CoolBeam(CBNum).SupAirCoolingRate,
405 : OutputProcessor::TimeStepType::System,
406 : OutputProcessor::StoreType::Average,
407 5 : CoolBeam(CBNum).Name);
408 10 : SetupOutputVariable(state,
409 : "Zone Air Terminal Supply Air Sensible Heating Energy",
410 : Constant::Units::J,
411 5 : CoolBeam(CBNum).SupAirHeatingEnergy,
412 : OutputProcessor::TimeStepType::System,
413 : OutputProcessor::StoreType::Sum,
414 5 : CoolBeam(CBNum).Name);
415 10 : SetupOutputVariable(state,
416 : "Zone Air Terminal Supply Air Sensible Heating Rate",
417 : Constant::Units::W,
418 5 : CoolBeam(CBNum).SupAirHeatingRate,
419 : OutputProcessor::TimeStepType::System,
420 : OutputProcessor::StoreType::Average,
421 5 : CoolBeam(CBNum).Name);
422 :
423 10 : SetupOutputVariable(state,
424 : "Zone Air Terminal Outdoor Air Volume Flow Rate",
425 : Constant::Units::m3_s,
426 5 : CoolBeam(CBNum).OutdoorAirFlowRate,
427 : OutputProcessor::TimeStepType::System,
428 : OutputProcessor::StoreType::Average,
429 5 : CoolBeam(CBNum).Name);
430 :
431 30 : for (ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
432 25 : if (CoolBeam(CBNum).AirOutNode == state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum) {
433 5 : CoolBeam(CBNum).ADUNum = ADUNum;
434 5 : state.dataDefineEquipment->AirDistUnit(ADUNum).InletNodeNum = CoolBeam(CBNum).AirInNode;
435 : }
436 : }
437 : // one assumes if there isn't one assigned, it's an error?
438 5 : if (CoolBeam(CBNum).ADUNum == 0) {
439 0 : ShowSevereError(
440 : state,
441 0 : format("{}No matching Air Distribution Unit, for Unit = [{},{}].", RoutineName, CurrentModuleObject, CoolBeam(CBNum).Name));
442 0 : ShowContinueError(state, format("...should have outlet node={}", state.dataLoopNodes->NodeID(CoolBeam(CBNum).AirOutNode)));
443 0 : ErrorsFound = true;
444 : } else {
445 :
446 : // Fill the Zone Equipment data with the supply air inlet node number of this unit.
447 5 : AirNodeFound = false;
448 35 : for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
449 30 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) {
450 5 : continue;
451 : }
452 45 : for (SupAirIn = 1; SupAirIn <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++SupAirIn) {
453 25 : if (CoolBeam(CBNum).AirOutNode == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(SupAirIn)) {
454 5 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).InNode = CoolBeam(CBNum).AirInNode;
455 5 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode = CoolBeam(CBNum).AirOutNode;
456 5 : state.dataDefineEquipment->AirDistUnit(CoolBeam(CBNum).ADUNum).TermUnitSizingNum =
457 5 : state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).TermUnitSizingIndex;
458 5 : state.dataDefineEquipment->AirDistUnit(CoolBeam(CBNum).ADUNum).ZoneEqNum = CtrlZone;
459 5 : CoolBeam(CBNum).CtrlZoneNum = CtrlZone;
460 5 : CoolBeam(CBNum).ctrlZoneInNodeIndex = SupAirIn;
461 5 : AirNodeFound = true;
462 5 : break;
463 : }
464 : }
465 : }
466 : }
467 5 : if (!AirNodeFound) {
468 0 : ShowSevereError(state, format("The outlet air node from the {} = {}", CurrentModuleObject, CoolBeam(CBNum).Name));
469 0 : ShowContinueError(state, format("did not have a matching Zone Equipment Inlet Node, Node ={}", Alphas(5)));
470 0 : ErrorsFound = true;
471 : }
472 : }
473 :
474 1 : Alphas.deallocate();
475 1 : cAlphaFields.deallocate();
476 1 : cNumericFields.deallocate();
477 1 : Numbers.deallocate();
478 1 : lAlphaBlanks.deallocate();
479 1 : lNumericBlanks.deallocate();
480 :
481 1 : if (ErrorsFound) {
482 0 : ShowFatalError(state, format("{}Errors found in getting input. Preceding conditions cause termination.", RoutineName));
483 : }
484 1 : }
485 :
486 36725 : void InitCoolBeam(EnergyPlusData &state,
487 : int const CBNum, // number of the current cooled beam unit being simulated
488 : bool const FirstHVACIteration // TRUE if first air loop solution this HVAC step
489 : )
490 : {
491 :
492 : // SUBROUTINE INFORMATION:
493 : // AUTHOR Fred Buhl
494 : // DATE WRITTEN February 6, 2009
495 : // MODIFIED na
496 : // RE-ENGINEERED na
497 :
498 : // PURPOSE OF THIS SUBROUTINE:
499 : // This subroutine is for initialization of the cooled beam units
500 :
501 : // METHODOLOGY EMPLOYED:
502 : // Uses the status flags to trigger initializations.
503 :
504 : // Using/Aliasing
505 : using DataZoneEquipment::CheckZoneEquipmentList;
506 : using PlantUtilities::InitComponentNodes;
507 : using PlantUtilities::ScanPlantLoopsForObject;
508 : using PlantUtilities::SetComponentFlowRate;
509 :
510 : // SUBROUTINE PARAMETER DEFINITIONS:
511 : static constexpr std::string_view RoutineName("InitCoolBeam");
512 :
513 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
514 : int InAirNode; // supply air inlet node number
515 : int OutAirNode; // unit air outlet node
516 : int InWaterNode; // unit inlet chilled water node
517 : int OutWaterNode; // unit outlet chilled water node
518 : Real64 RhoAir; // air density at outside pressure and standard temperature and humidity
519 : Real64 rho; // local fluid density
520 :
521 36725 : auto &coolBeam = state.dataHVACCooledBeam->CoolBeam(CBNum);
522 36725 : auto &ZoneEquipmentListChecked = state.dataHVACCooledBeam->ZoneEquipmentListChecked;
523 36725 : int NumCB = state.dataHVACCooledBeam->NumCB;
524 :
525 36725 : if (coolBeam.PlantLoopScanFlag && allocated(state.dataPlnt->PlantLoop)) {
526 5 : bool errFlag = false;
527 10 : ScanPlantLoopsForObject(
528 5 : state, coolBeam.Name, DataPlant::PlantEquipmentType::CooledBeamAirTerminal, coolBeam.CWPlantLoc, errFlag, _, _, _, _, _);
529 5 : if (errFlag) {
530 0 : ShowFatalError(state, "InitCoolBeam: Program terminated for previous conditions.");
531 : }
532 5 : coolBeam.PlantLoopScanFlag = false;
533 : }
534 :
535 36725 : if (!ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
536 1 : std::string CurrentModuleObject = "AirTerminal:SingleDuct:ConstantVolume:CooledBeam";
537 1 : ZoneEquipmentListChecked = true;
538 : // Check to see if there is a Air Distribution Unit on the Zone Equipment List
539 6 : for (int Loop = 1; Loop <= NumCB; ++Loop) {
540 5 : if (coolBeam.ADUNum == 0) {
541 0 : continue;
542 : }
543 5 : if (CheckZoneEquipmentList(state, "ZONEHVAC:AIRDISTRIBUTIONUNIT", state.dataDefineEquipment->AirDistUnit(coolBeam.ADUNum).Name)) {
544 5 : continue;
545 : }
546 0 : ShowSevereError(state,
547 0 : format("InitCoolBeam: ADU=[Air Distribution Unit,{}] is not on any ZoneHVAC:EquipmentList.",
548 0 : state.dataDefineEquipment->AirDistUnit(coolBeam.ADUNum).Name));
549 0 : ShowContinueError(state, format("...Unit=[{},{}] will not be simulated.", CurrentModuleObject, coolBeam.Name));
550 : }
551 1 : }
552 :
553 36725 : if (!state.dataGlobal->SysSizingCalc && coolBeam.MySizeFlag && !coolBeam.PlantLoopScanFlag) {
554 :
555 5 : SizeCoolBeam(state, CBNum);
556 :
557 5 : InWaterNode = coolBeam.CWInNode;
558 5 : OutWaterNode = coolBeam.CWOutNode;
559 5 : rho = state.dataPlnt->PlantLoop(coolBeam.CWPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
560 5 : coolBeam.MaxCoolWaterMassFlow = rho * coolBeam.MaxCoolWaterVolFlow;
561 5 : InitComponentNodes(state, 0.0, coolBeam.MaxCoolWaterMassFlow, InWaterNode, OutWaterNode);
562 5 : coolBeam.MySizeFlag = false;
563 : }
564 :
565 : // Do the Begin Environment initializations
566 36725 : if (state.dataGlobal->BeginEnvrnFlag && coolBeam.MyEnvrnFlag) {
567 70 : RhoAir = state.dataEnvrn->StdRhoAir;
568 70 : InAirNode = coolBeam.AirInNode;
569 70 : OutAirNode = coolBeam.AirOutNode;
570 : // set the mass flow rates from the input volume flow rates
571 70 : coolBeam.MaxAirMassFlow = RhoAir * coolBeam.MaxAirVolFlow;
572 70 : state.dataLoopNodes->Node(InAirNode).MassFlowRateMax = coolBeam.MaxAirMassFlow;
573 70 : state.dataLoopNodes->Node(OutAirNode).MassFlowRateMax = coolBeam.MaxAirMassFlow;
574 70 : state.dataLoopNodes->Node(InAirNode).MassFlowRateMin = 0.0;
575 70 : state.dataLoopNodes->Node(OutAirNode).MassFlowRateMin = 0.0;
576 :
577 70 : InWaterNode = coolBeam.CWInNode;
578 70 : OutWaterNode = coolBeam.CWOutNode;
579 70 : InitComponentNodes(state, 0.0, coolBeam.MaxCoolWaterMassFlow, InWaterNode, OutWaterNode);
580 :
581 70 : if (coolBeam.AirLoopNum == 0) { // fill air loop index
582 5 : if (coolBeam.CtrlZoneNum > 0 && coolBeam.ctrlZoneInNodeIndex > 0) {
583 5 : coolBeam.AirLoopNum =
584 5 : state.dataZoneEquip->ZoneEquipConfig(coolBeam.CtrlZoneNum).InletNodeAirLoopNum(coolBeam.ctrlZoneInNodeIndex);
585 5 : state.dataDefineEquipment->AirDistUnit(coolBeam.ADUNum).AirLoopNum = coolBeam.AirLoopNum;
586 : }
587 : }
588 :
589 70 : coolBeam.MyEnvrnFlag = false;
590 : } // end one time inits
591 :
592 36725 : if (!state.dataGlobal->BeginEnvrnFlag) {
593 36510 : coolBeam.MyEnvrnFlag = true;
594 : }
595 :
596 36725 : InAirNode = coolBeam.AirInNode;
597 36725 : OutAirNode = coolBeam.AirOutNode;
598 :
599 : // Do the start of HVAC time step initializations
600 36725 : if (FirstHVACIteration) {
601 : // check for upstream zero flow. If nonzero and schedule ON, set primary flow to max
602 13670 : if (coolBeam.availSched->getCurrentVal() > 0.0 && state.dataLoopNodes->Node(InAirNode).MassFlowRate > 0.0) {
603 13565 : state.dataLoopNodes->Node(InAirNode).MassFlowRate = coolBeam.MaxAirMassFlow;
604 : } else {
605 105 : state.dataLoopNodes->Node(InAirNode).MassFlowRate = 0.0;
606 : }
607 : // reset the max and min avail flows
608 13670 : if (coolBeam.availSched->getCurrentVal() > 0.0 && state.dataLoopNodes->Node(InAirNode).MassFlowRateMaxAvail > 0.0) {
609 13565 : state.dataLoopNodes->Node(InAirNode).MassFlowRateMaxAvail = coolBeam.MaxAirMassFlow;
610 13565 : state.dataLoopNodes->Node(InAirNode).MassFlowRateMinAvail = coolBeam.MaxAirMassFlow;
611 : } else {
612 105 : state.dataLoopNodes->Node(InAirNode).MassFlowRateMaxAvail = 0.0;
613 105 : state.dataLoopNodes->Node(InAirNode).MassFlowRateMinAvail = 0.0;
614 : }
615 : }
616 :
617 : // do these initializations every time step
618 36725 : InWaterNode = coolBeam.CWInNode;
619 36725 : coolBeam.TWIn = state.dataLoopNodes->Node(InWaterNode).Temp;
620 36725 : coolBeam.SupAirCoolingRate = 0.0;
621 36725 : coolBeam.SupAirHeatingRate = 0.0;
622 36725 : }
623 :
624 5 : void SizeCoolBeam(EnergyPlusData &state, int const CBNum)
625 : {
626 :
627 : // SUBROUTINE INFORMATION:
628 : // AUTHOR Fred Buhl
629 : // DATE WRITTEN February 10, 2009
630 : // MODIFIED na
631 : // RE-ENGINEERED na
632 :
633 : // PURPOSE OF THIS SUBROUTINE:
634 : // This subroutine is for sizing cooled beam units for which flow rates have not been
635 : // specified in the input
636 :
637 : // METHODOLOGY EMPLOYED:
638 : // Accesses zone sizing array for air flow rates and zone and plant sizing arrays to
639 : // calculate coil water flow rates.
640 :
641 : // Using/Aliasing
642 : using namespace DataSizing;
643 : using PlantUtilities::MyPlantSizingIndex;
644 : using PlantUtilities::RegisterPlantCompDesignFlow;
645 :
646 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
647 : static constexpr std::string_view RoutineName("SizeCoolBeam");
648 5 : int PltSizCoolNum(0); // index of plant sizing object for the cooling loop
649 5 : int NumBeams(0); // number of beams in the zone
650 5 : Real64 DesCoilLoad(0.0); // total cooling capacity of the beams in the zone [W]
651 5 : Real64 DesLoadPerBeam(0.0); // cooling capacity per individual beam [W]
652 5 : Real64 DesAirVolFlow(0.0); // design total supply air flow rate [m3/s]
653 5 : Real64 DesAirFlowPerBeam(0.0); // design supply air volumetric flow per beam [m3/s]
654 5 : Real64 RhoAir(0.0);
655 5 : Real64 CpAir(0.0);
656 5 : Real64 WaterVel(0.0); // design water velocity in beam
657 5 : Real64 IndAirFlowPerBeamL(0.0); // induced volumetric air flow rate per beam length [m3/s-m]
658 5 : Real64 DT(0.0); // air - water delta T [C]
659 5 : Real64 LengthX(0.0); // test value for beam length [m]
660 5 : Real64 Length(0.0); // beam length [m]
661 5 : Real64 ConvFlow(0.0); // convective and induced air mass flow rate across beam per beam plan area [kg/s-m2]
662 5 : Real64 K(0.0); // coil (beam) heat transfer coefficient [W/m2-K]
663 5 : Real64 WaterVolFlowPerBeam(0.0); // Cooling water volumetric flow per beam [m3]
664 : bool ErrorsFound;
665 : Real64 rho; // local fluid density
666 : Real64 Cp; // local fluid specific heat
667 :
668 5 : PltSizCoolNum = 0;
669 5 : DesAirVolFlow = 0.0;
670 5 : CpAir = 0.0;
671 5 : RhoAir = state.dataEnvrn->StdRhoAir;
672 5 : ErrorsFound = false;
673 :
674 5 : auto &coolBeam = state.dataHVACCooledBeam->CoolBeam(CBNum);
675 :
676 : // find the appropriate Plant Sizing object
677 5 : if (coolBeam.MaxAirVolFlow == AutoSize || coolBeam.BeamLength == AutoSize) {
678 5 : PltSizCoolNum = MyPlantSizingIndex(state, "cooled beam unit", coolBeam.Name, coolBeam.CWInNode, coolBeam.CWOutNode, ErrorsFound);
679 : }
680 :
681 5 : if (coolBeam.Kin == Constant::AutoCalculate) {
682 5 : if (coolBeam.CBType == CooledBeamType::Passive) {
683 1 : coolBeam.Kin = 0.0;
684 : } else {
685 4 : coolBeam.Kin = 2.0;
686 : }
687 5 : BaseSizer::reportSizerOutput(state, coolBeam.UnitType, coolBeam.Name, "Coefficient of Induction Kin", coolBeam.Kin);
688 : }
689 :
690 5 : if (coolBeam.MaxAirVolFlow == AutoSize) {
691 :
692 5 : if (state.dataSize->CurTermUnitSizingNum > 0) {
693 :
694 5 : CheckZoneSizing(state, coolBeam.UnitType, coolBeam.Name);
695 5 : coolBeam.MaxAirVolFlow = max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolVolFlow,
696 5 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow);
697 5 : if (coolBeam.MaxAirVolFlow < SmallAirVolFlow) {
698 0 : coolBeam.MaxAirVolFlow = 0.0;
699 : }
700 5 : BaseSizer::reportSizerOutput(state, coolBeam.UnitType, coolBeam.Name, "Supply Air Flow Rate [m3/s]", coolBeam.MaxAirVolFlow);
701 : }
702 : }
703 :
704 5 : if (coolBeam.MaxCoolWaterVolFlow == AutoSize) {
705 :
706 5 : if ((state.dataSize->CurZoneEqNum > 0) && (state.dataSize->CurTermUnitSizingNum > 0)) {
707 :
708 5 : CheckZoneSizing(state, coolBeam.UnitType, coolBeam.Name);
709 :
710 5 : if (PltSizCoolNum > 0) {
711 :
712 5 : if (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolMassFlow >= SmallAirVolFlow) {
713 5 : DesAirVolFlow = coolBeam.MaxAirVolFlow;
714 5 : CpAir = PsyCpAirFnW(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).CoolDesHumRat);
715 : // the design cooling coil load is the zone load minus whatever the central system does. Note that
716 : // DesCoolCoilInTempTU is really the primary air inlet temperature for the unit.
717 5 : if (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtCoolPeak > 0.0) {
718 5 : DesCoilLoad = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).NonAirSysDesCoolLoad -
719 10 : CpAir * RhoAir * DesAirVolFlow *
720 5 : (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtCoolPeak -
721 5 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolCoilInTempTU);
722 : } else {
723 0 : DesCoilLoad = CpAir * RhoAir * DesAirVolFlow *
724 0 : (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolCoilInTempTU -
725 0 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneSizThermSetPtHi);
726 : }
727 :
728 5 : rho = state.dataPlnt->PlantLoop(coolBeam.CWPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
729 :
730 5 : Cp = state.dataPlnt->PlantLoop(coolBeam.CWPlantLoc.loopNum)
731 5 : .glycol->getSpecificHeat(state, Constant::CWInitConvTemp, RoutineName);
732 :
733 5 : coolBeam.MaxCoolWaterVolFlow = DesCoilLoad / ((coolBeam.DesOutletWaterTemp - coolBeam.DesInletWaterTemp) * Cp * rho);
734 5 : coolBeam.MaxCoolWaterVolFlow = max(coolBeam.MaxCoolWaterVolFlow, 0.0);
735 5 : if (coolBeam.MaxCoolWaterVolFlow < SmallWaterVolFlow) {
736 0 : coolBeam.MaxCoolWaterVolFlow = 0.0;
737 : }
738 : } else {
739 0 : coolBeam.MaxCoolWaterVolFlow = 0.0;
740 : }
741 :
742 5 : BaseSizer::reportSizerOutput(
743 : state, coolBeam.UnitType, coolBeam.Name, "Maximum Total Chilled Water Flow Rate [m3/s]", coolBeam.MaxCoolWaterVolFlow);
744 : } else {
745 0 : ShowSevereError(state, "Autosizing of water flow requires a cooling loop Sizing:Plant object");
746 0 : ShowContinueError(state, format("Occurs in{} Object={}", coolBeam.UnitType, coolBeam.Name));
747 0 : ErrorsFound = true;
748 : }
749 : }
750 : }
751 :
752 5 : if (coolBeam.NumBeams == AutoSize) {
753 5 : rho = state.dataPlnt->PlantLoop(coolBeam.CWPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
754 :
755 5 : NumBeams = int(coolBeam.MaxCoolWaterVolFlow * rho / NomMassFlowPerBeam) + 1;
756 5 : coolBeam.NumBeams = double(NumBeams);
757 5 : BaseSizer::reportSizerOutput(state, coolBeam.UnitType, coolBeam.Name, "Number of Beams", coolBeam.NumBeams);
758 : }
759 :
760 5 : if (coolBeam.BeamLength == AutoSize) {
761 :
762 5 : if (state.dataSize->CurTermUnitSizingNum > 0) {
763 :
764 5 : CheckZoneSizing(state, coolBeam.UnitType, coolBeam.Name);
765 :
766 5 : if (PltSizCoolNum > 0) {
767 5 : rho = state.dataPlnt->PlantLoop(coolBeam.CWPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
768 :
769 5 : Cp = state.dataPlnt->PlantLoop(coolBeam.CWPlantLoc.loopNum).glycol->getSpecificHeat(state, Constant::CWInitConvTemp, RoutineName);
770 5 : DesCoilLoad = coolBeam.MaxCoolWaterVolFlow * (coolBeam.DesOutletWaterTemp - coolBeam.DesInletWaterTemp) * Cp * rho;
771 5 : if (DesCoilLoad > 0.0) {
772 5 : DesLoadPerBeam = DesCoilLoad / NumBeams;
773 5 : DesAirFlowPerBeam = coolBeam.MaxAirVolFlow / NumBeams;
774 5 : WaterVolFlowPerBeam = coolBeam.MaxCoolWaterVolFlow / NumBeams;
775 5 : WaterVel = WaterVolFlowPerBeam / (Constant::Pi * pow_2(coolBeam.InDiam) / 4.0);
776 5 : if (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtCoolPeak > 0.0) {
777 5 : DT = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtCoolPeak -
778 5 : 0.5 * (coolBeam.DesInletWaterTemp + coolBeam.DesOutletWaterTemp);
779 5 : if (DT <= 0.0) {
780 0 : DT = 7.8;
781 : }
782 : } else {
783 0 : DT = 7.8;
784 : }
785 5 : LengthX = 1.0;
786 71 : for (int Iter = 1; Iter <= 100; ++Iter) {
787 71 : IndAirFlowPerBeamL = coolBeam.K1 * std::pow(DT, coolBeam.n) + coolBeam.Kin * DesAirFlowPerBeam / LengthX;
788 71 : ConvFlow = (IndAirFlowPerBeamL / coolBeam.a0) * RhoAir;
789 71 : if (WaterVel > MinWaterVel) {
790 71 : K = coolBeam.a * std::pow(DT, coolBeam.n1) * std::pow(ConvFlow, coolBeam.n2) * std::pow(WaterVel, coolBeam.n3);
791 : } else {
792 0 : K = coolBeam.a * std::pow(DT, coolBeam.n1) * std::pow(ConvFlow, coolBeam.n2) * std::pow(MinWaterVel, coolBeam.n3) *
793 0 : (WaterVel / MinWaterVel);
794 : }
795 71 : Length = DesLoadPerBeam / (K * coolBeam.CoilArea * DT);
796 71 : if (coolBeam.Kin <= 0.0) {
797 1 : break;
798 : }
799 : // Check for convergence
800 70 : if (std::abs(Length - LengthX) > 0.01) {
801 : // New guess for length
802 66 : LengthX += 0.5 * (Length - LengthX);
803 : } else {
804 4 : break; // convergence achieved
805 : }
806 : }
807 : } else {
808 0 : Length = 0.0;
809 : }
810 5 : coolBeam.BeamLength = Length;
811 5 : coolBeam.BeamLength = max(coolBeam.BeamLength, 1.0);
812 5 : BaseSizer::reportSizerOutput(state, coolBeam.UnitType, coolBeam.Name, "Beam Length [m]", coolBeam.BeamLength);
813 : } else {
814 0 : ShowSevereError(state, "Autosizing of cooled beam length requires a cooling loop Sizing:Plant object");
815 0 : ShowContinueError(state, format("Occurs in{} Object={}", coolBeam.UnitType, coolBeam.Name));
816 0 : ErrorsFound = true;
817 : }
818 : }
819 : }
820 :
821 : // save the design water volumetric flow rate for use by the water loop sizing algorithms
822 5 : if (coolBeam.MaxCoolWaterVolFlow > 0.0) {
823 5 : RegisterPlantCompDesignFlow(state, coolBeam.CWInNode, coolBeam.MaxCoolWaterVolFlow);
824 : }
825 :
826 5 : if (ErrorsFound) {
827 0 : ShowFatalError(state, "Preceding cooled beam sizing errors cause program termination");
828 : }
829 5 : }
830 :
831 36725 : void ControlCoolBeam(EnergyPlusData &state,
832 : int const CBNum, // number of the current unit being simulated
833 : int const ZoneNum, // number of zone being served
834 : int const ZoneNodeNum, // zone node number
835 : [[maybe_unused]] bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
836 : Real64 &NonAirSysOutput // convective cooling by the beam system [W]
837 : )
838 : {
839 :
840 : // SUBROUTINE INFORMATION:
841 : // AUTHOR Fred Buhl
842 : // DATE WRITTEN Feb 12, 2009
843 : // MODIFIED na
844 : // RE-ENGINEERED na
845 :
846 : // PURPOSE OF THIS SUBROUTINE:
847 : // Simulate a cooled beam unit;
848 :
849 : // METHODOLOGY EMPLOYED:
850 : // (1) From the zone load and the Supply air inlet conditions calculate the beam load
851 : // (2) If there is a beam load, vary the water flow rate to match the beam load
852 :
853 : // REFERENCES:
854 : // na
855 :
856 : // Using/Aliasing
857 : using namespace DataZoneEnergyDemands;
858 : using PlantUtilities::SetComponentFlowRate;
859 :
860 : // Locals
861 : // SUBROUTINE ARGUMENT DEFINITIONS:
862 :
863 : // SUBROUTINE PARAMETER DEFINITIONS:
864 : // na
865 :
866 : // INTERFACE BLOCK SPECIFICATIONS:
867 : // na
868 :
869 : // DERIVED TYPE DEFINITIONS:
870 : // na
871 :
872 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
873 : Real64 QZnReq; // heating or cooling needed by zone [Watts]
874 : Real64 QToHeatSetPt; // [W] remaining load to heating setpoint
875 : Real64 QToCoolSetPt; // [W] remaining load to cooling setpoint
876 36725 : Real64 QMin(0.0); // cooled beam output at minimum water flow [W]
877 36725 : Real64 QMax(0.0); // cooled beam output at maximum water flow [W]
878 36725 : Real64 QSup(0.0); // heating or cooling by supply air [W]
879 36725 : Real64 PowerMet(0.0); // power supplied
880 36725 : Real64 CWFlow(0.0); // cold water flow [kg/s]
881 36725 : Real64 AirMassFlow(0.0); // air mass flow rate for the cooled beam system [kg/s]
882 36725 : Real64 MaxColdWaterFlow(0.0); // max water mass flow rate for the cooled beam system [kg/s]
883 36725 : Real64 MinColdWaterFlow(0.0); // min water mass flow rate for the cooled beam system [kg/s]
884 36725 : Real64 CpAirZn(0.0); // specific heat of air at zone conditions [J/kg-C]
885 36725 : Real64 CpAirSys(0.0); // specific heat of air at supply air conditions [J/kg-C]
886 36725 : Real64 TWOut(0.0); // outlet water tamperature [C]
887 : int ControlNode; // the water inlet node
888 : int InAirNode; // the air inlet node
889 : bool UnitOn; // TRUE if unit is on
890 : Real64 ErrTolerance;
891 36725 : auto &coolBeam = state.dataHVACCooledBeam->CoolBeam(CBNum);
892 :
893 36725 : UnitOn = true;
894 36725 : PowerMet = 0.0;
895 36725 : InAirNode = coolBeam.AirInNode;
896 36725 : ControlNode = coolBeam.CWInNode;
897 36725 : AirMassFlow = state.dataLoopNodes->Node(InAirNode).MassFlowRateMaxAvail;
898 36725 : QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputRequired;
899 36725 : QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToHeatSP;
900 36725 : QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToCoolSP;
901 36725 : CpAirZn = PsyCpAirFnW(state.dataLoopNodes->Node(ZoneNodeNum).HumRat);
902 36725 : CpAirSys = PsyCpAirFnW(state.dataLoopNodes->Node(InAirNode).HumRat);
903 36725 : MaxColdWaterFlow = coolBeam.MaxCoolWaterMassFlow;
904 36725 : SetComponentFlowRate(state, MaxColdWaterFlow, coolBeam.CWInNode, coolBeam.CWOutNode, coolBeam.CWPlantLoc);
905 36725 : MinColdWaterFlow = 0.0;
906 36725 : SetComponentFlowRate(state, MinColdWaterFlow, coolBeam.CWInNode, coolBeam.CWOutNode, coolBeam.CWPlantLoc);
907 :
908 36725 : if (coolBeam.availSched->getCurrentVal() <= 0.0) {
909 0 : UnitOn = false;
910 : }
911 36725 : if (MaxColdWaterFlow <= SmallMassFlow) {
912 20 : UnitOn = false;
913 : }
914 :
915 : // Set the unit's air inlet nodes mass flow rates
916 36725 : state.dataLoopNodes->Node(InAirNode).MassFlowRate = AirMassFlow;
917 : // set the air volumetric flow rate per beam
918 36725 : coolBeam.BeamFlow = state.dataLoopNodes->Node(InAirNode).MassFlowRate / (state.dataEnvrn->StdRhoAir * coolBeam.NumBeams);
919 : // fire the unit at min water flow
920 36725 : CalcCoolBeam(state, CBNum, ZoneNodeNum, MinColdWaterFlow, QMin, TWOut);
921 : // cooling by supply air
922 36725 : QSup = AirMassFlow * (CpAirSys * state.dataLoopNodes->Node(InAirNode).Temp - CpAirZn * state.dataLoopNodes->Node(ZoneNodeNum).Temp);
923 : // load on the beams is QToCoolSetPt-QSup
924 36725 : if (UnitOn) {
925 36705 : if ((QToCoolSetPt - QSup) < -SmallLoad) {
926 : // There is a cooling demand on the cooled beam system.
927 : // First, see if the system can meet the load
928 14965 : CalcCoolBeam(state, CBNum, ZoneNodeNum, MaxColdWaterFlow, QMax, TWOut);
929 14965 : if ((QMax < QToCoolSetPt - QSup - SmallLoad) && (QMax != QMin)) {
930 : // The cooled beam system can meet the demand.
931 : // Set up the iterative calculation of chilled water flow rate
932 14125 : ErrTolerance = 0.01;
933 92876 : auto f = [&state, CBNum, ZoneNodeNum, QToCoolSetPt, QSup, QMin, QMax](Real64 const CWFlow) {
934 92876 : Real64 const par3 = QToCoolSetPt - QSup;
935 92876 : Real64 UnitOutput(0.0);
936 92876 : Real64 TWOut(0.0);
937 92876 : CalcCoolBeam(state, CBNum, ZoneNodeNum, CWFlow, UnitOutput, TWOut);
938 92876 : return (par3 - UnitOutput) / (QMax - QMin);
939 14125 : };
940 14125 : int SolFlag = 0;
941 14125 : General::SolveRoot(state, ErrTolerance, 50, SolFlag, CWFlow, f, MinColdWaterFlow, MaxColdWaterFlow);
942 14125 : if (SolFlag == -1) {
943 0 : ShowWarningError(state, format("Cold water control failed in cooled beam unit {}", coolBeam.Name));
944 0 : ShowContinueError(state, " Iteration limit exceeded in calculating cold water mass flow rate");
945 14125 : } else if (SolFlag == -2) {
946 0 : ShowWarningError(state, format("Cold water control failed in cooled beam unit {}", coolBeam.Name));
947 0 : ShowContinueError(state, " Bad cold water flow limits");
948 : }
949 14125 : } else {
950 : // unit maxed out
951 840 : CWFlow = MaxColdWaterFlow;
952 : }
953 : } else {
954 : // unit has no load
955 21740 : CWFlow = MinColdWaterFlow;
956 : }
957 : } else {
958 : // unit Off
959 20 : CWFlow = MinColdWaterFlow;
960 : }
961 : // Get the cooling output at the chosen water flow rate
962 36725 : CalcCoolBeam(state, CBNum, ZoneNodeNum, CWFlow, PowerMet, TWOut);
963 36725 : coolBeam.BeamCoolingRate = -PowerMet;
964 36725 : if (QSup < 0.0) {
965 22006 : coolBeam.SupAirCoolingRate = std::abs(QSup);
966 : } else {
967 14719 : coolBeam.SupAirHeatingRate = QSup;
968 : }
969 36725 : coolBeam.CoolWaterMassFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRate;
970 36725 : coolBeam.TWOut = TWOut;
971 36725 : coolBeam.EnthWaterOut = state.dataLoopNodes->Node(ControlNode).Enthalpy + coolBeam.BeamCoolingRate;
972 : // Node(ControlNode)%MassFlowRate = CWFlow
973 36725 : NonAirSysOutput = PowerMet;
974 36725 : }
975 :
976 181291 : void CalcCoolBeam(EnergyPlusData &state,
977 : int const CBNum, // Unit index
978 : int const ZoneNode, // zone node number
979 : Real64 const CWFlow, // cold water flow [kg/s]
980 : Real64 &LoadMet, // load met by unit [W]
981 : Real64 &TWOut // chilled water outlet temperature [C]
982 : )
983 : {
984 :
985 : // SUBROUTINE INFORMATION:
986 : // AUTHOR Fred Buhl
987 : // DATE WRITTEN Feb 2009
988 : // MODIFIED na
989 : // RE-ENGINEERED na
990 :
991 : // PURPOSE OF THIS SUBROUTINE:
992 : // Simulate a cooled beam given the chilled water flow rate
993 :
994 : // METHODOLOGY EMPLOYED:
995 : // Uses the cooled beam equations; iteratively varies water outlet temperature
996 : // until air-side and water-side cooling outputs match.
997 :
998 : // REFERENCES:
999 : // na
1000 :
1001 : // Using/Aliasing
1002 : using PlantUtilities::SetComponentFlowRate;
1003 :
1004 : // Locals
1005 : // SUBROUTINE ARGUMENT DEFINITIONS:
1006 :
1007 : // SUBROUTINE PARAMETER DEFINITIONS:
1008 : static constexpr std::string_view RoutineName("CalcCoolBeam");
1009 :
1010 : // INTERFACE BLOCK SPECIFICATIONS
1011 : // na
1012 :
1013 : // DERIVED TYPE DEFINITIONS
1014 : // na
1015 :
1016 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1017 181291 : int Iter(0); // TWOut iteration index
1018 181291 : Real64 TWIn(0.0); // Inlet water temperature [C]
1019 181291 : Real64 ZTemp(0.0); // zone air temperature [C]
1020 181291 : Real64 WaterCoolPower(0.0); // cooling power from water side [W]
1021 181291 : Real64 DT(0.0); // approximate air - water delta T [C]
1022 181291 : Real64 IndFlow(0.0); // induced air flow rate per beam length [m3/s-m]
1023 181291 : Real64 CoilFlow(0.0); // mass air flow rate of air passing through "coil" [kg/m2-s]
1024 181291 : Real64 WaterVel(0.0); // water velocity [m/s]
1025 181291 : Real64 K(0.0); // coil heat transfer coefficient [W/m2-K]
1026 181291 : Real64 AirCoolPower(0.0); // cooling power from the air side [W]
1027 : Real64 Diff; // difference between water side cooling power and air side cooling power [W]
1028 181291 : Real64 CWFlowPerBeam(0.0); // water mass flow rate per beam
1029 181291 : Real64 Coeff(0.0); // iteration parameter
1030 181291 : Real64 Delta(0.0);
1031 181291 : Real64 mdot(0.0);
1032 : Real64 Cp; // local fluid specific heat
1033 : Real64 rho; // local fluid density
1034 :
1035 : // test CWFlow against plant
1036 181291 : mdot = CWFlow;
1037 181291 : auto const &coolBeam = state.dataHVACCooledBeam->CoolBeam(CBNum);
1038 :
1039 181291 : SetComponentFlowRate(state, mdot, coolBeam.CWInNode, coolBeam.CWOutNode, coolBeam.CWPlantLoc);
1040 :
1041 181291 : CWFlowPerBeam = mdot / coolBeam.NumBeams;
1042 181291 : TWIn = coolBeam.TWIn;
1043 :
1044 181291 : Cp = state.dataPlnt->PlantLoop(coolBeam.CWPlantLoc.loopNum).glycol->getSpecificHeat(state, TWIn, RoutineName);
1045 :
1046 181291 : rho = state.dataPlnt->PlantLoop(coolBeam.CWPlantLoc.loopNum).glycol->getDensity(state, TWIn, RoutineName);
1047 :
1048 181291 : TWOut = TWIn + 2.0;
1049 181291 : ZTemp = state.dataLoopNodes->Node(ZoneNode).Temp;
1050 181291 : if (mdot <= 0.0 || TWIn <= 0.0) {
1051 71770 : LoadMet = 0.0;
1052 71770 : TWOut = TWIn;
1053 71770 : return;
1054 : }
1055 2002787 : for (Iter = 1; Iter <= 200; ++Iter) {
1056 2002787 : if (Iter > 50 && Iter < 100) {
1057 35093 : Coeff = 0.1 * Coeff2;
1058 1967694 : } else if (Iter > 100) {
1059 346 : Coeff = 0.01 * Coeff2;
1060 : } else {
1061 1967348 : Coeff = Coeff2;
1062 : }
1063 :
1064 2002787 : WaterCoolPower = CWFlowPerBeam * Cp * (TWOut - TWIn);
1065 2002787 : DT = max(ZTemp - 0.5 * (TWIn + TWOut), 0.0);
1066 2002787 : IndFlow = coolBeam.K1 * std::pow(DT, coolBeam.n) + coolBeam.Kin * coolBeam.BeamFlow / coolBeam.BeamLength;
1067 2002787 : CoilFlow = (IndFlow / coolBeam.a0) * state.dataEnvrn->StdRhoAir;
1068 2002787 : WaterVel = CWFlowPerBeam / (rho * Constant::Pi * pow_2(coolBeam.InDiam) / 4.0);
1069 2002787 : if (WaterVel > MinWaterVel) {
1070 885372 : K = coolBeam.a * std::pow(DT, coolBeam.n1) * std::pow(CoilFlow, coolBeam.n2) * std::pow(WaterVel, coolBeam.n3);
1071 : } else {
1072 1117415 : K = coolBeam.a * std::pow(DT, coolBeam.n1) * std::pow(CoilFlow, coolBeam.n2) * std::pow(MinWaterVel, coolBeam.n3) *
1073 1117415 : (WaterVel / MinWaterVel);
1074 : }
1075 2002787 : AirCoolPower = K * coolBeam.CoilArea * DT * coolBeam.BeamLength;
1076 2002787 : Diff = WaterCoolPower - AirCoolPower;
1077 2002787 : Delta = TWOut * (std::abs(Diff) / Coeff);
1078 2002787 : if (std::abs(Diff) > 0.1) {
1079 1893266 : if (Diff < 0.0) {
1080 1617862 : TWOut += Delta; // increase TWout
1081 1617862 : if (TWOut > ZTemp) { // check that water outlet temperature is less than zone temperature
1082 0 : WaterCoolPower = 0.0;
1083 0 : TWOut = ZTemp;
1084 0 : break;
1085 : }
1086 : } else {
1087 275404 : TWOut -= Delta; // Decrease TWout
1088 275404 : if (TWOut < TWIn) {
1089 0 : TWOut = TWIn;
1090 : }
1091 : }
1092 : } else {
1093 : // water and air side outputs have converged
1094 109521 : break;
1095 : }
1096 : }
1097 109521 : LoadMet = -WaterCoolPower * coolBeam.NumBeams;
1098 : }
1099 :
1100 36725 : void UpdateCoolBeam(EnergyPlusData &state, int const CBNum)
1101 : {
1102 :
1103 : // SUBROUTINE INFORMATION:
1104 : // AUTHOR Fred Buhl
1105 : // DATE WRITTEN Feb 2009
1106 : // MODIFIED na
1107 : // RE-ENGINEERED na
1108 :
1109 : // PURPOSE OF THIS SUBROUTINE:
1110 : // This subroutine updates the cooled beam unit outlet nodes
1111 :
1112 : // METHODOLOGY EMPLOYED:
1113 : // Data is moved from the cooled beam unit data structure to the unit outlet nodes.
1114 :
1115 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1116 36725 : auto &coolBeam = state.dataHVACCooledBeam->CoolBeam(CBNum);
1117 36725 : auto const &airInletNode = state.dataLoopNodes->Node(coolBeam.AirInNode);
1118 36725 : auto &airOutletNode = state.dataLoopNodes->Node(coolBeam.AirOutNode);
1119 :
1120 : // Set the outlet air nodes of the unit; note that all quantities are unchanged
1121 36725 : airOutletNode.MassFlowRate = airInletNode.MassFlowRate;
1122 36725 : airOutletNode.Temp = airInletNode.Temp;
1123 36725 : airOutletNode.HumRat = airInletNode.HumRat;
1124 36725 : airOutletNode.Enthalpy = airInletNode.Enthalpy;
1125 :
1126 : // Set the outlet water nodes for the unit
1127 36725 : PlantUtilities::SafeCopyPlantNode(state, coolBeam.CWInNode, coolBeam.CWOutNode);
1128 :
1129 36725 : state.dataLoopNodes->Node(coolBeam.CWOutNode).Temp = coolBeam.TWOut;
1130 36725 : state.dataLoopNodes->Node(coolBeam.CWOutNode).Enthalpy = coolBeam.EnthWaterOut;
1131 :
1132 : // Set the air outlet nodes for properties that just pass through & not used
1133 36725 : airOutletNode.Quality = airInletNode.Quality;
1134 36725 : airOutletNode.Press = airInletNode.Press;
1135 36725 : airOutletNode.MassFlowRateMin = airInletNode.MassFlowRateMin;
1136 36725 : airOutletNode.MassFlowRateMax = airInletNode.MassFlowRateMax;
1137 36725 : airOutletNode.MassFlowRateMinAvail = airInletNode.MassFlowRateMinAvail;
1138 36725 : airOutletNode.MassFlowRateMaxAvail = airInletNode.MassFlowRateMaxAvail;
1139 :
1140 36725 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
1141 0 : airOutletNode.CO2 = airInletNode.CO2;
1142 : }
1143 :
1144 36725 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
1145 0 : airOutletNode.GenContam = airInletNode.GenContam;
1146 : }
1147 36725 : }
1148 :
1149 36725 : void ReportCoolBeam(EnergyPlusData &state, int const CBNum)
1150 : {
1151 :
1152 : // SUBROUTINE INFORMATION:
1153 : // AUTHOR Fred Buhl
1154 : // DATE WRITTEN Feb 2009
1155 : // MODIFIED na
1156 : // RE-ENGINEERED na
1157 :
1158 : // PURPOSE OF THIS SUBROUTINE:
1159 : // This subroutine updates the report variable for the cooled beam units
1160 :
1161 : // METHODOLOGY EMPLOYED:
1162 : // NA
1163 :
1164 : // REFERENCES:
1165 : // na
1166 :
1167 : // USE STATEMENTS:
1168 :
1169 : // Locals
1170 : // SUBROUTINE ARGUMENT DEFINITIONS:
1171 :
1172 : // SUBROUTINE PARAMETER DEFINITIONS:
1173 : // na
1174 :
1175 : // INTERFACE BLOCK SPECIFICATIONS
1176 : // na
1177 :
1178 : // DERIVED TYPE DEFINITIONS
1179 : // na
1180 :
1181 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1182 :
1183 : Real64 ReportingConstant;
1184 36725 : auto &coolBeam = state.dataHVACCooledBeam->CoolBeam(CBNum);
1185 :
1186 36725 : ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
1187 : // report the WaterCoil energy from this component
1188 36725 : coolBeam.BeamCoolingEnergy = coolBeam.BeamCoolingRate * ReportingConstant;
1189 36725 : coolBeam.SupAirCoolingEnergy = coolBeam.SupAirCoolingRate * ReportingConstant;
1190 36725 : coolBeam.SupAirHeatingEnergy = coolBeam.SupAirHeatingRate * ReportingConstant;
1191 :
1192 : // set zone OA volume flow rate report variable
1193 36725 : coolBeam.CalcOutdoorAirVolumeFlowRate(state);
1194 36725 : }
1195 :
1196 36725 : void CoolBeamData::CalcOutdoorAirVolumeFlowRate(EnergyPlusData &state)
1197 : {
1198 : // calculates zone outdoor air volume flow rate using the supply air flow rate and OA fraction
1199 36725 : if (this->AirLoopNum > 0) {
1200 36720 : this->OutdoorAirFlowRate = (state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate / state.dataEnvrn->StdRhoAir) *
1201 36720 : state.dataAirLoop->AirLoopFlow(this->AirLoopNum).OAFrac;
1202 : } else {
1203 5 : this->OutdoorAirFlowRate = 0.0;
1204 : }
1205 36725 : }
1206 :
1207 5 : void CoolBeamData::reportTerminalUnit(EnergyPlusData &state)
1208 : {
1209 : // populate the predefined equipment summary report related to air terminals
1210 5 : auto &orp = state.dataOutRptPredefined;
1211 5 : auto &adu = state.dataDefineEquipment->AirDistUnit(this->ADUNum);
1212 5 : if (!state.dataSize->TermUnitFinalZoneSizing.empty()) {
1213 5 : auto &sizing = state.dataSize->TermUnitFinalZoneSizing(adu.TermUnitSizingNum);
1214 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinFlow, adu.Name, sizing.DesCoolVolFlowMin);
1215 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinOutdoorFlow, adu.Name, sizing.MinOA);
1216 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermSupCoolingSP, adu.Name, sizing.CoolDesTemp);
1217 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermSupHeatingSP, adu.Name, sizing.HeatDesTemp);
1218 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermHeatingCap, adu.Name, sizing.DesHeatLoad);
1219 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermCoolingCap, adu.Name, sizing.DesCoolLoad);
1220 : }
1221 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermTypeInp, adu.Name, this->UnitType);
1222 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermPrimFlow, adu.Name, this->MaxAirVolFlow);
1223 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermSecdFlow, adu.Name, "n/a");
1224 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinFlowSch, adu.Name, "n/a");
1225 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMaxFlowReh, adu.Name, "n/a");
1226 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinOAflowSch, adu.Name, "n/a");
1227 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermHeatCoilType, adu.Name, "n/a");
1228 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermCoolCoilType, adu.Name, this->CBTypeString);
1229 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermFanType, adu.Name, "n/a");
1230 5 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermFanName, adu.Name, "n/a");
1231 5 : }
1232 :
1233 : } // namespace HVACCooledBeam
1234 :
1235 : } // namespace EnergyPlus
|