LCOV - code coverage report
Current view: top level - EnergyPlus - WaterToAirHeatPump.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 73.4 % 1095 804
Test Date: 2025-06-02 07:23:51 Functions: 92.9 % 14 13

            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              : 
      54              : // EnergyPlus Headers
      55              : #include <EnergyPlus/BranchNodeConnections.hh>
      56              : #include <EnergyPlus/CurveManager.hh>
      57              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      58              : #include <EnergyPlus/DataContaminantBalance.hh>
      59              : #include <EnergyPlus/DataHVACGlobals.hh>
      60              : #include <EnergyPlus/DataLoopNode.hh>
      61              : #include <EnergyPlus/FluidProperties.hh>
      62              : #include <EnergyPlus/General.hh>
      63              : #include <EnergyPlus/GlobalNames.hh>
      64              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      65              : #include <EnergyPlus/NodeInputManager.hh>
      66              : #include <EnergyPlus/OutputProcessor.hh>
      67              : #include <EnergyPlus/OutputReportPredefined.hh>
      68              : #include <EnergyPlus/Plant/DataPlant.hh>
      69              : #include <EnergyPlus/PlantUtilities.hh>
      70              : #include <EnergyPlus/Psychrometrics.hh>
      71              : #include <EnergyPlus/UtilityRoutines.hh>
      72              : #include <EnergyPlus/WaterToAirHeatPump.hh>
      73              : 
      74              : namespace EnergyPlus {
      75              : 
      76              : namespace WaterToAirHeatPump {
      77              :     // Module containing the Water to Air Heat Pump simulation routines
      78              : 
      79              :     // MODULE INFORMATION:
      80              :     //       AUTHOR         Hui Jin
      81              :     //       DATE WRITTEN   Oct 2000
      82              :     //       MODIFIED       Dan Fisher, Kenneth Tang (Jan 2004)
      83              :     //                      Brent Griffith, plant upgrades, fluid props
      84              : 
      85              :     // PURPOSE OF THIS MODULE:
      86              :     // To encapsulate the data and algorithms required to
      87              :     // manage the Water to Air Heat Pump Component
      88              : 
      89              :     // METHODOLOGY EMPLOYED:
      90              : 
      91              :     // REFERENCES:
      92              :     // Jin, H. 2002. Parameter Estimation Based Models of Water Source Heat Pumps. Phd Thesis.
      93              :     // Oklahoma State University.
      94              : 
      95      1891379 :     void SimWatertoAirHP(EnergyPlusData &state,
      96              :                          std::string_view CompName,     // component name
      97              :                          int &CompIndex,                // Index for Component name
      98              :                          Real64 const DesignAirflow,    // design air flow rate
      99              :                          HVAC::FanOp const fanOp,       // cycling scheme--either continuous fan/cycling compressor or
     100              :                          bool const FirstHVACIteration, // first iteration flag
     101              :                          bool const InitFlag,           // initialization flag used to suppress property routine errors
     102              :                          Real64 const SensLoad,         // sensible load
     103              :                          Real64 const LatentLoad,       // latent load
     104              :                          HVAC::CompressorOp const compressorOp,
     105              :                          Real64 const PartLoadRatio)
     106              :     {
     107              : 
     108              :         // SUBROUTINE INFORMATION:
     109              :         //       AUTHOR         Hui Jin
     110              :         //       DATE WRITTEN   Oct 2000
     111              :         //       MODIFIED       Dan Fisher, Kenneth Tang (Jan 2004)
     112              : 
     113              :         // PURPOSE OF THIS SUBROUTINE:
     114              :         // This subroutine manages Water to Air Heat Pump component simulation.
     115              : 
     116              :         // shut off after compressor cycle off  [s]
     117              :         // cycling fan/cycling compressor
     118              : 
     119              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     120              :         int HPNum; // The WatertoAirHP that you are currently loading input into
     121              : 
     122              :         // Obtains and Allocates WatertoAirHP related parameters from input file
     123      1891379 :         if (state.dataWaterToAirHeatPump->GetCoilsInputFlag) { // First time subroutine has been entered
     124            0 :             GetWatertoAirHPInput(state);
     125            0 :             state.dataWaterToAirHeatPump->GetCoilsInputFlag = false;
     126              :         }
     127              : 
     128      1891379 :         if (CompIndex == 0) {
     129            0 :             HPNum = Util::FindItemInList(CompName, state.dataWaterToAirHeatPump->WatertoAirHP);
     130            0 :             if (HPNum == 0) {
     131            0 :                 ShowFatalError(state, format("WaterToAir HP not found={}", CompName));
     132              :             }
     133            0 :             CompIndex = HPNum;
     134              :         } else {
     135      1891379 :             HPNum = CompIndex;
     136      1891379 :             if (HPNum > state.dataWaterToAirHeatPump->NumWatertoAirHPs || HPNum < 1) {
     137            0 :                 ShowFatalError(state,
     138            0 :                                format("SimWatertoAirHP: Invalid CompIndex passed={}, Number of Water to Air HPs={}, WaterToAir HP name={}",
     139              :                                       HPNum,
     140            0 :                                       state.dataWaterToAirHeatPump->NumWatertoAirHPs,
     141              :                                       CompName));
     142              :             }
     143      1891379 :             if (state.dataWaterToAirHeatPump->CheckEquipName(HPNum)) {
     144           38 :                 if (!CompName.empty() && CompName != state.dataWaterToAirHeatPump->WatertoAirHP(HPNum).Name) {
     145            0 :                     ShowFatalError(
     146              :                         state,
     147            0 :                         format("SimWatertoAirHP: Invalid CompIndex passed={}, WaterToAir HP name={}, stored WaterToAir HP Name for that index={}",
     148              :                                HPNum,
     149              :                                CompName,
     150            0 :                                state.dataWaterToAirHeatPump->WatertoAirHP(HPNum).Name));
     151              :                 }
     152           38 :                 state.dataWaterToAirHeatPump->CheckEquipName(HPNum) = false;
     153              :             }
     154              :         }
     155              :         // Calculate the Correct Water to Air HP Model with the current HPNum
     156              : 
     157      1891379 :         if (state.dataWaterToAirHeatPump->WatertoAirHP(HPNum).WAHPType == DataPlant::PlantEquipmentType::CoilWAHPCoolingParamEst) {
     158       945692 :             InitWatertoAirHP(state, HPNum, InitFlag, SensLoad, LatentLoad, DesignAirflow, PartLoadRatio);
     159       945692 :             CalcWatertoAirHPCooling(state, HPNum, fanOp, FirstHVACIteration, InitFlag, SensLoad, compressorOp, PartLoadRatio);
     160              : 
     161       945692 :             UpdateWatertoAirHP(state, HPNum);
     162              : 
     163       945687 :         } else if (state.dataWaterToAirHeatPump->WatertoAirHP(HPNum).WAHPType == DataPlant::PlantEquipmentType::CoilWAHPHeatingParamEst) {
     164       945687 :             InitWatertoAirHP(state, HPNum, InitFlag, SensLoad, LatentLoad, DesignAirflow, PartLoadRatio);
     165       945687 :             CalcWatertoAirHPHeating(state, HPNum, fanOp, FirstHVACIteration, InitFlag, SensLoad, compressorOp, PartLoadRatio);
     166              : 
     167       945687 :             UpdateWatertoAirHP(state, HPNum);
     168              : 
     169              :         } else {
     170            0 :             ShowFatalError(state, "SimWatertoAirHP: AirtoAir heatpump not in either HEATING or COOLING");
     171              :         }
     172      1891379 :     }
     173              : 
     174              :     // Get Input Section of the Module
     175              :     //******************************************************************************
     176              : 
     177            6 :     void GetWatertoAirHPInput(EnergyPlusData &state)
     178              :     {
     179              : 
     180              :         // SUBROUTINE INFORMATION:
     181              :         //       AUTHOR         Hui Jin
     182              :         //       DATE WRITTEN   Oct 2000
     183              :         //       MODIFIED       Dan Fisher, Kenneth Tang (Jan 2004)
     184              : 
     185              :         // PURPOSE OF THIS SUBROUTINE:
     186              :         // Obtains input data for HPs and stores it in HP data structures
     187              : 
     188              :         // METHODOLOGY EMPLOYED:
     189              :         // Uses "Get" routines to read in data.
     190              : 
     191              :         // SUBROUTINE PARAMETER DEFINITIONS:
     192              :         static constexpr std::string_view RoutineName("GetWatertoAirHPInput: "); // include trailing blank space
     193              :         static constexpr std::string_view routineName = "GetWatertoAirHPInput";
     194              : 
     195              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     196              :         int HPNum; // The Water to Air HP that you are currently loading input into
     197              :         int NumCool;
     198              :         int NumHeat;
     199              :         int WatertoAirHPNum;
     200              :         int NumAlphas;
     201              :         int NumParams;
     202              :         int NumNums;
     203            6 :         int MaxNums(0);   // Maximum number of numeric input fields
     204            6 :         int MaxAlphas(0); // Maximum number of alpha input fields
     205              :         int IOStat;
     206            6 :         bool ErrorsFound(false);         // If errors detected in input
     207            6 :         std::string CurrentModuleObject; // for ease in getting objects
     208            6 :         Array1D_string AlphArray;        // Alpha input items for object
     209            6 :         Array1D_string cAlphaFields;     // Alpha field names
     210            6 :         Array1D_string cNumericFields;   // Numeric field names
     211            6 :         Array1D<Real64> NumArray;        // Numeric input items for object
     212            6 :         Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     213            6 :         Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     214              : 
     215            6 :         constexpr std::array<std::string_view, static_cast<int>(CompressorType::Num)> CompressTypeNamesUC{"RECIPROCATING", "ROTARY", "SCROLL"};
     216              : 
     217            6 :         NumCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation");
     218            6 :         NumHeat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:WaterToAirHeatPump:ParameterEstimation");
     219            6 :         state.dataWaterToAirHeatPump->NumWatertoAirHPs = NumCool + NumHeat;
     220            6 :         HPNum = 0;
     221              : 
     222            6 :         if (state.dataWaterToAirHeatPump->NumWatertoAirHPs <= 0) {
     223            0 :             ShowSevereError(state, "No Equipment found in SimWatertoAirHP");
     224            0 :             ErrorsFound = true;
     225              :         }
     226              : 
     227              :         // Allocate Arrays
     228            6 :         if (state.dataWaterToAirHeatPump->NumWatertoAirHPs > 0) {
     229            6 :             state.dataWaterToAirHeatPump->WatertoAirHP.allocate(state.dataWaterToAirHeatPump->NumWatertoAirHPs);
     230            6 :             state.dataWaterToAirHeatPump->CheckEquipName.dimension(state.dataWaterToAirHeatPump->NumWatertoAirHPs, true);
     231              :         }
     232              : 
     233            6 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     234              :             state, "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation", NumParams, NumAlphas, NumNums);
     235            6 :         MaxNums = max(MaxNums, NumNums);
     236            6 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     237            6 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     238              :             state, "Coil:Heating:WaterToAirHeatPump:ParameterEstimation", NumParams, NumAlphas, NumNums);
     239            6 :         MaxNums = max(MaxNums, NumNums);
     240            6 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     241            6 :         AlphArray.allocate(MaxAlphas);
     242            6 :         cAlphaFields.allocate(MaxAlphas);
     243            6 :         lAlphaBlanks.dimension(MaxAlphas, true);
     244            6 :         cNumericFields.allocate(MaxNums);
     245            6 :         lNumericBlanks.dimension(MaxNums, true);
     246            6 :         NumArray.dimension(MaxNums, 0.0);
     247              : 
     248              :         // Get the data for detailed cooling Heat Pump
     249            6 :         CurrentModuleObject = "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation";
     250              : 
     251           25 :         for (WatertoAirHPNum = 1; WatertoAirHPNum <= NumCool; ++WatertoAirHPNum) {
     252              : 
     253           19 :             ++HPNum;
     254              : 
     255           19 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     256              :                                                                      CurrentModuleObject,
     257              :                                                                      HPNum,
     258              :                                                                      AlphArray,
     259              :                                                                      NumAlphas,
     260              :                                                                      NumArray,
     261              :                                                                      NumNums,
     262              :                                                                      IOStat,
     263              :                                                                      lNumericBlanks,
     264              :                                                                      lAlphaBlanks,
     265              :                                                                      cAlphaFields,
     266              :                                                                      cNumericFields);
     267              : 
     268           19 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, AlphArray(1)};
     269              :             // ErrorsFound will be set to True if problem was found, left untouched otherwise
     270           19 :             GlobalNames::VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, CurrentModuleObject + " Name");
     271              : 
     272           19 :             auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
     273              : 
     274           19 :             heatPump.Name = AlphArray(1);
     275           19 :             heatPump.WatertoAirHPType = "COOLING";
     276           19 :             heatPump.WAHPType = DataPlant::PlantEquipmentType::CoilWAHPCoolingParamEst;
     277           19 :             heatPump.Refrigerant = AlphArray(3);
     278           19 :             if (heatPump.Refrigerant.empty()) {
     279            0 :                 ShowSevereEmptyField(state, eoh, cAlphaFields(3));
     280            0 :                 ErrorsFound = true;
     281           19 :             } else if ((heatPump.refrig = Fluid::GetRefrig(state, heatPump.Refrigerant)) == nullptr) {
     282            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(3), AlphArray(3));
     283            0 :                 ErrorsFound = true;
     284              :             }
     285           19 :             heatPump.DesignWaterVolFlowRate = NumArray(1);
     286           19 :             heatPump.CoolingCapacity = NumArray(2);
     287           19 :             heatPump.Twet_Rated = NumArray(3);
     288           19 :             heatPump.Gamma_Rated = NumArray(4);
     289              : 
     290           19 :             heatPump.HighPressCutoff = NumArray(5);
     291           19 :             heatPump.LowPressCutoff = NumArray(6);
     292              : 
     293           19 :             heatPump.WaterInletNodeNum = GetOnlySingleNode(state,
     294           19 :                                                            AlphArray(4),
     295              :                                                            ErrorsFound,
     296              :                                                            DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpParameterEstimation,
     297           19 :                                                            AlphArray(1),
     298              :                                                            DataLoopNode::NodeFluidType::Water,
     299              :                                                            DataLoopNode::ConnectionType::Inlet,
     300              :                                                            NodeInputManager::CompFluidStream::Secondary,
     301              :                                                            DataLoopNode::ObjectIsNotParent);
     302           19 :             heatPump.WaterOutletNodeNum = GetOnlySingleNode(state,
     303           19 :                                                             AlphArray(5),
     304              :                                                             ErrorsFound,
     305              :                                                             DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpParameterEstimation,
     306           19 :                                                             AlphArray(1),
     307              :                                                             DataLoopNode::NodeFluidType::Water,
     308              :                                                             DataLoopNode::ConnectionType::Outlet,
     309              :                                                             NodeInputManager::CompFluidStream::Secondary,
     310              :                                                             DataLoopNode::ObjectIsNotParent);
     311           19 :             heatPump.AirInletNodeNum = GetOnlySingleNode(state,
     312           19 :                                                          AlphArray(6),
     313              :                                                          ErrorsFound,
     314              :                                                          DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpParameterEstimation,
     315           19 :                                                          AlphArray(1),
     316              :                                                          DataLoopNode::NodeFluidType::Air,
     317              :                                                          DataLoopNode::ConnectionType::Inlet,
     318              :                                                          NodeInputManager::CompFluidStream::Primary,
     319              :                                                          DataLoopNode::ObjectIsNotParent);
     320           19 :             heatPump.AirOutletNodeNum = GetOnlySingleNode(state,
     321           19 :                                                           AlphArray(7),
     322              :                                                           ErrorsFound,
     323              :                                                           DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpParameterEstimation,
     324           19 :                                                           AlphArray(1),
     325              :                                                           DataLoopNode::NodeFluidType::Air,
     326              :                                                           DataLoopNode::ConnectionType::Outlet,
     327              :                                                           NodeInputManager::CompFluidStream::Primary,
     328              :                                                           DataLoopNode::ObjectIsNotParent);
     329              : 
     330              :             // 2010-01-13 ESL: Jason Glazer noted that these were out of order previously, but they are good now
     331           19 :             heatPump.LoadSideTotalUACoeff = NumArray(7);
     332           19 :             heatPump.LoadSideOutsideUACoeff = NumArray(8);
     333              : 
     334           19 :             if ((heatPump.LoadSideOutsideUACoeff < Constant::rTinyValue) || (heatPump.LoadSideTotalUACoeff < Constant::rTinyValue)) {
     335            0 :                 ShowSevereError(state, format("Input problem for {}={}", CurrentModuleObject, heatPump.Name));
     336            0 :                 ShowContinueError(state, " One or both load side UA values entered are below tolerance, likely zero or blank.");
     337            0 :                 ShowContinueError(state, " Verify inputs, as the parameter syntax for this object went through a change with");
     338            0 :                 ShowContinueError(state, "  the release of EnergyPlus version 5.");
     339            0 :                 ErrorsFound = true;
     340              :             }
     341              : 
     342           19 :             heatPump.SuperheatTemp = NumArray(9);
     343           19 :             heatPump.PowerLosses = NumArray(10);
     344           19 :             heatPump.LossFactor = NumArray(11);
     345              : 
     346           19 :             heatPump.compressorType = static_cast<CompressorType>(getEnumValue(CompressTypeNamesUC, Util::makeUPPER(AlphArray(2))));
     347              : 
     348           19 :             switch (heatPump.compressorType) {
     349            0 :             case CompressorType::Reciprocating: {
     350            0 :                 heatPump.CompPistonDisp = NumArray(12);
     351            0 :                 heatPump.CompSucPressDrop = NumArray(13);
     352            0 :                 heatPump.CompClearanceFactor = NumArray(14);
     353            0 :                 break;
     354              :             }
     355            0 :             case CompressorType::Rotary: {
     356            0 :                 heatPump.CompPistonDisp = NumArray(12);
     357            0 :                 heatPump.CompSucPressDrop = NumArray(13);
     358            0 :                 break;
     359              :             }
     360           19 :             case CompressorType::Scroll: {
     361           19 :                 heatPump.RefVolFlowRate = NumArray(15);
     362           19 :                 heatPump.VolumeRatio = NumArray(16);
     363           19 :                 heatPump.LeakRateCoeff = NumArray(17);
     364           19 :                 break;
     365              :             }
     366            0 :             default: {
     367            0 :                 ShowSevereError(
     368              :                     state,
     369            0 :                     format("{}Invalid {} ({}) entered. {}={}", RoutineName, cAlphaFields(2), AlphArray(2), CurrentModuleObject, heatPump.Name));
     370            0 :                 ErrorsFound = true;
     371            0 :                 break;
     372              :             }
     373              :             }
     374              : 
     375           19 :             heatPump.SourceSideUACoeff = NumArray(18);
     376           19 :             heatPump.SourceSideHTR1 = NumArray(19);
     377           19 :             heatPump.SourceSideHTR2 = NumArray(20);
     378           19 :             heatPump.PLFCurveIndex = Curve::GetCurveIndex(state, AlphArray(8)); // convert curve name to number
     379              : 
     380           19 :             if (heatPump.PLFCurveIndex == 0) {
     381            0 :                 if (lAlphaBlanks(8)) {
     382            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, heatPump.Name));
     383            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
     384              :                 } else {
     385            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, heatPump.Name));
     386            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), AlphArray(8)));
     387              :                 }
     388            0 :                 ErrorsFound = true;
     389              :             } else {
     390              :                 // Verify Curve Object, only legal types are Quadratic or Cubic
     391           38 :                 ErrorsFound |= Curve::CheckCurveDims(state,
     392              :                                                      heatPump.PLFCurveIndex, // Curve index
     393              :                                                      {1},                    // Valid dimensions
     394              :                                                      RoutineName,            // Routine name
     395              :                                                      CurrentModuleObject,    // Object Type
     396              :                                                      heatPump.Name,          // Object Name
     397           19 :                                                      cAlphaFields(8));       // Field Name
     398              : 
     399           19 :                 if (!ErrorsFound) {
     400              :                     //     Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
     401           19 :                     Real64 MinCurveVal = 999.0;
     402           19 :                     Real64 MaxCurveVal = -999.0;
     403           19 :                     Real64 CurveInput = 0.0;
     404           19 :                     Real64 MinCurvePLR{0.0};
     405           19 :                     Real64 MaxCurvePLR{0.0};
     406              : 
     407         1919 :                     while (CurveInput <= 1.0) {
     408         1900 :                         Real64 CurveVal = Curve::CurveValue(state, heatPump.PLFCurveIndex, CurveInput);
     409         1900 :                         if (CurveVal < MinCurveVal) {
     410           19 :                             MinCurveVal = CurveVal;
     411           19 :                             MinCurvePLR = CurveInput;
     412              :                         }
     413         1900 :                         if (CurveVal > MaxCurveVal) {
     414         1900 :                             MaxCurveVal = CurveVal;
     415         1900 :                             MaxCurvePLR = CurveInput;
     416              :                         }
     417         1900 :                         CurveInput += 0.01;
     418              :                     }
     419           19 :                     if (MinCurveVal < 0.7) {
     420            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, heatPump.Name));
     421            0 :                         ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFields(8), AlphArray(8)));
     422            0 :                         ShowContinueError(state,
     423            0 :                                           format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
     424            0 :                         ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
     425            0 :                         Curve::SetCurveOutputMinValue(state, heatPump.PLFCurveIndex, ErrorsFound, 0.7);
     426              :                     }
     427              : 
     428           19 :                     if (MaxCurveVal > 1.0) {
     429            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, heatPump.Name));
     430            0 :                         ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(8), AlphArray(8)));
     431            0 :                         ShowContinueError(state,
     432            0 :                                           format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
     433            0 :                         ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
     434            0 :                         Curve::SetCurveOutputMaxValue(state, heatPump.PLFCurveIndex, ErrorsFound, 1.0);
     435              :                     }
     436              :                 }
     437              :             }
     438              : 
     439           19 :             heatPump.MaxONOFFCyclesperHour = NumArray(21);
     440           19 :             heatPump.LatentCapacityTimeConstant = NumArray(22);
     441           19 :             heatPump.FanDelayTime = NumArray(23);
     442              : 
     443           38 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(4), AlphArray(5), "Water Nodes");
     444           19 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(6), AlphArray(7), "Air Nodes");
     445              : 
     446              :             // Setup Report variables for the detailed cooling Heat Pump
     447              :             // CurrentModuleObject = "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation"
     448           38 :             SetupOutputVariable(state,
     449              :                                 "Cooling Coil Electricity Energy",
     450              :                                 Constant::Units::J,
     451           19 :                                 heatPump.Energy,
     452              :                                 OutputProcessor::TimeStepType::System,
     453              :                                 OutputProcessor::StoreType::Sum,
     454           19 :                                 heatPump.Name,
     455              :                                 Constant::eResource::Electricity,
     456              :                                 OutputProcessor::Group::HVAC,
     457              :                                 OutputProcessor::EndUseCat::Cooling);
     458           38 :             SetupOutputVariable(state,
     459              :                                 "Cooling Coil Total Cooling Energy",
     460              :                                 Constant::Units::J,
     461           19 :                                 heatPump.EnergyLoadTotal,
     462              :                                 OutputProcessor::TimeStepType::System,
     463              :                                 OutputProcessor::StoreType::Sum,
     464           19 :                                 heatPump.Name,
     465              :                                 Constant::eResource::EnergyTransfer,
     466              :                                 OutputProcessor::Group::HVAC,
     467              :                                 OutputProcessor::EndUseCat::CoolingCoils);
     468           38 :             SetupOutputVariable(state,
     469              :                                 "Cooling Coil Sensible Cooling Energy",
     470              :                                 Constant::Units::J,
     471           19 :                                 heatPump.EnergySensible,
     472              :                                 OutputProcessor::TimeStepType::System,
     473              :                                 OutputProcessor::StoreType::Sum,
     474           19 :                                 heatPump.Name);
     475           38 :             SetupOutputVariable(state,
     476              :                                 "Cooling Coil Latent Cooling Energy",
     477              :                                 Constant::Units::J,
     478           19 :                                 heatPump.EnergyLatent,
     479              :                                 OutputProcessor::TimeStepType::System,
     480              :                                 OutputProcessor::StoreType::Sum,
     481           19 :                                 heatPump.Name);
     482           38 :             SetupOutputVariable(state,
     483              :                                 "Cooling Coil Source Side Heat Transfer Energy",
     484              :                                 Constant::Units::J,
     485           19 :                                 heatPump.EnergySource,
     486              :                                 OutputProcessor::TimeStepType::System,
     487              :                                 OutputProcessor::StoreType::Sum,
     488           19 :                                 heatPump.Name,
     489              :                                 Constant::eResource::PlantLoopCoolingDemand,
     490              :                                 OutputProcessor::Group::HVAC,
     491              :                                 OutputProcessor::EndUseCat::CoolingCoils);
     492              : 
     493              :             // save the design source side flow rate for use by plant loop sizing algorithms
     494           19 :             PlantUtilities::RegisterPlantCompDesignFlow(state, heatPump.WaterInletNodeNum, 0.5 * heatPump.DesignWaterVolFlowRate);
     495              : 
     496              :             // create predefined report entries
     497           19 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilType, heatPump.Name, CurrentModuleObject);
     498           19 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, heatPump.Name, heatPump.CoolingCapacity);
     499           19 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSensCap, heatPump.Name, "-");
     500           19 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilLatCap, heatPump.Name, "-");
     501           19 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, heatPump.Name, "-");
     502           19 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, heatPump.Name, "-");
     503              :         }
     504              : 
     505            6 :         CurrentModuleObject = "Coil:Heating:WaterToAirHeatPump:ParameterEstimation";
     506              : 
     507           25 :         for (WatertoAirHPNum = 1; WatertoAirHPNum <= NumHeat; ++WatertoAirHPNum) {
     508              : 
     509           19 :             ++HPNum;
     510              : 
     511           19 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     512              :                                                                      CurrentModuleObject,
     513              :                                                                      WatertoAirHPNum,
     514              :                                                                      AlphArray,
     515              :                                                                      NumAlphas,
     516              :                                                                      NumArray,
     517              :                                                                      NumNums,
     518              :                                                                      IOStat,
     519              :                                                                      lNumericBlanks,
     520              :                                                                      lAlphaBlanks,
     521              :                                                                      cAlphaFields,
     522              :                                                                      cNumericFields);
     523              : 
     524           19 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, AlphArray(1)};
     525              : 
     526              :             // ErrorsFound will be set to True if problem was found, left untouched otherwise
     527           19 :             GlobalNames::VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, CurrentModuleObject + " Name");
     528           19 :             auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
     529              : 
     530           19 :             heatPump.Name = AlphArray(1);
     531           19 :             heatPump.WatertoAirHPType = "HEATING";
     532           19 :             heatPump.WAHPType = DataPlant::PlantEquipmentType::CoilWAHPHeatingParamEst;
     533           19 :             heatPump.Refrigerant = AlphArray(3);
     534           19 :             if (heatPump.Refrigerant.empty()) {
     535            0 :                 ShowSevereEmptyField(state, eoh, cAlphaFields(3));
     536            0 :                 ErrorsFound = true;
     537           19 :             } else if ((heatPump.refrig = Fluid::GetRefrig(state, heatPump.Refrigerant)) == nullptr) {
     538            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(3), AlphArray(3));
     539            0 :                 ErrorsFound = true;
     540              :             }
     541           19 :             heatPump.DesignWaterVolFlowRate = NumArray(1);
     542           19 :             heatPump.HeatingCapacity = NumArray(2);
     543              : 
     544           19 :             heatPump.HighPressCutoff = NumArray(3);
     545           19 :             heatPump.LowPressCutoff = NumArray(4);
     546              : 
     547           19 :             heatPump.WaterInletNodeNum = GetOnlySingleNode(state,
     548           19 :                                                            AlphArray(4),
     549              :                                                            ErrorsFound,
     550              :                                                            DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpParameterEstimation,
     551           19 :                                                            AlphArray(1),
     552              :                                                            DataLoopNode::NodeFluidType::Water,
     553              :                                                            DataLoopNode::ConnectionType::Inlet,
     554              :                                                            NodeInputManager::CompFluidStream::Secondary,
     555              :                                                            DataLoopNode::ObjectIsNotParent);
     556           19 :             heatPump.WaterOutletNodeNum = GetOnlySingleNode(state,
     557           19 :                                                             AlphArray(5),
     558              :                                                             ErrorsFound,
     559              :                                                             DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpParameterEstimation,
     560           19 :                                                             AlphArray(1),
     561              :                                                             DataLoopNode::NodeFluidType::Water,
     562              :                                                             DataLoopNode::ConnectionType::Outlet,
     563              :                                                             NodeInputManager::CompFluidStream::Secondary,
     564              :                                                             DataLoopNode::ObjectIsNotParent);
     565           19 :             heatPump.AirInletNodeNum = GetOnlySingleNode(state,
     566           19 :                                                          AlphArray(6),
     567              :                                                          ErrorsFound,
     568              :                                                          DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpParameterEstimation,
     569           19 :                                                          AlphArray(1),
     570              :                                                          DataLoopNode::NodeFluidType::Air,
     571              :                                                          DataLoopNode::ConnectionType::Inlet,
     572              :                                                          NodeInputManager::CompFluidStream::Primary,
     573              :                                                          DataLoopNode::ObjectIsNotParent);
     574           19 :             heatPump.AirOutletNodeNum = GetOnlySingleNode(state,
     575           19 :                                                           AlphArray(7),
     576              :                                                           ErrorsFound,
     577              :                                                           DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpParameterEstimation,
     578           19 :                                                           AlphArray(1),
     579              :                                                           DataLoopNode::NodeFluidType::Air,
     580              :                                                           DataLoopNode::ConnectionType::Outlet,
     581              :                                                           NodeInputManager::CompFluidStream::Primary,
     582              :                                                           DataLoopNode::ObjectIsNotParent);
     583              : 
     584           19 :             heatPump.LoadSideTotalUACoeff = NumArray(5);
     585           19 :             if (heatPump.LoadSideTotalUACoeff < Constant::rTinyValue) {
     586            0 :                 ShowSevereError(state, format("Input problem for {}={}", CurrentModuleObject, heatPump.Name));
     587            0 :                 ShowContinueError(state, " Load side UA value is less than tolerance, likely zero or blank.");
     588            0 :                 ShowContinueError(state, " Verify inputs, as the parameter syntax for this object went through a change with");
     589            0 :                 ShowContinueError(state, "  the release of EnergyPlus version 5.");
     590            0 :                 ErrorsFound = true;
     591              :             }
     592              : 
     593           19 :             heatPump.SuperheatTemp = NumArray(6);
     594           19 :             heatPump.PowerLosses = NumArray(7);
     595           19 :             heatPump.LossFactor = NumArray(8);
     596              : 
     597           19 :             heatPump.compressorType = static_cast<CompressorType>(getEnumValue(CompressTypeNamesUC, Util::makeUPPER(AlphArray(2))));
     598              : 
     599           19 :             switch (heatPump.compressorType) {
     600            0 :             case CompressorType::Reciprocating: {
     601            0 :                 heatPump.CompPistonDisp = NumArray(9);
     602            0 :                 heatPump.CompSucPressDrop = NumArray(10);
     603            0 :                 heatPump.CompClearanceFactor = NumArray(11);
     604            0 :                 break;
     605              :             }
     606            0 :             case CompressorType::Rotary: {
     607            0 :                 heatPump.CompPistonDisp = NumArray(9);
     608            0 :                 heatPump.CompSucPressDrop = NumArray(10);
     609            0 :                 break;
     610              :             }
     611           19 :             case CompressorType::Scroll: {
     612           19 :                 heatPump.RefVolFlowRate = NumArray(12);
     613           19 :                 heatPump.VolumeRatio = NumArray(13);
     614           19 :                 heatPump.LeakRateCoeff = NumArray(14);
     615           19 :                 break;
     616              :             }
     617            0 :             default: {
     618            0 :                 ShowSevereError(
     619              :                     state,
     620            0 :                     format("{}Invalid {} ({}) entered. {}={}", RoutineName, cAlphaFields(2), AlphArray(2), CurrentModuleObject, heatPump.Name));
     621            0 :                 ErrorsFound = true;
     622            0 :                 break;
     623              :             }
     624              :             }
     625              : 
     626           19 :             heatPump.SourceSideUACoeff = NumArray(15);
     627           19 :             heatPump.SourceSideHTR1 = NumArray(16);
     628           19 :             heatPump.SourceSideHTR2 = NumArray(17);
     629              : 
     630           19 :             heatPump.PLFCurveIndex = Curve::GetCurveIndex(state, AlphArray(8)); // convert curve name to number
     631              : 
     632           19 :             if (heatPump.PLFCurveIndex == 0) {
     633            0 :                 if (lAlphaBlanks(8)) {
     634            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, heatPump.Name));
     635            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
     636              :                 } else {
     637            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, heatPump.Name));
     638            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), AlphArray(8)));
     639              :                 }
     640            0 :                 ErrorsFound = true;
     641              :             } else {
     642              :                 // Verify Curve Object, only legal types are Quadratic or Cubic
     643           38 :                 ErrorsFound |= Curve::CheckCurveDims(state,
     644              :                                                      heatPump.PLFCurveIndex, // Curve index
     645              :                                                      {1},                    // Valid dimensions
     646              :                                                      RoutineName,            // Routine name
     647              :                                                      CurrentModuleObject,    // Object Type
     648              :                                                      heatPump.Name,          // Object Name
     649           19 :                                                      cAlphaFields(8));       // Field Name
     650              : 
     651           19 :                 if (!ErrorsFound) {
     652              :                     //     Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
     653           19 :                     Real64 MinCurveVal = 999.0;
     654           19 :                     Real64 MaxCurveVal = -999.0;
     655           19 :                     Real64 CurveInput = 0.0;
     656           19 :                     Real64 MinCurvePLR{0.0};
     657           19 :                     Real64 MaxCurvePLR{0.0};
     658              : 
     659         1919 :                     while (CurveInput <= 1.0) {
     660         1900 :                         Real64 CurveVal = Curve::CurveValue(state, heatPump.PLFCurveIndex, CurveInput);
     661         1900 :                         if (CurveVal < MinCurveVal) {
     662           19 :                             MinCurveVal = CurveVal;
     663           19 :                             MinCurvePLR = CurveInput;
     664              :                         }
     665         1900 :                         if (CurveVal > MaxCurveVal) {
     666         1900 :                             MaxCurveVal = CurveVal;
     667         1900 :                             MaxCurvePLR = CurveInput;
     668              :                         }
     669         1900 :                         CurveInput += 0.01;
     670              :                     }
     671           19 :                     if (MinCurveVal < 0.7) {
     672            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, heatPump.Name));
     673            0 :                         ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFields(9), AlphArray(9)));
     674            0 :                         ShowContinueError(state,
     675            0 :                                           format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
     676            0 :                         ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
     677            0 :                         Curve::SetCurveOutputMinValue(state, heatPump.PLFCurveIndex, ErrorsFound, 0.7);
     678              :                     }
     679              : 
     680           19 :                     if (MaxCurveVal > 1.0) {
     681            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, heatPump.Name));
     682            0 :                         ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), AlphArray(9)));
     683            0 :                         ShowContinueError(state,
     684            0 :                                           format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
     685            0 :                         ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
     686            0 :                         Curve::SetCurveOutputMaxValue(state, heatPump.PLFCurveIndex, ErrorsFound, 1.0);
     687              :                     }
     688              :                 }
     689              :             }
     690              : 
     691           38 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(4), AlphArray(5), "Water Nodes");
     692           19 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(6), AlphArray(7), "Air Nodes");
     693              : 
     694              :             // CurrentModuleObject = "Coil:Heating:WaterToAirHeatPump:ParameterEstimation"
     695           38 :             SetupOutputVariable(state,
     696              :                                 "Heating Coil Electricity Energy",
     697              :                                 Constant::Units::J,
     698           19 :                                 heatPump.Energy,
     699              :                                 OutputProcessor::TimeStepType::System,
     700              :                                 OutputProcessor::StoreType::Sum,
     701           19 :                                 heatPump.Name,
     702              :                                 Constant::eResource::Electricity,
     703              :                                 OutputProcessor::Group::HVAC,
     704              :                                 OutputProcessor::EndUseCat::Heating);
     705           38 :             SetupOutputVariable(state,
     706              :                                 "Heating Coil Heating Energy",
     707              :                                 Constant::Units::J,
     708           19 :                                 heatPump.EnergyLoadTotal,
     709              :                                 OutputProcessor::TimeStepType::System,
     710              :                                 OutputProcessor::StoreType::Sum,
     711           19 :                                 heatPump.Name,
     712              :                                 Constant::eResource::EnergyTransfer,
     713              :                                 OutputProcessor::Group::HVAC,
     714              :                                 OutputProcessor::EndUseCat::HeatingCoils);
     715           38 :             SetupOutputVariable(state,
     716              :                                 "Heating Coil Source Side Heat Transfer Energy",
     717              :                                 Constant::Units::J,
     718           19 :                                 heatPump.EnergySource,
     719              :                                 OutputProcessor::TimeStepType::System,
     720              :                                 OutputProcessor::StoreType::Sum,
     721           19 :                                 heatPump.Name,
     722              :                                 Constant::eResource::PlantLoopHeatingDemand,
     723              :                                 OutputProcessor::Group::HVAC,
     724              :                                 OutputProcessor::EndUseCat::HeatingCoils);
     725              : 
     726              :             // save the design source side flow rate for use by plant loop sizing algorithms
     727           19 :             PlantUtilities::RegisterPlantCompDesignFlow(state, heatPump.WaterInletNodeNum, 0.5 * heatPump.DesignWaterVolFlowRate);
     728              : 
     729              :             // create predefined report entries
     730           19 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, heatPump.Name, CurrentModuleObject);
     731           19 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, heatPump.Name, heatPump.HeatingCapacity);
     732           19 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, heatPump.Name, "-");
     733              :         }
     734              : 
     735            6 :         AlphArray.deallocate();
     736            6 :         cAlphaFields.deallocate();
     737            6 :         lAlphaBlanks.deallocate();
     738            6 :         cNumericFields.deallocate();
     739            6 :         lNumericBlanks.deallocate();
     740            6 :         NumArray.deallocate();
     741              : 
     742            6 :         if (ErrorsFound) {
     743            0 :             ShowFatalError(state, format("{}Errors found getting input. Program terminates.", RoutineName));
     744              :         }
     745              : 
     746           44 :         for (HPNum = 1; HPNum <= state.dataWaterToAirHeatPump->NumWatertoAirHPs; ++HPNum) {
     747              : 
     748           38 :             auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
     749           38 :             if (heatPump.WAHPType == DataPlant::PlantEquipmentType::CoilWAHPCoolingParamEst) {
     750              :                 // COOLING COIL: Setup Report variables for the Heat Pump
     751           38 :                 SetupOutputVariable(state,
     752              :                                     "Cooling Coil Electricity Rate",
     753              :                                     Constant::Units::W,
     754           19 :                                     heatPump.Power,
     755              :                                     OutputProcessor::TimeStepType::System,
     756              :                                     OutputProcessor::StoreType::Average,
     757           19 :                                     heatPump.Name);
     758              : 
     759           38 :                 SetupOutputVariable(state,
     760              :                                     "Cooling Coil Total Cooling Rate",
     761              :                                     Constant::Units::W,
     762           19 :                                     heatPump.QLoadTotal,
     763              :                                     OutputProcessor::TimeStepType::System,
     764              :                                     OutputProcessor::StoreType::Average,
     765           19 :                                     heatPump.Name);
     766              : 
     767           38 :                 SetupOutputVariable(state,
     768              :                                     "Cooling Coil Sensible Cooling Rate",
     769              :                                     Constant::Units::W,
     770           19 :                                     heatPump.QSensible,
     771              :                                     OutputProcessor::TimeStepType::System,
     772              :                                     OutputProcessor::StoreType::Average,
     773           19 :                                     heatPump.Name);
     774              : 
     775           38 :                 SetupOutputVariable(state,
     776              :                                     "Cooling Coil Latent Cooling Rate",
     777              :                                     Constant::Units::W,
     778           19 :                                     heatPump.QLatent,
     779              :                                     OutputProcessor::TimeStepType::System,
     780              :                                     OutputProcessor::StoreType::Average,
     781           19 :                                     heatPump.Name);
     782              : 
     783           38 :                 SetupOutputVariable(state,
     784              :                                     "Cooling Coil Source Side Heat Transfer Rate",
     785              :                                     Constant::Units::W,
     786           19 :                                     heatPump.QSource,
     787              :                                     OutputProcessor::TimeStepType::System,
     788              :                                     OutputProcessor::StoreType::Average,
     789           19 :                                     heatPump.Name);
     790              : 
     791           38 :                 SetupOutputVariable(state,
     792              :                                     "Cooling Coil Part Load Ratio",
     793              :                                     Constant::Units::None,
     794           19 :                                     heatPump.PartLoadRatio,
     795              :                                     OutputProcessor::TimeStepType::System,
     796              :                                     OutputProcessor::StoreType::Average,
     797           19 :                                     heatPump.Name);
     798           38 :                 SetupOutputVariable(state,
     799              :                                     "Cooling Coil Runtime Fraction",
     800              :                                     Constant::Units::None,
     801           19 :                                     heatPump.RunFrac,
     802              :                                     OutputProcessor::TimeStepType::System,
     803              :                                     OutputProcessor::StoreType::Average,
     804           19 :                                     heatPump.Name);
     805              : 
     806           38 :                 SetupOutputVariable(state,
     807              :                                     "Cooling Coil Air Mass Flow Rate",
     808              :                                     Constant::Units::kg_s,
     809           19 :                                     heatPump.OutletAirMassFlowRate,
     810              :                                     OutputProcessor::TimeStepType::System,
     811              :                                     OutputProcessor::StoreType::Average,
     812           19 :                                     heatPump.Name);
     813           38 :                 SetupOutputVariable(state,
     814              :                                     "Cooling Coil Air Inlet Temperature",
     815              :                                     Constant::Units::C,
     816           19 :                                     heatPump.InletAirDBTemp,
     817              :                                     OutputProcessor::TimeStepType::System,
     818              :                                     OutputProcessor::StoreType::Average,
     819           19 :                                     heatPump.Name);
     820           38 :                 SetupOutputVariable(state,
     821              :                                     "Cooling Coil Air Inlet Humidity Ratio",
     822              :                                     Constant::Units::kgWater_kgDryAir,
     823           19 :                                     heatPump.InletAirHumRat,
     824              :                                     OutputProcessor::TimeStepType::System,
     825              :                                     OutputProcessor::StoreType::Average,
     826           19 :                                     heatPump.Name);
     827           38 :                 SetupOutputVariable(state,
     828              :                                     "Cooling Coil Air Outlet Temperature",
     829              :                                     Constant::Units::C,
     830           19 :                                     heatPump.OutletAirDBTemp,
     831              :                                     OutputProcessor::TimeStepType::System,
     832              :                                     OutputProcessor::StoreType::Average,
     833           19 :                                     heatPump.Name);
     834           38 :                 SetupOutputVariable(state,
     835              :                                     "Cooling Coil Air Outlet Humidity Ratio",
     836              :                                     Constant::Units::kgWater_kgDryAir,
     837           19 :                                     heatPump.OutletAirHumRat,
     838              :                                     OutputProcessor::TimeStepType::System,
     839              :                                     OutputProcessor::StoreType::Average,
     840           19 :                                     heatPump.Name);
     841              : 
     842           38 :                 SetupOutputVariable(state,
     843              :                                     "Cooling Coil Source Side Mass Flow Rate",
     844              :                                     Constant::Units::kg_s,
     845           19 :                                     heatPump.OutletWaterMassFlowRate,
     846              :                                     OutputProcessor::TimeStepType::System,
     847              :                                     OutputProcessor::StoreType::Average,
     848           19 :                                     heatPump.Name);
     849           38 :                 SetupOutputVariable(state,
     850              :                                     "Cooling Coil Source Side Inlet Temperature",
     851              :                                     Constant::Units::C,
     852           19 :                                     heatPump.InletWaterTemp,
     853              :                                     OutputProcessor::TimeStepType::System,
     854              :                                     OutputProcessor::StoreType::Average,
     855           19 :                                     heatPump.Name);
     856           38 :                 SetupOutputVariable(state,
     857              :                                     "Cooling Coil Source Side Outlet Temperature",
     858              :                                     Constant::Units::C,
     859           19 :                                     heatPump.OutletWaterTemp,
     860              :                                     OutputProcessor::TimeStepType::System,
     861              :                                     OutputProcessor::StoreType::Average,
     862           19 :                                     heatPump.Name);
     863           19 :             } else if (heatPump.WAHPType == DataPlant::PlantEquipmentType::CoilWAHPHeatingParamEst) {
     864              :                 // HEATING COIL Setup Report variables for the Heat Pump
     865           38 :                 SetupOutputVariable(state,
     866              :                                     "Heating Coil Electricity Rate",
     867              :                                     Constant::Units::W,
     868           19 :                                     heatPump.Power,
     869              :                                     OutputProcessor::TimeStepType::System,
     870              :                                     OutputProcessor::StoreType::Average,
     871           19 :                                     heatPump.Name);
     872              : 
     873           38 :                 SetupOutputVariable(state,
     874              :                                     "Heating Coil Heating Rate",
     875              :                                     Constant::Units::W,
     876           19 :                                     heatPump.QLoadTotal,
     877              :                                     OutputProcessor::TimeStepType::System,
     878              :                                     OutputProcessor::StoreType::Average,
     879           19 :                                     heatPump.Name);
     880              : 
     881           38 :                 SetupOutputVariable(state,
     882              :                                     "Heating Coil Sensible Heating Rate",
     883              :                                     Constant::Units::W,
     884           19 :                                     heatPump.QSensible,
     885              :                                     OutputProcessor::TimeStepType::System,
     886              :                                     OutputProcessor::StoreType::Average,
     887           19 :                                     heatPump.Name);
     888              : 
     889           38 :                 SetupOutputVariable(state,
     890              :                                     "Heating Coil Source Side Heat Transfer Rate",
     891              :                                     Constant::Units::W,
     892           19 :                                     heatPump.QSource,
     893              :                                     OutputProcessor::TimeStepType::System,
     894              :                                     OutputProcessor::StoreType::Average,
     895           19 :                                     heatPump.Name);
     896              : 
     897           38 :                 SetupOutputVariable(state,
     898              :                                     "Heating Coil Part Load Ratio",
     899              :                                     Constant::Units::None,
     900           19 :                                     heatPump.PartLoadRatio,
     901              :                                     OutputProcessor::TimeStepType::System,
     902              :                                     OutputProcessor::StoreType::Average,
     903           19 :                                     heatPump.Name);
     904           38 :                 SetupOutputVariable(state,
     905              :                                     "Heating Coil Runtime Fraction",
     906              :                                     Constant::Units::None,
     907           19 :                                     heatPump.RunFrac,
     908              :                                     OutputProcessor::TimeStepType::System,
     909              :                                     OutputProcessor::StoreType::Average,
     910           19 :                                     heatPump.Name);
     911              : 
     912           38 :                 SetupOutputVariable(state,
     913              :                                     "Heating Coil Air Mass Flow Rate",
     914              :                                     Constant::Units::kg_s,
     915           19 :                                     heatPump.OutletAirMassFlowRate,
     916              :                                     OutputProcessor::TimeStepType::System,
     917              :                                     OutputProcessor::StoreType::Average,
     918           19 :                                     heatPump.Name);
     919           38 :                 SetupOutputVariable(state,
     920              :                                     "Heating Coil Air Inlet Temperature",
     921              :                                     Constant::Units::C,
     922           19 :                                     heatPump.InletAirDBTemp,
     923              :                                     OutputProcessor::TimeStepType::System,
     924              :                                     OutputProcessor::StoreType::Average,
     925           19 :                                     heatPump.Name);
     926           38 :                 SetupOutputVariable(state,
     927              :                                     "Heating Coil Air Inlet Humidity Ratio",
     928              :                                     Constant::Units::kgWater_kgDryAir,
     929           19 :                                     heatPump.InletAirHumRat,
     930              :                                     OutputProcessor::TimeStepType::System,
     931              :                                     OutputProcessor::StoreType::Average,
     932           19 :                                     heatPump.Name);
     933           38 :                 SetupOutputVariable(state,
     934              :                                     "Heating Coil Air Outlet Temperature",
     935              :                                     Constant::Units::C,
     936           19 :                                     heatPump.OutletAirDBTemp,
     937              :                                     OutputProcessor::TimeStepType::System,
     938              :                                     OutputProcessor::StoreType::Average,
     939           19 :                                     heatPump.Name);
     940           38 :                 SetupOutputVariable(state,
     941              :                                     "Heating Coil Air Outlet Humidity Ratio",
     942              :                                     Constant::Units::kgWater_kgDryAir,
     943           19 :                                     heatPump.OutletAirHumRat,
     944              :                                     OutputProcessor::TimeStepType::System,
     945              :                                     OutputProcessor::StoreType::Average,
     946           19 :                                     heatPump.Name);
     947              : 
     948           38 :                 SetupOutputVariable(state,
     949              :                                     "Heating Coil Source Side Mass Flow Rate",
     950              :                                     Constant::Units::kg_s,
     951           19 :                                     heatPump.OutletWaterMassFlowRate,
     952              :                                     OutputProcessor::TimeStepType::System,
     953              :                                     OutputProcessor::StoreType::Average,
     954           19 :                                     heatPump.Name);
     955           38 :                 SetupOutputVariable(state,
     956              :                                     "Heating Coil Source Side Inlet Temperature",
     957              :                                     Constant::Units::C,
     958           19 :                                     heatPump.InletWaterTemp,
     959              :                                     OutputProcessor::TimeStepType::System,
     960              :                                     OutputProcessor::StoreType::Average,
     961           19 :                                     heatPump.Name);
     962           38 :                 SetupOutputVariable(state,
     963              :                                     "Heating Coil Source Side Outlet Temperature",
     964              :                                     Constant::Units::C,
     965           19 :                                     heatPump.OutletWaterTemp,
     966              :                                     OutputProcessor::TimeStepType::System,
     967              :                                     OutputProcessor::StoreType::Average,
     968           19 :                                     heatPump.Name);
     969              :             }
     970              :         }
     971            6 :     }
     972              : 
     973      1891379 :     void InitWatertoAirHP(EnergyPlusData &state,
     974              :                           int const HPNum, // index to main heat pump data structure
     975              :                           bool const InitFlag,
     976              :                           Real64 const SensLoad,
     977              :                           Real64 const LatentLoad,
     978              :                           Real64 const DesignAirFlow,
     979              :                           Real64 const PartLoadRatio)
     980              :     {
     981              : 
     982              :         // SUBROUTINE INFORMATION:
     983              :         //       AUTHOR         Hui Jin
     984              :         //       DATE WRITTEN   Oct 2000
     985              :         //       MODIFIED       Dan Fisher, Kenneth Tang (Jan 2004)
     986              :         //                      Brent Griffith, Sept 2010, plant upgrades, general fluid properties
     987              : 
     988              :         // PURPOSE OF THIS SUBROUTINE:
     989              :         // This subroutine is for initializations of the Water to Air HP Components.
     990              : 
     991              :         // METHODOLOGY EMPLOYED:
     992              :         // Uses the status flags to trigger initializations.
     993              : 
     994              :         // Using/Aliasing
     995      1891379 :         auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
     996              : 
     997              :         static constexpr std::string_view RoutineName("InitWatertoAirHP");
     998      1891379 :         int WaterInletNode = heatPump.WaterInletNodeNum;
     999              : 
    1000      1891379 :         if (state.dataWaterToAirHeatPump->MyOneTimeFlag) {
    1001            6 :             state.dataWaterToAirHeatPump->MyEnvrnFlag.allocate(state.dataWaterToAirHeatPump->NumWatertoAirHPs);
    1002            6 :             state.dataWaterToAirHeatPump->MyPlantScanFlag.allocate(state.dataWaterToAirHeatPump->NumWatertoAirHPs);
    1003            6 :             state.dataWaterToAirHeatPump->MyEnvrnFlag = true;
    1004            6 :             state.dataWaterToAirHeatPump->MyPlantScanFlag = true;
    1005            6 :             state.dataWaterToAirHeatPump->MyOneTimeFlag = false;
    1006              :         }
    1007              : 
    1008      1891379 :         if (state.dataWaterToAirHeatPump->MyPlantScanFlag(HPNum) && allocated(state.dataPlnt->PlantLoop)) {
    1009           38 :             bool errFlag = false;
    1010           38 :             PlantUtilities::ScanPlantLoopsForObject(state, heatPump.Name, heatPump.WAHPType, heatPump.plantLoc, errFlag, _, _, _, _, _);
    1011              : 
    1012           38 :             if (state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).FluidName == "WATER") {
    1013           34 :                 if (heatPump.SourceSideUACoeff < Constant::rTinyValue) {
    1014            0 :                     ShowSevereError(state, format("Input problem for water to air heat pump, \"{}\".", heatPump.Name));
    1015            0 :                     ShowContinueError(state, " Source side UA value is less than tolerance, likely zero or blank.");
    1016            0 :                     ShowContinueError(state, " Verify inputs, as the parameter syntax for this object went through a change with");
    1017            0 :                     ShowContinueError(state, "  the release of EnergyPlus version 5.");
    1018            0 :                     errFlag = true;
    1019              :                 }
    1020              :             } else {
    1021            4 :                 if ((heatPump.SourceSideHTR1 < Constant::rTinyValue) || (heatPump.SourceSideHTR2 < Constant::rTinyValue)) {
    1022            0 :                     ShowSevereError(state, format("Input problem for water to air heat pump, \"{}\".", heatPump.Name));
    1023            0 :                     ShowContinueError(state, " A source side heat transfer resistance value is less than tolerance, likely zero or blank.");
    1024            0 :                     ShowContinueError(state, " Verify inputs, as the parameter syntax for this object went through a change with");
    1025            0 :                     ShowContinueError(state, "  the release of EnergyPlus version 5.");
    1026            0 :                     errFlag = true;
    1027              :                 }
    1028              :             }
    1029              : 
    1030           38 :             if (errFlag) {
    1031            0 :                 ShowFatalError(state, "InitWatertoAirHP: Program terminated for previous conditions.");
    1032              :             }
    1033              : 
    1034           38 :             state.dataWaterToAirHeatPump->MyPlantScanFlag(HPNum) = false;
    1035              :         }
    1036              : 
    1037              :         // Do the Begin Environment initializations
    1038      1891599 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataWaterToAirHeatPump->MyEnvrnFlag(HPNum) &&
    1039          220 :             !state.dataWaterToAirHeatPump->MyPlantScanFlag(HPNum)) {
    1040              : 
    1041              :             // Initialize all report variables to a known state at beginning of simulation
    1042          220 :             heatPump.Power = 0.0;
    1043          220 :             heatPump.Energy = 0.0;
    1044          220 :             heatPump.QLoadTotal = 0.0;
    1045          220 :             heatPump.QSensible = 0.0;
    1046          220 :             heatPump.QLatent = 0.0;
    1047          220 :             heatPump.QSource = 0.0;
    1048          220 :             heatPump.EnergyLoadTotal = 0.0;
    1049          220 :             heatPump.EnergySensible = 0.0;
    1050          220 :             heatPump.EnergyLatent = 0.0;
    1051          220 :             heatPump.EnergySource = 0.0;
    1052          220 :             heatPump.RunFrac = 0.0;
    1053          220 :             heatPump.PartLoadRatio = 0.0;
    1054          220 :             heatPump.OutletAirDBTemp = 0.0;
    1055          220 :             heatPump.OutletAirHumRat = 0.0;
    1056          220 :             heatPump.InletAirDBTemp = 0.0;
    1057          220 :             heatPump.InletAirHumRat = 0.0;
    1058          220 :             heatPump.OutletWaterTemp = 0.0;
    1059          220 :             heatPump.InletWaterTemp = 0.0;
    1060          220 :             heatPump.InletAirMassFlowRate = 0.0;
    1061          220 :             heatPump.InletWaterMassFlowRate = 0.0;
    1062          220 :             heatPump.OutletAirEnthalpy = 0.0;
    1063          220 :             heatPump.OutletWaterEnthalpy = 0.0;
    1064              : 
    1065              :             // The rest of the one time initializations
    1066          220 :             Real64 rho = state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).glycol->getDensity(state, Constant::InitConvTemp, RoutineName);
    1067          220 :             Real64 Cp = state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).glycol->getSpecificHeat(state, Constant::InitConvTemp, RoutineName);
    1068              : 
    1069          220 :             heatPump.DesignWaterMassFlowRate = rho * heatPump.DesignWaterVolFlowRate;
    1070              : 
    1071          220 :             int PlantOutletNode = DataPlant::CompData::getPlantComponent(state, heatPump.plantLoc).NodeNumOut;
    1072          220 :             PlantUtilities::InitComponentNodes(state, 0.0, heatPump.DesignWaterMassFlowRate, WaterInletNode, PlantOutletNode);
    1073              : 
    1074          220 :             state.dataLoopNodes->Node(WaterInletNode).Temp = 5.0;
    1075          220 :             state.dataLoopNodes->Node(WaterInletNode).Enthalpy = Cp * state.dataLoopNodes->Node(WaterInletNode).Temp;
    1076          220 :             state.dataLoopNodes->Node(WaterInletNode).Quality = 0.0;
    1077          220 :             state.dataLoopNodes->Node(WaterInletNode).Press = 0.0;
    1078          220 :             state.dataLoopNodes->Node(WaterInletNode).HumRat = 0.0;
    1079              : 
    1080          220 :             state.dataLoopNodes->Node(PlantOutletNode).Temp = 5.0;
    1081          220 :             state.dataLoopNodes->Node(PlantOutletNode).Enthalpy = Cp * state.dataLoopNodes->Node(WaterInletNode).Temp;
    1082          220 :             state.dataLoopNodes->Node(PlantOutletNode).Quality = 0.0;
    1083          220 :             state.dataLoopNodes->Node(PlantOutletNode).Press = 0.0;
    1084          220 :             state.dataLoopNodes->Node(PlantOutletNode).HumRat = 0.0;
    1085              : 
    1086          220 :             heatPump.SimFlag = true;
    1087              : 
    1088          220 :             state.dataWaterToAirHeatPump->MyEnvrnFlag(HPNum) = false;
    1089              :         } // End If for the Begin Environment initializations
    1090              : 
    1091      1891379 :         if (!state.dataGlobal->BeginEnvrnFlag) {
    1092      1890378 :             state.dataWaterToAirHeatPump->MyEnvrnFlag(HPNum) = true;
    1093              :         }
    1094              : 
    1095              :         // Do the following initializations (every time step): This should be the info from
    1096              :         // the previous components outlets or the node data in this section.
    1097              :         // First set the conditions for the air into the heat pump model
    1098              : 
    1099              :         // Set water and air inlet nodes
    1100      1891379 :         int AirInletNode = heatPump.AirInletNodeNum;
    1101              : 
    1102      1891379 :         if (((SensLoad != 0.0 || LatentLoad != 0.0) || (SensLoad == 0.0 && InitFlag)) && state.dataLoopNodes->Node(AirInletNode).MassFlowRate > 0.0 &&
    1103              :             PartLoadRatio > 0.0) {
    1104              :             // set the water side flow rate to the design flow rate unless constrained by
    1105              :             // the demand side manager (MIN/MAX available). now done by call to setcomponentFlowRate
    1106       666833 :             heatPump.InletWaterMassFlowRate = heatPump.DesignWaterMassFlowRate;
    1107       666833 :             heatPump.InletAirMassFlowRate = DesignAirFlow; // This is required instead of the node temperature
    1108              :             // because the air loop operates handles part load for
    1109              :             // cycling equipment by modulating the air flow rate
    1110              :             // the heat pump model requires an accurate (i.e. full load
    1111              :             // flow rate for accurate simulation.
    1112              :         } else { // heat pump is off
    1113      1224546 :             heatPump.InletWaterMassFlowRate = 0.0;
    1114              : 
    1115      1224546 :             heatPump.InletAirMassFlowRate = 0.0;
    1116              :         }
    1117              :         // constrain water flow provided by plant
    1118      1891379 :         PlantUtilities::SetComponentFlowRate(
    1119      1891379 :             state, heatPump.InletWaterMassFlowRate, heatPump.WaterInletNodeNum, heatPump.WaterOutletNodeNum, heatPump.plantLoc);
    1120              : 
    1121      1891379 :         heatPump.InletWaterTemp = state.dataLoopNodes->Node(WaterInletNode).Temp;
    1122              :         //  IF (WatertoAirHP(HPNum)%InletWaterTemp < 0.0) THEN  ! Debug trap
    1123              :         //    Temptemp         = Node(WaterInletNode)%Temp
    1124              :         //  ENDIF
    1125      1891379 :         heatPump.InletWaterEnthalpy = state.dataLoopNodes->Node(WaterInletNode).Enthalpy;
    1126              : 
    1127      1891379 :         heatPump.InletAirDBTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
    1128      1891379 :         heatPump.InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
    1129      1891379 :         heatPump.InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
    1130              : 
    1131      1891379 :         heatPump.Power = 0.0;
    1132      1891379 :         heatPump.Energy = 0.0;
    1133      1891379 :         heatPump.QLoadTotal = 0.0;
    1134      1891379 :         heatPump.QSensible = 0.0;
    1135      1891379 :         heatPump.QLatent = 0.0;
    1136      1891379 :         heatPump.QSource = 0.0;
    1137      1891379 :         heatPump.EnergyLoadTotal = 0.0;
    1138      1891379 :         heatPump.EnergySensible = 0.0;
    1139      1891379 :         heatPump.EnergyLatent = 0.0;
    1140      1891379 :         heatPump.EnergySource = 0.0;
    1141      1891379 :         heatPump.RunFrac = 0.0;
    1142      1891379 :         heatPump.OutletAirDBTemp = 0.0;
    1143      1891379 :         heatPump.OutletAirHumRat = 0.0;
    1144      1891379 :         heatPump.OutletWaterTemp = 0.0;
    1145      1891379 :         heatPump.OutletAirEnthalpy = 0.0;
    1146      1891379 :         heatPump.OutletWaterEnthalpy = 0.0;
    1147      1891379 :     }
    1148              : 
    1149       945692 :     void CalcWatertoAirHPCooling(EnergyPlusData &state,
    1150              :                                  int const HPNum,                      // heat pump number
    1151              :                                  HVAC::FanOp const fanOp,              // fan/compressor cycling scheme indicator
    1152              :                                  bool const FirstHVACIteration,        // first iteration flag
    1153              :                                  [[maybe_unused]] bool const InitFlag, // suppress property errors if true
    1154              :                                  Real64 const SensDemand,
    1155              :                                  HVAC::CompressorOp const compressorOp,
    1156              :                                  Real64 const PartLoadRatio)
    1157              :     {
    1158              : 
    1159              :         // SUBROUTINE INFORMATION:
    1160              :         //       AUTHOR         Hui Jin
    1161              :         //       DATE WRITTEN   Oct 2000
    1162              :         //       MODIFIED       Dan Fisher, Kenneth Tang (Jan 2004), R. Raustad (Oct 2006) Revised iteration technique
    1163              : 
    1164              :         // PURPOSE OF THIS SUBROUTINE:
    1165              :         // Simulates a parameter estimation based water to air heat pump model
    1166              : 
    1167              :         // Using/Aliasing
    1168       945692 :         auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
    1169              : 
    1170              :         // SUBROUTINE PARAMETER DEFINITIONS:
    1171       945692 :         constexpr Real64 CpWater(4210.0);         // Specific heat of water J/kg_C
    1172       945692 :         constexpr Real64 DegreeofSuperheat(80.0); // Initial guess of degree of superheat
    1173       945692 :         constexpr Real64 gamma(1.114);            // Expansion Coefficient
    1174       945692 :         constexpr Real64 ERR(0.01);               // Error Value
    1175       945692 :         constexpr Real64 PB(1.013e5);             // Barometric Pressure (Pa)
    1176              : 
    1177       945692 :         constexpr int STOP1(1000); // Iteration stopper1
    1178       945692 :         constexpr int STOP2(1000); // Iteration stopper2
    1179       945692 :         constexpr int STOP3(1000); // Iteration stopper3
    1180              : 
    1181              :         static constexpr std::string_view RoutineNameSourceSideInletTemp("CalcWatertoAirHPCooling:SourceSideInletTemp");
    1182              :         static constexpr std::string_view RoutineNameSourceSideTemp("CalcWatertoAirHPCooling:SourceSideTemp");
    1183              :         static constexpr std::string_view RoutineNameLoadSideTemp("CalcWatertoAirHPCooling:LoadSideTemp");
    1184              :         static constexpr std::string_view RoutineNameLoadSideSurfaceTemp("CalcWatertoAirHPCooling:LoadSideSurfaceTemp");
    1185              :         static constexpr std::string_view RoutineNameLoadSideEvapTemp("CalcWatertoAirHPCooling:LoadSideEvapTemp");
    1186              :         static constexpr std::string_view RoutineNameLoadSideOutletEnthalpy("CalcWatertoAirHPCooling:LoadSideOutletEnthalpy");
    1187              :         static constexpr std::string_view RoutineNameCompressInletTemp("CalcWatertoAirHPCooling:CompressInletTemp");
    1188              :         static constexpr std::string_view RoutineNameSuctionPr("CalcWatertoAirHPCooling:SuctionPr");
    1189              :         static constexpr std::string_view RoutineNameCompSuctionTemp("CalcWatertoAirHPCooling:CompSuctionTemp");
    1190              : 
    1191              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1192              :         int NumIteration3;                // Number of Iteration3
    1193              :         int NumIteration4;                // Number of Iteration4 (use of latent degradation model ONLY)
    1194              :         Real64 Quality;                   // Quality of Refrigerant
    1195              :         Real64 SourceSideOutletTemp;      // Source Side Outlet Temperature [C]
    1196              :         Real64 SourceSideVolFlowRate;     // Source Side Volumetric Flow Rate [m3/s]
    1197              :         Real64 DegradFactor;              // Degradation Factor [~]
    1198              :         Real64 CpFluid;                   // Specific heat of source side fluid(J/kg)
    1199              :         Real64 LoadSideInletWBTemp;       // Wet-bulb temperature of indoor inlet air [C]
    1200              :         Real64 LoadSideInletDBTemp;       // Load Side Inlet Dry Bulb Temp [C]
    1201              :         Real64 LoadSideInletHumRat;       // Load Side Inlet Humidity Ratio [kg/kg]
    1202              :         Real64 LoadSideOutletDBTemp;      // Load Side Outlet Dry Bulb Temperature [C]
    1203              :         Real64 LoadSideOutletHumRat;      // Load Side Outlet Humidity Ratio [kg/kg]
    1204              :         Real64 LoadSideAirInletEnth;      // Load Side Inlet Enthalpy [J/kg]
    1205              :         Real64 LoadSideAirOutletEnth;     // Load Side Outlet Enthalpy [J/kg]
    1206              :         Real64 EffectiveSurfaceTemp;      // Effective Surface Temperature [C]
    1207              :         Real64 EffectiveSatEnth;          // Saturated Enthalpy of Air Corresponding to the Effective Surface Temperature [J/kg]
    1208              :         Real64 QSource;                   // Source Side Heat Transfer Rate [W]
    1209              :         Real64 QLoadTotal;                // Load Side Total Heat Transfer Rate [W]
    1210              :         Real64 QSensible;                 // Load Side Sensible Heat Transfer Rate [W]
    1211              :         Real64 Power;                     // Power Consumption [W]
    1212              :         Real64 EvapTemp;                  // Evaporating Temperature [C]
    1213              :         Real64 ANTUWET;                   // Number of Transfer Unit for Wet Condition
    1214              :         Real64 EffectWET;                 // Load Side Heat Exchanger Effectiveness
    1215              :         Real64 EvapSatEnth;               // Saturated Enthalpy of Air Corresponding to the Evaporating Temperature [J/kg]
    1216              :         Real64 SourceSideEffect;          // Source Side Heat Exchanger Effectiveness
    1217              :         Real64 SourceSideTemp;            // Source Side Saturated Refrigerant Temperature [C]
    1218              :         Real64 LoadSideTemp;              // Load Side Saturated Refrigerant Temperature [C]
    1219              :         Real64 SourceSidePressure;        // Source Side Saturated Refrigerant Pressure [Pa]
    1220              :         Real64 LoadSidePressure;          // Load Side Saturated Refrigerant Pressure [Pa]
    1221              :         Real64 SuctionPr;                 // Compressor Suction Pressure [Pa]
    1222              :         Real64 DischargePr;               // Compressor Discharge Pressure [Pa]
    1223              :         Real64 CompressInletTemp;         // Temperature of the Refrigerant Entering the Compressor [C]
    1224              :         Real64 MassRef;                   // Mass Flow Rate of Refrigerant [kg/s]
    1225              :         Real64 SourceSideOutletEnth;      // Enthalpy of Refrigerant leaving the Source Side Heat Exchanger [J/kg]
    1226              :         Real64 LoadSideOutletEnth;        // Enthalpy of Refrigerant leaving the Load Side Heat Exchanger [J/kg]
    1227              :         Real64 CpAir;                     // Specific Heat of Air [J/kg_C]
    1228              :         Real64 SuperHeatEnth;             // Enthalpy of the Superheated Refrigerant [J/kg]
    1229              :         Real64 CompSuctionTemp1;          // Guess of the Temperature of the Refrigerant Entering the Compressor #1 [C]
    1230              :         Real64 CompSuctionTemp2;          // Guess of the Temperature of the Refrigerant Entering the Compressor #2 [C]
    1231              :         Real64 CompSuctionEnth;           // Enthalpy of the Refrigerant Entering the Compressor [J/kg]
    1232              :         Real64 CompSuctionDensity;        // Density of the Refrigerant Entering the Compressor [kg/m3]
    1233              :         Real64 CompSuctionSatTemp;        // Temperature of Saturated Refrigerant at Compressor Suction Pressure [C]
    1234              :         bool LatDegradModelSimFlag;       // Latent degradation model simulation flag
    1235              :         bool StillSimulatingFlag;         // Final Simulation Flag
    1236              :         bool Converged;                   // overall convergence Flag
    1237              :         Real64 QLatRated;                 // Qlatent at rated conditions of indoor(TDB,TWB)=(26.7C,19.4C)
    1238              :         Real64 QLatActual;                // Qlatent at actual operating conditions
    1239              :         Real64 SHRss;                     // Sensible heat ratio at steady state
    1240              :         Real64 SHReff;                    // Effective sensible heat ratio at part-load condition
    1241              :         int SolFlag;                      // Solution flag returned from RegulaFalsi function
    1242              :         Real64 LoadSideAirInletEnth_Unit; // calc conditions for unit
    1243              :         Real64 LoadResidual;              // loop convergence criteria
    1244              :         Real64 SourceResidual;            // loop convergence criteria
    1245       945692 :         Real64 RelaxParam(0.5);           // Relaxation Parameter
    1246              : 
    1247       945692 :         if (state.dataWaterToAirHeatPump->firstTime) {
    1248              :             // Set indoor air conditions to the rated condition
    1249            6 :             state.dataWaterToAirHeatPump->LoadSideInletDBTemp_Init = 26.7;
    1250            6 :             state.dataWaterToAirHeatPump->LoadSideInletHumRat_Init = 0.0111;
    1251            6 :             state.dataWaterToAirHeatPump->LoadSideAirInletEnth_Init = Psychrometrics::PsyHFnTdbW(
    1252            6 :                 state.dataWaterToAirHeatPump->LoadSideInletDBTemp_Init, state.dataWaterToAirHeatPump->LoadSideInletHumRat_Init);
    1253            6 :             state.dataWaterToAirHeatPump->firstTime = false;
    1254              :         }
    1255              : 
    1256              :         //  SET LOCAL VARIABLES FROM DATA STRUCTURE (for code readability)
    1257              :         // Set indoor air conditions to the actual condition
    1258       945692 :         CpAir = Psychrometrics::PsyCpAirFnW(heatPump.InletAirHumRat);
    1259       945692 :         LoadSideAirInletEnth_Unit = Psychrometrics::PsyHFnTdbW(heatPump.InletAirDBTemp, heatPump.InletAirHumRat);
    1260       945692 :         SourceSideVolFlowRate =
    1261       945692 :             heatPump.InletWaterMassFlowRate /
    1262       945692 :             state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).glycol->getDensity(state, heatPump.InletWaterTemp, RoutineNameSourceSideInletTemp);
    1263              : 
    1264       945692 :         StillSimulatingFlag = true;
    1265              : 
    1266              :         // If heat pump is not operating, return
    1267       945692 :         if (SensDemand == 0.0 || heatPump.InletAirMassFlowRate <= 0.0 || heatPump.InletWaterMassFlowRate <= 0.0) {
    1268       696787 :             heatPump.SimFlag = false;
    1269       696787 :             return;
    1270              :         } else {
    1271       248905 :             heatPump.SimFlag = true;
    1272              :         }
    1273              : 
    1274       248905 :         if (compressorOp == HVAC::CompressorOp::Off) {
    1275            0 :             heatPump.SimFlag = false;
    1276            0 :             return;
    1277              :         }
    1278              : 
    1279       248905 :         if (FirstHVACIteration) {
    1280        51550 :             state.dataWaterToAirHeatPump->initialQSource_calc = heatPump.CoolingCapacity;
    1281        51550 :             state.dataWaterToAirHeatPump->initialQLoadTotal_calc = heatPump.CoolingCapacity;
    1282              :         }
    1283              : 
    1284       248905 :         if (state.dataWaterToAirHeatPump->initialQLoadTotal_calc == 0.0) {
    1285            0 :             state.dataWaterToAirHeatPump->initialQLoadTotal_calc = heatPump.CoolingCapacity;
    1286              :         }
    1287       248905 :         if (state.dataWaterToAirHeatPump->initialQSource_calc == 0.0) {
    1288            0 :             state.dataWaterToAirHeatPump->initialQSource_calc = heatPump.CoolingCapacity;
    1289              :         }
    1290              : 
    1291              :         // Loop the calculation at least twice depending whether the latent degradation model
    1292              :         // is enabled. 1st iteration to calculate the QLatent(rated) at (TDB,TWB)indoorair=(26.7C,19.4C)
    1293              :         // and 2nd iteration to calculate the  QLatent(actual)
    1294              : 
    1295              :         // Calculate Part Load Factor and Runtime Fraction
    1296       248905 :         Real64 PLF = 1.0; // part load factor as a function of PLR, RTF = PLR / PLF
    1297       248905 :         if (heatPump.PLFCurveIndex > 0) {
    1298       248905 :             PLF = Curve::CurveValue(state, heatPump.PLFCurveIndex, PartLoadRatio); // Calculate part-load factor
    1299              :         }
    1300       248905 :         if (fanOp == HVAC::FanOp::Cycling) {
    1301       248905 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
    1302              :         }
    1303       248905 :         heatPump.RunFrac = PartLoadRatio / PLF;
    1304              : 
    1305       248905 :         QLatRated = 0.0;
    1306       248905 :         QLatActual = 0.0;
    1307              :         // IF((RuntimeFrac .GE. 1.0) .OR. (Twet_rated .LE. 0.0) .OR. (Gamma_rated .LE. 0.0)) THEN
    1308              :         // Cycling fan does not required latent degradation model, only the constant fan case
    1309       248905 :         if ((heatPump.RunFrac >= 1.0) || (heatPump.Twet_Rated <= 0.0) || (heatPump.Gamma_Rated <= 0.0) || (fanOp == HVAC::FanOp::Cycling)) {
    1310       248905 :             LatDegradModelSimFlag = false;
    1311              :             // Set NumIteration4=1 so that latent model would quit after 1 simulation with the actual condition
    1312       248905 :             NumIteration4 = 1;
    1313              :         } else {
    1314            0 :             LatDegradModelSimFlag = true;
    1315              :             // Set NumIteration4=0 so that latent model would simulate twice with rated and actual condition
    1316            0 :             NumIteration4 = 0;
    1317              :         }
    1318              : 
    1319              :         // Tuned Hoisted quantities out of nested loop that don't change
    1320       248905 :         Real64 const LoadSideMassFlowRate_CpAir_inv(1.0 / (heatPump.InletAirMassFlowRate * CpAir));
    1321              :         Real64 const LoadSideEffec(1.0 -
    1322       248905 :                                    std::exp(-heatPump.LoadSideOutsideUACoeff *
    1323       248905 :                                             LoadSideMassFlowRate_CpAir_inv)); // Load Side Effectiveness based on Outside Heat Transfer Coefficient
    1324       248905 :         Real64 const LoadSideEffec_MassFlowRate_inv(1.0 / (LoadSideEffec * heatPump.InletAirMassFlowRate));
    1325       248905 :         ANTUWET = heatPump.LoadSideTotalUACoeff * LoadSideMassFlowRate_CpAir_inv;
    1326       248905 :         EffectWET = 1.0 - std::exp(-ANTUWET);
    1327              : 
    1328              :         while (true) {
    1329       248905 :             ++NumIteration4;
    1330       248905 :             if (NumIteration4 == 1) {
    1331              :                 // Set indoor air conditions to the rated condition
    1332            0 :                 LoadSideInletDBTemp = state.dataWaterToAirHeatPump->LoadSideInletDBTemp_Init;
    1333            0 :                 LoadSideInletHumRat = state.dataWaterToAirHeatPump->LoadSideInletHumRat_Init;
    1334            0 :                 LoadSideAirInletEnth = state.dataWaterToAirHeatPump->LoadSideAirInletEnth_Init;
    1335              :             } else {
    1336              :                 // Set indoor air conditions to the actual condition
    1337       248905 :                 LoadSideInletDBTemp = heatPump.InletAirDBTemp;
    1338       248905 :                 LoadSideInletHumRat = heatPump.InletAirHumRat;
    1339       248905 :                 LoadSideAirInletEnth = LoadSideAirInletEnth_Unit;
    1340              :             }
    1341              : 
    1342              :             // Outerloop: Calculate source side heat transfer
    1343       248905 :             int NumIteration2 = 0;
    1344       248905 :             Converged = false;
    1345       248905 :             StillSimulatingFlag = true;
    1346       248905 :             SourceResidual = 1.0;
    1347       885789 :             while (StillSimulatingFlag) {
    1348       636884 :                 if (Converged) {
    1349       248905 :                     StillSimulatingFlag = false;
    1350              :                 }
    1351              : 
    1352       636884 :                 ++NumIteration2;
    1353       636884 :                 if (NumIteration2 == 1) {
    1354       248905 :                     RelaxParam = 0.5;
    1355              :                 }
    1356              : 
    1357       636884 :                 if (NumIteration2 > STOP2) {
    1358            0 :                     heatPump.SimFlag = false;
    1359            0 :                     return;
    1360              :                 }
    1361              : 
    1362              :                 // Innerloop: Calculate load side heat transfer
    1363       636884 :                 NumIteration3 = 0;
    1364       636884 :                 LoadResidual = 1.0;
    1365      1536472 :                 while (LoadResidual > ERR) {
    1366              : 
    1367       899588 :                     ++NumIteration3;
    1368              : 
    1369       899588 :                     if (NumIteration3 > STOP3) {
    1370            0 :                         heatPump.SimFlag = false;
    1371            0 :                         return;
    1372              :                     }
    1373              : 
    1374              :                     // Determine Effectiveness of Source Side
    1375       899588 :                     CpFluid = state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum)
    1376       899588 :                                   .glycol->getSpecificHeat(state, heatPump.InletWaterTemp, RoutineNameSourceSideInletTemp);
    1377              : 
    1378       899588 :                     if (state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).glycol->Num == Fluid::GlycolNum_Water) {
    1379       864483 :                         SourceSideEffect = 1.0 - std::exp(-heatPump.SourceSideUACoeff / (CpFluid * heatPump.InletWaterMassFlowRate));
    1380              :                     } else {
    1381        35105 :                         DegradFactor = DegradF(state, state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).glycol, heatPump.InletWaterTemp);
    1382        35105 :                         SourceSideEffect =
    1383        35105 :                             1.0 / ((heatPump.SourceSideHTR1 * std::pow(SourceSideVolFlowRate, -0.8)) / DegradFactor + heatPump.SourceSideHTR2);
    1384              :                     }
    1385              : 
    1386              :                     // Determine Source Side Tempertaure (Condensing Temp in this case)
    1387       899588 :                     SourceSideTemp = heatPump.InletWaterTemp + state.dataWaterToAirHeatPump->initialQSource_calc /
    1388       899588 :                                                                    (SourceSideEffect * CpFluid * heatPump.InletWaterMassFlowRate);
    1389              : 
    1390              :                     // Compute the Effective Surface Temperature
    1391       899588 :                     EffectiveSatEnth = LoadSideAirInletEnth - state.dataWaterToAirHeatPump->initialQLoadTotal_calc * LoadSideEffec_MassFlowRate_inv;
    1392              : 
    1393       899588 :                     EffectiveSurfaceTemp = Psychrometrics::PsyTsatFnHPb(state, EffectiveSatEnth, PB, RoutineNameLoadSideSurfaceTemp);
    1394              : 
    1395       899588 :                     QSensible = heatPump.InletAirMassFlowRate * CpAir * (LoadSideInletDBTemp - EffectiveSurfaceTemp) * LoadSideEffec;
    1396       899588 :                     EvapSatEnth =
    1397       899588 :                         LoadSideAirInletEnth - state.dataWaterToAirHeatPump->initialQLoadTotal_calc / (EffectWET * heatPump.InletAirMassFlowRate);
    1398              : 
    1399       899588 :                     EvapTemp = Psychrometrics::PsyTsatFnHPb(state, EvapSatEnth, PB, RoutineNameLoadSideEvapTemp);
    1400              : 
    1401              :                     // Load Side Saturated Temperature (Evaporating Temp in this case)
    1402       899588 :                     LoadSideTemp = EvapTemp;
    1403              : 
    1404              :                     // Determine the Load Side and Source Side Saturated Temp (evaporating and condensing pressures)
    1405       899588 :                     SourceSidePressure = heatPump.refrig->getSatPressure(state, SourceSideTemp, RoutineNameSourceSideTemp);
    1406       899588 :                     LoadSidePressure = heatPump.refrig->getSatPressure(state, LoadSideTemp, RoutineNameLoadSideTemp);
    1407              : 
    1408       899588 :                     if (LoadSidePressure < heatPump.LowPressCutoff && !FirstHVACIteration) {
    1409            0 :                         if (!state.dataGlobal->WarmupFlag) {
    1410            0 :                             ShowRecurringWarningErrorAtEnd(
    1411              :                                 state,
    1412            0 :                                 format("WaterToAir Heat pump:cooling [{}] shut off on low pressure < {:.0R}", heatPump.Name, heatPump.LowPressCutoff),
    1413            0 :                                 heatPump.LowPressClgError,
    1414              :                                 LoadSidePressure,
    1415              :                                 LoadSidePressure,
    1416              :                                 _,
    1417              :                                 "[Pa]",
    1418              :                                 "[Pa]");
    1419              :                         }
    1420            0 :                         heatPump.SimFlag = false;
    1421            0 :                         return;
    1422              :                     }
    1423              : 
    1424       899588 :                     if (SourceSidePressure > heatPump.HighPressCutoff && !FirstHVACIteration) {
    1425            0 :                         if (!state.dataGlobal->WarmupFlag) {
    1426            0 :                             ShowRecurringWarningErrorAtEnd(state,
    1427            0 :                                                            format("WaterToAir Heat pump:cooling [{}] shut off on high pressure > {:.0R}",
    1428            0 :                                                                   heatPump.Name,
    1429            0 :                                                                   heatPump.HighPressCutoff),
    1430            0 :                                                            heatPump.HighPressClgError,
    1431            0 :                                                            heatPump.InletWaterTemp,
    1432            0 :                                                            heatPump.InletWaterTemp,
    1433              :                                                            _,
    1434              :                                                            "SourceSideInletTemp[C]",
    1435              :                                                            "SourceSideInletTemp[C]");
    1436              :                         }
    1437            0 :                         heatPump.SimFlag = false;
    1438            0 :                         return;
    1439              :                     }
    1440              : 
    1441              :                     // Determine Suction Pressure & Discharge Pressure at Compressor Exit
    1442       899588 :                     if (heatPump.compressorType == CompressorType::Reciprocating) { // RECIPROCATING
    1443            0 :                         SuctionPr = LoadSidePressure - heatPump.CompSucPressDrop;
    1444            0 :                         DischargePr = SourceSidePressure + heatPump.CompSucPressDrop;
    1445       899588 :                     } else if (heatPump.compressorType == CompressorType::Rotary) { // ROTARY
    1446            0 :                         SuctionPr = LoadSidePressure;
    1447            0 :                         DischargePr = SourceSidePressure + heatPump.CompSucPressDrop;
    1448       899588 :                     } else if (heatPump.compressorType == CompressorType::Scroll) { // SCROLL
    1449       899588 :                         SuctionPr = LoadSidePressure;
    1450       899588 :                         DischargePr = SourceSidePressure;
    1451              :                     }
    1452              : 
    1453              :                     // Determine the Load Side Outlet Enthalpy (Saturated Gas)
    1454       899588 :                     Quality = 1.0;
    1455       899588 :                     LoadSideOutletEnth = heatPump.refrig->getSatEnthalpy(state, LoadSideTemp, Quality, RoutineNameLoadSideTemp);
    1456              : 
    1457              :                     // Determine Source Side Outlet Enthalpy (Saturated Liquid)
    1458       899588 :                     Quality = 0.0;
    1459       899588 :                     SourceSideOutletEnth = heatPump.refrig->getSatEnthalpy(state, SourceSideTemp, Quality, RoutineNameSourceSideTemp);
    1460              :                     // Determine Superheated Temperature of the Load Side outlet/compressor Inlet
    1461       899588 :                     CompressInletTemp = LoadSideTemp + heatPump.SuperheatTemp;
    1462              : 
    1463              :                     // Determine the Enthalpy of the Superheated Fluid at Load Side Outlet/Compressor Inlet
    1464       899588 :                     SuperHeatEnth = heatPump.refrig->getSupHeatEnthalpy(state, CompressInletTemp, LoadSidePressure, RoutineNameCompressInletTemp);
    1465              : 
    1466              :                     // Determining the suction state of the fluid from inlet state involves interation
    1467              :                     // Method employed...
    1468              :                     // Determine the saturated temp at suction pressure, shoot out into the superheated region find the enthalpy
    1469              :                     // check that with the inlet enthalpy ( as suction loss is isenthalpic). Iterate till desired accuracy is reached
    1470       899588 :                     if (!Converged) {
    1471       650683 :                         CompSuctionSatTemp = heatPump.refrig->getSatTemperature(state, SuctionPr, RoutineNameSuctionPr);
    1472       650683 :                         CompSuctionTemp1 = CompSuctionSatTemp;
    1473              : 
    1474              :                         // Shoot into the Superheated Region
    1475       650683 :                         CompSuctionTemp2 = CompSuctionSatTemp + DegreeofSuperheat;
    1476              :                     }
    1477              : 
    1478      2698764 :                     auto f = [&state, &heatPump, SuctionPr, SuperHeatEnth](Real64 const CompSuctionTemp) {
    1479              :                         static constexpr std::string_view RoutineName("CalcWaterToAirHPHeating:CalcCompSuctionTemp");
    1480      2698764 :                         Real64 compSuctionEnth = heatPump.refrig->getSupHeatEnthalpy(state, CompSuctionTemp, SuctionPr, RoutineName);
    1481      2698764 :                         return (compSuctionEnth - SuperHeatEnth) / SuperHeatEnth;
    1482       899588 :                     };
    1483              : 
    1484      1799176 :                     General::SolveRoot(
    1485       899588 :                         state, ERR, STOP1, SolFlag, state.dataWaterToAirHeatPump->CompSuctionTemp, f, CompSuctionTemp1, CompSuctionTemp2);
    1486       899588 :                     if (SolFlag == -1) {
    1487            0 :                         heatPump.SimFlag = false;
    1488            0 :                         return;
    1489              :                     }
    1490       899588 :                     CompSuctionEnth = heatPump.refrig->getSupHeatEnthalpy(
    1491       899588 :                         state, state.dataWaterToAirHeatPump->CompSuctionTemp, SuctionPr, RoutineNameCompSuctionTemp);
    1492       899588 :                     CompSuctionDensity = heatPump.refrig->getSupHeatDensity(
    1493       899588 :                         state, state.dataWaterToAirHeatPump->CompSuctionTemp, SuctionPr, RoutineNameCompSuctionTemp);
    1494              : 
    1495              :                     // Find Refrigerant Flow Rate
    1496       899588 :                     switch (heatPump.compressorType) {
    1497            0 :                     case CompressorType::Reciprocating: {
    1498            0 :                         MassRef =
    1499            0 :                             heatPump.CompPistonDisp * CompSuctionDensity *
    1500            0 :                             (1.0 + heatPump.CompClearanceFactor - heatPump.CompClearanceFactor * std::pow(DischargePr / SuctionPr, 1.0 / gamma));
    1501            0 :                         break;
    1502              :                     }
    1503            0 :                     case CompressorType::Rotary: {
    1504            0 :                         MassRef = heatPump.CompPistonDisp * CompSuctionDensity;
    1505            0 :                         break;
    1506              :                     }
    1507       899588 :                     case CompressorType::Scroll: {
    1508       899588 :                         MassRef = heatPump.RefVolFlowRate * CompSuctionDensity - heatPump.LeakRateCoeff * (DischargePr / SuctionPr);
    1509       899588 :                         break;
    1510              :                     }
    1511            0 :                     default:
    1512            0 :                         break;
    1513              :                     }
    1514       899588 :                     MassRef = max(0.0, MassRef);
    1515              : 
    1516              :                     // Find the Load Side Heat Transfer
    1517       899588 :                     QLoadTotal = MassRef * (LoadSideOutletEnth - SourceSideOutletEnth);
    1518       899588 :                     LoadResidual = std::abs(QLoadTotal - state.dataWaterToAirHeatPump->initialQLoadTotal_calc) /
    1519       899588 :                                    state.dataWaterToAirHeatPump->initialQLoadTotal_calc;
    1520      1799176 :                     state.dataWaterToAirHeatPump->initialQLoadTotal_calc +=
    1521       899588 :                         RelaxParam * (QLoadTotal - state.dataWaterToAirHeatPump->initialQLoadTotal_calc);
    1522       899588 :                     if (NumIteration3 > 8) {
    1523            0 :                         RelaxParam = 0.3;
    1524              :                     }
    1525              :                 }
    1526              : 
    1527              :                 // Determine the Power Consumption
    1528       636884 :                 switch (heatPump.compressorType) {
    1529            0 :                 case CompressorType::Reciprocating:
    1530              :                 case CompressorType::Rotary: {
    1531            0 :                     Power = heatPump.PowerLosses + (1.0 / heatPump.LossFactor) * (MassRef * gamma / (gamma - 1.0) * SuctionPr / CompSuctionDensity *
    1532            0 :                                                                                   (std::pow(DischargePr / SuctionPr, (gamma - 1.0) / gamma) - 1.0));
    1533            0 :                     break;
    1534              :                 }
    1535       636884 :                 case CompressorType::Scroll: {
    1536       636884 :                     Power = heatPump.PowerLosses + (1.0 / heatPump.LossFactor) * (gamma / (gamma - 1.0)) * SuctionPr * heatPump.RefVolFlowRate *
    1537       636884 :                                                        (((gamma - 1.0) / gamma) * ((DischargePr / SuctionPr) / heatPump.VolumeRatio) +
    1538       636884 :                                                         ((1.0 / gamma) * std::pow(heatPump.VolumeRatio, gamma - 1.0)) - 1.0);
    1539       636884 :                     break;
    1540              :                 }
    1541            0 :                 default:
    1542            0 :                     break;
    1543              :                 }
    1544              : 
    1545              :                 // Determine the Sourceside Heat Rate
    1546       636884 :                 QSource = Power + QLoadTotal;
    1547       636884 :                 SourceResidual =
    1548       636884 :                     std::abs(QSource - state.dataWaterToAirHeatPump->initialQSource_calc) / state.dataWaterToAirHeatPump->initialQSource_calc;
    1549       636884 :                 if (SourceResidual < ERR) {
    1550       497810 :                     Converged = true;
    1551              :                 }
    1552       636884 :                 state.dataWaterToAirHeatPump->initialQSource_calc += RelaxParam * (QSource - state.dataWaterToAirHeatPump->initialQSource_calc);
    1553       636884 :                 if (NumIteration2 > 8) {
    1554            0 :                     RelaxParam = 0.2;
    1555              :                 }
    1556              :             }
    1557              : 
    1558       248905 :             if (SuctionPr < heatPump.LowPressCutoff) {
    1559            0 :                 ShowWarningError(state, "Heat pump:cooling shut down on low pressure");
    1560            0 :                 heatPump.SimFlag = false;
    1561              :             }
    1562              : 
    1563       248905 :             if (DischargePr > heatPump.HighPressCutoff && !FirstHVACIteration) {
    1564            0 :                 ShowWarningError(state, "Heat pump:cooling shut down on high pressure");
    1565            0 :                 heatPump.SimFlag = false;
    1566              :             }
    1567              : 
    1568       248905 :             if (QSensible > QLoadTotal) {
    1569            0 :                 QSensible = QLoadTotal;
    1570              :             }
    1571              : 
    1572       248905 :             if (LatDegradModelSimFlag) {
    1573            0 :                 if (NumIteration4 == 1) {
    1574            0 :                     QLatRated = QLoadTotal - QSensible;
    1575              : 
    1576            0 :                 } else if (NumIteration4 == 2) {
    1577            0 :                     QLatActual = QLoadTotal - QSensible;
    1578            0 :                     SHRss = QSensible / QLoadTotal;
    1579            0 :                     LoadSideInletWBTemp = Psychrometrics::PsyTwbFnTdbWPb(state, LoadSideInletDBTemp, LoadSideInletHumRat, PB);
    1580            0 :                     SHReff = CalcEffectiveSHR(
    1581              :                         state, HPNum, SHRss, fanOp, heatPump.RunFrac, QLatRated, QLatActual, LoadSideInletDBTemp, LoadSideInletWBTemp);
    1582              :                     //   Update sensible capacity based on effective SHR
    1583            0 :                     QSensible = QLoadTotal * SHReff;
    1584            0 :                     goto LOOPLatentDegradationModel_exit;
    1585              :                 }
    1586              :             } else {
    1587              : 
    1588       248905 :                 SHReff = QSensible / QLoadTotal;
    1589       248905 :                 goto LOOPLatentDegradationModel_exit;
    1590              :             }
    1591            0 :         }
    1592       248905 :     LOOPLatentDegradationModel_exit:;
    1593              : 
    1594              :         // calculate coil outlet state variables
    1595       248905 :         LoadSideAirOutletEnth = LoadSideAirInletEnth - QLoadTotal / heatPump.InletAirMassFlowRate;
    1596       248905 :         LoadSideOutletDBTemp = LoadSideInletDBTemp - QSensible * LoadSideMassFlowRate_CpAir_inv;
    1597       248905 :         LoadSideOutletHumRat = Psychrometrics::PsyWFnTdbH(state, LoadSideOutletDBTemp, LoadSideAirOutletEnth, RoutineNameLoadSideOutletEnthalpy);
    1598       248905 :         SourceSideOutletTemp = heatPump.InletWaterTemp + QSource / (heatPump.InletWaterMassFlowRate * CpWater);
    1599              : 
    1600              :         // Actual outlet conditions are "average" for time step
    1601       248905 :         if (fanOp == HVAC::FanOp::Continuous) {
    1602              :             // continuous fan, cycling compressor
    1603            0 :             heatPump.OutletAirEnthalpy = PartLoadRatio * LoadSideAirOutletEnth + (1.0 - PartLoadRatio) * LoadSideAirInletEnth;
    1604            0 :             heatPump.OutletAirHumRat = PartLoadRatio * LoadSideOutletHumRat + (1.0 - PartLoadRatio) * LoadSideInletHumRat;
    1605            0 :             heatPump.OutletAirDBTemp = Psychrometrics::PsyTdbFnHW(heatPump.OutletAirEnthalpy, heatPump.OutletAirHumRat);
    1606              :         } else {
    1607              :             // default to cycling fan, cycling compressor
    1608       248905 :             heatPump.OutletAirEnthalpy = LoadSideAirOutletEnth;
    1609       248905 :             heatPump.OutletAirHumRat = LoadSideOutletHumRat;
    1610       248905 :             heatPump.OutletAirDBTemp = LoadSideOutletDBTemp;
    1611              :         }
    1612              : 
    1613              :         // scale heat transfer rates and power to run time
    1614       248905 :         QLoadTotal *= PartLoadRatio;
    1615       248905 :         QSensible *= PartLoadRatio;
    1616       248905 :         Power *= heatPump.RunFrac;
    1617       248905 :         QSource *= PartLoadRatio;
    1618              : 
    1619              :         // Update heat pump data structure
    1620       248905 :         state.dataHVACGlobal->DXElecCoolingPower = Power;
    1621       248905 :         heatPump.Power = Power;
    1622       248905 :         heatPump.QLoadTotal = QLoadTotal;
    1623       248905 :         heatPump.QSensible = QSensible;
    1624       248905 :         heatPump.QLatent = QLoadTotal - QSensible;
    1625       248905 :         heatPump.QSource = QSource;
    1626       248905 :         heatPump.PartLoadRatio = PartLoadRatio;
    1627              : 
    1628              :         //  Air-side outlet conditions are already calculated above
    1629       248905 :         heatPump.OutletAirMassFlowRate = heatPump.InletAirMassFlowRate;
    1630       248905 :         heatPump.OutletWaterTemp = SourceSideOutletTemp;
    1631       248905 :         heatPump.OutletWaterMassFlowRate = heatPump.InletWaterMassFlowRate;
    1632       248905 :         heatPump.OutletWaterEnthalpy = heatPump.InletWaterEnthalpy + QSource / heatPump.InletWaterMassFlowRate;
    1633              :     }
    1634              : 
    1635       945687 :     void CalcWatertoAirHPHeating(EnergyPlusData &state,
    1636              :                                  int const HPNum,                      // heat pump number
    1637              :                                  HVAC::FanOp const fanOp,              // fan/compressor cycling scheme indicator
    1638              :                                  bool const FirstHVACIteration,        // first iteration flag
    1639              :                                  [[maybe_unused]] bool const InitFlag, // first iteration flag
    1640              :                                  Real64 const SensDemand,
    1641              :                                  HVAC::CompressorOp const compressorOp,
    1642              :                                  Real64 const PartLoadRatio)
    1643              :     {
    1644              : 
    1645              :         // SUBROUTINE INFORMATION:
    1646              :         //       AUTHOR         Hui Jin
    1647              :         //       DATE WRITTEN   Oct 2000
    1648              :         //       MODIFIED       R. Raustad (Oct 2006) Revised iteration technique
    1649              : 
    1650              :         // PURPOSE OF THIS SUBROUTINE:
    1651              :         // Simulates a parameter estimation based water to air heat pump model
    1652              : 
    1653              :         // Using/Aliasing
    1654       945687 :         auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
    1655              : 
    1656              :         // SUBROUTINE PARAMETER DEFINITIONS:
    1657       945687 :         Real64 constexpr CpWater(4210.0);         // Specific heat of water J/kg_C
    1658       945687 :         Real64 constexpr DegreeofSuperheat(80.0); // Initial guess of degree of superheat
    1659       945687 :         Real64 constexpr gamma(1.114);            // Expnasion Coefficient
    1660       945687 :         Real64 RelaxParam(0.5);                   // Relaxation Parameter
    1661       945687 :         Real64 constexpr ERR(0.01);               // Error Value
    1662       945687 :         int constexpr STOP1(1000);                // Iteration stopper1
    1663       945687 :         int constexpr STOP2(1000);                // Iteration stopper2
    1664       945687 :         int constexpr STOP3(1000);                // Iteration stopper3
    1665              : 
    1666              :         static constexpr std::string_view RoutineNameSourceSideInletTemp("CalcWatertoAirHPHeating:SourceSideInletTemp");
    1667              :         static constexpr std::string_view RoutineNameSourceSideTemp("CalcWatertoAirHPHeating:SourceSideTemp");
    1668              :         static constexpr std::string_view RoutineNameLoadSideTemp("CalcWatertoAirHPHeating:LoadSideTemp");
    1669              :         static constexpr std::string_view RoutineNameLoadSideOutletEnthalpy("CalcWatertoAirHPHeating:LoadSideOutletEnthalpy");
    1670              :         static constexpr std::string_view RoutineNameCompressInletTemp("CalcWatertoAirHPHeating:CompressInletTemp");
    1671              :         static constexpr std::string_view RoutineNameSuctionPr("CalcWatertoAirHPHeating:SuctionPr");
    1672              :         static constexpr std::string_view RoutineNameCompSuctionTemp("CalcWatertoAirHPHeating:CompSuctionTemp");
    1673              : 
    1674              :         int NumIteration3; // Number of Iteration3
    1675              :         Real64 Quality;
    1676              :         Real64 SourceSideOutletTemp;  // Source Side Outlet Temperature [C]
    1677              :         Real64 SourceSideVolFlowRate; // Source Side Volumetric Flow Rate [m3/s]
    1678              :         Real64 CpFluid;               // Specific heat of source side fluid(J/kg)
    1679              :         Real64 LoadSideOutletDBTemp;  // Load Side Outlet Dry Bulb Temperature [C]
    1680              :         Real64 LoadSideOutletHumRat;  // Load Side Outlet Humidity Ratio [kg/kg]
    1681              :         Real64 LoadSideAirOutletEnth; // Load Side Outlet Enthalpy [J/kg]
    1682              :         Real64 CpAir;                 // Specific Heat of Air [J/kg_C]
    1683              :         Real64 DegradFactor;          // Degradation Factor [~]
    1684              :         Real64 QSource;               // Source Side Heat Transfer Rate [W]
    1685              :         Real64 QLoadTotal;            // Load Side Heat Transfer Rate [W]
    1686              :         Real64 Power;                 // Power Consumption [W]
    1687              : 
    1688              :         Real64 SourceSideEffect;     // Source Side Heat Exchanger Effectiveness
    1689              :         Real64 SourceSideTemp;       // Source Side Saturated Refrigerant Temperature [C]
    1690              :         Real64 LoadSideTemp;         // Load Side Saturated Refrigerant Temperature [C]
    1691              :         Real64 SourceSidePressure;   // Source Side Saturated Refrigerant Pressure [Pa]
    1692              :         Real64 LoadSidePressure;     // Load Side Saturated Refrigerant Pressure [Pa]
    1693              :         Real64 SuctionPr;            // Compressor Suction Pressure [Pa]
    1694              :         Real64 DischargePr;          // Compressor Discharge Pressure [Pa]
    1695              :         Real64 CompressInletTemp;    // Temperature of the Refrigerant Entering the Compressor [C]
    1696              :         Real64 MassRef;              // Mass Flow Rate of Refrigerant [kg/s]
    1697              :         Real64 SourceSideOutletEnth; // Enthalpy of Refrigerant leaving the Source Side Heat Exchanger [J/kg]
    1698              :         Real64 LoadSideOutletEnth;   // Enthalpy of Refrigerant leaving the Load Side Heat Exchanger [J/kg]
    1699              :         Real64 SuperHeatEnth;        // Enthalpy of the Superheated Refrigerant [J/kg]
    1700              :         Real64 CompSuctionTemp1;     // Guess of the Temperature of the Refrigerant Entering the
    1701              :         // Compressor #1 [C]
    1702              :         Real64 CompSuctionTemp2; // Guess of the Temperature of the Refrigerant Entering the
    1703              :         // Compressor #2 [C]
    1704              :         Real64 CompSuctionTemp;    // Temperature of the Refrigerant Entering the Compressor [C]
    1705              :         Real64 CompSuctionEnth;    // Enthalpy of the Refrigerant Entering the Compressor [J/kg]
    1706              :         Real64 CompSuctionDensity; // Density of the Refrigerant Entering the Compressorkg/m3
    1707              :         Real64 CompSuctionSatTemp; // Temperature of Saturated Refrigerant at Compressor Suction Pressure [C]
    1708              :         bool StillSimulatingFlag;  // Final Simulation Flag
    1709              :         bool Converged;            // Overall convergence Flag
    1710              :         int SolFlag;               // Solution flag returned from RegulaFalsi function
    1711              :         Real64 LoadResidual;       // loop convergence criteria
    1712              :         Real64 SourceResidual;     // loop convergence criteria
    1713              : 
    1714              :         //  LOAD LOCAL VARIABLES FROM DATA STRUCTURE (for code readability)
    1715              : 
    1716       945687 :         CpAir = Psychrometrics::PsyCpAirFnW(heatPump.InletAirHumRat);
    1717       945687 :         SourceSideVolFlowRate =
    1718       945687 :             heatPump.InletWaterMassFlowRate /
    1719       945687 :             state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).glycol->getDensity(state, heatPump.InletWaterTemp, RoutineNameSourceSideInletTemp);
    1720              : 
    1721              :         // If heat pump is not operating, return
    1722       945687 :         if (SensDemand == 0.0 || heatPump.InletAirMassFlowRate <= 0.0 || heatPump.InletWaterMassFlowRate <= 0.0) {
    1723       527759 :             heatPump.SimFlag = false;
    1724       527759 :             return;
    1725              :         } else {
    1726       417928 :             heatPump.SimFlag = true;
    1727              :         }
    1728              : 
    1729       417928 :         if (compressorOp == HVAC::CompressorOp::Off) {
    1730            0 :             heatPump.SimFlag = false;
    1731            0 :             return;
    1732              :         }
    1733              : 
    1734       417928 :         if (FirstHVACIteration) {
    1735        86596 :             state.dataWaterToAirHeatPump->initialQLoad = heatPump.HeatingCapacity;
    1736        86596 :             state.dataWaterToAirHeatPump->initialQSource = heatPump.HeatingCapacity;
    1737              :         }
    1738              : 
    1739       417928 :         if (state.dataWaterToAirHeatPump->initialQLoad == 0.0) {
    1740            0 :             state.dataWaterToAirHeatPump->initialQLoad = heatPump.HeatingCapacity;
    1741              :         }
    1742       417928 :         if (state.dataWaterToAirHeatPump->initialQSource == 0.0) {
    1743            0 :             state.dataWaterToAirHeatPump->initialQSource = heatPump.HeatingCapacity;
    1744              :         }
    1745              : 
    1746              :         // Tuned Hoisted quantities out of nested loop that don't change
    1747       417928 :         Real64 const LoadSideMassFlowRate_CpAir_inv(1.0 / (heatPump.InletAirMassFlowRate * CpAir));
    1748              :         Real64 const LoadSideEffect(1.0 -
    1749       417928 :                                     std::exp(-heatPump.LoadSideTotalUACoeff *
    1750       417928 :                                              LoadSideMassFlowRate_CpAir_inv)); // Load Side Effectiveness based on Outside Heat Transfer Coefficient
    1751       417928 :         Real64 const LoadSideEffect_CpAir_MassFlowRate_inv(1.0 / (LoadSideEffect * CpAir * heatPump.InletAirMassFlowRate));
    1752              : 
    1753              :         // Outerloop: calculate load side heat transfer
    1754       417928 :         NumIteration3 = 0;
    1755       417928 :         Converged = false;
    1756       417928 :         StillSimulatingFlag = true;
    1757       417928 :         LoadResidual = 1.0;
    1758      1627809 :         while (StillSimulatingFlag) {
    1759      1209881 :             if (Converged) {
    1760       417928 :                 StillSimulatingFlag = false;
    1761              :             }
    1762              : 
    1763      1209881 :             ++NumIteration3;
    1764      1209881 :             if (NumIteration3 == 1) {
    1765       417928 :                 RelaxParam = 0.5;
    1766              :             }
    1767              : 
    1768      1209881 :             if (NumIteration3 > STOP3) {
    1769            0 :                 heatPump.SimFlag = false;
    1770            0 :                 return;
    1771              :             }
    1772              : 
    1773              :             // Innerloop: calculate load side heat transfer
    1774      1209881 :             int NumIteration2 = 0;
    1775      1209881 :             SourceResidual = 1.0;
    1776      2964932 :             while (SourceResidual > ERR) {
    1777              : 
    1778      1755051 :                 ++NumIteration2;
    1779              : 
    1780      1755051 :                 if (NumIteration2 > STOP2) {
    1781            0 :                     heatPump.SimFlag = false;
    1782            0 :                     return;
    1783              :                 }
    1784              : 
    1785              :                 // Determine Effectiveness of Source Side
    1786      1755051 :                 CpFluid = state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum)
    1787      1755051 :                               .glycol->getSpecificHeat(state, heatPump.InletWaterTemp, RoutineNameSourceSideInletTemp);
    1788              : 
    1789      1755051 :                 if (state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).glycol->Num == Fluid::GlycolNum_Water) {
    1790      1472725 :                     SourceSideEffect = 1.0 - std::exp(-heatPump.SourceSideUACoeff / (CpFluid * heatPump.InletWaterMassFlowRate));
    1791              :                 } else {
    1792       282326 :                     DegradFactor = DegradF(state, state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).glycol, heatPump.InletWaterTemp);
    1793       282326 :                     SourceSideEffect =
    1794       282326 :                         1.0 / ((heatPump.SourceSideHTR1 * std::pow(SourceSideVolFlowRate, -0.8)) / DegradFactor + heatPump.SourceSideHTR2);
    1795              :                 }
    1796              : 
    1797              :                 // Determine Source Side Tempertaure (Evap. Temp for this mode)
    1798      3510102 :                 SourceSideTemp = heatPump.InletWaterTemp -
    1799      1755051 :                                  state.dataWaterToAirHeatPump->initialQSource / (SourceSideEffect * CpFluid * heatPump.InletWaterMassFlowRate);
    1800              : 
    1801              :                 // Determine Load Side Tempertaure (Condensing Temp for this mode)
    1802      1755051 :                 LoadSideTemp = heatPump.InletAirDBTemp + state.dataWaterToAirHeatPump->initialQLoad * LoadSideEffect_CpAir_MassFlowRate_inv;
    1803              : 
    1804              :                 // Determine the Load Side and Source Side Saturated Temp (evaporating and condensing pressures)
    1805      1755051 :                 SourceSidePressure = heatPump.refrig->getSatPressure(state, SourceSideTemp, RoutineNameSourceSideTemp);
    1806      1755051 :                 LoadSidePressure = heatPump.refrig->getSatPressure(state, LoadSideTemp, RoutineNameLoadSideTemp);
    1807      1755051 :                 if (SourceSidePressure < heatPump.LowPressCutoff && !FirstHVACIteration) {
    1808            0 :                     if (!state.dataGlobal->WarmupFlag) {
    1809            0 :                         ShowRecurringWarningErrorAtEnd(
    1810              :                             state,
    1811            0 :                             format("WaterToAir Heat pump:heating [{}] shut off on low pressure < {:.0R}", heatPump.Name, heatPump.LowPressCutoff),
    1812            0 :                             heatPump.LowPressHtgError,
    1813              :                             SourceSidePressure,
    1814              :                             SourceSidePressure,
    1815              :                             _,
    1816              :                             "[Pa]",
    1817              :                             "[Pa]");
    1818              :                     }
    1819            0 :                     heatPump.SimFlag = false;
    1820            0 :                     return;
    1821              :                 }
    1822              : 
    1823      1755051 :                 if (LoadSidePressure > heatPump.HighPressCutoff && !FirstHVACIteration) {
    1824            0 :                     if (!state.dataGlobal->WarmupFlag) {
    1825            0 :                         ShowRecurringWarningErrorAtEnd(
    1826              :                             state,
    1827            0 :                             format("WaterToAir Heat pump:heating [{}] shut off on high pressure > {:.0R}", heatPump.Name, heatPump.HighPressCutoff),
    1828            0 :                             heatPump.HighPressHtgError,
    1829            0 :                             heatPump.InletWaterTemp,
    1830            0 :                             heatPump.InletWaterTemp,
    1831              :                             _,
    1832              :                             "SourceSideInletTemp[C]",
    1833              :                             "SourceSideInletTemp[C]");
    1834              :                     }
    1835              :                     //         CALL ShowWarningError(state, 'Heat pump:heating shut off on high pressure')
    1836              :                     //         WRITE(CErrCount,*) SourceSideInletTemp
    1837              :                     //         CErrCount=ADJUSTL(CErrCount)
    1838              :                     //         CALL ShowContinueError(state, 'Source side inlet temperature too low, T='//TRIM(CErrCount))
    1839              :                     //         CALL ShowContinueError(state, 'Heat pump heating demand not met by plant side')
    1840            0 :                     heatPump.SimFlag = false;
    1841            0 :                     return;
    1842              :                 }
    1843              : 
    1844              :                 // Determine Suction Pressure at Compressor Entrance & Discharge Pressure at Compressor Exit
    1845      1755051 :                 switch (heatPump.compressorType) {
    1846            0 :                 case CompressorType::Reciprocating: {
    1847            0 :                     SuctionPr = SourceSidePressure - heatPump.CompSucPressDrop;
    1848            0 :                     DischargePr = LoadSidePressure + heatPump.CompSucPressDrop;
    1849            0 :                     break;
    1850              :                 }
    1851            0 :                 case CompressorType::Rotary: {
    1852            0 :                     SuctionPr = SourceSidePressure;
    1853            0 :                     DischargePr = LoadSidePressure + heatPump.CompSucPressDrop;
    1854            0 :                     break;
    1855              :                 }
    1856      1755051 :                 case CompressorType::Scroll: {
    1857      1755051 :                     SuctionPr = SourceSidePressure;
    1858      1755051 :                     DischargePr = LoadSidePressure;
    1859      1755051 :                     break;
    1860              :                 }
    1861            0 :                 default:
    1862            0 :                     break;
    1863              :                 }
    1864              : 
    1865              :                 // Determine the Source Side Outlet Enthalpy
    1866              :                 // Quality of the refrigerant leaving the evaporator is saturated gas
    1867      1755051 :                 Quality = 1.0;
    1868      1755051 :                 SourceSideOutletEnth = heatPump.refrig->getSatEnthalpy(state, SourceSideTemp, Quality, RoutineNameSourceSideTemp);
    1869              : 
    1870              :                 // Determine Load Side Outlet Enthalpy
    1871              :                 // Quality of the refrigerant leaving the condenser is saturated liguid
    1872      1755051 :                 Quality = 0.0;
    1873      1755051 :                 LoadSideOutletEnth = heatPump.refrig->getSatEnthalpy(state, LoadSideTemp, Quality, RoutineNameLoadSideTemp);
    1874              : 
    1875              :                 // Determine Superheated Temperature of the Source Side outlet/compressor Inlet
    1876      1755051 :                 CompressInletTemp = SourceSideTemp + heatPump.SuperheatTemp;
    1877              : 
    1878              :                 // Determine the Enathalpy of the Superheated Fluid at Source Side Outlet/Compressor Inlet
    1879      1755051 :                 SuperHeatEnth = heatPump.refrig->getSupHeatEnthalpy(state, CompressInletTemp, SourceSidePressure, RoutineNameCompressInletTemp);
    1880              : 
    1881              :                 // Determining the suction state of the fluid from inlet state involves interation
    1882              :                 // Method employed...
    1883              :                 // Determine the saturated temp at suction pressure, shoot out into the superheated region find the enthalpy
    1884              :                 // check that with the inlet enthalpy ( as suction loss is isenthalpic). Iterate till desired accuracy is reached
    1885              : 
    1886      1755051 :                 if (!Converged) {
    1887      1337123 :                     CompSuctionSatTemp = heatPump.refrig->getSatTemperature(state, SuctionPr, RoutineNameSuctionPr);
    1888      1337123 :                     CompSuctionTemp1 = CompSuctionSatTemp;
    1889              : 
    1890              :                     // Shoot into the Superheated Region
    1891      1337123 :                     CompSuctionTemp2 = CompSuctionSatTemp + DegreeofSuperheat;
    1892              :                 }
    1893              : 
    1894      5265153 :                 auto f = [&state, &heatPump, SuctionPr, SuperHeatEnth](Real64 const CompSuctionTemp) {
    1895              :                     static constexpr std::string_view RoutineName("CalcWaterToAirHPHeating:CalcCompSuctionTemp");
    1896      5265153 :                     Real64 compSuctionEnth = heatPump.refrig->getSupHeatEnthalpy(state, CompSuctionTemp, SuctionPr, RoutineName);
    1897      5265153 :                     return (compSuctionEnth - SuperHeatEnth) / SuperHeatEnth;
    1898      1755051 :                 };
    1899              : 
    1900      1755051 :                 General::SolveRoot(state, ERR, STOP1, SolFlag, CompSuctionTemp, f, CompSuctionTemp1, CompSuctionTemp2);
    1901      1755051 :                 if (SolFlag == -1) {
    1902            0 :                     heatPump.SimFlag = false;
    1903            0 :                     return;
    1904              :                 }
    1905      1755051 :                 CompSuctionEnth = heatPump.refrig->getSupHeatEnthalpy(state, CompSuctionTemp, SuctionPr, RoutineNameCompSuctionTemp);
    1906      1755051 :                 CompSuctionDensity = heatPump.refrig->getSupHeatDensity(state, CompSuctionTemp, SuctionPr, RoutineNameCompSuctionTemp);
    1907              : 
    1908              :                 // Find Refrigerant Flow Rate
    1909      1755051 :                 switch (heatPump.compressorType) {
    1910            0 :                 case CompressorType::Reciprocating: {
    1911            0 :                     MassRef = heatPump.CompPistonDisp * CompSuctionDensity *
    1912            0 :                               (1 + heatPump.CompClearanceFactor - heatPump.CompClearanceFactor * std::pow(DischargePr / SuctionPr, 1 / gamma));
    1913            0 :                     break;
    1914              :                 }
    1915            0 :                 case CompressorType::Rotary: {
    1916            0 :                     MassRef = heatPump.CompPistonDisp * CompSuctionDensity;
    1917            0 :                     break;
    1918              :                 }
    1919      1755051 :                 case CompressorType::Scroll: {
    1920      1755051 :                     MassRef = heatPump.RefVolFlowRate * CompSuctionDensity - heatPump.LeakRateCoeff * (DischargePr / SuctionPr);
    1921      1755051 :                     break;
    1922              :                 }
    1923            0 :                 default:
    1924            0 :                     break;
    1925              :                 }
    1926      1755051 :                 MassRef = max(0.0, MassRef);
    1927              : 
    1928              :                 // Find the Source Side Heat Transfer
    1929      1755051 :                 QSource = MassRef * (SourceSideOutletEnth - LoadSideOutletEnth);
    1930      1755051 :                 SourceResidual = std::abs(QSource - state.dataWaterToAirHeatPump->initialQSource) / state.dataWaterToAirHeatPump->initialQSource;
    1931      1755051 :                 state.dataWaterToAirHeatPump->initialQSource += RelaxParam * (QSource - state.dataWaterToAirHeatPump->initialQSource);
    1932      1755051 :                 if (NumIteration2 > 8) {
    1933            0 :                     RelaxParam = 0.3;
    1934              :                 }
    1935              :             }
    1936              : 
    1937              :             // Determine the Power Consumption
    1938      1209881 :             switch (heatPump.compressorType) {
    1939            0 :             case CompressorType::Reciprocating:
    1940              :             case CompressorType::Rotary: {
    1941            0 :                 Power = heatPump.PowerLosses + (1 / heatPump.LossFactor) * (MassRef * gamma / (gamma - 1) * SuctionPr / CompSuctionDensity *
    1942            0 :                                                                             (std::pow(DischargePr / SuctionPr, (gamma - 1) / gamma) - 1));
    1943            0 :                 break;
    1944              :             }
    1945      1209881 :             case CompressorType::Scroll: {
    1946      1209881 :                 Power = heatPump.PowerLosses + (1 / heatPump.LossFactor) * (gamma / (gamma - 1)) * SuctionPr * heatPump.RefVolFlowRate *
    1947      1209881 :                                                    (((gamma - 1) / gamma) * ((DischargePr / SuctionPr) / heatPump.VolumeRatio) +
    1948      1209881 :                                                     ((1 / gamma) * std::pow(heatPump.VolumeRatio, gamma - 1)) - 1);
    1949      1209881 :                 break;
    1950              :             }
    1951            0 :             default:
    1952            0 :                 break;
    1953              :             }
    1954              : 
    1955              :             // Determine the Load Side Heat Rate
    1956      1209881 :             QLoadTotal = Power + QSource;
    1957      1209881 :             LoadResidual = std::abs(QLoadTotal - state.dataWaterToAirHeatPump->initialQLoad) / state.dataWaterToAirHeatPump->initialQLoad;
    1958      1209881 :             if (LoadResidual < ERR) {
    1959       835856 :                 Converged = true;
    1960              :             }
    1961      1209881 :             state.dataWaterToAirHeatPump->initialQLoad += RelaxParam * (QLoadTotal - state.dataWaterToAirHeatPump->initialQLoad);
    1962      1209881 :             if (NumIteration3 > 8) {
    1963            0 :                 RelaxParam = 0.2;
    1964              :             }
    1965              :         }
    1966              : 
    1967       417928 :         if (SuctionPr < heatPump.LowPressCutoff && !FirstHVACIteration) {
    1968            0 :             ShowWarningError(state, "Heat pump:heating shut down on low pressure");
    1969            0 :             heatPump.SimFlag = false;
    1970            0 :             return;
    1971              :         }
    1972              : 
    1973       417928 :         if (DischargePr > heatPump.HighPressCutoff && !FirstHVACIteration) {
    1974            0 :             ShowWarningError(state, "Heat pump:heating shut down on high pressure");
    1975            0 :             heatPump.SimFlag = false;
    1976            0 :             return;
    1977              :         }
    1978              : 
    1979              :         // calculate coil outlet state variables
    1980       417928 :         LoadSideAirOutletEnth = heatPump.InletAirEnthalpy + QLoadTotal / heatPump.InletAirMassFlowRate;
    1981       417928 :         LoadSideOutletDBTemp = heatPump.InletAirDBTemp + QLoadTotal / (heatPump.InletAirMassFlowRate * CpAir);
    1982       417928 :         LoadSideOutletHumRat = Psychrometrics::PsyWFnTdbH(state, LoadSideOutletDBTemp, LoadSideAirOutletEnth, RoutineNameLoadSideOutletEnthalpy);
    1983       417928 :         SourceSideOutletTemp = heatPump.InletWaterTemp - QSource / (heatPump.InletWaterMassFlowRate * CpWater);
    1984              : 
    1985              :         // Calculate actual outlet conditions for the run time fraction
    1986              :         // Actual outlet conditions are "average" for time step
    1987       417928 :         if (fanOp == HVAC::FanOp::Continuous) {
    1988              :             // continuous fan, cycling compressor
    1989            0 :             heatPump.OutletAirEnthalpy = PartLoadRatio * LoadSideAirOutletEnth + (1.0 - PartLoadRatio) * heatPump.InletAirEnthalpy;
    1990            0 :             heatPump.OutletAirHumRat = PartLoadRatio * LoadSideOutletHumRat + (1.0 - PartLoadRatio) * heatPump.InletAirHumRat;
    1991            0 :             heatPump.OutletAirDBTemp = Psychrometrics::PsyTdbFnHW(heatPump.OutletAirEnthalpy, heatPump.OutletAirHumRat);
    1992              :         } else {
    1993              :             // default to cycling fan, cycling compressor
    1994       417928 :             heatPump.OutletAirEnthalpy = LoadSideAirOutletEnth;
    1995       417928 :             heatPump.OutletAirHumRat = LoadSideOutletHumRat;
    1996       417928 :             heatPump.OutletAirDBTemp = LoadSideOutletDBTemp;
    1997              :         }
    1998              : 
    1999              :         // Calculate Part Load Factor and Runtime Fraction
    2000       417928 :         Real64 PLF = 1.0; // part load factor as a function of PLR, RTF = PLR / PLF
    2001       417928 :         if (heatPump.PLFCurveIndex > 0) {
    2002       417928 :             PLF = Curve::CurveValue(state, heatPump.PLFCurveIndex, PartLoadRatio); // Calculate part-load factor
    2003              :         }
    2004       417928 :         if (fanOp == HVAC::FanOp::Cycling) {
    2005       417928 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
    2006              :         }
    2007       417928 :         heatPump.RunFrac = PartLoadRatio / PLF;
    2008              : 
    2009              :         // scale heat transfer rates and power to run time
    2010       417928 :         QLoadTotal *= PartLoadRatio;
    2011       417928 :         Power *= heatPump.RunFrac;
    2012       417928 :         QSource *= PartLoadRatio;
    2013              : 
    2014              :         // Update heat pump data structure
    2015       417928 :         state.dataHVACGlobal->DXElecHeatingPower = Power;
    2016       417928 :         heatPump.Power = Power;
    2017       417928 :         heatPump.QLoadTotal = QLoadTotal;
    2018       417928 :         heatPump.QSensible = QLoadTotal;
    2019              : 
    2020       417928 :         heatPump.QSource = QSource;
    2021       417928 :         heatPump.PartLoadRatio = PartLoadRatio;
    2022       417928 :         heatPump.OutletAirMassFlowRate = heatPump.InletAirMassFlowRate;
    2023       417928 :         heatPump.OutletWaterTemp = SourceSideOutletTemp;
    2024       417928 :         heatPump.OutletWaterMassFlowRate = heatPump.InletWaterMassFlowRate;
    2025       417928 :         heatPump.OutletWaterEnthalpy = heatPump.InletWaterEnthalpy - QSource / heatPump.InletWaterMassFlowRate;
    2026              :     }
    2027              : 
    2028      1891379 :     void UpdateWatertoAirHP(EnergyPlusData &state, int const HPNum)
    2029              :     {
    2030              :         // SUBROUTINE INFORMATION:
    2031              :         //       AUTHOR         Hui Jin
    2032              :         //       DATE WRITTEN   Oct 2000
    2033              : 
    2034              :         // PURPOSE OF THIS SUBROUTINE:
    2035              :         // This subroutine updates the Water to Air Heat Pump outlet nodes.
    2036              : 
    2037              :         // METHODOLOGY EMPLOYED:
    2038              :         // Data is moved from the HP data structure to the HP outlet nodes.
    2039              : 
    2040              :         // Using/Aliasing
    2041      1891379 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    2042      1891379 :         auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
    2043              : 
    2044              :         // WatertoAirHP(HPNum)%SimFlag=.FALSE.
    2045      1891379 :         if (!heatPump.SimFlag) {
    2046              :             // Heatpump is off; just pass through conditions
    2047      1224546 :             heatPump.Power = 0.0;
    2048      1224546 :             heatPump.Energy = 0.0;
    2049      1224546 :             heatPump.QLoadTotal = 0.0;
    2050      1224546 :             heatPump.QSensible = 0.0;
    2051      1224546 :             heatPump.QLatent = 0.0;
    2052      1224546 :             heatPump.QSource = 0.0;
    2053      1224546 :             heatPump.RunFrac = 0.0;
    2054      1224546 :             heatPump.PartLoadRatio = 0.0;
    2055      1224546 :             heatPump.OutletAirDBTemp = heatPump.InletAirDBTemp;
    2056      1224546 :             heatPump.OutletAirHumRat = heatPump.InletAirHumRat;
    2057      1224546 :             heatPump.OutletWaterTemp = heatPump.InletWaterTemp;
    2058      1224546 :             heatPump.OutletAirMassFlowRate = heatPump.InletAirMassFlowRate;
    2059      1224546 :             heatPump.OutletWaterMassFlowRate = heatPump.InletWaterMassFlowRate;
    2060      1224546 :             heatPump.OutletAirEnthalpy = heatPump.InletAirEnthalpy;
    2061      1224546 :             heatPump.OutletWaterEnthalpy = heatPump.InletWaterEnthalpy;
    2062              :         }
    2063              : 
    2064              :         // Set the outlet air nodes of the WatertoAirHP
    2065      1891379 :         state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).MassFlowRate = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRate;
    2066      1891379 :         state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).Temp = heatPump.OutletAirDBTemp;
    2067      1891379 :         state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).HumRat = heatPump.OutletAirHumRat;
    2068      1891379 :         state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).Enthalpy = heatPump.OutletAirEnthalpy;
    2069              : 
    2070              :         // Set the outlet nodes for properties that just pass through & not used
    2071      1891379 :         PlantUtilities::SafeCopyPlantNode(state, heatPump.WaterInletNodeNum, heatPump.WaterOutletNodeNum);
    2072              :         // Set the outlet water nodes for the heat pump
    2073      1891379 :         state.dataLoopNodes->Node(heatPump.WaterOutletNodeNum).Temp = heatPump.OutletWaterTemp;
    2074      1891379 :         state.dataLoopNodes->Node(heatPump.WaterOutletNodeNum).Enthalpy = heatPump.OutletWaterEnthalpy;
    2075              : 
    2076              :         // Set the outlet nodes for properties that just pass through & not used
    2077      1891379 :         state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).Quality = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).Quality;
    2078      1891379 :         state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).Press = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).Press;
    2079      1891379 :         state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).MassFlowRateMin = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRateMin;
    2080      1891379 :         state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).MassFlowRateMax = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRateMax;
    2081      1891379 :         state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).MassFlowRateMinAvail =
    2082      1891379 :             state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRateMinAvail;
    2083      1891379 :         state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).MassFlowRateMaxAvail =
    2084      1891379 :             state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRateMaxAvail;
    2085              : 
    2086              :         // Pass through the load side mass flow rates
    2087      1891379 :         heatPump.InletAirMassFlowRate = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRate;
    2088      1891379 :         heatPump.OutletAirMassFlowRate = heatPump.InletAirMassFlowRate;
    2089              : 
    2090      1891379 :         heatPump.Energy = heatPump.Power * TimeStepSysSec;
    2091      1891379 :         heatPump.EnergyLoadTotal = heatPump.QLoadTotal * TimeStepSysSec;
    2092      1891379 :         heatPump.EnergySensible = heatPump.QSensible * TimeStepSysSec;
    2093      1891379 :         heatPump.EnergyLatent = heatPump.QLatent * TimeStepSysSec;
    2094      1891379 :         heatPump.EnergySource = heatPump.QSource * TimeStepSysSec;
    2095              : 
    2096      1891379 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    2097            0 :             state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).CO2 = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).CO2;
    2098              :         }
    2099      1891379 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    2100            0 :             state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).GenContam = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).GenContam;
    2101              :         }
    2102      1891379 :     }
    2103              : 
    2104              :     //        End of Update subroutines for the WatertoAirHP Module
    2105              :     // *****************************************************************************
    2106              : 
    2107            0 :     Real64 CalcEffectiveSHR(EnergyPlusData &state,
    2108              :                             int const HPNum,         // Index number for cooling coil
    2109              :                             Real64 const SHRss,      // Steady-state sensible heat ratio
    2110              :                             HVAC::FanOp const fanOp, // fan/compressor cycling scheme indicator
    2111              :                             Real64 const RTF,        // Compressor run-time fraction
    2112              :                             Real64 const QLatRated,  // Rated latent capacity
    2113              :                             Real64 const QLatActual, // Actual latent capacity
    2114              :                             Real64 const EnteringDB, // Entering air dry-bulb temperature
    2115              :                             Real64 const EnteringWB  // Entering air wet-bulb temperature
    2116              :     )
    2117              :     {
    2118              : 
    2119              :         // FUNCTION INFORMATION:
    2120              :         //    AUTHOR         Richard Raustad, FSEC
    2121              :         //    DATE WRITTEN   September 2003
    2122              :         //    MODIFIED       Kenneth Tang (Aug 2004) Added capability for simulating FanOp::Cycling
    2123              : 
    2124              :         // PURPOSE OF THIS FUNCTION:
    2125              :         //    Adjust sensible heat ratio to account for degradation of DX coil latent
    2126              :         //    capacity at part-load (cycling) conditions.
    2127              : 
    2128              :         // METHODOLOGY EMPLOYED:
    2129              :         //    With model parameters entered by the user, the part-load latent performance
    2130              :         //    of a DX cooling coil is determined for a constant air flow system with
    2131              :         //    a cooling coil that cycles on/off. The model calculates the time
    2132              :         //    required for condensate to begin falling from the cooling coil.
    2133              :         //    Runtimes greater than this are integrated to a "part-load" latent
    2134              :         //    capacity which is used to determine the "part-load" sensible heat ratio.
    2135              :         //    See reference below for additional details (linear decay model, Eq. 8b).
    2136              :         // REFERENCES:
    2137              :         //   "A Model to Predict the Latent Capacity of Air Conditioners and
    2138              :         //    Heat Pumps at Part-Load Conditions with Constant Fan Operation"
    2139              :         //    1996 ASHRAE Transactions, Volume 102, Part 1, Pp. 266 - 274,
    2140              :         //    Hugh I. Henderson, Jr., P.E., Kannan Rengarajan, P.E.
    2141              : 
    2142              :         // Using/Aliasing
    2143            0 :         auto const &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
    2144              : 
    2145              :         // Return value
    2146              :         Real64 SHReff; // Effective sensible heat ratio, includes degradation due to cycling effects
    2147              : 
    2148              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    2149              :         Real64 Twet; // Nominal time for condensate to begin leaving the coil's condensate drain line
    2150              :         //   at the current operating conditions (sec)
    2151              :         Real64 Gamma; // Initial moisture evaporation rate divided by steady-state AC latent capacity
    2152              :         //   at the current operating conditions
    2153              :         Real64 Twet_max; // Maximum allowed value for Twet
    2154              :         // shut off after compressor cycle off  [s]
    2155              : 
    2156              :         Real64 Ton;     // Coil on time (sec)
    2157              :         Real64 Toff;    // Coil off time (sec)
    2158              :         Real64 Toffa;   // Actual coil off time (sec). Equations valid for Toff <= (2.0 * Twet/Gamma)
    2159              :         Real64 aa;      // Intermediate variable
    2160              :         Real64 To1;     // Intermediate variable (first guess at To). To = time to the start of moisture removal
    2161              :         Real64 To2;     // Intermediate variable (second guess at To). To = time to the start of moisture removal
    2162              :         Real64 Error;   // Error for iteration (DO) loop
    2163              :         Real64 LHRmult; // Latent Heat Ratio (LHR) multiplier. The effective latent heat ratio LHR = (1-SHRss)*LHRmult
    2164              : 
    2165              :         //  No moisture evaporation (latent degradation) occurs for runtime fraction of 1.0
    2166              :         //  All latent degradation model parameters cause divide by 0.0 if not greater than 0.0
    2167              :         //  Latent degradation model parameters initialize to 0.0 meaning no evaporation model used.
    2168            0 :         if ((RTF >= 1.0) || (QLatRated == 0.0) || (QLatActual == 0.0) || (heatPump.Twet_Rated <= 0.0) || (heatPump.Gamma_Rated <= 0.0) ||
    2169            0 :             (heatPump.MaxONOFFCyclesperHour <= 0.0) || (heatPump.LatentCapacityTimeConstant <= 0.0) || (RTF <= 0.0)) {
    2170            0 :             SHReff = SHRss;
    2171            0 :             return SHReff;
    2172              :         }
    2173              : 
    2174            0 :         Twet_max = 9999.0; // high limit for Twet
    2175              : 
    2176              :         //  Calculate the model parameters at the actual operating conditions
    2177            0 :         Twet = min(heatPump.Twet_Rated * QLatRated / (QLatActual + 1.e-10), Twet_max);
    2178            0 :         Gamma = heatPump.Gamma_Rated * QLatRated * (EnteringDB - EnteringWB) / ((26.7 - 19.4) * QLatActual + 1.e-10);
    2179              : 
    2180              :         //  Calculate the compressor on and off times using a conventional thermostat curve
    2181            0 :         Ton = 3600.0 / (4.0 * heatPump.MaxONOFFCyclesperHour * (1.0 - RTF)); // duration of cooling coil on-cycle (sec)
    2182              : 
    2183            0 :         if ((fanOp == HVAC::FanOp::Cycling) && (heatPump.FanDelayTime != 0.0)) {
    2184              :             //  For FanOp::Cycling, moisture is evaporated from the cooling coil back to the air stream
    2185              :             //  until the fan cycle off. Assume no evaporation from the coil after the fan shuts off.
    2186            0 :             Toff = heatPump.FanDelayTime;
    2187              :         } else {
    2188              :             //  For FanOp::Continuous, moisture is evaporated from the cooling coil back to the air stream
    2189              :             //  for the entire heat pump off-cycle.
    2190            0 :             Toff = 3600.0 / (4.0 * heatPump.MaxONOFFCyclesperHour * RTF); // duration of cooling coil off-cycle (sec)
    2191              :         }
    2192              : 
    2193              :         //  Cap Toff to meet the equation restriction
    2194            0 :         if (Gamma > 0.0) {
    2195            0 :             Toffa = min(Toff, 2.0 * Twet / Gamma);
    2196              :         } else {
    2197            0 :             Toffa = Toff;
    2198              :         }
    2199              : 
    2200              :         //  Use sucessive substitution to solve for To
    2201            0 :         aa = (Gamma * Toffa) - (0.25 / Twet) * pow_2(Gamma) * pow_2(Toffa);
    2202              : 
    2203            0 :         To1 = aa + heatPump.LatentCapacityTimeConstant;
    2204            0 :         Error = 1.0;
    2205            0 :         while (Error > 0.001) {
    2206            0 :             To2 = aa - heatPump.LatentCapacityTimeConstant * std::expm1(-To1 / heatPump.LatentCapacityTimeConstant);
    2207            0 :             Error = std::abs((To2 - To1) / To1);
    2208            0 :             To1 = To2;
    2209              :         }
    2210              : 
    2211              :         //  Adjust Sensible Heat Ratio (SHR) using Latent Heat Ratio (LHR) multiplier
    2212              :         //  Floating underflow errors occur when -Ton/LatentCapacityTimeConstant is a large negative number.
    2213              :         //  Cap lower limit at -700 to avoid the underflow errors.
    2214            0 :         aa = std::exp(max(-700.0, -Ton / heatPump.LatentCapacityTimeConstant));
    2215              :         //  Calculate latent heat ratio multiplier
    2216            0 :         LHRmult = max(((Ton - To2) / (Ton + heatPump.LatentCapacityTimeConstant * (aa - 1.0))), 0.0);
    2217              : 
    2218              :         //  Calculate part-load or "effective" sensible heat ratio
    2219            0 :         SHReff = 1.0 - (1.0 - SHRss) * LHRmult;
    2220              : 
    2221            0 :         if (SHReff < SHRss) {
    2222            0 :             SHReff = SHRss; // Effective SHR can be less than the steady-state SHR
    2223              :         }
    2224            0 :         if (SHReff > 1.0) {
    2225            0 :             SHReff = 1.0; // Effective sensible heat ratio can't be greater than 1.0
    2226              :         }
    2227              : 
    2228            0 :         return SHReff;
    2229              :     }
    2230              : 
    2231       317431 :     Real64 DegradF(EnergyPlusData &state,
    2232              :                    Fluid::GlycolProps *glycol,
    2233              :                    Real64 &Temp // Temperature of the fluid
    2234              :     )
    2235              :     {
    2236              :         // FUNCTION INFORMATION:
    2237              :         //    AUTHOR         Kenneth Tang
    2238              :         //    DATE WRITTEN   October 2004
    2239              : 
    2240              :         // PURPOSE OF THIS FUNCTION:
    2241              :         //    Calculate the degradation factor to predict the heat pump performance
    2242              :         //    when antifreeze is used.
    2243              :         // METHODOLOGY EMPLOYED:
    2244              :         //    Use FluidProperties to calculate the properties of water and glycol
    2245              :         //    at the given temperature. Then substitute the properties into the equation.
    2246              :         // REFERENCES:
    2247              :         //    Jin, H. 2002. Parameter Estimation Based Models of Water Source Heat Pumps. Phd Thesis.
    2248              :         //    Oklahoma State University.
    2249              : 
    2250              :         // Return value
    2251              :         Real64 DegradF;
    2252              : 
    2253              :         // FUNCTION PARAMETER DEFINITIONS:
    2254              :         static constexpr std::string_view CalledFrom("HVACWaterToAir:DegradF");
    2255              : 
    2256              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    2257              :         Real64 VisWater;       // Viscosity of water [mPa-s]
    2258              :         Real64 DensityWater;   // Density of water [kg/m3]
    2259              :         Real64 CpWater;        // Specific heat of water [J/kg-K]
    2260              :         Real64 CondWater;      // Conductivity of water [W/m-K]
    2261              :         Real64 VisCoolant;     // Viscosity of water [mPa-s]
    2262              :         Real64 DensityCoolant; // Density of water [kg/m3]
    2263              :         Real64 CpCoolant;      // Specific heat of water [J/kg-K]
    2264              :         Real64 CondCoolant;    // Conductivity of water [W/m-K]
    2265              : 
    2266       317431 :         auto *water = Fluid::GetWater(state);
    2267              : 
    2268       317431 :         VisWater = water->getViscosity(state, Temp, CalledFrom);
    2269       317431 :         DensityWater = water->getDensity(state, Temp, CalledFrom);
    2270       317431 :         CpWater = water->getSpecificHeat(state, Temp, CalledFrom);
    2271       317431 :         CondWater = water->getConductivity(state, Temp, CalledFrom);
    2272       317431 :         VisCoolant = glycol->getViscosity(state, Temp, CalledFrom);
    2273       317431 :         DensityCoolant = glycol->getDensity(state, Temp, CalledFrom);
    2274       317431 :         CpCoolant = glycol->getSpecificHeat(state, Temp, CalledFrom);
    2275       317431 :         CondCoolant = glycol->getConductivity(state, Temp, CalledFrom);
    2276              : 
    2277       317431 :         DegradF = std::pow(VisCoolant / VisWater, -0.47) * std::pow(DensityCoolant / DensityWater, 0.8) * std::pow(CpCoolant / CpWater, 0.33) *
    2278       317431 :                   std::pow(CondCoolant / CondWater, 0.67);
    2279              : 
    2280       317431 :         return DegradF;
    2281              :     }
    2282              : 
    2283           38 :     int GetCoilIndex(EnergyPlusData &state,
    2284              :                      std::string const &CoilType, // must match coil types in this module
    2285              :                      std::string const &CoilName, // must match coil names for the coil type
    2286              :                      bool &ErrorsFound            // set to true if problem
    2287              :     )
    2288              :     {
    2289              : 
    2290              :         // FUNCTION INFORMATION:
    2291              :         //       AUTHOR         R. Raustad
    2292              :         //       DATE WRITTEN   August 2007
    2293              : 
    2294              :         // PURPOSE OF THIS FUNCTION:
    2295              :         // This function looks up the given coil and returns the index.  If
    2296              :         // incorrect coil type or name is given, ErrorsFound is returned as true and value is returned
    2297              :         // as zero.
    2298              : 
    2299              :         // Obtains and Allocates WatertoAirHP related parameters from input file
    2300           38 :         if (state.dataWaterToAirHeatPump->GetCoilsInputFlag) { // First time subroutine has been entered
    2301            6 :             GetWatertoAirHPInput(state);
    2302            6 :             state.dataWaterToAirHeatPump->GetCoilsInputFlag = false;
    2303              :         }
    2304              : 
    2305           38 :         int IndexNum = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPump->WatertoAirHP);
    2306              : 
    2307           38 :         if (IndexNum == 0) {
    2308            0 :             ShowSevereError(state, format("Could not find CoilType=\"{}\" with Name=\"{}\"", CoilType, CoilName));
    2309            0 :             ErrorsFound = true;
    2310              :         }
    2311              : 
    2312           38 :         return IndexNum;
    2313              :     }
    2314              : 
    2315           33 :     Real64 GetCoilCapacity(EnergyPlusData &state,
    2316              :                            std::string const &CoilType, // must match coil types in this module
    2317              :                            std::string const &CoilName, // must match coil names for the coil type
    2318              :                            bool &ErrorsFound            // set to true if problem
    2319              :     )
    2320              :     {
    2321              : 
    2322              :         // FUNCTION INFORMATION:
    2323              :         //       AUTHOR         Linda Lawrie
    2324              :         //       DATE WRITTEN   February 2006
    2325              : 
    2326              :         // PURPOSE OF THIS FUNCTION:
    2327              :         // This function looks up the coil capacity for the given coil and returns it.  If
    2328              :         // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
    2329              :         // as negative.
    2330              : 
    2331              :         // Return value
    2332              :         Real64 CoilCapacity; // returned capacity of matched coil
    2333              : 
    2334              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    2335              :         int WhichCoil;
    2336              : 
    2337              :         // Obtains and Allocates WatertoAirHP related parameters from input file
    2338           33 :         if (state.dataWaterToAirHeatPump->GetCoilsInputFlag) { // First time subroutine has been entered
    2339            0 :             GetWatertoAirHPInput(state);
    2340            0 :             state.dataWaterToAirHeatPump->GetCoilsInputFlag = false;
    2341              :         }
    2342              : 
    2343           52 :         if (Util::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION") ||
    2344           52 :             Util::SameString(CoilType, "COIL:COOLING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION")) {
    2345           33 :             WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPump->WatertoAirHP);
    2346           33 :             if (WhichCoil != 0) {
    2347           33 :                 if (Util::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION")) {
    2348           14 :                     CoilCapacity = state.dataWaterToAirHeatPump->WatertoAirHP(WhichCoil).HeatingCapacity;
    2349              :                 } else {
    2350           19 :                     CoilCapacity = state.dataWaterToAirHeatPump->WatertoAirHP(WhichCoil).CoolingCapacity;
    2351              :                 }
    2352              :             }
    2353              :         } else {
    2354            0 :             WhichCoil = 0;
    2355              :         }
    2356              : 
    2357           33 :         if (WhichCoil == 0) {
    2358            0 :             ShowSevereError(state, format("Could not find CoilType=\"{}\" with Name=\"{}\"", CoilType, CoilName));
    2359            0 :             ErrorsFound = true;
    2360            0 :             CoilCapacity = -1000.0;
    2361              :         }
    2362              : 
    2363           33 :         return CoilCapacity;
    2364              :     }
    2365              : 
    2366           28 :     int GetCoilInletNode(EnergyPlusData &state,
    2367              :                          std::string const &CoilType, // must match coil types in this module
    2368              :                          std::string const &CoilName, // must match coil names for the coil type
    2369              :                          bool &ErrorsFound            // set to true if problem
    2370              :     )
    2371              :     {
    2372              : 
    2373              :         // FUNCTION INFORMATION:
    2374              :         //       AUTHOR         Linda Lawrie
    2375              :         //       DATE WRITTEN   February 2006
    2376              : 
    2377              :         // PURPOSE OF THIS FUNCTION:
    2378              :         // This function looks up the given coil and returns the inlet node.  If
    2379              :         // incorrect coil type or name is given, ErrorsFound is returned as true and value is returned
    2380              :         // as zero.
    2381              : 
    2382              :         // Return value
    2383              :         int NodeNumber; // returned outlet node of matched coil
    2384              : 
    2385              :         // Obtains and Allocates WatertoAirHP related parameters from input file
    2386           28 :         if (state.dataWaterToAirHeatPump->GetCoilsInputFlag) { // First time subroutine has been entered
    2387            0 :             GetWatertoAirHPInput(state);
    2388            0 :             state.dataWaterToAirHeatPump->GetCoilsInputFlag = false;
    2389              :         }
    2390              : 
    2391           28 :         int WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPump->WatertoAirHP);
    2392           28 :         if (WhichCoil != 0) {
    2393           28 :             NodeNumber = state.dataWaterToAirHeatPump->WatertoAirHP(WhichCoil).AirInletNodeNum;
    2394              :         }
    2395              : 
    2396           28 :         if (WhichCoil == 0) {
    2397            0 :             ShowSevereError(state, format("Could not find CoilType=\"{}\" with Name=\"{}\"", CoilType, CoilName));
    2398            0 :             ErrorsFound = true;
    2399            0 :             NodeNumber = 0;
    2400              :         }
    2401              : 
    2402           28 :         return NodeNumber;
    2403              :     }
    2404              : 
    2405           28 :     int GetCoilOutletNode(EnergyPlusData &state,
    2406              :                           std::string const &CoilType, // must match coil types in this module
    2407              :                           std::string const &CoilName, // must match coil names for the coil type
    2408              :                           bool &ErrorsFound            // set to true if problem
    2409              :     )
    2410              :     {
    2411              : 
    2412              :         // FUNCTION INFORMATION:
    2413              :         //       AUTHOR         R. Raustad
    2414              :         //       DATE WRITTEN   July 2007
    2415              : 
    2416              :         // PURPOSE OF THIS FUNCTION:
    2417              :         // This function looks up the given coil and returns the outlet node.  If
    2418              :         // incorrect coil type or name is given, ErrorsFound is returned as true and value is returned
    2419              :         // as zero.
    2420              : 
    2421              :         // Return value
    2422              :         int NodeNumber; // returned outlet node of matched coil
    2423              : 
    2424              :         // Obtains and Allocates WatertoAirHP related parameters from input file
    2425           28 :         if (state.dataWaterToAirHeatPump->GetCoilsInputFlag) { // First time subroutine has been entered
    2426            0 :             GetWatertoAirHPInput(state);
    2427            0 :             state.dataWaterToAirHeatPump->GetCoilsInputFlag = false;
    2428              :         }
    2429              : 
    2430           28 :         int WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPump->WatertoAirHP);
    2431           28 :         if (WhichCoil != 0) {
    2432           28 :             NodeNumber = state.dataWaterToAirHeatPump->WatertoAirHP(WhichCoil).AirOutletNodeNum;
    2433              :         }
    2434              : 
    2435           28 :         if (WhichCoil == 0) {
    2436            0 :             ShowSevereError(state, format("Could not find CoilType=\"{}\" with Name=\"{}\"", CoilType, CoilName));
    2437            0 :             ErrorsFound = true;
    2438            0 :             NodeNumber = 0;
    2439              :         }
    2440              : 
    2441           28 :         return NodeNumber;
    2442              :     }
    2443              : 
    2444              : } // namespace WaterToAirHeatPump
    2445              : 
    2446              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1