LCOV - code coverage report
Current view: top level - EnergyPlus - HVACCooledBeam.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 501 557 89.9 %
Date: 2024-08-24 18:31:18 Functions: 11 11 100.0 %

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

Generated by: LCOV version 1.14