LCOV - code coverage report
Current view: top level - EnergyPlus - HVACFourPipeBeam.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 76.3 % 764 583
Test Date: 2025-05-22 16:09:37 Functions: 77.8 % 18 14

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <cmath>
      50              : 
      51              : // ObjexxFCL Headers
      52              : #include <ObjexxFCL/Array.functions.hh>
      53              : #include <ObjexxFCL/Fmath.hh>
      54              : 
      55              : // EnergyPlus Headers
      56              : #include <EnergyPlus/AirTerminalUnit.hh>
      57              : #include <EnergyPlus/Autosizing/Base.hh>
      58              : #include <EnergyPlus/BranchNodeConnections.hh>
      59              : #include <EnergyPlus/CurveManager.hh>
      60              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      61              : #include <EnergyPlus/DataContaminantBalance.hh>
      62              : #include <EnergyPlus/DataDefineEquip.hh>
      63              : #include <EnergyPlus/DataEnvironment.hh>
      64              : #include <EnergyPlus/DataHVACGlobals.hh>
      65              : #include <EnergyPlus/DataIPShortCuts.hh>
      66              : #include <EnergyPlus/DataLoopNode.hh>
      67              : #include <EnergyPlus/DataSizing.hh>
      68              : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      69              : #include <EnergyPlus/DataZoneEquipment.hh>
      70              : #include <EnergyPlus/FluidProperties.hh>
      71              : #include <EnergyPlus/General.hh>
      72              : #include <EnergyPlus/GeneralRoutines.hh>
      73              : #include <EnergyPlus/HVACFourPipeBeam.hh>
      74              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      75              : #include <EnergyPlus/NodeInputManager.hh>
      76              : #include <EnergyPlus/OutputProcessor.hh>
      77              : #include <EnergyPlus/OutputReportPredefined.hh>
      78              : #include <EnergyPlus/Plant/DataPlant.hh>
      79              : #include <EnergyPlus/PlantUtilities.hh>
      80              : #include <EnergyPlus/Psychrometrics.hh>
      81              : #include <EnergyPlus/ScheduleManager.hh>
      82              : #include <EnergyPlus/UtilityRoutines.hh>
      83              : 
      84              : namespace EnergyPlus {
      85              : 
      86              : namespace FourPipeBeam {
      87              : 
      88              :     //    HVACFourPipeBeam::HVACFourPipeBeam(){}
      89              :     ///// Note use of shared_ptr here is not a good pattern, not to be replicated without further discussion.
      90            4 :     std::shared_ptr<AirTerminalUnit> HVACFourPipeBeam::fourPipeBeamFactory(EnergyPlusData &state, std::string objectName)
      91              :     {
      92              : 
      93              :         using BranchNodeConnections::TestCompSet;
      94              :         using DataLoopNode::ObjectIsNotParent;
      95              :         using DataLoopNode::ObjectIsParent;
      96              :         using NodeInputManager::GetOnlySingleNode;
      97              :         using namespace DataSizing;
      98              :         using Curve::GetCurveIndex;
      99              :         static constexpr std::string_view routineName("FourPipeBeamFactory "); // include trailing blank space
     100              : 
     101              :         int beamIndex; // loop index
     102              : 
     103              :         //  certain object in the input file
     104            4 :         bool errFlag = false;
     105            4 :         bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
     106            4 :         bool found = false;
     107              :         bool airNodeFound;
     108              :         int aDUIndex;
     109              : 
     110              :         ///// Note use of shared_ptr here is not a good pattern, not to be replicated without further discussion.
     111            4 :         std::shared_ptr<HVACFourPipeBeam> thisBeam(new HVACFourPipeBeam());
     112            4 :         auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     113              :         // find the number of cooled beam units
     114            4 :         cCurrentModuleObject = "AirTerminal:SingleDuct:ConstantVolume:FourPipeBeam";
     115              : 
     116              :         // find beam index from name
     117            4 :         beamIndex = state.dataInputProcessing->inputProcessor->getObjectItemNum(state, cCurrentModuleObject, objectName);
     118            4 :         if (beamIndex > 0) {
     119              :             int IOStatus;
     120            4 :             int NumAlphas = 16;
     121            4 :             int NumNumbers = 11;
     122            8 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     123              :                                                                      cCurrentModuleObject,
     124              :                                                                      beamIndex,
     125            4 :                                                                      state.dataIPShortCut->cAlphaArgs,
     126              :                                                                      NumAlphas,
     127            4 :                                                                      state.dataIPShortCut->rNumericArgs,
     128              :                                                                      NumNumbers,
     129              :                                                                      IOStatus,
     130            4 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
     131            4 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     132            4 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     133            4 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     134            4 :             found = true;
     135              :         } else {
     136            0 :             ErrorsFound = true;
     137              :         }
     138              : 
     139            4 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)};
     140              : 
     141            4 :         errFlag = false;
     142            4 :         GlobalNames::VerifyUniqueADUName(state, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1), errFlag, cCurrentModuleObject + " Name");
     143            4 :         if (errFlag) {
     144            0 :             ErrorsFound = true;
     145              :         }
     146            4 :         thisBeam->name = state.dataIPShortCut->cAlphaArgs(1);
     147            4 :         thisBeam->unitType = cCurrentModuleObject;
     148              : 
     149            4 :         if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     150            1 :             thisBeam->airAvailSched = Sched::GetScheduleAlwaysOn(state);
     151            3 :         } else if ((thisBeam->airAvailSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(2))) == nullptr) {
     152            0 :             ShowSevereItemNotFound(state, eoh, state.dataIPShortCut->cAlphaFieldNames(2), state.dataIPShortCut->cAlphaArgs(2));
     153            0 :             ErrorsFound = true;
     154              :         }
     155              : 
     156            4 :         if (state.dataIPShortCut->lAlphaFieldBlanks(3)) {
     157            1 :             thisBeam->coolingAvailSched = Sched::GetScheduleAlwaysOn(state);
     158            3 :         } else if ((thisBeam->coolingAvailSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(3))) == nullptr) {
     159            0 :             ShowSevereItemNotFound(state, eoh, state.dataIPShortCut->cAlphaFieldNames(3), state.dataIPShortCut->cAlphaArgs(3));
     160            0 :             ErrorsFound = true;
     161              :         }
     162            4 :         if (state.dataIPShortCut->lAlphaFieldBlanks(4)) {
     163            1 :             thisBeam->heatingAvailSched = Sched::GetScheduleAlwaysOn(state);
     164            3 :         } else if ((thisBeam->heatingAvailSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(4))) == nullptr) {
     165            0 :             ShowSevereItemNotFound(state, eoh, state.dataIPShortCut->cAlphaFieldNames(4), state.dataIPShortCut->cAlphaArgs(4));
     166            0 :             ErrorsFound = true;
     167              :         }
     168              : 
     169            4 :         thisBeam->airInNodeNum = GetOnlySingleNode(state,
     170            4 :                                                    state.dataIPShortCut->cAlphaArgs(5),
     171              :                                                    ErrorsFound,
     172              :                                                    DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeFourPipeBeam,
     173            4 :                                                    state.dataIPShortCut->cAlphaArgs(1),
     174              :                                                    DataLoopNode::NodeFluidType::Air,
     175              :                                                    DataLoopNode::ConnectionType::Inlet,
     176              :                                                    NodeInputManager::CompFluidStream::Primary,
     177              :                                                    ObjectIsNotParent,
     178            4 :                                                    state.dataIPShortCut->cAlphaFieldNames(5));
     179            4 :         thisBeam->airOutNodeNum = GetOnlySingleNode(state,
     180            4 :                                                     state.dataIPShortCut->cAlphaArgs(6),
     181              :                                                     ErrorsFound,
     182              :                                                     DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeFourPipeBeam,
     183            4 :                                                     state.dataIPShortCut->cAlphaArgs(1),
     184              :                                                     DataLoopNode::NodeFluidType::Air,
     185              :                                                     DataLoopNode::ConnectionType::Outlet,
     186              :                                                     NodeInputManager::CompFluidStream::Primary,
     187              :                                                     ObjectIsNotParent,
     188            4 :                                                     state.dataIPShortCut->cAlphaFieldNames(6));
     189            4 :         if (state.dataIPShortCut->lAlphaFieldBlanks(7) && state.dataIPShortCut->lAlphaFieldBlanks(8)) { // no chilled water nodes, no beam cooling
     190            0 :             thisBeam->beamCoolingPresent = false;
     191            4 :         } else if (state.dataIPShortCut->lAlphaFieldBlanks(7) &&
     192            0 :                    !state.dataIPShortCut->lAlphaFieldBlanks(8)) { // outlet node but no inlet node for chilled water
     193            0 :             thisBeam->beamCoolingPresent = false;
     194            0 :             ShowWarningError(state,
     195            0 :                              format("{}{}: missing {} for {}={}, simulation continues with no beam cooling",
     196              :                                     routineName,
     197              :                                     cCurrentModuleObject,
     198            0 :                                     state.dataIPShortCut->cAlphaFieldNames(7),
     199            0 :                                     state.dataIPShortCut->cAlphaFieldNames(1),
     200            0 :                                     state.dataIPShortCut->cAlphaArgs(1)));
     201            8 :         } else if (!state.dataIPShortCut->lAlphaFieldBlanks(7) &&
     202            4 :                    state.dataIPShortCut->lAlphaFieldBlanks(8)) { // inlet node but no outlet node for chilled water
     203            0 :             thisBeam->beamCoolingPresent = false;
     204            0 :             ShowWarningError(state,
     205            0 :                              format("{}{}: missing {} for {}={}, simulation continues with no beam cooling",
     206              :                                     routineName,
     207              :                                     cCurrentModuleObject,
     208            0 :                                     state.dataIPShortCut->cAlphaFieldNames(8),
     209            0 :                                     state.dataIPShortCut->cAlphaFieldNames(1),
     210            0 :                                     state.dataIPShortCut->cAlphaArgs(1)));
     211              :         } else {
     212            4 :             thisBeam->beamCoolingPresent = true;
     213            4 :             thisBeam->cWInNodeNum = GetOnlySingleNode(state,
     214            4 :                                                       state.dataIPShortCut->cAlphaArgs(7),
     215              :                                                       ErrorsFound,
     216              :                                                       DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeFourPipeBeam,
     217            4 :                                                       state.dataIPShortCut->cAlphaArgs(1),
     218              :                                                       DataLoopNode::NodeFluidType::Water,
     219              :                                                       DataLoopNode::ConnectionType::Inlet,
     220              :                                                       NodeInputManager::CompFluidStream::Secondary,
     221              :                                                       ObjectIsParent,
     222            4 :                                                       state.dataIPShortCut->cAlphaFieldNames(7));
     223            4 :             thisBeam->cWOutNodeNum = GetOnlySingleNode(state,
     224            4 :                                                        state.dataIPShortCut->cAlphaArgs(8),
     225              :                                                        ErrorsFound,
     226              :                                                        DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeFourPipeBeam,
     227            4 :                                                        state.dataIPShortCut->cAlphaArgs(1),
     228              :                                                        DataLoopNode::NodeFluidType::Water,
     229              :                                                        DataLoopNode::ConnectionType::Outlet,
     230              :                                                        NodeInputManager::CompFluidStream::Secondary,
     231              :                                                        ObjectIsParent,
     232            4 :                                                        state.dataIPShortCut->cAlphaFieldNames(8));
     233              :         }
     234            4 :         if (state.dataIPShortCut->lAlphaFieldBlanks(9) && state.dataIPShortCut->lAlphaFieldBlanks(10)) { // no hot water nodes, no beam heating
     235            0 :             thisBeam->beamHeatingPresent = false;
     236            4 :         } else if (state.dataIPShortCut->lAlphaFieldBlanks(9) &&
     237            0 :                    !state.dataIPShortCut->lAlphaFieldBlanks(10)) { // outlet node but no inlet node for hot water
     238            0 :             thisBeam->beamHeatingPresent = false;
     239            0 :             ShowWarningError(state,
     240            0 :                              format("{}{}: missing {} for {}={}, simulation continues with no beam heating",
     241              :                                     routineName,
     242              :                                     cCurrentModuleObject,
     243            0 :                                     state.dataIPShortCut->cAlphaFieldNames(9),
     244            0 :                                     state.dataIPShortCut->cAlphaFieldNames(1),
     245            0 :                                     state.dataIPShortCut->cAlphaArgs(1)));
     246            8 :         } else if (!state.dataIPShortCut->lAlphaFieldBlanks(9) &&
     247            4 :                    state.dataIPShortCut->lAlphaFieldBlanks(10)) { // inlet node but no outlet node for hot water
     248            0 :             thisBeam->beamHeatingPresent = false;
     249            0 :             ShowWarningError(state,
     250            0 :                              format("{}{}: missing {} for {}={}, simulation continues with no beam heating",
     251              :                                     routineName,
     252              :                                     cCurrentModuleObject,
     253            0 :                                     state.dataIPShortCut->cAlphaFieldNames(10),
     254            0 :                                     state.dataIPShortCut->cAlphaFieldNames(1),
     255            0 :                                     state.dataIPShortCut->cAlphaArgs(1)));
     256              :         } else {
     257            4 :             thisBeam->beamHeatingPresent = true;
     258            4 :             thisBeam->hWInNodeNum = GetOnlySingleNode(state,
     259            4 :                                                       state.dataIPShortCut->cAlphaArgs(9),
     260              :                                                       ErrorsFound,
     261              :                                                       DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeFourPipeBeam,
     262            4 :                                                       state.dataIPShortCut->cAlphaArgs(1),
     263              :                                                       DataLoopNode::NodeFluidType::Water,
     264              :                                                       DataLoopNode::ConnectionType::Inlet,
     265              :                                                       NodeInputManager::CompFluidStream::Secondary,
     266              :                                                       ObjectIsParent,
     267            4 :                                                       state.dataIPShortCut->cAlphaFieldNames(9));
     268            4 :             thisBeam->hWOutNodeNum = GetOnlySingleNode(state,
     269            4 :                                                        state.dataIPShortCut->cAlphaArgs(10),
     270              :                                                        ErrorsFound,
     271              :                                                        DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeFourPipeBeam,
     272            4 :                                                        state.dataIPShortCut->cAlphaArgs(1),
     273              :                                                        DataLoopNode::NodeFluidType::Water,
     274              :                                                        DataLoopNode::ConnectionType::Outlet,
     275              :                                                        NodeInputManager::CompFluidStream::Secondary,
     276              :                                                        ObjectIsParent,
     277            4 :                                                        state.dataIPShortCut->cAlphaFieldNames(10));
     278              :         }
     279            4 :         thisBeam->vDotDesignPrimAir = state.dataIPShortCut->rNumericArgs(1);
     280            4 :         if (thisBeam->vDotDesignPrimAir == AutoSize) {
     281            4 :             thisBeam->vDotDesignPrimAirWasAutosized = true;
     282              :         }
     283            4 :         thisBeam->vDotDesignCW = state.dataIPShortCut->rNumericArgs(2);
     284            4 :         if (thisBeam->vDotDesignCW == AutoSize && thisBeam->beamCoolingPresent) {
     285            4 :             thisBeam->vDotDesignCWWasAutosized = true;
     286              :         }
     287            4 :         thisBeam->vDotDesignHW = state.dataIPShortCut->rNumericArgs(3);
     288            4 :         if (thisBeam->vDotDesignHW == AutoSize && thisBeam->beamHeatingPresent) {
     289            4 :             thisBeam->vDotDesignHWWasAutosized = true;
     290              :         }
     291            4 :         thisBeam->totBeamLength = state.dataIPShortCut->rNumericArgs(4);
     292            4 :         if (thisBeam->totBeamLength == AutoSize) {
     293            4 :             thisBeam->totBeamLengthWasAutosized = true;
     294              :         }
     295            4 :         thisBeam->vDotNormRatedPrimAir = state.dataIPShortCut->rNumericArgs(5);
     296            4 :         thisBeam->qDotNormRatedCooling = state.dataIPShortCut->rNumericArgs(6);
     297            4 :         thisBeam->deltaTempRatedCooling = state.dataIPShortCut->rNumericArgs(7);
     298            4 :         thisBeam->vDotNormRatedCW = state.dataIPShortCut->rNumericArgs(8);
     299              : 
     300            4 :         thisBeam->modCoolingQdotDeltaTFuncNum = GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(11));
     301            4 :         if (thisBeam->modCoolingQdotDeltaTFuncNum == 0 && thisBeam->beamCoolingPresent) {
     302            0 :             ShowSevereError(state, format("{}{}=\"{}\"", routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     303            0 :             ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(11), state.dataIPShortCut->cAlphaArgs(11)));
     304            0 :             ErrorsFound = true;
     305              :         }
     306            4 :         thisBeam->modCoolingQdotAirFlowFuncNum = GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(12));
     307            4 :         if (thisBeam->modCoolingQdotAirFlowFuncNum == 0 && thisBeam->beamCoolingPresent) {
     308            0 :             ShowSevereError(state, format("{}{}=\"{}\"", routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     309            0 :             ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(12), state.dataIPShortCut->cAlphaArgs(12)));
     310            0 :             ErrorsFound = true;
     311              :         }
     312            4 :         thisBeam->modCoolingQdotCWFlowFuncNum = GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(13));
     313            4 :         if (thisBeam->modCoolingQdotCWFlowFuncNum == 0 && thisBeam->beamCoolingPresent) {
     314            0 :             ShowSevereError(state, format("{}{}=\"{}\"", routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     315            0 :             ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(13), state.dataIPShortCut->cAlphaArgs(13)));
     316            0 :             ErrorsFound = true;
     317              :         }
     318            4 :         thisBeam->qDotNormRatedHeating = state.dataIPShortCut->rNumericArgs(9);
     319            4 :         thisBeam->deltaTempRatedHeating = state.dataIPShortCut->rNumericArgs(10);
     320            4 :         thisBeam->vDotNormRatedHW = state.dataIPShortCut->rNumericArgs(11);
     321            4 :         thisBeam->modHeatingQdotDeltaTFuncNum = GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(14));
     322            4 :         if (thisBeam->modHeatingQdotDeltaTFuncNum == 0 && thisBeam->beamHeatingPresent) {
     323            0 :             ShowSevereError(state, format("{}{}=\"{}\"", routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     324            0 :             ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(14), state.dataIPShortCut->cAlphaArgs(14)));
     325            0 :             ErrorsFound = true;
     326              :         }
     327            4 :         thisBeam->modHeatingQdotAirFlowFuncNum = GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(15));
     328            4 :         if (thisBeam->modHeatingQdotAirFlowFuncNum == 0 && thisBeam->beamHeatingPresent) {
     329            0 :             ShowSevereError(state, format("{}{}=\"{}\"", routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     330            0 :             ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(15), state.dataIPShortCut->cAlphaArgs(15)));
     331            0 :             ErrorsFound = true;
     332              :         }
     333            4 :         thisBeam->modHeatingQdotHWFlowFuncNum = GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(16));
     334            4 :         if (thisBeam->modHeatingQdotHWFlowFuncNum == 0 && thisBeam->beamHeatingPresent) {
     335            0 :             ShowSevereError(state, format("{}{}=\"{}\"", routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     336            0 :             ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(16), state.dataIPShortCut->cAlphaArgs(16)));
     337            0 :             ErrorsFound = true;
     338              :         }
     339              :         // Register component set data
     340            8 :         TestCompSet(state,
     341              :                     cCurrentModuleObject,
     342            4 :                     thisBeam->name,
     343            4 :                     state.dataLoopNodes->NodeID(thisBeam->airInNodeNum),
     344            4 :                     state.dataLoopNodes->NodeID(thisBeam->airOutNodeNum),
     345              :                     "Air Nodes");
     346            4 :         if (thisBeam->beamCoolingPresent) {
     347           12 :             TestCompSet(state,
     348              :                         cCurrentModuleObject,
     349            4 :                         thisBeam->name,
     350            4 :                         state.dataLoopNodes->NodeID(thisBeam->cWInNodeNum),
     351            4 :                         state.dataLoopNodes->NodeID(thisBeam->cWOutNodeNum),
     352              :                         "Chilled Water Nodes");
     353              :         }
     354            4 :         if (thisBeam->beamHeatingPresent) {
     355           12 :             TestCompSet(state,
     356              :                         cCurrentModuleObject,
     357            4 :                         thisBeam->name,
     358            4 :                         state.dataLoopNodes->NodeID(thisBeam->hWInNodeNum),
     359            4 :                         state.dataLoopNodes->NodeID(thisBeam->hWOutNodeNum),
     360              :                         "Hot Water Nodes");
     361              :         }
     362              : 
     363              :         // Setup the Cooled Beam reporting variables
     364            4 :         if (thisBeam->beamCoolingPresent) {
     365            8 :             SetupOutputVariable(state,
     366              :                                 "Zone Air Terminal Beam Sensible Cooling Energy",
     367              :                                 Constant::Units::J,
     368            4 :                                 thisBeam->beamCoolingEnergy,
     369              :                                 OutputProcessor::TimeStepType::System,
     370              :                                 OutputProcessor::StoreType::Sum,
     371            4 :                                 thisBeam->name,
     372              :                                 Constant::eResource::EnergyTransfer,
     373              :                                 OutputProcessor::Group::HVAC,
     374              :                                 OutputProcessor::EndUseCat::CoolingCoils);
     375            8 :             SetupOutputVariable(state,
     376              :                                 "Zone Air Terminal Beam Sensible Cooling Rate",
     377              :                                 Constant::Units::W,
     378            4 :                                 thisBeam->beamCoolingRate,
     379              :                                 OutputProcessor::TimeStepType::System,
     380              :                                 OutputProcessor::StoreType::Average,
     381            4 :                                 thisBeam->name);
     382              :         }
     383            4 :         if (thisBeam->beamHeatingPresent) {
     384            8 :             SetupOutputVariable(state,
     385              :                                 "Zone Air Terminal Beam Sensible Heating Energy",
     386              :                                 Constant::Units::J,
     387            4 :                                 thisBeam->beamHeatingEnergy,
     388              :                                 OutputProcessor::TimeStepType::System,
     389              :                                 OutputProcessor::StoreType::Sum,
     390            4 :                                 thisBeam->name,
     391              :                                 Constant::eResource::EnergyTransfer,
     392              :                                 OutputProcessor::Group::HVAC,
     393              :                                 OutputProcessor::EndUseCat::HeatingCoils);
     394            8 :             SetupOutputVariable(state,
     395              :                                 "Zone Air Terminal Beam Sensible Heating Rate",
     396              :                                 Constant::Units::W,
     397            4 :                                 thisBeam->beamHeatingRate,
     398              :                                 OutputProcessor::TimeStepType::System,
     399              :                                 OutputProcessor::StoreType::Average,
     400            4 :                                 thisBeam->name);
     401              :         }
     402            8 :         SetupOutputVariable(state,
     403              :                             "Zone Air Terminal Primary Air Sensible Cooling Energy",
     404              :                             Constant::Units::J,
     405            4 :                             thisBeam->supAirCoolingEnergy,
     406              :                             OutputProcessor::TimeStepType::System,
     407              :                             OutputProcessor::StoreType::Sum,
     408            4 :                             thisBeam->name);
     409            8 :         SetupOutputVariable(state,
     410              :                             "Zone Air Terminal Primary Air Sensible Cooling Rate",
     411              :                             Constant::Units::W,
     412            4 :                             thisBeam->supAirCoolingRate,
     413              :                             OutputProcessor::TimeStepType::System,
     414              :                             OutputProcessor::StoreType::Average,
     415            4 :                             thisBeam->name);
     416            8 :         SetupOutputVariable(state,
     417              :                             "Zone Air Terminal Primary Air Sensible Heating Energy",
     418              :                             Constant::Units::J,
     419            4 :                             thisBeam->supAirHeatingEnergy,
     420              :                             OutputProcessor::TimeStepType::System,
     421              :                             OutputProcessor::StoreType::Sum,
     422            4 :                             thisBeam->name);
     423            8 :         SetupOutputVariable(state,
     424              :                             "Zone Air Terminal Primary Air Sensible Heating Rate",
     425              :                             Constant::Units::W,
     426            4 :                             thisBeam->supAirHeatingRate,
     427              :                             OutputProcessor::TimeStepType::System,
     428              :                             OutputProcessor::StoreType::Average,
     429            4 :                             thisBeam->name);
     430            8 :         SetupOutputVariable(state,
     431              :                             "Zone Air Terminal Primary Air Flow Rate",
     432              :                             Constant::Units::m3_s,
     433            4 :                             thisBeam->primAirFlow,
     434              :                             OutputProcessor::TimeStepType::System,
     435              :                             OutputProcessor::StoreType::Average,
     436            4 :                             thisBeam->name);
     437              : 
     438            8 :         SetupOutputVariable(state,
     439              :                             "Zone Air Terminal Outdoor Air Volume Flow Rate",
     440              :                             Constant::Units::m3_s,
     441            4 :                             thisBeam->OutdoorAirFlowRate,
     442              :                             OutputProcessor::TimeStepType::System,
     443              :                             OutputProcessor::StoreType::Average,
     444            4 :                             thisBeam->name);
     445              : 
     446            4 :         airNodeFound = false;
     447            8 :         for (aDUIndex = 1; aDUIndex <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++aDUIndex) {
     448            4 :             if (thisBeam->airOutNodeNum == state.dataDefineEquipment->AirDistUnit(aDUIndex).OutletNodeNum) {
     449            4 :                 thisBeam->aDUNum = aDUIndex;
     450            4 :                 state.dataDefineEquipment->AirDistUnit(aDUIndex).InletNodeNum = thisBeam->airInNodeNum;
     451              :             }
     452              :         }
     453              :         // assumes if there isn't one assigned, it's an error
     454            4 :         if (thisBeam->aDUNum == 0) {
     455            0 :             ShowSevereError(state,
     456            0 :                             format("{}No matching Air Distribution Unit, for Unit = [{},{}].", routineName, cCurrentModuleObject, thisBeam->name));
     457            0 :             ShowContinueError(state, format("...should have outlet node={}", state.dataLoopNodes->NodeID(thisBeam->airOutNodeNum)));
     458            0 :             ErrorsFound = true;
     459              :         } else {
     460              : 
     461              :             // Fill the Zone Equipment data with the supply air inlet node number of this unit.
     462            8 :             for (int ctrlZone = 1; ctrlZone <= state.dataGlobal->NumOfZones; ++ctrlZone) {
     463            4 :                 if (!state.dataZoneEquip->ZoneEquipConfig(ctrlZone).IsControlled) continue;
     464            4 :                 for (int supAirIn = 1; supAirIn <= state.dataZoneEquip->ZoneEquipConfig(ctrlZone).NumInletNodes; ++supAirIn) {
     465            4 :                     if (thisBeam->airOutNodeNum == state.dataZoneEquip->ZoneEquipConfig(ctrlZone).InletNode(supAirIn)) {
     466            4 :                         thisBeam->zoneIndex = ctrlZone;
     467            4 :                         thisBeam->zoneNodeIndex = state.dataZoneEquip->ZoneEquipConfig(ctrlZone).ZoneNode;
     468            4 :                         thisBeam->ctrlZoneInNodeIndex = supAirIn;
     469            4 :                         state.dataZoneEquip->ZoneEquipConfig(ctrlZone).AirDistUnitCool(supAirIn).InNode = thisBeam->airInNodeNum;
     470            4 :                         state.dataZoneEquip->ZoneEquipConfig(ctrlZone).AirDistUnitCool(supAirIn).OutNode = thisBeam->airOutNodeNum;
     471            4 :                         state.dataDefineEquipment->AirDistUnit(thisBeam->aDUNum).TermUnitSizingNum =
     472            4 :                             state.dataZoneEquip->ZoneEquipConfig(ctrlZone).AirDistUnitCool(supAirIn).TermUnitSizingIndex;
     473            4 :                         thisBeam->termUnitSizingNum = state.dataDefineEquipment->AirDistUnit(thisBeam->aDUNum).TermUnitSizingNum;
     474            4 :                         state.dataDefineEquipment->AirDistUnit(thisBeam->aDUNum).ZoneEqNum = ctrlZone;
     475            4 :                         if (thisBeam->beamHeatingPresent) {
     476            4 :                             state.dataZoneEquip->ZoneEquipConfig(ctrlZone).AirDistUnitHeat(supAirIn).InNode = thisBeam->airInNodeNum;
     477            4 :                             state.dataZoneEquip->ZoneEquipConfig(ctrlZone).AirDistUnitHeat(supAirIn).OutNode = thisBeam->airOutNodeNum;
     478              :                         }
     479            4 :                         airNodeFound = true;
     480            4 :                         break;
     481              :                     }
     482              :                 }
     483              :             }
     484              :         }
     485            4 :         if (!airNodeFound) {
     486            0 :             ShowSevereError(state, format("The outlet air node from the {} = {}", cCurrentModuleObject, thisBeam->name));
     487            0 :             ShowContinueError(state, format("did not have a matching Zone Equipment Inlet Node, Node ={}", state.dataIPShortCut->cAlphaArgs(5)));
     488            0 :             ErrorsFound = true;
     489              :         }
     490              : 
     491            4 :         if (found && !ErrorsFound) {
     492            4 :             state.dataFourPipeBeam->FourPipeBeams.push_back(thisBeam);
     493            4 :             return thisBeam;
     494              :         } else {
     495            0 :             ShowFatalError(state, format("{}Errors found in getting input. Preceding conditions cause termination.", routineName));
     496            0 :             return nullptr;
     497              :         }
     498            4 :     }
     499              : 
     500            0 :     int HVACFourPipeBeam::getAirLoopNum()
     501              :     {
     502            0 :         return airLoopNum;
     503              :     }
     504              : 
     505            0 :     int HVACFourPipeBeam::getZoneIndex()
     506              :     {
     507            0 :         return zoneIndex;
     508              :     }
     509              : 
     510            1 :     Real64 HVACFourPipeBeam::getPrimAirDesignVolFlow()
     511              :     {
     512            1 :         return vDotDesignPrimAir;
     513              :     }
     514              : 
     515            0 :     int HVACFourPipeBeam::getTermUnitSizingIndex()
     516              :     {
     517            0 :         return termUnitSizingNum;
     518              :     }
     519              : 
     520           37 :     void HVACFourPipeBeam::simulate(EnergyPlusData &state,
     521              :                                     bool const FirstHVACIteration, // TRUE if first HVAC iteration in time step
     522              :                                     Real64 &NonAirSysOutput        // convective cooling by the beam system [W]
     523              :     )
     524              :     {
     525              : 
     526              :         // initialize the unit
     527           37 :         this->init(state, FirstHVACIteration);
     528              : 
     529              :         // control and simulate the beam
     530           36 :         if (!this->mySizeFlag) {
     531           33 :             this->control(state, FirstHVACIteration, NonAirSysOutput);
     532              : 
     533              :             // Update the current unit's outlet nodes.
     534           33 :             this->update(state);
     535              : 
     536              :             // Fill the report variables.
     537           33 :             this->report(state);
     538              :         }
     539           36 :     }
     540              : 
     541           37 :     void HVACFourPipeBeam::init(EnergyPlusData &state,
     542              :                                 bool const FirstHVACIteration // TRUE if first air loop solution this HVAC step
     543              :     )
     544              :     {
     545              : 
     546              :         // Using
     547              :         using DataZoneEquipment::CheckZoneEquipmentList;
     548              :         using PlantUtilities::InitComponentNodes;
     549              :         using PlantUtilities::ScanPlantLoopsForObject;
     550              :         using PlantUtilities::SetComponentFlowRate;
     551              : 
     552              :         static constexpr std::string_view routineName("HVACFourPipeBeam::init");
     553              : 
     554           37 :         if (this->plantLoopScanFlag && allocated(state.dataPlnt->PlantLoop)) {
     555            3 :             bool errFlag = false;
     556            3 :             if (this->beamCoolingPresent) {
     557            9 :                 ScanPlantLoopsForObject(state,
     558              :                                         this->name,
     559              :                                         DataPlant::PlantEquipmentType::FourPipeBeamAirTerminal,
     560            3 :                                         this->cWplantLoc,
     561              :                                         errFlag,
     562              :                                         _,
     563              :                                         _,
     564              :                                         _,
     565            3 :                                         this->cWInNodeNum,
     566              :                                         _);
     567            3 :                 if (errFlag) {
     568            0 :                     ShowFatalError(state, format("{} Program terminated for previous conditions.", routineName));
     569              :                 }
     570              :             }
     571            3 :             if (this->beamHeatingPresent) {
     572            9 :                 ScanPlantLoopsForObject(state,
     573              :                                         this->name,
     574              :                                         DataPlant::PlantEquipmentType::FourPipeBeamAirTerminal,
     575            3 :                                         this->hWplantLoc,
     576              :                                         errFlag,
     577              :                                         _,
     578              :                                         _,
     579              :                                         _,
     580            3 :                                         this->hWInNodeNum,
     581              :                                         _);
     582            3 :                 if (errFlag) {
     583            0 :                     ShowFatalError(state, format("{} Program terminated for previous conditions.", routineName));
     584              :                 }
     585              :             }
     586            3 :             this->plantLoopScanFlag = false;
     587              :         }
     588              : 
     589           37 :         if (!this->zoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
     590              :             // Check to see if there is a Air Distribution Unit on the Zone Equipment List
     591            3 :             if (this->aDUNum != 0) {
     592            3 :                 if (!CheckZoneEquipmentList(state, "ZONEHVAC:AIRDISTRIBUTIONUNIT", state.dataDefineEquipment->AirDistUnit(this->aDUNum).Name)) {
     593            0 :                     ShowSevereError(state,
     594            0 :                                     format("{}: ADU=[Air Distribution Unit,{}] is not on any ZoneHVAC:EquipmentList.",
     595              :                                            routineName,
     596            0 :                                            state.dataDefineEquipment->AirDistUnit(this->aDUNum).Name));
     597            0 :                     ShowContinueError(state, format("...Unit=[{},{}] will not be simulated.", this->unitType, this->name));
     598              :                 }
     599            3 :                 this->zoneEquipmentListChecked = true;
     600              :             }
     601              :         }
     602              : 
     603           37 :         if (!state.dataGlobal->SysSizingCalc && this->mySizeFlag && !this->plantLoopScanFlag) {
     604              :             //    if ( SysSizingCalc && this->mySizeFlag && ! this->plantLoopScanFlag ) {
     605            3 :             this->airLoopNum = state.dataZoneEquip->ZoneEquipConfig(this->zoneIndex).InletNodeAirLoopNum(this->ctrlZoneInNodeIndex);
     606            3 :             state.dataDefineEquipment->AirDistUnit(this->aDUNum).AirLoopNum = this->airLoopNum;
     607            3 :             this->set_size(state);          // calculate autosize values (in any) and convert volume flow rates to mass flow rates
     608            2 :             if (this->beamCoolingPresent) { // initialize chilled water design mass flow rate in plant routines
     609            2 :                 InitComponentNodes(state, 0.0, this->mDotDesignCW, this->cWInNodeNum, this->cWOutNodeNum);
     610              :             }
     611            2 :             if (this->beamHeatingPresent) { // initialize hot water design mass flow rate in plant routines
     612            2 :                 InitComponentNodes(state, 0.0, this->mDotDesignHW, this->hWInNodeNum, this->hWOutNodeNum);
     613              :             }
     614            2 :             this->mySizeFlag = false;
     615              :         }
     616              : 
     617              :         // Do the Begin Environment initializations
     618           36 :         if (state.dataGlobal->BeginEnvrnFlag && this->myEnvrnFlag) {
     619              : 
     620            4 :             state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRateMax = this->mDotDesignPrimAir;
     621            4 :             state.dataLoopNodes->Node(this->airOutNodeNum).MassFlowRateMax = this->mDotDesignPrimAir;
     622            4 :             state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRateMin = 0.0;
     623            4 :             state.dataLoopNodes->Node(this->airOutNodeNum).MassFlowRateMin = 0.0;
     624              : 
     625            4 :             if (this->beamCoolingPresent) { // initialize chilled water design mass flow rate in plant routines
     626            4 :                 InitComponentNodes(state, 0.0, this->mDotDesignCW, this->cWInNodeNum, this->cWOutNodeNum);
     627              :             }
     628            4 :             if (this->beamHeatingPresent) { // initialize hot water design mass flow rate in plant routines
     629            4 :                 InitComponentNodes(state, 0.0, this->mDotDesignHW, this->hWInNodeNum, this->hWOutNodeNum);
     630              :             }
     631              : 
     632            4 :             if (this->airLoopNum == 0) { // fill air loop index
     633            0 :                 if (this->zoneIndex > 0 && this->ctrlZoneInNodeIndex > 0) {
     634            0 :                     this->airLoopNum = state.dataZoneEquip->ZoneEquipConfig(this->zoneIndex).InletNodeAirLoopNum(this->ctrlZoneInNodeIndex);
     635              :                 }
     636              :             }
     637              : 
     638            4 :             this->myEnvrnFlag = false;
     639              :         } // end one time inits
     640              : 
     641           36 :         if (!state.dataGlobal->BeginEnvrnFlag) {
     642           24 :             this->myEnvrnFlag = true;
     643              :         }
     644              : 
     645              :         // Do the start of HVAC time step initializations
     646           36 :         if (FirstHVACIteration) {
     647              :             // check availability schedules and set flags
     648           24 :             this->airAvailable = (this->airAvailSched->getCurrentVal() > 0.0);
     649           24 :             this->coolingAvailable = (this->airAvailable && beamCoolingPresent && (this->coolingAvailSched->getCurrentVal() > 0.0));
     650           24 :             this->heatingAvailable = (this->airAvailable && beamHeatingPresent && (this->heatingAvailSched->getCurrentVal() > 0.0));
     651              : 
     652              :             // check for upstream zero flow. If nonzero and air available, set primary flow to max
     653           24 :             if (this->airAvailable && state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRate > 0.0) {
     654           19 :                 state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRate = this->mDotDesignPrimAir;
     655              :             } else {
     656            5 :                 state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRate = 0.0;
     657              :             }
     658              :             // reset the max and min avail flows
     659           24 :             if (this->airAvailable && state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRateMaxAvail > 0.0) {
     660           19 :                 state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRateMaxAvail = this->mDotDesignPrimAir;
     661           19 :                 state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRateMinAvail = this->mDotDesignPrimAir;
     662              :             } else {
     663            5 :                 state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRateMaxAvail = 0.0;
     664            5 :                 state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRateMinAvail = 0.0;
     665              :             }
     666              :         }
     667              : 
     668              :         // do these initializations every time step
     669           36 :         if (beamCoolingPresent) {
     670           36 :             this->cWTempIn = state.dataLoopNodes->Node(this->cWInNodeNum).Temp;
     671           36 :             this->cWTempOut = this->cWTempIn;
     672              :         }
     673           36 :         if (beamHeatingPresent) {
     674           36 :             this->hWTempIn = state.dataLoopNodes->Node(this->hWInNodeNum).Temp;
     675           36 :             this->hWTempOut = this->hWTempIn;
     676              :         }
     677           36 :         this->mDotSystemAir = state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRateMaxAvail;
     678           36 :         state.dataLoopNodes->Node(this->airInNodeNum).MassFlowRate = this->mDotSystemAir;
     679           36 :         this->tDBZoneAirTemp = state.dataLoopNodes->Node(this->zoneNodeIndex).Temp;
     680           36 :         this->tDBSystemAir = state.dataLoopNodes->Node(this->airInNodeNum).Temp;
     681           36 :         this->cpZoneAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->zoneNodeIndex).HumRat);
     682           36 :         this->cpSystemAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->airInNodeNum).HumRat);
     683           36 :         this->qDotBeamCooling = 0.0;
     684           36 :         this->qDotBeamHeating = 0.0;
     685           36 :         this->supAirCoolingRate = 0.0;
     686           36 :         this->supAirHeatingRate = 0.0;
     687           36 :         this->beamCoolingRate = 0.0;
     688           36 :         this->beamHeatingRate = 0.0;
     689           36 :         this->primAirFlow = 0.0;
     690              : 
     691           36 :     } // init
     692              : 
     693            3 :     void HVACFourPipeBeam::set_size(EnergyPlusData &state)
     694              :     {
     695              : 
     696              :         // Using
     697              :         using namespace DataSizing;
     698              :         using PlantUtilities::MyPlantSizingIndex;
     699              :         using PlantUtilities::RegisterPlantCompDesignFlow;
     700              :         using Psychrometrics::PsyCpAirFnW;
     701              :         using namespace std::placeholders;
     702              : 
     703              :         static constexpr std::string_view routineName("HVACFourPipeBeam::set_size ");
     704              : 
     705            3 :         bool ErrorsFound = false;
     706              :         Real64 rho;                     // local fluid density
     707              :         bool noHardSizeAnchorAvailable; // aid for complex logic surrounding mix of hard size and autosizes
     708            3 :         Real64 cpAir = 0.0;
     709            3 :         Real64 ErrTolerance = 0.001;
     710              : 
     711            3 :         Real64 mDotAirSolutionHeating = 0.0;
     712            3 :         Real64 mDotAirSolutionCooling = 0.0;
     713            3 :         Real64 originalTermUnitSizeMaxVDot = 0.0;
     714            3 :         Real64 originalTermUnitSizeCoolVDot = 0.0;
     715            3 :         Real64 originalTermUnitSizeHeatVDot = 0.0;
     716              : 
     717              :         // convert rated primary flow rate to mass flow rate using standard pressure and dry air at 20.0
     718            3 :         this->mDotNormRatedPrimAir = this->vDotNormRatedPrimAir * state.dataEnvrn->rhoAirSTP;
     719              : 
     720            3 :         noHardSizeAnchorAvailable = false;
     721              : 
     722            3 :         if (state.dataSize->CurTermUnitSizingNum > 0) {
     723            3 :             originalTermUnitSizeMaxVDot = std::max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolVolFlow,
     724            3 :                                                    state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow);
     725            3 :             originalTermUnitSizeCoolVDot = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolVolFlow;
     726            3 :             originalTermUnitSizeHeatVDot = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow;
     727              :         }
     728              : 
     729            3 :         if (this->totBeamLengthWasAutosized && this->vDotDesignPrimAirWasAutosized && this->vDotDesignCWWasAutosized &&
     730            3 :             this->vDotDesignHWWasAutosized) {
     731            3 :             noHardSizeAnchorAvailable = true;
     732            0 :         } else if (this->totBeamLengthWasAutosized && this->vDotDesignPrimAirWasAutosized && this->vDotDesignCWWasAutosized && !beamHeatingPresent) {
     733            0 :             noHardSizeAnchorAvailable = true;
     734            0 :         } else if (this->totBeamLengthWasAutosized && this->vDotDesignPrimAirWasAutosized && !this->beamCoolingPresent &&
     735            0 :                    this->vDotDesignHWWasAutosized) {
     736            0 :             noHardSizeAnchorAvailable = true;
     737            0 :         } else if (!this->totBeamLengthWasAutosized) { // the simplest case is where length is not autosized
     738              :             // use the normalized rated values (likely defaulted ) with length to calculate any that are autosized
     739            0 :             if (this->vDotDesignPrimAirWasAutosized) {
     740            0 :                 this->vDotDesignPrimAir = this->vDotNormRatedPrimAir * this->totBeamLength;
     741              :             }
     742            0 :             if (this->vDotDesignCWWasAutosized) {
     743            0 :                 this->vDotDesignCW = this->vDotNormRatedCW * this->totBeamLength;
     744              :             }
     745            0 :             if (vDotDesignHWWasAutosized) {
     746            0 :                 this->vDotDesignHW = this->vDotNormRatedHW * this->totBeamLength;
     747              :             }
     748              :         } else { // need to find beam length
     749              :             // the next simplest case is if the supply air rate is given
     750            0 :             if (!this->vDotDesignPrimAirWasAutosized) { //
     751              :                 // find length from air flow rate and then proceed
     752            0 :                 this->totBeamLength = this->vDotDesignPrimAir / this->vDotNormRatedPrimAir;
     753            0 :                 if (this->vDotDesignCWWasAutosized) {
     754            0 :                     this->vDotDesignCW = this->vDotNormRatedCW * this->totBeamLength;
     755              :                 }
     756            0 :                 if (vDotDesignHWWasAutosized) {
     757            0 :                     this->vDotDesignHW = this->vDotNormRatedHW * this->totBeamLength;
     758              :                 }
     759              :             } else {                                                               // both air and length are autosized
     760            0 :                 if (this->beamCoolingPresent && !this->vDotDesignCWWasAutosized) { // we have a chilled water flow rate to use
     761            0 :                     this->totBeamLength = this->vDotDesignCW / this->vDotNormRatedCW;
     762            0 :                     this->vDotDesignPrimAir = this->vDotNormRatedPrimAir * this->totBeamLength;
     763            0 :                     if (vDotDesignHWWasAutosized) {
     764            0 :                         this->vDotDesignHW = this->vDotNormRatedHW * this->totBeamLength;
     765              :                     }
     766            0 :                 } else if (this->beamHeatingPresent && !this->vDotDesignHWWasAutosized) { // we have a hot water flow rate to use
     767            0 :                     this->totBeamLength = this->vDotDesignHW / this->vDotNormRatedHW;
     768            0 :                     this->vDotDesignPrimAir = this->vDotNormRatedPrimAir * this->totBeamLength;
     769            0 :                     if (this->vDotDesignCWWasAutosized) { // don't think it can come here but...
     770            0 :                         this->vDotDesignCW = this->vDotNormRatedCW * this->totBeamLength;
     771              :                     }
     772              :                 } else {
     773              :                     // should not come here, developer exception
     774              :                 }
     775              :             } // no air flow rate
     776              :         }     // no beam length
     777              : 
     778            6 :         if (noHardSizeAnchorAvailable && (state.dataSize->CurZoneEqNum > 0) &&
     779            3 :             (state.dataSize->CurTermUnitSizingNum > 0)) { // need to use central sizing results to calculate
     780              : 
     781              :             // set up for solver
     782              : 
     783            3 :             CheckZoneSizing(state, this->unitType, this->name);
     784              :             // minimum flow rate is from air flow rate on the terminal unit final zone size ( typically ventilation minimum and may be too low)
     785            3 :             Real64 minFlow(0.0);
     786            3 :             Real64 maxFlowCool(0.0);
     787            3 :             minFlow = std::min(state.dataEnvrn->StdRhoAir * originalTermUnitSizeMaxVDot,
     788            3 :                                state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).MinOA * state.dataEnvrn->StdRhoAir);
     789            3 :             minFlow = std::max(0.0, minFlow);
     790              :             // max flow is as if the air supply was sufficient to provide all the conditioning
     791              : 
     792            3 :             if (beamCoolingPresent) {
     793            3 :                 cpAir = PsyCpAirFnW(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolCoilInHumRatTU);
     794              : 
     795            3 :                 if ((state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtCoolPeak -
     796            3 :                      state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolCoilInTempTU) >
     797              :                     2.0) { // avoid div by zero and blow up
     798            3 :                     maxFlowCool = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolLoad /
     799            3 :                                   (cpAir * (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtCoolPeak -
     800            3 :                                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolCoilInTempTU));
     801              :                 } else {
     802            0 :                     maxFlowCool = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolLoad / (cpAir * 2.0);
     803              :                 }
     804            3 :                 if (minFlow * 3.0 >= maxFlowCool) {
     805            2 :                     minFlow = maxFlowCool / 3.0; // make sure min is significantly lower than max.
     806              :                 }
     807              : 
     808            3 :                 int pltSizCoolNum = MyPlantSizingIndex(state, "four pipe beam unit", this->name, this->cWInNodeNum, this->cWOutNodeNum, ErrorsFound);
     809            3 :                 if (pltSizCoolNum == 0) {
     810            0 :                     ShowSevereError(state, "Autosizing of water flow requires a cooling loop Sizing:Plant object");
     811            0 :                     ShowContinueError(state, format("Occurs in {} Object={}", this->unitType, this->name));
     812            0 :                     ErrorsFound = true;
     813              :                 } else {
     814            3 :                     this->cWTempIn = state.dataSize->PlantSizData(pltSizCoolNum).ExitTemp;
     815              :                 }
     816            3 :                 this->mDotHW = 0.0;
     817            3 :                 this->tDBZoneAirTemp = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtCoolPeak;
     818            3 :                 this->tDBSystemAir = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolCoilInTempTU;
     819            3 :                 this->cpZoneAir = PsyCpAirFnW(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneHumRatAtCoolPeak);
     820            3 :                 this->cpSystemAir = PsyCpAirFnW(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolCoilInHumRatTU);
     821            3 :                 this->qDotZoneReq = -1.0 * state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolLoad;
     822            3 :                 this->qDotZoneToCoolSetPt = -1.0 * state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolLoad;
     823            3 :                 this->airAvailable = true;
     824            3 :                 this->coolingAvailable = true;
     825            3 :                 this->heatingAvailable = false;
     826            9 :                 auto f = [&state, this](Real64 const airFlow) {
     827              :                     static constexpr std::string_view routineName("Real64 HVACFourPipeBeam::residualSizing ");
     828            9 :                     this->mDotSystemAir = airFlow;
     829            9 :                     this->vDotDesignPrimAir = this->mDotSystemAir / state.dataEnvrn->StdRhoAir;
     830            9 :                     this->totBeamLength = this->vDotDesignPrimAir / this->vDotNormRatedPrimAir;
     831            9 :                     if (this->vDotDesignCWWasAutosized) {
     832            9 :                         this->vDotDesignCW = this->vDotNormRatedCW * this->totBeamLength;
     833              :                         Real64 const rho =
     834            9 :                             state.dataPlnt->PlantLoop(this->cWplantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
     835            9 :                         this->mDotNormRatedCW = this->vDotNormRatedCW * rho;
     836            9 :                         this->mDotCW = this->vDotDesignCW * rho;
     837            9 :                         if (this->beamCoolingPresent) {
     838            9 :                             PlantUtilities::InitComponentNodes(state, 0.0, this->mDotCW, this->cWInNodeNum, this->cWOutNodeNum);
     839              :                         }
     840              :                     }
     841            9 :                     if (vDotDesignHWWasAutosized) {
     842            9 :                         this->vDotDesignHW = this->vDotNormRatedHW * this->totBeamLength;
     843              :                         Real64 const rho =
     844            9 :                             state.dataPlnt->PlantLoop(this->hWplantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, routineName);
     845            9 :                         this->mDotNormRatedHW = this->vDotNormRatedHW * rho;
     846            9 :                         this->mDotHW = this->vDotDesignHW * rho;
     847            9 :                         if (this->beamHeatingPresent) {
     848            9 :                             PlantUtilities::InitComponentNodes(state, 0.0, this->mDotHW, this->hWInNodeNum, this->hWOutNodeNum);
     849              :                         }
     850              :                     }
     851            9 :                     this->calc(state);
     852            9 :                     if (this->qDotZoneReq != 0.0) {
     853            9 :                         return ((this->qDotZoneReq - this->qDotTotalDelivered) / this->qDotZoneReq);
     854              :                     } else {
     855            0 :                         return 1.0;
     856              :                     }
     857            3 :                 };
     858            3 :                 int SolFlag = 0;
     859            3 :                 General::SolveRoot(state, ErrTolerance, 50, SolFlag, mDotAirSolutionCooling, f, minFlow, maxFlowCool);
     860            3 :                 if (SolFlag == -1) {
     861            0 :                     ShowWarningError(state, format("Cooling load sizing search failed in four pipe beam unit called {}", this->name));
     862            0 :                     ShowContinueError(state, "  Iteration limit exceeded in calculating size for design cooling load");
     863            3 :                 } else if (SolFlag == -2) {
     864            0 :                     ShowWarningError(state, format("Cooling load sizing search failed in four pipe beam unit called {}", this->name));
     865            0 :                     ShowContinueError(state, "  Bad size limits");
     866              :                 }
     867              :             }
     868              : 
     869            3 :             if (beamHeatingPresent) {
     870            3 :                 cpAir = PsyCpAirFnW(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInHumRatTU);
     871            3 :                 Real64 maxFlowHeat = 0.0;
     872            3 :                 if ((state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInTempTU -
     873            3 :                      state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtHeatPeak) >
     874              :                     2.0) { // avoid div by zero and blow up
     875            0 :                     maxFlowHeat = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatLoad /
     876            0 :                                   (cpAir * (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInTempTU -
     877            0 :                                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtHeatPeak));
     878              :                 } else {
     879            3 :                     maxFlowHeat = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatLoad / (cpAir * 2.0);
     880              :                 }
     881              : 
     882            3 :                 int pltSizHeatNum = MyPlantSizingIndex(state, "four pipe beam unit", this->name, this->hWInNodeNum, this->hWOutNodeNum, ErrorsFound);
     883            3 :                 if (pltSizHeatNum == 0) {
     884            0 :                     ShowSevereError(state, "Autosizing of water flow requires a heating loop Sizing:Plant object");
     885            0 :                     ShowContinueError(state, format("Occurs in {} Object={}", this->unitType, this->name));
     886            0 :                     ErrorsFound = true;
     887              :                 } else {
     888            3 :                     this->hWTempIn = state.dataSize->PlantSizData(pltSizHeatNum).ExitTemp;
     889              :                 }
     890            3 :                 this->mDotCW = 0.0;
     891            3 :                 this->tDBZoneAirTemp = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtHeatPeak;
     892            3 :                 this->tDBSystemAir = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInTempTU;
     893            3 :                 this->cpZoneAir = PsyCpAirFnW(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneHumRatAtHeatPeak);
     894            3 :                 this->cpSystemAir = PsyCpAirFnW(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInHumRatTU);
     895            3 :                 this->qDotZoneReq = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatLoad;
     896            3 :                 this->qDotZoneToHeatSetPt = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatLoad;
     897            3 :                 this->airAvailable = true;
     898            3 :                 this->heatingAvailable = true;
     899            3 :                 this->coolingAvailable = false;
     900            9 :                 auto f = [&state, this](Real64 const airFlow) {
     901              :                     static constexpr std::string_view routineName("Real64 HVACFourPipeBeam::residualSizing ");
     902            9 :                     this->mDotSystemAir = airFlow;
     903            9 :                     this->vDotDesignPrimAir = this->mDotSystemAir / state.dataEnvrn->StdRhoAir;
     904            9 :                     this->totBeamLength = this->vDotDesignPrimAir / this->vDotNormRatedPrimAir;
     905            9 :                     if (this->vDotDesignCWWasAutosized) {
     906            9 :                         this->vDotDesignCW = this->vDotNormRatedCW * this->totBeamLength;
     907              :                         Real64 const rho =
     908            9 :                             state.dataPlnt->PlantLoop(this->cWplantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
     909            9 :                         this->mDotNormRatedCW = this->vDotNormRatedCW * rho;
     910            9 :                         this->mDotCW = this->vDotDesignCW * rho;
     911            9 :                         if (this->beamCoolingPresent) {
     912            9 :                             PlantUtilities::InitComponentNodes(state, 0.0, this->mDotCW, this->cWInNodeNum, this->cWOutNodeNum);
     913              :                         }
     914              :                     }
     915            9 :                     if (vDotDesignHWWasAutosized) {
     916            9 :                         this->vDotDesignHW = this->vDotNormRatedHW * this->totBeamLength;
     917              :                         Real64 const rho =
     918            9 :                             state.dataPlnt->PlantLoop(this->hWplantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, routineName);
     919            9 :                         this->mDotNormRatedHW = this->vDotNormRatedHW * rho;
     920            9 :                         this->mDotHW = this->vDotDesignHW * rho;
     921            9 :                         if (this->beamHeatingPresent) {
     922            9 :                             PlantUtilities::InitComponentNodes(state, 0.0, this->mDotHW, this->hWInNodeNum, this->hWOutNodeNum);
     923              :                         }
     924              :                     }
     925            9 :                     this->calc(state);
     926            9 :                     if (this->qDotZoneReq != 0.0) {
     927            9 :                         return ((this->qDotZoneReq - this->qDotTotalDelivered) / this->qDotZoneReq);
     928              :                     } else {
     929            0 :                         return 1.0;
     930              :                     }
     931            3 :                 };
     932            3 :                 int SolFlag = 0;
     933            3 :                 General::SolveRoot(state, ErrTolerance, 50, SolFlag, mDotAirSolutionHeating, f, 0.0, maxFlowHeat);
     934            3 :                 if (SolFlag == -1) {
     935            0 :                     ShowWarningError(state, format("Heating load sizing search failed in four pipe beam unit called {}", this->name));
     936            0 :                     ShowContinueError(state, "  Iteration limit exceeded in calculating size for design heating load");
     937            3 :                 } else if (SolFlag == -2) {
     938            0 :                     ShowWarningError(state, format("Heating load sizing search failed in four pipe beam unit called {}", this->name));
     939            0 :                     ShowContinueError(state, "  Bad size limits");
     940              :                 }
     941              :             }
     942              : 
     943              :             // take the larger of heating and cooling
     944            3 :             this->mDotDesignPrimAir = std::max(mDotAirSolutionHeating, mDotAirSolutionCooling);
     945              :             // make sure this is higher than the zone OA requirement
     946            3 :             this->mDotDesignPrimAir =
     947            6 :                 std::max(this->mDotDesignPrimAir,
     948            3 :                          state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).MinOA * state.dataEnvrn->StdRhoAir);
     949            3 :             this->vDotDesignPrimAir = this->mDotDesignPrimAir / state.dataEnvrn->StdRhoAir;
     950            3 :             this->totBeamLength = this->vDotDesignPrimAir / this->vDotNormRatedPrimAir;
     951            3 :             if (this->vDotDesignCWWasAutosized) {
     952            3 :                 this->vDotDesignCW = this->vDotNormRatedCW * this->totBeamLength;
     953              :             }
     954            3 :             if (vDotDesignHWWasAutosized) {
     955            3 :                 this->vDotDesignHW = this->vDotNormRatedHW * this->totBeamLength;
     956              :             }
     957              :         }
     958              :         // fill in mass flow rate versions of working variables (regardless of autosizing )
     959            3 :         this->mDotDesignPrimAir = this->vDotDesignPrimAir * state.dataEnvrn->StdRhoAir;
     960              : 
     961            3 :         if ((originalTermUnitSizeMaxVDot > 0.0) && (originalTermUnitSizeMaxVDot != this->vDotDesignPrimAir) && (state.dataSize->CurZoneEqNum > 0)) {
     962            3 :             if ((state.dataSize->SysSizingRunDone) && (this->airLoopNum > 0)) {
     963              :                 // perturb system size to handle change in system size calculated without knowing about 4 pipe beam
     964              :                 // Note that this approach is not necessarily appropriate for coincident system design option
     965              :                 // and it might be moved to make such adjustments in SizingManager::ManageSystemSizingAdjustments()
     966            2 :                 state.dataSize->FinalSysSizing(this->airLoopNum).DesMainVolFlow += (this->vDotDesignPrimAir - originalTermUnitSizeMaxVDot);
     967            2 :                 state.dataSize->FinalSysSizing(this->airLoopNum).DesCoolVolFlow += (this->vDotDesignPrimAir - originalTermUnitSizeCoolVDot);
     968            2 :                 state.dataSize->FinalSysSizing(this->airLoopNum).DesHeatVolFlow += (this->vDotDesignPrimAir - originalTermUnitSizeHeatVDot);
     969            2 :                 state.dataSize->FinalSysSizing(this->airLoopNum).MassFlowAtCoolPeak +=
     970            2 :                     (this->vDotDesignPrimAir - originalTermUnitSizeCoolVDot) * state.dataEnvrn->StdRhoAir;
     971              : 
     972            4 :                 BaseSizer::reportSizerOutput(state,
     973              :                                              this->unitType,
     974              :                                              this->name,
     975              :                                              "AirLoopHVAC Design Supply Air Flow Rate Adjustment [m3/s]",
     976            2 :                                              (this->vDotDesignPrimAir - originalTermUnitSizeMaxVDot));
     977              :             } else {
     978            2 :                 ShowSevereError(state, "Four pipe beam requires system sizing. Turn on system sizing.");
     979            3 :                 ShowFatalError(state, "Program terminating due to previous errors");
     980              :             }
     981              :         }
     982              : 
     983            2 :         if (this->beamCoolingPresent) {
     984            2 :             rho = state.dataPlnt->PlantLoop(this->cWplantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
     985            2 :             this->mDotNormRatedCW = this->vDotNormRatedCW * rho;
     986            2 :             this->mDotDesignCW = this->vDotDesignCW * rho;
     987            2 :             PlantUtilities::InitComponentNodes(state, 0.0, this->mDotDesignCW, this->cWInNodeNum, this->cWOutNodeNum);
     988              :         }
     989            2 :         if (this->beamHeatingPresent) {
     990            2 :             rho = state.dataPlnt->PlantLoop(this->hWplantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, routineName);
     991            2 :             this->mDotNormRatedHW = this->vDotNormRatedHW * rho;
     992            2 :             this->mDotDesignHW = this->vDotDesignHW * rho;
     993            2 :             PlantUtilities::InitComponentNodes(state, 0.0, this->mDotDesignHW, this->hWInNodeNum, this->hWOutNodeNum);
     994              :         }
     995              : 
     996              :         // report final sizes if autosized
     997            2 :         if (this->vDotDesignPrimAirWasAutosized) {
     998            2 :             BaseSizer::reportSizerOutput(state, this->unitType, this->name, "Supply Air Flow Rate [m3/s]", this->vDotDesignPrimAir);
     999              :         }
    1000            2 :         if (this->vDotDesignCWWasAutosized) {
    1001            2 :             BaseSizer::reportSizerOutput(state, this->unitType, this->name, "Maximum Total Chilled Water Flow Rate [m3/s]", this->vDotDesignCW);
    1002              :         }
    1003            2 :         if (this->vDotDesignHWWasAutosized) {
    1004            2 :             BaseSizer::reportSizerOutput(state, this->unitType, this->name, "Maximum Total Hot Water Flow Rate [m3/s]", this->vDotDesignHW);
    1005              :         }
    1006            2 :         if (this->totBeamLengthWasAutosized) {
    1007            2 :             BaseSizer::reportSizerOutput(state, this->unitType, this->name, "Zone Total Beam Length [m]", this->totBeamLength);
    1008              :         }
    1009              :         // save the design water volume flow rate for use by the water loop sizing algorithms
    1010            2 :         if (this->vDotDesignCW > 0.0 && this->beamCoolingPresent) {
    1011            2 :             RegisterPlantCompDesignFlow(state, this->cWInNodeNum, this->vDotDesignCW);
    1012              :         }
    1013            2 :         if (this->vDotDesignHW > 0.0 && this->beamHeatingPresent) {
    1014            2 :             RegisterPlantCompDesignFlow(state, this->hWInNodeNum, this->vDotDesignHW);
    1015              :         }
    1016            2 :         if (ErrorsFound) {
    1017            0 :             ShowFatalError(state, "Preceding four pipe beam sizing errors cause program termination");
    1018              :         }
    1019              : 
    1020            2 :     } // set_size
    1021              : 
    1022           33 :     void HVACFourPipeBeam::control(EnergyPlusData &state,
    1023              :                                    [[maybe_unused]] bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
    1024              :                                    Real64 &NonAirSysOutput                         // convective cooling by the beam system [W]
    1025              :     )
    1026              :     {
    1027              : 
    1028              :         // Using/Aliasing
    1029              :         using namespace DataZoneEnergyDemands;
    1030              :         using PlantUtilities::SetComponentFlowRate;
    1031              :         using namespace std::placeholders;
    1032              : 
    1033              :         int SolFlag;
    1034              :         Real64 ErrTolerance;
    1035              : 
    1036           33 :         NonAirSysOutput = 0.0; // initialize
    1037              : 
    1038           33 :         if (this->mDotSystemAir < HVAC::VerySmallMassFlow ||
    1039           31 :             (!this->airAvailable && !this->coolingAvailable && !this->heatingAvailable)) { // unit is off
    1040            2 :             this->mDotHW = 0.0;
    1041            2 :             if (this->beamHeatingPresent) {
    1042            2 :                 SetComponentFlowRate(state, this->mDotHW, this->hWInNodeNum, this->hWOutNodeNum, this->hWplantLoc);
    1043              :             }
    1044            2 :             this->hWTempOut = this->hWTempIn;
    1045              :             // assume if there is still flow that unit has an internal bypass and convector does not still heat
    1046            2 :             this->mDotCW = 0.0;
    1047            2 :             this->cWTempOut = this->cWTempIn;
    1048            2 :             if (this->beamCoolingPresent) {
    1049            2 :                 SetComponentFlowRate(state, this->mDotCW, this->cWInNodeNum, this->cWOutNodeNum, this->cWplantLoc);
    1050              :             }
    1051              :             // assume if there is still flow that unit has an internal bypass and convector does not still cool
    1052              :             // don't even need to run calc
    1053            2 :             return;
    1054              :         }
    1055              : 
    1056           31 :         if (this->airAvailable && this->mDotSystemAir > HVAC::VerySmallMassFlow && !this->coolingAvailable && !this->heatingAvailable) {
    1057            0 :             this->mDotHW = 0.0;
    1058            0 :             if (this->beamHeatingPresent) {
    1059            0 :                 SetComponentFlowRate(state, this->mDotHW, this->hWInNodeNum, this->hWOutNodeNum, this->hWplantLoc);
    1060              :             }
    1061              :             // assume if there is still flow that unit has an internal bypass and convector does not still heat
    1062            0 :             this->hWTempOut = this->hWTempIn;
    1063            0 :             this->mDotCW = 0.0;
    1064            0 :             if (this->beamCoolingPresent) {
    1065            0 :                 SetComponentFlowRate(state, this->mDotCW, this->cWInNodeNum, this->cWOutNodeNum, this->cWplantLoc);
    1066              :             }
    1067              :             // assume if there is still flow that unit has an internal bypass and convector does not still cool
    1068            0 :             this->cWTempOut = this->cWTempIn;
    1069            0 :             this->calc(state);
    1070              : 
    1071            0 :             return;
    1072              :         }
    1073              : 
    1074              :         // get zone loads
    1075           31 :         this->qDotZoneReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->zoneIndex).RemainingOutputRequired;
    1076           31 :         this->qDotZoneToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->zoneIndex).RemainingOutputReqToHeatSP;
    1077           31 :         this->qDotZoneToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->zoneIndex).RemainingOutputReqToCoolSP;
    1078              : 
    1079              :         // decide if beam is in heating or cooling
    1080              : 
    1081           31 :         this->qDotSystemAir = this->mDotSystemAir * ((this->cpSystemAir * this->tDBSystemAir) - (this->cpZoneAir * this->tDBZoneAirTemp));
    1082              : 
    1083           31 :         this->qDotBeamReq = this->qDotZoneReq - this->qDotSystemAir;
    1084              : 
    1085           31 :         if (this->qDotBeamReq < -HVAC::SmallLoad && this->coolingAvailable) { // beam cooling needed
    1086              :             // first calc with max chilled water flow
    1087           10 :             this->mDotHW = 0.0;
    1088           10 :             if (this->beamHeatingPresent) {
    1089           10 :                 SetComponentFlowRate(state, this->mDotHW, this->hWInNodeNum, this->hWOutNodeNum, this->hWplantLoc);
    1090              :             }
    1091           10 :             this->hWTempOut = this->hWTempIn;
    1092           10 :             this->mDotCW = this->mDotDesignCW;
    1093           10 :             this->calc(state);
    1094           10 :             if (this->qDotBeamCooling < (qDotBeamReq - HVAC::SmallLoad)) {
    1095              :                 // can overcool, modulate chilled water flow rate to meet load
    1096            8 :                 this->qDotBeamCoolingMax = this->qDotBeamCooling;
    1097            8 :                 ErrTolerance = 0.01;
    1098           28 :                 auto f = [&state, this](Real64 const cWFlow) {
    1099           28 :                     this->mDotHW = 0.0;
    1100           28 :                     this->mDotCW = cWFlow;
    1101           28 :                     this->calc(state);
    1102           28 :                     if (this->qDotBeamCoolingMax != 0.0) {
    1103           28 :                         return (((this->qDotZoneToCoolSetPt - this->qDotSystemAir) - this->qDotBeamCooling) / this->qDotBeamCoolingMax);
    1104              :                     } else {
    1105            0 :                         return 1.0;
    1106              :                     }
    1107            8 :                 };
    1108            8 :                 General::SolveRoot(state, ErrTolerance, 50, SolFlag, this->mDotCW, f, 0.0, this->mDotDesignCW);
    1109            8 :                 if (SolFlag == -1) {
    1110              :                     // ShowWarningError( "Cold water control failed in four pipe beam unit called " + this->name );
    1111              :                     // ShowContinueError(state,  "  Iteration limit exceeded in calculating cold water mass flow rate" );
    1112            8 :                 } else if (SolFlag == -2) {
    1113              :                     // ShowWarningError( "Cold water control failed in four pipe beam unit called " + this->name );
    1114              :                     // ShowContinueError(state,  "  Bad cold water flow limits" );
    1115              :                 }
    1116            8 :                 this->calc(state);
    1117            8 :                 NonAirSysOutput = this->qDotBeamCooling;
    1118            8 :                 return;
    1119              :             } else { // can run flat out without overcooling, which we just did
    1120            2 :                 NonAirSysOutput = this->qDotBeamCooling;
    1121            2 :                 return;
    1122              :             }
    1123              : 
    1124           21 :         } else if (qDotBeamReq > HVAC::SmallLoad && this->heatingAvailable) { // beam heating needed
    1125              :             // first calc with max hot water flow
    1126           19 :             this->mDotCW = 0.0;
    1127           19 :             if (this->beamCoolingPresent) {
    1128           19 :                 SetComponentFlowRate(state, this->mDotCW, this->cWInNodeNum, this->cWOutNodeNum, this->cWplantLoc);
    1129              :             }
    1130           19 :             this->cWTempOut = this->cWTempIn;
    1131           19 :             this->mDotHW = this->mDotDesignHW;
    1132           19 :             this->calc(state);
    1133           19 :             if (this->qDotBeamHeating > (qDotBeamReq + HVAC::SmallLoad)) {
    1134           15 :                 this->qDotBeamHeatingMax = this->qDotBeamHeating;
    1135              :                 // can overheat, modulate hot water flow to meet load
    1136           15 :                 ErrTolerance = 0.01;
    1137           54 :                 auto f = [&state, this](Real64 const hWFlow) {
    1138           54 :                     this->mDotHW = hWFlow;
    1139           54 :                     this->mDotCW = 0.0;
    1140           54 :                     this->calc(state);
    1141           54 :                     if (this->qDotBeamHeatingMax != 0.0) {
    1142           54 :                         return (((this->qDotZoneToHeatSetPt - this->qDotSystemAir) - this->qDotBeamHeating) / this->qDotBeamHeatingMax);
    1143              :                     } else {
    1144            0 :                         return 1.0;
    1145              :                     }
    1146           15 :                 };
    1147           15 :                 General::SolveRoot(state, ErrTolerance, 50, SolFlag, this->mDotHW, f, 0.0, this->mDotDesignHW);
    1148           15 :                 if (SolFlag == -1) {
    1149              :                     // ShowWarningError( "Hot water control failed in four pipe beam unit called " + this->name );
    1150              :                     // ShowContinueError(state,  "  Iteration limit exceeded in calculating hot water mass flow rate" );
    1151           15 :                 } else if (SolFlag == -2) {
    1152              :                     // ShowWarningError( "Hot water control failed in four pipe beam called " + this->name );
    1153              :                     // ShowContinueError(state,  "  Bad hot water flow limits" );
    1154              :                 }
    1155           15 :                 this->calc(state);
    1156           15 :                 NonAirSysOutput = this->qDotBeamHeating;
    1157           15 :                 return;
    1158              : 
    1159              :             } else { // can run flat out without overheating, which we just did
    1160            4 :                 NonAirSysOutput = this->qDotBeamHeating;
    1161            4 :                 return;
    1162              :             }
    1163              : 
    1164              :         } else {
    1165            2 :             this->mDotHW = 0.0;
    1166            2 :             if (this->beamHeatingPresent) {
    1167            2 :                 SetComponentFlowRate(state, this->mDotHW, this->hWInNodeNum, this->hWOutNodeNum, this->hWplantLoc);
    1168              :             }
    1169            2 :             this->hWTempOut = this->hWTempIn;
    1170              :             // assume if there is still flow that unit has an internal bypass and convector does not still heat
    1171            2 :             this->mDotCW = 0.0;
    1172            2 :             this->cWTempOut = this->cWTempIn;
    1173            2 :             if (this->beamCoolingPresent) {
    1174            2 :                 SetComponentFlowRate(state, this->mDotCW, this->cWInNodeNum, this->cWOutNodeNum, this->cWplantLoc);
    1175              :             }
    1176              :             // assume if there is still flow that unit has an internal bypass and convector does not still cool
    1177              :             // don't even need to run calc
    1178            2 :             return;
    1179              :         }
    1180              :     }
    1181              : 
    1182          152 :     void HVACFourPipeBeam::calc(EnergyPlusData &state)
    1183              :     {
    1184              : 
    1185              :         // Using/Aliasing
    1186              :         using PlantUtilities::SetComponentFlowRate;
    1187              : 
    1188              :         // Locals
    1189              :         // SUBROUTINE ARGUMENT DEFINITIONS:
    1190              : 
    1191              :         // SUBROUTINE PARAMETER DEFINITIONS:
    1192              :         static constexpr std::string_view routineName("HVACFourPipeBeam::calc ");
    1193              : 
    1194              :         // INTERFACE BLOCK SPECIFICATIONS
    1195              :         // na
    1196              : 
    1197              :         // DERIVED TYPE DEFINITIONS
    1198              :         // na
    1199              : 
    1200              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1201              :         Real64 fModCoolCWMdot;  // Cooling capacity modification factor function of chilled water flow rate
    1202              :         Real64 fModCoolDeltaT;  // Cooling capacity modification factor function of air-water temperature difference
    1203              :         Real64 fModCoolAirMdot; // Cooling capacity modification factor function of primary air flow rate
    1204              :         Real64 fModHeatHWMdot;  // Heating capacity modification factor function of hot water flow rate
    1205              :         Real64 fModHeatDeltaT;  // Heating capacity modification factor function of water - air temperature difference
    1206              :         Real64 fModHeatAirMdot; // Heating capacity modification factor function of primary air flow rate
    1207              :         Real64 cp;              // local fluid specific heat
    1208              : 
    1209          152 :         this->qDotBeamHeating = 0.0;
    1210          152 :         this->qDotBeamCooling = 0.0;
    1211          152 :         this->qDotSystemAir = this->mDotSystemAir * ((this->cpSystemAir * this->tDBSystemAir) - (this->cpZoneAir * this->tDBZoneAirTemp));
    1212              : 
    1213          152 :         if (this->coolingAvailable && this->mDotCW > HVAC::VerySmallMassFlow) {
    1214              :             // test chilled water flow against plant, it might not all be available
    1215           41 :             SetComponentFlowRate(state, this->mDotCW, this->cWInNodeNum, this->cWOutNodeNum, this->cWplantLoc);
    1216              :             fModCoolCWMdot =
    1217           41 :                 Curve::CurveValue(state, this->modCoolingQdotCWFlowFuncNum, ((this->mDotCW / this->totBeamLength) / this->mDotNormRatedCW));
    1218              :             fModCoolDeltaT =
    1219           41 :                 Curve::CurveValue(state, this->modCoolingQdotDeltaTFuncNum, ((this->tDBZoneAirTemp - this->cWTempIn) / this->deltaTempRatedCooling));
    1220           82 :             fModCoolAirMdot = Curve::CurveValue(
    1221           41 :                 state, this->modCoolingQdotAirFlowFuncNum, ((this->mDotSystemAir / this->totBeamLength) / this->mDotNormRatedPrimAir));
    1222           41 :             this->qDotBeamCooling = -1.0 * this->qDotNormRatedCooling * fModCoolDeltaT * fModCoolAirMdot * fModCoolCWMdot * this->totBeamLength;
    1223           41 :             cp = state.dataPlnt->PlantLoop(this->cWplantLoc.loopNum).glycol->getSpecificHeat(state, this->cWTempIn, routineName);
    1224           41 :             if (this->mDotCW > 0.0) {
    1225           39 :                 this->cWTempOut = this->cWTempIn - (this->qDotBeamCooling / (this->mDotCW * cp));
    1226              :             } else {
    1227            2 :                 this->cWTempOut = this->cWTempIn;
    1228              :             }
    1229              :             // check if non physical temperature rise, can't be warmer than air
    1230           41 :             if (this->cWTempOut > (std::max(this->tDBSystemAir, this->tDBZoneAirTemp) - 1.0)) {
    1231              :                 // throw recurring warning as this indicates a problem in beam model input
    1232            0 :                 ShowRecurringWarningErrorAtEnd(state,
    1233            0 :                                                std::string{routineName} + " four pipe beam name " + this->name +
    1234              :                                                    ", chilled water outlet temperature is too warm. Capacity was limited. check beam capacity input ",
    1235            0 :                                                this->cWTempOutErrorCount,
    1236            0 :                                                this->cWTempOut,
    1237            0 :                                                this->cWTempOut);
    1238              :                 //  restrict it within 1.0 C of warmest air and recalculate cooling
    1239            0 :                 this->cWTempOut = (std::max(this->tDBSystemAir, this->tDBZoneAirTemp) - 1.0);
    1240            0 :                 this->qDotBeamCooling = this->mDotCW * cp * (this->cWTempIn - this->cWTempOut);
    1241              :             }
    1242              :         } else {
    1243          111 :             this->mDotCW = 0.0;
    1244          111 :             if (this->beamCoolingPresent) {
    1245          111 :                 SetComponentFlowRate(state, this->mDotCW, this->cWInNodeNum, this->cWOutNodeNum, this->cWplantLoc);
    1246              :             }
    1247          111 :             this->cWTempOut = this->cWTempIn;
    1248          111 :             this->qDotBeamCooling = 0.0;
    1249              :         }
    1250          152 :         if (this->heatingAvailable && this->mDotHW > HVAC::VerySmallMassFlow) {
    1251              :             // test hot water flow against plant, it might not all be available
    1252           71 :             SetComponentFlowRate(state, this->mDotHW, this->hWInNodeNum, this->hWOutNodeNum, this->hWplantLoc);
    1253              :             fModHeatHWMdot =
    1254           71 :                 Curve::CurveValue(state, this->modHeatingQdotHWFlowFuncNum, ((this->mDotHW / this->totBeamLength) / this->mDotNormRatedHW));
    1255              :             fModHeatDeltaT =
    1256           71 :                 Curve::CurveValue(state, this->modHeatingQdotDeltaTFuncNum, ((this->hWTempIn - this->tDBZoneAirTemp) / this->deltaTempRatedHeating));
    1257          142 :             fModHeatAirMdot = Curve::CurveValue(
    1258           71 :                 state, this->modHeatingQdotAirFlowFuncNum, ((this->mDotSystemAir / this->totBeamLength) / this->mDotNormRatedPrimAir));
    1259           71 :             this->qDotBeamHeating = this->qDotNormRatedHeating * fModHeatDeltaT * fModHeatAirMdot * fModHeatHWMdot * this->totBeamLength;
    1260           71 :             cp = state.dataPlnt->PlantLoop(this->hWplantLoc.loopNum).glycol->getSpecificHeat(state, this->hWTempIn, routineName);
    1261           71 :             if (this->mDotHW > 0.0) {
    1262           67 :                 this->hWTempOut = this->hWTempIn - (this->qDotBeamHeating / (this->mDotHW * cp));
    1263              :             } else {
    1264            4 :                 this->hWTempOut = this->hWTempIn;
    1265              :             }
    1266              :             // check if non physical temperature drop, can't be cooler than air
    1267           71 :             if (this->hWTempOut < (std::min(this->tDBSystemAir, this->tDBZoneAirTemp) + 1.0)) {
    1268              :                 // throw recurring warning as this indicates a problem in beam model input
    1269            0 :                 ShowRecurringWarningErrorAtEnd(state,
    1270            0 :                                                std::string{routineName} + " four pipe beam name " + this->name +
    1271              :                                                    ", hot water outlet temperature is too cool. Capacity was limited. check beam capacity input ",
    1272            0 :                                                this->hWTempOutErrorCount,
    1273            0 :                                                this->hWTempOut,
    1274            0 :                                                this->hWTempOut);
    1275              :                 //  restrict it within 1.0 C of warmest air and recalculate cooling
    1276            0 :                 this->hWTempOut = (std::min(this->tDBSystemAir, this->tDBZoneAirTemp) + 1.0);
    1277            0 :                 this->qDotBeamHeating = this->mDotHW * cp * (this->hWTempIn - this->hWTempOut);
    1278              :             }
    1279              :         } else {
    1280           81 :             this->mDotHW = 0.0;
    1281           81 :             if (this->beamHeatingPresent) {
    1282           81 :                 SetComponentFlowRate(state, this->mDotHW, this->hWInNodeNum, this->hWOutNodeNum, this->hWplantLoc);
    1283              :             }
    1284           81 :             this->hWTempOut = this->hWTempIn;
    1285           81 :             this->qDotBeamHeating = 0.0;
    1286              :         }
    1287              : 
    1288          152 :         this->qDotTotalDelivered = this->qDotSystemAir + this->qDotBeamCooling + this->qDotBeamHeating;
    1289          152 :     }
    1290              : 
    1291           33 :     void HVACFourPipeBeam::update(EnergyPlusData &state) const // update node date elsewhere in EnergyPlus, does not change state of this
    1292              :     {
    1293           33 :         auto &Node(state.dataLoopNodes->Node);
    1294              : 
    1295              :         using PlantUtilities::SafeCopyPlantNode;
    1296              : 
    1297              :         // Set the outlet air nodes of the unit; note that all quantities are unchanged from inlet to outlet
    1298           33 :         Node(this->airOutNodeNum).MassFlowRate = Node(this->airInNodeNum).MassFlowRate;
    1299           33 :         Node(this->airOutNodeNum).Temp = Node(this->airInNodeNum).Temp;
    1300           33 :         Node(this->airOutNodeNum).HumRat = Node(this->airInNodeNum).HumRat;
    1301           33 :         Node(this->airOutNodeNum).Enthalpy = Node(this->airInNodeNum).Enthalpy;
    1302           33 :         Node(this->airOutNodeNum).Quality = Node(this->airInNodeNum).Quality;
    1303           33 :         Node(this->airOutNodeNum).Press = Node(this->airInNodeNum).Press;
    1304           33 :         Node(this->airOutNodeNum).MassFlowRateMin = Node(this->airInNodeNum).MassFlowRateMin;
    1305           33 :         Node(this->airOutNodeNum).MassFlowRateMax = Node(this->airInNodeNum).MassFlowRateMax;
    1306           33 :         Node(this->airOutNodeNum).MassFlowRateMinAvail = Node(this->airInNodeNum).MassFlowRateMinAvail;
    1307           33 :         Node(this->airOutNodeNum).MassFlowRateMaxAvail = Node(this->airInNodeNum).MassFlowRateMaxAvail;
    1308              : 
    1309           33 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    1310            0 :             Node(this->airOutNodeNum).CO2 = Node(this->airInNodeNum).CO2;
    1311              :         }
    1312              : 
    1313           33 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    1314            0 :             Node(this->airOutNodeNum).GenContam = Node(this->airInNodeNum).GenContam;
    1315              :         }
    1316              : 
    1317              :         // Set the outlet water nodes for the unit
    1318              : 
    1319           33 :         if (this->beamCoolingPresent) {
    1320           33 :             SafeCopyPlantNode(state, this->cWInNodeNum, this->cWOutNodeNum);
    1321           33 :             Node(this->cWOutNodeNum).Temp = this->cWTempOut;
    1322              :         }
    1323           33 :         if (this->beamHeatingPresent) {
    1324           33 :             SafeCopyPlantNode(state, this->hWInNodeNum, this->hWOutNodeNum);
    1325           33 :             Node(this->hWOutNodeNum).Temp = this->hWTempOut;
    1326              :         }
    1327           33 :     }
    1328              : 
    1329           33 :     void HVACFourPipeBeam::report(EnergyPlusData &state) // fill out local output variables for reporting
    1330              :     {
    1331              : 
    1332              :         Real64 ReportingConstant;
    1333              : 
    1334           33 :         ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
    1335              : 
    1336           33 :         if (this->beamCoolingPresent) {
    1337           33 :             this->beamCoolingRate = std::abs(this->qDotBeamCooling); // report var has positive sign convention
    1338           33 :             this->beamCoolingEnergy = this->beamCoolingRate * ReportingConstant;
    1339              :         }
    1340           33 :         if (this->beamHeatingPresent) {
    1341           33 :             this->beamHeatingRate = this->qDotBeamHeating;
    1342           33 :             this->beamHeatingEnergy = this->beamHeatingRate * ReportingConstant;
    1343              :         }
    1344           33 :         if (qDotSystemAir <= 0.0) { // cooling
    1345           20 :             this->supAirCoolingRate = std::abs(this->qDotSystemAir);
    1346           20 :             this->supAirHeatingRate = 0.0;
    1347              :         } else {
    1348           13 :             this->supAirHeatingRate = this->qDotSystemAir;
    1349           13 :             this->supAirCoolingRate = 0.0;
    1350              :         }
    1351           33 :         this->supAirCoolingEnergy = this->supAirCoolingRate * ReportingConstant;
    1352           33 :         this->supAirHeatingEnergy = this->supAirHeatingRate * ReportingConstant;
    1353              : 
    1354           33 :         this->primAirFlow = this->mDotSystemAir / state.dataEnvrn->StdRhoAir;
    1355              : 
    1356           33 :         this->CalcOutdoorAirVolumeFlowRate(state);
    1357           33 :     }
    1358              : 
    1359           33 :     void HVACFourPipeBeam::CalcOutdoorAirVolumeFlowRate(EnergyPlusData &state)
    1360              :     {
    1361              :         // calculates zone outdoor air volume flow rate using the supply air flow rate and OA fraction
    1362           33 :         if (this->airLoopNum > 0) {
    1363           33 :             this->OutdoorAirFlowRate = (state.dataLoopNodes->Node(this->airOutNodeNum).MassFlowRate / state.dataEnvrn->StdRhoAir) *
    1364           33 :                                        state.dataAirLoop->AirLoopFlow(this->airLoopNum).OAFrac;
    1365              :         } else {
    1366            0 :             this->OutdoorAirFlowRate = 0.0;
    1367              :         }
    1368           33 :     }
    1369              : 
    1370            0 :     void HVACFourPipeBeam::reportTerminalUnit(EnergyPlusData &state)
    1371              :     {
    1372              :         // populate the predefined equipment summary report related to air terminals
    1373            0 :         auto &orp = state.dataOutRptPredefined;
    1374            0 :         auto &adu = state.dataDefineEquipment->AirDistUnit(this->aDUNum);
    1375            0 :         if (!state.dataSize->TermUnitFinalZoneSizing.empty()) {
    1376            0 :             auto &sizing = state.dataSize->TermUnitFinalZoneSizing(adu.TermUnitSizingNum);
    1377            0 :             OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinFlow, adu.Name, sizing.DesCoolVolFlowMin);
    1378            0 :             OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinOutdoorFlow, adu.Name, sizing.MinOA);
    1379            0 :             OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermSupCoolingSP, adu.Name, sizing.CoolDesTemp);
    1380            0 :             OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermSupHeatingSP, adu.Name, sizing.HeatDesTemp);
    1381            0 :             OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermHeatingCap, adu.Name, sizing.DesHeatLoad);
    1382            0 :             OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermCoolingCap, adu.Name, sizing.DesCoolLoad);
    1383              :         }
    1384            0 :         OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermTypeInp, adu.Name, "AirTerminal:SingleDuct:ConstantVolume:FourPipeBeam");
    1385            0 :         OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermPrimFlow, adu.Name, this->vDotNormRatedPrimAir);
    1386            0 :         OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermSecdFlow, adu.Name, "n/a");
    1387            0 :         OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinFlowSch, adu.Name, "n/a");
    1388            0 :         OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMaxFlowReh, adu.Name, "n/a");
    1389            0 :         OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinOAflowSch, adu.Name, "n/a");
    1390            0 :         if (this->beamHeatingPresent) {
    1391            0 :             OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermHeatCoilType, adu.Name, "Included");
    1392              :         } else {
    1393            0 :             OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermHeatCoilType, adu.Name, "None");
    1394              :         }
    1395              : 
    1396            0 :         if (this->beamCoolingPresent) {
    1397            0 :             OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermCoolCoilType, adu.Name, "Included");
    1398              :         } else {
    1399            0 :             OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermCoolCoilType, adu.Name, "None");
    1400              :         }
    1401            0 :         OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermFanType, adu.Name, "n/a");
    1402            0 :         OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermFanName, adu.Name, "n/a");
    1403            0 :     }
    1404              : 
    1405              : } // namespace FourPipeBeam
    1406              : 
    1407              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1