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