LCOV - code coverage report
Current view: top level - EnergyPlus - DXCoils.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 66.4 % 8874 5890
Test Date: 2025-05-22 16:09:37 Functions: 88.5 % 61 54

            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              : #include <string>
      51              : 
      52              : // ObjexxFCL Headers
      53              : #include <ObjexxFCL/Fmath.hh>
      54              : 
      55              : // EnergyPlus Headers
      56              : #include <EnergyPlus/Autosizing/All_Simple_Sizing.hh>
      57              : #include <EnergyPlus/Autosizing/CoolingAirFlowSizing.hh>
      58              : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
      59              : #include <EnergyPlus/Autosizing/CoolingSHRSizing.hh>
      60              : #include <EnergyPlus/Autosizing/HeatingAirFlowSizing.hh>
      61              : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
      62              : #include <EnergyPlus/BranchNodeConnections.hh>
      63              : #include <EnergyPlus/CurveManager.hh>
      64              : #include <EnergyPlus/DXCoils.hh>
      65              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      66              : #include <EnergyPlus/DataAirSystems.hh>
      67              : #include <EnergyPlus/DataBranchNodeConnections.hh>
      68              : #include <EnergyPlus/DataContaminantBalance.hh>
      69              : #include <EnergyPlus/DataEnvironment.hh>
      70              : #include <EnergyPlus/DataGlobalConstants.hh>
      71              : #include <EnergyPlus/DataHeatBalance.hh>
      72              : #include <EnergyPlus/DataLoopNode.hh>
      73              : #include <EnergyPlus/DataPrecisionGlobals.hh>
      74              : #include <EnergyPlus/DataSizing.hh>
      75              : #include <EnergyPlus/DataWater.hh>
      76              : #include <EnergyPlus/EMSManager.hh>
      77              : #include <EnergyPlus/Fans.hh>
      78              : #include <EnergyPlus/General.hh>
      79              : #include <EnergyPlus/GeneralRoutines.hh>
      80              : #include <EnergyPlus/GlobalNames.hh>
      81              : #include <EnergyPlus/HVACVariableRefrigerantFlow.hh>
      82              : #include <EnergyPlus/HeatBalanceInternalHeatGains.hh>
      83              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      84              : #include <EnergyPlus/NodeInputManager.hh>
      85              : #include <EnergyPlus/OutAirNodeManager.hh>
      86              : #include <EnergyPlus/OutputProcessor.hh>
      87              : #include <EnergyPlus/OutputReportPredefined.hh>
      88              : #include <EnergyPlus/Psychrometrics.hh>
      89              : #include <EnergyPlus/ScheduleManager.hh>
      90              : #include <EnergyPlus/SimAirServingZones.hh>
      91              : #include <EnergyPlus/StandardRatings.hh>
      92              : #include <EnergyPlus/UtilityRoutines.hh>
      93              : #include <EnergyPlus/WaterManager.hh>
      94              : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      95              : 
      96              : namespace EnergyPlus::DXCoils {
      97              : 
      98              : // Module containing the DX coil simulation routines
      99              : 
     100              : // MODULE INFORMATION:
     101              : //       AUTHOR         Fred Buhl
     102              : //       DATE WRITTEN   May 2000
     103              : //       MODIFIED       Aug 2000, Don Shirey, Sept 2000, Feb/Oct 2001, Sept 2003, Jan 2004
     104              : //                      Feb 2005, M. J. Witte, GARD Analytics, Inc., Add new coil type COIL:DX:MultiMode:CoolingEmpirical: Work supported by
     105              : //                      ASHRAE research project 1254-RP Aug 2006, B Griffith, NREL, Added water system interactions for new water manager, Feb
     106              : //                      2010, B Nigusse, FSEC, Added Standard Rating for Coil:Cooling:DX:SingleSpeed Apr 2010, Chandan Sharma, FSEC, Added basin
     107              : //                      heater routines for Coil:Cooling:DX:SingleSpeed, Coil:Cooling:DX:TwoSpeed,
     108              : //                                Coil:Cooling:DX:MultiSpeed, and Coil:Cooling:DX:TwoStageWithHumidityControlMode
     109              : //                      Feb 2013, Bereket Nigusse, FSEC, Added DX Coil Model For 100% OA systems
     110              : //                      Jul 2015, RP Zhang, XF Pang, LBNL, Added new coil type for VRF-FluidTemperatureControl Model
     111              : 
     112              : // PURPOSE OF THIS MODULE:
     113              : // To encapsulate the data and algorithms required to simulate DX cooling coils in
     114              : // EnergyPlus. Module currently models air-cooled or evap-cooled direct expansion systems
     115              : // (split or packaged). Air-side performance is modeled to determine coil discharge
     116              : // air conditions. The module also determines the DX unit's electrical energy usage.
     117              : // Neither the air-side performance nor the electrical energy usage includes the effect
     118              : // of supply air fan heat/energy usage. The supply air fan is modeled by other modules.
     119              : 
     120              : // USE STATEMENTS:
     121              : // Use statements for data only modules
     122              : // Using/Aliasing
     123              : using namespace DataLoopNode;
     124              : using namespace Psychrometrics;
     125              : 
     126              : // Functions
     127              : 
     128       521504 : void SimDXCoil(EnergyPlusData &state,
     129              :                std::string_view CompName,             // name of the fan coil unit
     130              :                HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
     131              :                bool const FirstHVACIteration,         // True when first HVAC iteration
     132              :                int &CompIndex,
     133              :                HVAC::FanOp const fanOp,                                      // allows parent object to control fan mode
     134              :                ObjexxFCL::Optional<Real64 const> PartLoadRatio,              // part load ratio (for single speed cycling unit)
     135              :                ObjexxFCL::Optional<Real64 const> OnOffAFR,                   // ratio of compressor on airflow to compressor off airflow
     136              :                ObjexxFCL::Optional<Real64 const> CoilCoolingHeatingPLRRatio, // used for cycling fan RH control
     137              :                ObjexxFCL::Optional<Real64 const> MaxCap,                     // maximum cooling capacity of VRF terminal units
     138              :                ObjexxFCL::Optional<Real64 const> CompCyclingRatio            // cycling ratio of VRF condenser connected to this TU
     139              : )
     140              : {
     141              : 
     142              :     // SUBROUTINE INFORMATION:
     143              :     //       AUTHOR         Fred Buhl
     144              :     //       DATE WRITTEN   May 2000
     145              :     //       MODIFIED       Don Shirey, Sept 2000, October 2001, June 2005
     146              : 
     147              :     // PURPOSE OF THIS SUBROUTINE:
     148              :     // Manages the simulation of a single speed on/off DX coil.
     149              : 
     150              :     // Using/Aliasing
     151              : 
     152              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     153              :     int DXCoilNum;       // index of fan coil unit being simulated
     154              :     Real64 AirFlowRatio; // ratio of compressor on airflow to compressor off airflow
     155              :     Real64 CompCycRatio; // compressor cycling ratio of VRF condenser
     156              : 
     157              :     // First time SimDXCoil is called, get the input for all the DX coils (condensing units)
     158       521504 :     if (state.dataDXCoils->GetCoilsInputFlag) {
     159            0 :         GetDXCoils(state);
     160            0 :         state.dataDXCoils->GetCoilsInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
     161              :     }
     162              : 
     163       521504 :     if (CompIndex == 0) {
     164            7 :         DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
     165            7 :         if (DXCoilNum == 0) {
     166            0 :             ShowFatalError(state, format("DX Coil not found={}", CompName));
     167              :         }
     168            7 :         CompIndex = DXCoilNum;
     169              :     } else {
     170       521497 :         DXCoilNum = CompIndex;
     171       521497 :         if (DXCoilNum > state.dataDXCoils->NumDXCoils || DXCoilNum < 1) {
     172            0 :             ShowFatalError(state,
     173            0 :                            format("SimDXCoil: Invalid CompIndex passed={}, Number of DX Coils={}, Coil name={}",
     174              :                                   DXCoilNum,
     175            0 :                                   state.dataDXCoils->NumDXCoils,
     176              :                                   CompName));
     177              :         }
     178       521497 :         if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
     179           86 :             if (!CompName.empty() && CompName != state.dataDXCoils->DXCoil(DXCoilNum).Name) {
     180            0 :                 ShowFatalError(state,
     181            0 :                                format("SimDXCoil: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
     182              :                                       DXCoilNum,
     183              :                                       CompName,
     184            0 :                                       state.dataDXCoils->DXCoil(DXCoilNum).Name));
     185              :             }
     186           86 :             state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
     187              :         }
     188              :     }
     189              : 
     190       521504 :     if (present(OnOffAFR)) {
     191       414840 :         AirFlowRatio = OnOffAFR;
     192              :     } else {
     193       106664 :         AirFlowRatio = 1.0;
     194              :     }
     195              : 
     196       521504 :     if (present(CompCyclingRatio)) {
     197        38582 :         CompCycRatio = CompCyclingRatio;
     198              :     } else {
     199       482922 :         CompCycRatio = 1.0;
     200              :     }
     201              : 
     202              :     // Initialize the DX coil unit
     203       521504 :     InitDXCoil(state, DXCoilNum);
     204              : 
     205              :     // Select the correct unit type
     206       521504 :     switch (state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType_Num) { // Autodesk:OPTIONAL PartLoadRatio, MaxCap used in this block without PRESENT check
     207       247087 :     case HVAC::CoilDX_CoolingSingleSpeed: {
     208       247087 :         if (present(CoilCoolingHeatingPLRRatio)) {
     209        59945 :             CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration, PartLoadRatio, fanOp, _, AirFlowRatio, CoilCoolingHeatingPLRRatio);
     210              :         } else {
     211       187142 :             CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration, PartLoadRatio, fanOp, _, AirFlowRatio);
     212              :         }
     213       247087 :     } break;
     214       127966 :     case HVAC::CoilDX_HeatingEmpirical: {
     215       127966 :         CalcDXHeatingCoil(state, DXCoilNum, PartLoadRatio, fanOp, AirFlowRatio);
     216       127966 :     } break;
     217          161 :     case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
     218              :     case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
     219              :         //   call the HPWHDXCoil routine to calculate water side performance set up the DX coil info for air-side calcs
     220          161 :         CalcHPWHDXCoil(state, DXCoilNum, PartLoadRatio);
     221              :         //    CALL CalcDoe2DXCoil(state, DXCoilNum, compressorOp, FirstHVACIteration,PartLoadRatio), perform air-side calculations
     222          161 :         CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp);
     223          161 :     } break;
     224        49492 :     case HVAC::CoilVRF_Cooling: {
     225        49492 :         CalcVRFCoolingCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, CompCycRatio, _, AirFlowRatio, MaxCap);
     226        49492 :     } break;
     227        49492 :     case HVAC::CoilVRF_Heating: {
     228        49492 :         CalcDXHeatingCoil(state, DXCoilNum, PartLoadRatio, fanOp, AirFlowRatio, MaxCap);
     229        49492 :     } break;
     230        23653 :     case HVAC::CoilVRF_FluidTCtrl_Cooling: {
     231        23653 :         CalcVRFCoolingCoil_FluidTCtrl(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, CompCycRatio, _, _, MaxCap);
     232        23653 :     } break;
     233        23653 :     case HVAC::CoilVRF_FluidTCtrl_Heating: {
     234        23653 :         CalcVRFHeatingCoil_FluidTCtrl(state, compressorOp, DXCoilNum, PartLoadRatio, fanOp, _, MaxCap);
     235        23653 :     } break;
     236            0 :     default: {
     237            0 :         ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
     238            0 :         ShowContinueError(state, format("Invalid DX Coil Type={}", state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType));
     239            0 :         ShowFatalError(state, "Preceding condition causes termination.");
     240            0 :     } break;
     241              :     }
     242              : 
     243              :     // Update the unit outlet nodes
     244       521504 :     UpdateDXCoil(state, DXCoilNum);
     245              : 
     246              :     // Report the result of the simulation
     247       521504 :     ReportDXCoil(state, DXCoilNum);
     248       521504 : }
     249              : 
     250        17558 : void SimDXCoilMultiSpeed(EnergyPlusData &state,
     251              :                          std::string_view CompName, // name of the fan coil unit
     252              :                          Real64 const SpeedRatio,   // = (CompressorSpeed - CompressorSpeedMin) /
     253              :                          Real64 const CycRatio,     // cycling part load ratio for variable speed
     254              :                          int &CompIndex,
     255              :                          ObjexxFCL::Optional_int_const SpeedNum,       // Speed number for multispeed cooling coil only
     256              :                          ObjexxFCL::Optional<HVAC::FanOp const> fanOp, // Fan operation mode
     257              :                          HVAC::CompressorOp compressorOp,              // Compressor on/off; 1=on, 0=off
     258              :                          ObjexxFCL::Optional_int_const SingleMode      // Single mode operation Yes/No; 1=Yes, 0=No
     259              : )
     260              : {
     261              : 
     262              :     // SUBROUTINE INFORMATION:
     263              :     //       AUTHOR         Fred Buhl
     264              :     //       DATE WRITTEN   September 2002
     265              :     //       MODIFIED       Lixing Gu, Sep. 2007
     266              : 
     267              :     // PURPOSE OF THIS SUBROUTINE:
     268              :     // Manages the simulation of a multi speed DX coil.
     269              : 
     270              :     // Using/Aliasing
     271              : 
     272              :     // Locals
     273              :     // SUBROUTINE ARGUMENT DEFINITIONS:
     274              :     //   (CompressorSpeedMax - CompressorSpeedMin)
     275              :     // for variable speed or 2 speed compressors
     276              :     // or 2 speed compressors
     277              : 
     278              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     279              :     int DXCoilNum;      // index of fan coil unit being simulated
     280              :     int SingleModeOper; // SingleMode Operation
     281              : 
     282              :     // First time SimDXCoil is called, get the input for all the DX coils (condensing units)
     283        17558 :     if (state.dataDXCoils->GetCoilsInputFlag) {
     284            0 :         GetDXCoils(state);
     285            0 :         state.dataDXCoils->GetCoilsInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
     286              :     }
     287              : 
     288              :     //  find correct DX Coil
     289              : 
     290        17558 :     if (CompIndex == 0) {
     291            0 :         DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
     292            0 :         if (DXCoilNum == 0) {
     293            0 :             ShowFatalError(state, format("DX Coil not found={}", CompName));
     294              :         }
     295            0 :         CompIndex = DXCoilNum;
     296              :     } else {
     297        17558 :         DXCoilNum = CompIndex;
     298        17558 :         if (DXCoilNum > state.dataDXCoils->NumDXCoils || DXCoilNum < 1) {
     299            0 :             ShowFatalError(state,
     300            0 :                            format("SimDXCoilMultiSpeed: Invalid CompIndex passed={}, Number of DX Coils={}, Coil name={}",
     301              :                                   DXCoilNum,
     302            0 :                                   state.dataDXCoils->NumDXCoils,
     303              :                                   CompName));
     304              :         }
     305        17558 :         if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
     306           17 :             if (!CompName.empty() && CompName != state.dataDXCoils->DXCoil(DXCoilNum).Name) {
     307            0 :                 ShowFatalError(state,
     308            0 :                                format("SimDXCoilMultiSpeed: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
     309              :                                       DXCoilNum,
     310              :                                       CompName,
     311            0 :                                       state.dataDXCoils->DXCoil(DXCoilNum).Name));
     312              :             }
     313           17 :             state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
     314              :         }
     315              :     }
     316              : 
     317        17558 :     if (present(SingleMode)) {
     318          212 :         SingleModeOper = SingleMode;
     319              :     } else {
     320        17346 :         SingleModeOper = 0;
     321              :     }
     322              : 
     323              :     // Initialize the DX coil unit
     324        17558 :     InitDXCoil(state, DXCoilNum);
     325              : 
     326              :     // Select the correct unit type
     327        17558 :     switch (state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType_Num) {
     328        17109 :     case HVAC::CoilDX_CoolingTwoSpeed: {
     329        17109 :         CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio);
     330        17109 :     } break;
     331          250 :     case HVAC::CoilDX_MultiSpeedCooling: {
     332          250 :         if (present(SpeedNum))
     333          250 :             CalcMultiSpeedDXCoilCooling(state,
     334              :                                         DXCoilNum,
     335              :                                         SpeedRatio,
     336              :                                         CycRatio,
     337              :                                         SpeedNum,
     338              :                                         fanOp,
     339              :                                         compressorOp,
     340              :                                         SingleModeOper); // Autodesk:OPTIONAL fanOp, CompressorOp used without PRESENT check
     341              : 
     342          250 :     } break;
     343          199 :     case HVAC::CoilDX_MultiSpeedHeating: {
     344          199 :         if (present(SpeedNum))
     345          199 :             CalcMultiSpeedDXCoilHeating(state,
     346              :                                         DXCoilNum,
     347              :                                         SpeedRatio,
     348              :                                         CycRatio,
     349              :                                         SpeedNum,
     350              :                                         fanOp,
     351              :                                         SingleModeOper); // Autodesk:OPTIONAL fanOp used without PRESENT check
     352              : 
     353          199 :     } break;
     354            0 :     default: {
     355            0 :         ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
     356            0 :         ShowContinueError(state, format("Invalid DX Coil Type={}", state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType));
     357            0 :         ShowFatalError(state, "Preceding condition causes termination.");
     358            0 :     } break;
     359              :     }
     360              : 
     361              :     // Update the unit outlet nodes
     362        17558 :     UpdateDXCoil(state, DXCoilNum);
     363              : 
     364              :     // Report the result of the simulation
     365        17558 :     ReportDXCoil(state, DXCoilNum);
     366        17558 : }
     367              : 
     368            0 : void SimDXCoilMultiMode(EnergyPlusData &state,
     369              :                         std::string_view CompName,                              // name of the fan coil unit
     370              :                         [[maybe_unused]] HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off !unused1208
     371              :                         bool const FirstHVACIteration,                          // true if first hvac iteration
     372              :                         Real64 const PartLoadRatio,                             // part load ratio
     373              :                         HVAC::CoilMode const DehumidMode,                       // dehumidification mode (0=normal, 1=enhanced)
     374              :                         int &CompIndex,
     375              :                         HVAC::FanOp const fanOp // allows parent object to control fan mode
     376              : )
     377              : {
     378              : 
     379              :     // SUBROUTINE INFORMATION:
     380              :     //       AUTHOR         M. J. Witte (based on SimDXCoilMultiSpeed by Fred Buhl)
     381              :     //       DATE WRITTEN   February 2005
     382              :     //       MODIFIED       April 2010, Chandan sharma, added basin heater
     383              : 
     384              :     // PURPOSE OF THIS SUBROUTINE:
     385              :     // Manages the simulation of a DX coil with multiple performance modes, such as
     386              :     // multiple stages, or sub-cool reheat for humidity control.
     387              : 
     388              :     // Using/Aliasing
     389              : 
     390              :     // SUBROUTINE PARAMETER DEFINITIONS:
     391              :     static constexpr std::string_view RoutineName("SimDXCoilMultiMode");
     392              : 
     393              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     394              :     int DXCoilNum; // index of coil being simulated
     395              :     int PerfMode;  // Performance mode for MultiMode DX coil; Always 1 for other coil types
     396              :     // 1-2=normal mode: 1=stage 1 only, 2=stage 1&2
     397              :     // 3-4=enhanced dehumidification mode: 3=stage 1 only, 4=stage 1&2
     398              :     Real64 AirMassFlow; // Dry air mass flow rate through coil [kg/s]
     399              : 
     400              :     Real64 S1OutletAirTemp;     // Stage 1   Outlet air dry bulb temp [C]
     401              :     Real64 S1OutletAirHumRat;   // Stage 1   Outlet air humidity ratio [kgWater/kgDryAir]
     402              :     Real64 S1OutletAirEnthalpy; // Stage 1   Outlet air enthalpy
     403              :     Real64 S1PLR;               // Stage 1   Ratio of actual sensible cooling load to
     404              :     //           steady-state sensible cooling capacity
     405              :     Real64 S1TotalCoolingEnergyRate; // Stage 1   Total cooling rate [W]
     406              :     Real64 S1SensCoolingEnergyRate;  // Stage 1   Sensible cooling rate [W]
     407              :     Real64 S1LatCoolingEnergyRate;   // Stage 1   Latent cooling rate [W]
     408              :     Real64 S1ElecCoolingPower;       // Stage 1   Electric power input [W]
     409            0 :     Real64 S1RuntimeFraction(0.0);   // Stage 1   Run time fraction (overlaps with stage1&2 run time)
     410              :     Real64 S1EvapCondPumpElecPower;  // Stage 1   Evaporative condenser pump electric power input [W]
     411              :     Real64 S1EvapWaterConsumpRate;   // Stage 1   Evap condenser water consumption rate [m3/s]
     412              :     Real64 S1CrankcaseHeaterPower;   // Stage 1   Report variable for average crankcase heater power [W]
     413              :     Real64 S1FFullLoadOutAirTemp;    // Stage 1   Full load outlet temperature [C]
     414              :     Real64 S1FullLoadOutAirHumRat;   // Stage 1   Full load outlet humidity ratio [kgWater/kgDryAir]
     415              : 
     416              :     Real64 S12OutletAirTemp;     // Stage 1&2 Outlet air dry bulb temp [C]
     417              :     Real64 S12OutletAirHumRat;   // Stage 1&2 Outlet air humidity ratio [kgWater/kgDryAir]
     418              :     Real64 S12OutletAirEnthalpy; // Stage 1&2 Outlet air enthalpy
     419              :     //                                       !           steady-state sensible cooling capacity
     420              :     Real64 S12TotalCoolingEnergyRate; // Stage 1&2 Total cooling rate [W]
     421              :     Real64 S12SensCoolingEnergyRate;  // Stage 1&2 Sensible cooling rate [W]
     422              :     Real64 S12LatCoolingEnergyRate;   // Stage 1&2 Latent cooling rate [W]
     423              :     Real64 S12ElecCoolingPower;       // Stage 1&2 Electric power input [W]
     424              :     Real64 S12ElecCoolFullLoadPower;  // Stage 1&2 Electric power input at full load (PLR=1) [W]
     425            0 :     Real64 S12RuntimeFraction(0.0);   // Stage 1&2 Run time fraction (overlaps with stage1 run time)
     426              :     Real64 S12EvapCondPumpElecPower;  // Stage 1&2 Evaporative condenser pump electric power input [W]
     427              :     Real64 S12EvapWaterConsumpRate;   // Stage 1&2 Evap condenser water consumption rate [m3/s]
     428              :     Real64 S12CrankcaseHeaterPower;   // Stage 1&2 Report variable for average crankcase heater power [W]
     429              :     Real64 S2PLR;                     // Stage 2   Ratio of actual sensible cooling load to
     430              :     //           steady-state sensible cooling capacity
     431              :     Real64 TSat;      // calculation to avoid calling psych routines twice
     432              :     Real64 NodePress; // Pressure at condenser inlet node (Pa)
     433              : 
     434              :     // First time SimDXCoil is called, get the input for all the DX coils (condensing units)
     435            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
     436            0 :         GetDXCoils(state);
     437            0 :         state.dataDXCoils->GetCoilsInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
     438              :     }
     439              : 
     440              :     //  find correct DX Coil
     441            0 :     if (CompIndex == 0) {
     442            0 :         DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
     443            0 :         if (DXCoilNum == 0) {
     444            0 :             ShowFatalError(state, format("DX Coil not found={}", CompName));
     445              :         }
     446            0 :         CompIndex = DXCoilNum;
     447              :     } else {
     448            0 :         DXCoilNum = CompIndex;
     449            0 :         if (DXCoilNum > state.dataDXCoils->NumDXCoils || DXCoilNum < 1) {
     450            0 :             ShowFatalError(state,
     451            0 :                            format("SimDXCoilMultiMode: Invalid CompIndex passed={}, Number of DX Coils={}, Coil name={}",
     452              :                                   DXCoilNum,
     453            0 :                                   state.dataDXCoils->NumDXCoils,
     454              :                                   CompName));
     455              :         }
     456            0 :         if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
     457            0 :             if ((CompName != "") && (CompName != state.dataDXCoils->DXCoil(DXCoilNum).Name)) {
     458            0 :                 ShowFatalError(state,
     459            0 :                                format("SimDXCoilMultiMode: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
     460              :                                       DXCoilNum,
     461              :                                       CompName,
     462            0 :                                       state.dataDXCoils->DXCoil(DXCoilNum).Name));
     463              :             }
     464            0 :             state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
     465              :         }
     466              :     }
     467              : 
     468              :     // Initialize the DX coil unit
     469            0 :     InitDXCoil(state, DXCoilNum);
     470              : 
     471            0 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
     472              :     // Select the correct unit type
     473            0 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
     474              :         // Initialize local variables
     475            0 :         S1RuntimeFraction = 0.0;
     476            0 :         S1OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
     477            0 :         S1OutletAirHumRat = thisDXCoil.InletAirHumRat;
     478            0 :         S1OutletAirTemp = thisDXCoil.InletAirTemp;
     479            0 :         S1ElecCoolingPower = 0.0;
     480            0 :         S1TotalCoolingEnergyRate = 0.0;
     481            0 :         S1SensCoolingEnergyRate = 0.0;
     482            0 :         S1LatCoolingEnergyRate = 0.0;
     483            0 :         S1CrankcaseHeaterPower = 0.0;
     484            0 :         S1EvapWaterConsumpRate = 0.0;
     485            0 :         S1EvapCondPumpElecPower = 0.0;
     486              : 
     487            0 :         S12RuntimeFraction = 0.0;
     488            0 :         S12OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
     489            0 :         S12OutletAirHumRat = thisDXCoil.InletAirHumRat;
     490            0 :         S12OutletAirTemp = thisDXCoil.InletAirTemp;
     491            0 :         S12ElecCoolingPower = 0.0;
     492            0 :         S12TotalCoolingEnergyRate = 0.0;
     493            0 :         S12SensCoolingEnergyRate = 0.0;
     494            0 :         S12LatCoolingEnergyRate = 0.0;
     495            0 :         S12CrankcaseHeaterPower = 0.0;
     496            0 :         S12EvapWaterConsumpRate = 0.0;
     497            0 :         S12EvapCondPumpElecPower = 0.0;
     498              : 
     499            0 :         thisDXCoil.DehumidificationMode = DehumidMode;
     500            0 :         if ((int)DehumidMode > thisDXCoil.NumDehumidModes) {
     501            0 :             ShowFatalError(state,
     502            0 :                            format("{} \"{}\" - Requested enhanced dehumidification mode not available.", thisDXCoil.DXCoilType, thisDXCoil.Name));
     503              :         }
     504              : 
     505              :         // If a single-stage coil OR If part load is zero,
     506              :         // run stage 1 at zero part load to set leaving conditions
     507            0 :         if ((thisDXCoil.NumCapacityStages == 1) || (PartLoadRatio <= 0.0)) {
     508              :             // Run stage 1 at its part load
     509            0 :             PerfMode = (int)DehumidMode * 2 + 1; // This.  This is not good.  Don't do math on enums.
     510            0 :             CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, PerfMode);
     511            0 :             S1PLR = PartLoadRatio;
     512            0 :             S2PLR = 0.0;
     513              :         } else {
     514              :             // If a two-stage coil
     515              :             // Run stage 1 at full load
     516            0 :             PerfMode = (int)DehumidMode * 2 + 1;
     517            0 :             CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
     518            0 :             S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
     519            0 :             if (S1SensCoolingEnergyRate > 0.0) {
     520            0 :                 S1PLR = PartLoadRatio;
     521              :             } else {
     522            0 :                 S1PLR = 0.0;
     523              :             }
     524              :             // Run stage 1+2 at full load
     525            0 :             if (thisDXCoil.NumCapacityStages >= 2) {
     526            0 :                 PerfMode = (int)DehumidMode * 2 + 2;
     527            0 :                 CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
     528            0 :                 S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
     529            0 :                 S12ElecCoolFullLoadPower = thisDXCoil.ElecCoolingPower;
     530              :             }
     531              : 
     532              :             // Determine run-time fractions for each stage based on sensible capacities
     533              :             //   Relationships:
     534              :             //     Stage 1   PLR1=   Load/Cap1
     535              :             //     Stage1+2  PLR12=  Load/Cap12
     536              :             //     Stage 2   PLR2=   (Load-Cap1)/(Cap2)
     537              :             //     PLR = Load/(Cap1+Cap2)
     538              :             //     Load= PLR*(Cap1+Cap2)
     539              :             //     PLR1= MIN(1,(PLR*(Cap1+Cap2)/Cap1))
     540              :             //     PLR2= MIN(1,((PLR*(Cap1+Cap2)-Cap1)/Cap2))
     541              : 
     542            0 :             if (S1SensCoolingEnergyRate > 0.0) {
     543            0 :                 S1PLR = PartLoadRatio * S12SensCoolingEnergyRate / S1SensCoolingEnergyRate;
     544              :             } else {
     545            0 :                 S1PLR = 0.0;
     546              :             }
     547            0 :             S1PLR = min(1.0, S1PLR);
     548            0 :             S1PLR = max(0.0, S1PLR);
     549            0 :             if ((S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) > 0.0) {
     550            0 :                 S2PLR = (PartLoadRatio * S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) / (S12SensCoolingEnergyRate - S1SensCoolingEnergyRate);
     551              :             } else {
     552            0 :                 S2PLR = 0.0;
     553              :             }
     554            0 :             S2PLR = min(1.0, S2PLR);
     555            0 :             S2PLR = max(0.0, S2PLR);
     556              : 
     557              :             // Run stage 1 at its part load
     558            0 :             PerfMode = (int)DehumidMode * 2 + 1;
     559            0 :             CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, S1PLR, fanOp, PerfMode);
     560              :         }
     561              :         // For stage-1 only operation, all outputs are set by CalcDoe2DXCoil.
     562              :         // No further adjustments are necessary.
     563              : 
     564              :         // Run stage 2 if needed and available
     565            0 :         if ((S2PLR > 0.0) && (thisDXCoil.NumCapacityStages >= 2)) {
     566              :             // Store stage 1 outputs
     567            0 :             S1RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
     568            0 :             S1OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
     569            0 :             S1OutletAirHumRat = thisDXCoil.OutletAirHumRat;
     570            0 :             S1OutletAirTemp = thisDXCoil.OutletAirTemp;
     571            0 :             S1ElecCoolingPower = thisDXCoil.ElecCoolingPower;
     572            0 :             S1TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
     573            0 :             S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
     574            0 :             S1LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
     575            0 :             S1CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
     576            0 :             S1EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
     577            0 :             S1EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
     578              : 
     579              :             // Save first stage full load outlet conditions to pass to heat recovery
     580            0 :             S1FFullLoadOutAirTemp = state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
     581            0 :             S1FullLoadOutAirHumRat = state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum);
     582              : 
     583              :             // Run stage 1+2 at its part load
     584            0 :             PerfMode = (int)DehumidMode * 2 + 2;
     585            0 :             CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, S2PLR, fanOp, PerfMode);
     586            0 :             S12RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
     587            0 :             S12OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
     588            0 :             S12OutletAirHumRat = thisDXCoil.OutletAirHumRat;
     589            0 :             S12OutletAirTemp = thisDXCoil.OutletAirTemp;
     590            0 :             S12ElecCoolingPower = thisDXCoil.ElecCoolingPower;
     591            0 :             S12TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
     592            0 :             S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
     593            0 :             S12LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
     594            0 :             S12CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
     595            0 :             S12EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
     596            0 :             S12EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
     597              : 
     598              :             // Determine combined performance
     599            0 :             thisDXCoil.OutletAirEnthalpy = (1.0 - S2PLR) * S1OutletAirEnthalpy + S2PLR * S12OutletAirEnthalpy;
     600            0 :             thisDXCoil.OutletAirHumRat = (1.0 - S2PLR) * S1OutletAirHumRat + S2PLR * S12OutletAirHumRat;
     601            0 :             thisDXCoil.OutletAirTemp = PsyTdbFnHW(thisDXCoil.OutletAirEnthalpy, thisDXCoil.OutletAirHumRat);
     602              :             // Check for saturation error and modify temperature at constant enthalpy
     603            0 :             if (thisDXCoil.CondenserInletNodeNum(PerfMode) != 0) {
     604            0 :                 NodePress = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(PerfMode)).Press;
     605              :                 // If node is not connected to anything, pressure = default, use weather data
     606            0 :                 if (NodePress == state.dataLoopNodes->DefaultNodeValues.Press) NodePress = state.dataEnvrn->OutBaroPress;
     607            0 :                 TSat = PsyTsatFnHPb(state, thisDXCoil.OutletAirEnthalpy, NodePress, RoutineName);
     608            0 :                 if (thisDXCoil.OutletAirTemp < TSat) {
     609            0 :                     thisDXCoil.OutletAirTemp = TSat;
     610              :                 }
     611            0 :                 thisDXCoil.OutletAirHumRat = PsyWFnTdbH(state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirEnthalpy, RoutineName);
     612              :             } else {
     613            0 :                 TSat = PsyTsatFnHPb(state, thisDXCoil.OutletAirEnthalpy, state.dataEnvrn->OutBaroPress, RoutineName);
     614            0 :                 if (thisDXCoil.OutletAirTemp < TSat) {
     615            0 :                     thisDXCoil.OutletAirTemp = TSat;
     616              :                 }
     617              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
     618              :                 //      IF(DXCoil(DXCoilNum)%OutletAirTemp .LT. PsyTsatFnHPb(DXCoil(DXCoilNum)%OutletAirEnthalpy, &
     619              :                 //                 Node(DXCoil(DXCoilNum)%AirInNode)%Press)) THEN
     620              :                 //        DXCoil(DXCoilNum)%OutletAirTemp = PsyTsatFnHPb(DXCoil(DXCoilNum)%OutletAirEnthalpy, &
     621              :                 //                 Node(DXCoil(DXCoilNum)%AirInNode)%Press)
     622            0 :                 thisDXCoil.OutletAirHumRat = PsyWFnTdbH(state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirEnthalpy, RoutineName);
     623              :             }
     624              : 
     625              :             //      DXCoil(DXCoilNum)%ElecCoolingPower = (1-S12RuntimeFraction)*S1ElecCoolingPower &
     626              :             //                                             +S12RuntimeFraction*S12ElecCoolingPower
     627              :             //  S12ElecCoolingPower overstates S1 portion of power, because it is also adjust by S12PLR
     628              :             //  So, must make an adjustment for S12ElecCoolingPower/S12ElecCoolFullLoadPower
     629              :             //  when subtracting off S1ElecCoolingPower
     630            0 :             if (S12ElecCoolFullLoadPower > 0.0) {
     631            0 :                 thisDXCoil.ElecCoolingPower =
     632            0 :                     S1RuntimeFraction * S1ElecCoolingPower +
     633            0 :                     S12RuntimeFraction * (S12ElecCoolingPower - S1ElecCoolingPower * S12ElecCoolingPower / S12ElecCoolFullLoadPower);
     634              :             } else {
     635            0 :                 thisDXCoil.ElecCoolingPower = 0.0;
     636              :             }
     637              : 
     638            0 :             thisDXCoil.CoolingCoilRuntimeFraction = S1RuntimeFraction;
     639              : 
     640            0 :             AirMassFlow = thisDXCoil.InletAirMassFlowRate;
     641            0 :             CalcComponentSensibleLatentOutput(AirMassFlow,
     642              :                                               thisDXCoil.InletAirTemp,
     643              :                                               thisDXCoil.InletAirHumRat,
     644              :                                               thisDXCoil.OutletAirTemp,
     645              :                                               thisDXCoil.OutletAirHumRat,
     646            0 :                                               thisDXCoil.SensCoolingEnergyRate,
     647            0 :                                               thisDXCoil.LatCoolingEnergyRate,
     648            0 :                                               thisDXCoil.TotalCoolingEnergyRate);
     649              : 
     650            0 :             thisDXCoil.EvapWaterConsumpRate = (1.0 - S12RuntimeFraction) * S1EvapWaterConsumpRate + S12RuntimeFraction * S12EvapWaterConsumpRate;
     651            0 :             thisDXCoil.EvapCondPumpElecPower = (1.0 - S12RuntimeFraction) * S1EvapCondPumpElecPower + S12RuntimeFraction * S12EvapCondPumpElecPower;
     652              : 
     653              :             // Stage 1 runtime sets the crankcase heater power
     654            0 :             thisDXCoil.CrankcaseHeaterPower = S1CrankcaseHeaterPower;
     655              : 
     656            0 :             state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
     657            0 :             state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
     658              : 
     659              :             //     calculate average full load outlet conditions for second stage operation
     660            0 :             state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) =
     661            0 :                 (1.0 - S2PLR) * S1FFullLoadOutAirTemp + S2PLR * state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
     662            0 :             state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) =
     663            0 :                 (1.0 - S2PLR) * S1FullLoadOutAirHumRat + S2PLR * state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum);
     664              : 
     665              :         } // End if stage 2 is operating
     666              : 
     667              :         //   set the part load ratio and heat reclaim capacity for use by desuperheater heating coils
     668            0 :         thisDXCoil.PartLoadRatio = S1PLR;
     669            0 :         state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = S1PLR;
     670              : 
     671              :         //   Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
     672            0 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
     673              : 
     674            0 :         thisDXCoil.CoolingCoilStg2RuntimeFrac = S12RuntimeFraction;
     675              : 
     676              :         //   Calculate basin heater power
     677            0 :         CalcBasinHeaterPowerForMultiModeDXCoil(state, DXCoilNum, DehumidMode);
     678              :     } else {
     679            0 :         ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
     680            0 :         ShowContinueError(state, format("Invalid DX Coil Type={}", thisDXCoil.DXCoilType));
     681            0 :         ShowFatalError(state, "Preceding condition causes termination.");
     682              :     }
     683              : 
     684              :     // Update the unit outlet nodes
     685            0 :     UpdateDXCoil(state, DXCoilNum);
     686              : 
     687              :     // Report the result of the simulation
     688            0 :     ReportDXCoil(state, DXCoilNum);
     689            0 : }
     690              : 
     691          135 : void GetDXCoils(EnergyPlusData &state)
     692              : {
     693              : 
     694              :     // SUBROUTINE INFORMATION:
     695              :     //       AUTHOR         Fred Buhl
     696              :     //       DATE WRITTEN   May 2000
     697              :     //       MODIFIED       Aug 2000, Don Shirey, Sept 2000, Feb/Oct 2001, Sept 2003, Jan/July 2004
     698              :     //                      Feb 2005, M. J. Witte, GARD Analytics, Inc., Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
     699              :     //                      May 2005, Rich Raustad, FSEC, Added COIL:DX:HeatPumpWaterHeater
     700              :     //                      Jun 2007, L. Gu, FSEC, Added new coil type COIL:DX:MULTISPEED:COOLING and COIL:DX:MULTISPEED:HEATING
     701              :     //                      Apr 2010, Chandan Sharma, FSEC, added basin heater inputs
     702              :     //                      Jul 2015, RP Zhang, XF Pang, LBNL, Added new coil type for VRF-FluidTemperatureControl Model
     703              : 
     704              :     // PURPOSE OF THIS SUBROUTINE:
     705              :     // Obtains input data for DX coils and stores it in DX coil data structure
     706              : 
     707              :     // METHODOLOGY EMPLOYED:
     708              :     // Uses "Get" routines to read in data.
     709              : 
     710              :     // Using/Aliasing
     711              :     using BranchNodeConnections::TestCompSet;
     712              :     using Curve::checkCurveIsNormalizedToOne;
     713              :     using Curve::CurveValue;
     714              :     using Curve::GetCurveIndex;
     715              :     using DataSizing::AutoSize;
     716              :     using EMSManager::ManageEMS;
     717              : 
     718              :     using GlobalNames::VerifyUniqueCoilName;
     719              :     using NodeInputManager::GetOnlySingleNode;
     720              :     using OutAirNodeManager::CheckOutAirNodeNumber;
     721              :     using WaterManager::SetupTankDemandComponent;
     722              :     using WaterManager::SetupTankSupplyComponent;
     723              : 
     724              :     // SUBROUTINE PARAMETER DEFINITIONS:
     725              :     static constexpr std::string_view RoutineName("GetDXCoils: "); // include trailing blank space
     726              :     static constexpr std::string_view routineName = "GetDXCoils";  // include trailing blank space
     727              : 
     728          135 :     constexpr Real64 minOATCompDXCooling = -25.0; // min OAT for compressor operation for DX cooling coils
     729              : 
     730              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     731              :     int DXCoilIndex;                 // loop index
     732              :     int DXCoilNum;                   // current DX coil number
     733              :     int NumAlphas;                   // Number of alphas in input
     734              :     int NumNumbers;                  // Number of numeric items in input
     735          135 :     Array1D_string Alphas2;          // Alpha input items for object
     736          135 :     Array1D<Real64> Numbers2;        // Numeric input items for object
     737          135 :     Array1D_string cAlphaFields2;    // Alpha field names
     738          135 :     Array1D_string cNumericFields2;  // Numeric field names
     739          135 :     Array1D_bool lAlphaBlanks2;      // Logical array, alpha field input BLANK = .TRUE.
     740          135 :     Array1D_bool lNumericBlanks2;    // Logical array, numeric field input BLANK = .TRUE.
     741              :     int NumAlphas2;                  // Number of alphas in input for performance object
     742              :     int NumNumbers2;                 // Number of numeric items in input for performance object
     743              :     int IOStatus;                    // Input status returned from GetObjectItem
     744          135 :     bool ErrorsFound(false);         // Set to true if errors in input, fatal at end of routine
     745              :     int DXHPWaterHeaterCoilNum;      // Loop index for 1,NumDXHeatPumpWaterHeaterCoils
     746              :     int CapacityStageNum;            // Loop index for 1,Number of capacity stages
     747              :     int DehumidModeNum;              // Loop index for 1,Number of enhanced dehumidification modes
     748              :     int PerfModeNum;                 // Performance mode index
     749              :     int PerfObjectNum;               // Item number for performance object
     750              :     int AlphaIndex;                  // Index for current alpha field
     751          135 :     std::string CurrentModuleObject; // Object type for getting and error messages
     752          135 :     std::string PerfObjectType;      // Performance object type for getting and error messages
     753          135 :     std::string PerfObjectName;      // Performance object name for getting and error messages
     754              :     Real64 InletAirTemp;             // Used to pass proper inlet air temp to HPWH DX coil performance curves
     755              :     Real64 InletWaterTemp;           // Used to pass proper inlet water temp to HPWH DX coil performance curves
     756              :     int I;                           // Index of speeds
     757              :     Real64 CurveVal;                 // Used to verify modifier curves equal 1 at rated conditions
     758          135 :     Array1D_string Alphas;           // Alpha input items for object
     759          135 :     Array1D_string cAlphaFields;     // Alpha field names
     760          135 :     Array1D_string cNumericFields;   // Numeric field names
     761          135 :     Array1D<Real64> Numbers;         // Numeric input items for object
     762          135 :     Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     763          135 :     Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     764          135 :     int MaxNumbers(0);               // Maximum number of numeric input fields
     765          135 :     int MaxAlphas(0);                // Maximum number of alpha input fields
     766          135 :     int TotalArgs(0);                // Total number of alpha and numeric arguments (max) for a
     767              :     //   certain object in the input file
     768              :     Real64 MinCurveVal; // used for testing PLF curve output
     769              :     Real64 MinCurvePLR; // used for testing PLF curve output
     770              :     Real64 MaxCurveVal; // used for testing PLF curve output
     771              :     Real64 MaxCurvePLR; // used for testing PLF curve output
     772              :     Real64 CurveInput;  // index used for testing PLF curve output
     773              : 
     774              :     // find number of each type of DX coil and calculate the total number
     775          135 :     state.dataDXCoils->NumDoe2DXCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:SingleSpeed");
     776          135 :     state.dataDXCoils->NumDXHeatingCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:SingleSpeed");
     777          135 :     state.dataDXCoils->NumDXMulSpeedCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoSpeed");
     778          270 :     state.dataDXCoils->NumDXMulModeCoils =
     779          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode");
     780          270 :     state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils =
     781          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped));
     782          270 :     state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils =
     783          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped));
     784          135 :     state.dataDXCoils->NumDXMulSpeedCoolCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:MultiSpeed");
     785          135 :     state.dataDXCoils->NumDXMulSpeedHeatCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:MultiSpeed");
     786          270 :     state.dataDXCoils->NumVRFCoolingCoils =
     787          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling));
     788          270 :     state.dataDXCoils->NumVRFHeatingCoils =
     789          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating));
     790          270 :     state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils =
     791          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling));
     792          270 :     state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils =
     793          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating));
     794              : 
     795          135 :     state.dataDXCoils->NumDXCoils = state.dataDXCoils->NumDoe2DXCoils + state.dataDXCoils->NumDXHeatingCoils + state.dataDXCoils->NumDXMulSpeedCoils +
     796          135 :                                     state.dataDXCoils->NumDXMulModeCoils + state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils +
     797          135 :                                     state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils + state.dataDXCoils->NumDXMulSpeedCoolCoils +
     798          135 :                                     state.dataDXCoils->NumDXMulSpeedHeatCoils + state.dataDXCoils->NumVRFCoolingCoils +
     799          135 :                                     state.dataDXCoils->NumVRFHeatingCoils + state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils +
     800          135 :                                     state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils;
     801              : 
     802              :     // Determine max number of alpha and numeric arguments for all objects being read, in order to allocate local arrays
     803          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
     804          135 :     MaxNumbers = NumNumbers;
     805          135 :     MaxAlphas = NumAlphas;
     806          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
     807          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     808          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     809          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:TwoSpeed", TotalArgs, NumAlphas, NumNumbers);
     810          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     811          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     812          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     813              :         state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode", TotalArgs, NumAlphas, NumNumbers);
     814          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     815          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     816          270 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     817          135 :         state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped), TotalArgs, NumAlphas, NumNumbers);
     818          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     819          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     820          270 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     821          135 :         state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped), TotalArgs, NumAlphas, NumNumbers);
     822          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     823          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     824          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:MultiSpeed", TotalArgs, NumAlphas, NumNumbers);
     825          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     826          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     827          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:MultiSpeed", TotalArgs, NumAlphas, NumNumbers);
     828          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     829          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     830          270 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     831          135 :         state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling), TotalArgs, NumAlphas, NumNumbers);
     832          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     833          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     834          270 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     835          135 :         state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating), TotalArgs, NumAlphas, NumNumbers);
     836          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     837          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     838          270 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     839          135 :         state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling), TotalArgs, NumAlphas, NumNumbers);
     840          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     841          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     842          270 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     843          135 :         state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating), TotalArgs, NumAlphas, NumNumbers);
     844          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     845          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     846          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "CoilPerformance:DX:Cooling", TotalArgs, NumAlphas, NumNumbers);
     847          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     848          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     849              : 
     850          135 :     Alphas.allocate(MaxAlphas);
     851          135 :     cAlphaFields.allocate(MaxAlphas);
     852          135 :     cNumericFields.allocate(MaxNumbers);
     853          135 :     Numbers.dimension(MaxNumbers, 0.0);
     854          135 :     lAlphaBlanks.dimension(MaxAlphas, true);
     855          135 :     lNumericBlanks.dimension(MaxNumbers, true);
     856              : 
     857          135 :     Alphas2.allocate(MaxAlphas);
     858          135 :     cAlphaFields2.allocate(MaxAlphas);
     859          135 :     cNumericFields2.allocate(MaxNumbers);
     860          135 :     Numbers2.dimension(MaxNumbers, 0.0);
     861          135 :     lAlphaBlanks2.dimension(MaxAlphas, true);
     862          135 :     lNumericBlanks2.dimension(MaxNumbers, true);
     863              : 
     864              :     // allocate the data structure
     865              : 
     866              :     // Derived types
     867          135 :     state.dataDXCoils->DXCoil.allocate(state.dataDXCoils->NumDXCoils);
     868          135 :     state.dataDXCoils->DXCoilNumericFields.allocate(state.dataDXCoils->NumDXCoils);
     869          135 :     state.dataHeatBal->HeatReclaimDXCoil.allocate(state.dataDXCoils->NumDXCoils);
     870          135 :     state.dataDXCoils->CheckEquipName.dimension(state.dataDXCoils->NumDXCoils, true);
     871              : 
     872              :     // Module level variable arrays
     873          135 :     state.dataDXCoils->DXCoilOutletTemp.allocate(state.dataDXCoils->NumDXCoils);
     874          135 :     state.dataDXCoils->DXCoilOutletHumRat.allocate(state.dataDXCoils->NumDXCoils);
     875          135 :     state.dataDXCoils->DXCoilPartLoadRatio.allocate(state.dataDXCoils->NumDXCoils);
     876          135 :     state.dataDXCoils->DXCoilFanOp.allocate(state.dataDXCoils->NumDXCoils);
     877          135 :     state.dataDXCoils->DXCoilFullLoadOutAirTemp.allocate(state.dataDXCoils->NumDXCoils);
     878          135 :     state.dataDXCoils->DXCoilFullLoadOutAirHumRat.allocate(state.dataDXCoils->NumDXCoils);
     879          135 :     state.dataDXCoils->DXCoilTotalCooling.allocate(state.dataDXCoils->NumDXCoils);
     880          135 :     state.dataDXCoils->DXCoilTotalHeating.allocate(state.dataDXCoils->NumDXCoils);
     881          135 :     state.dataDXCoils->DXCoilCoolInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
     882          135 :     state.dataDXCoils->DXCoilHeatInletAirDBTemp.allocate(state.dataDXCoils->NumDXCoils);
     883          135 :     state.dataDXCoils->DXCoilHeatInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
     884              : 
     885              :     // initialize the module level arrays
     886          135 :     state.dataDXCoils->DXCoilOutletTemp = 0.0;
     887          135 :     state.dataDXCoils->DXCoilOutletHumRat = 0.0;
     888          135 :     state.dataDXCoils->DXCoilPartLoadRatio = 0.0;
     889          135 :     state.dataDXCoils->DXCoilFanOp = HVAC::FanOp::Invalid;
     890          135 :     state.dataDXCoils->DXCoilFullLoadOutAirTemp = 0.0;
     891          135 :     state.dataDXCoils->DXCoilFullLoadOutAirHumRat = 0.0;
     892              : 
     893              :     // initialize the coil counter
     894          135 :     DXCoilNum = 0;
     895              : 
     896              :     // Loop over the Doe2 DX Coils and get & load the data
     897          135 :     CurrentModuleObject = "Coil:Cooling:DX:SingleSpeed";
     898          197 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilIndex) {
     899              : 
     900           62 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     901              :                                                                  CurrentModuleObject,
     902              :                                                                  DXCoilIndex,
     903              :                                                                  Alphas,
     904              :                                                                  NumAlphas,
     905              :                                                                  Numbers,
     906              :                                                                  NumNumbers,
     907              :                                                                  IOStatus,
     908              :                                                                  lNumericBlanks,
     909              :                                                                  lAlphaBlanks,
     910              :                                                                  cAlphaFields,
     911              :                                                                  cNumericFields);
     912              : 
     913           62 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
     914              : 
     915           62 :         ++DXCoilNum;
     916              :         // allocate single performance mode for numeric field strings used for sizing routine
     917           62 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
     918           62 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
     919           62 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
     920              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
     921           62 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
     922              : 
     923           62 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
     924           62 :         thisDXCoil.Name = Alphas(1);
     925              :         // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
     926           62 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
     927           62 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
     928           62 :         thisDXCoil.DXCoilType = CurrentModuleObject;
     929           62 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingSingleSpeed;
     930           62 :         if (lAlphaBlanks(2)) {
     931           10 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
     932           52 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
     933            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
     934            0 :             ErrorsFound = true;
     935              :         }
     936           62 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
     937           62 :         thisDXCoil.RatedSHR(1) = Numbers(2);
     938           62 :         thisDXCoil.RatedCOP(1) = Numbers(3);
     939           62 :         if (thisDXCoil.RatedCOP(1) <= 0.0) {
     940            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
     941            0 :             ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(3), Numbers(3)));
     942            0 :             ErrorsFound = true;
     943              :         }
     944              : 
     945           62 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
     946           62 :         thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
     947           62 :         thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
     948              : 
     949           62 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
     950           62 :                                                  Alphas(3),
     951              :                                                  ErrorsFound,
     952              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
     953           62 :                                                  Alphas(1),
     954              :                                                  DataLoopNode::NodeFluidType::Air,
     955              :                                                  DataLoopNode::ConnectionType::Inlet,
     956              :                                                  NodeInputManager::CompFluidStream::Primary,
     957              :                                                  ObjectIsNotParent);
     958              : 
     959          124 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
     960           62 :                                                   Alphas(4),
     961              :                                                   ErrorsFound,
     962              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
     963           62 :                                                   Alphas(1),
     964              :                                                   DataLoopNode::NodeFluidType::Air,
     965              :                                                   DataLoopNode::ConnectionType::Outlet,
     966              :                                                   NodeInputManager::CompFluidStream::Primary,
     967              :                                                   ObjectIsNotParent);
     968              : 
     969           62 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
     970              : 
     971           62 :         thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
     972           62 :         if (thisDXCoil.CCapFTemp(1) == 0) {
     973            0 :             if (lAlphaBlanks(5)) {
     974            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
     975            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
     976              :             } else {
     977            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
     978            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
     979              :             }
     980            0 :             ErrorsFound = true;
     981              :         } else {
     982              :             // Verify Curve Object, only legal type is BiQuadratic
     983          186 :             ErrorsFound |= Curve::CheckCurveDims(state,
     984           62 :                                                  thisDXCoil.CCapFTemp(1), // Curve index
     985              :                                                  {2},                     // Valid dimensions
     986              :                                                  RoutineName,             // Routine name
     987              :                                                  CurrentModuleObject,     // Object Type
     988              :                                                  thisDXCoil.Name,         // Object Name
     989           62 :                                                  cAlphaFields(5));        // Field Name
     990              : 
     991           62 :             if (!ErrorsFound) {
     992           62 :                 checkCurveIsNormalizedToOne(state,
     993          186 :                                             std::string{RoutineName} + CurrentModuleObject,
     994           62 :                                             thisDXCoil.Name,
     995           62 :                                             thisDXCoil.CCapFTemp(1),
     996           62 :                                             cAlphaFields(5),
     997           62 :                                             Alphas(5),
     998              :                                             RatedInletWetBulbTemp,
     999              :                                             RatedOutdoorAirTemp);
    1000              :             }
    1001              :         }
    1002              : 
    1003           62 :         thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
    1004           62 :         if (thisDXCoil.CCapFFlow(1) == 0) {
    1005            0 :             if (lAlphaBlanks(6)) {
    1006            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1007            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
    1008              :             } else {
    1009            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1010            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
    1011              :             }
    1012            0 :             ErrorsFound = true;
    1013              :         } else {
    1014              :             // Verify Curve Object, only legal type is Quadratic
    1015          186 :             ErrorsFound |= Curve::CheckCurveDims(state,
    1016           62 :                                                  thisDXCoil.CCapFFlow(1), // Curve index
    1017              :                                                  {1},                     // Valid dimensions
    1018              :                                                  RoutineName,             // Routine name
    1019              :                                                  CurrentModuleObject,     // Object Type
    1020              :                                                  thisDXCoil.Name,         // Object Name
    1021           62 :                                                  cAlphaFields(6));        // Field Name
    1022              : 
    1023           62 :             if (!ErrorsFound) {
    1024           62 :                 checkCurveIsNormalizedToOne(
    1025          248 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
    1026              :             }
    1027              :         }
    1028              : 
    1029           62 :         thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
    1030           62 :         if (thisDXCoil.EIRFTemp(1) == 0) {
    1031            0 :             if (lAlphaBlanks(7)) {
    1032            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1033            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
    1034              :             } else {
    1035            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1036            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
    1037              :             }
    1038            0 :             ErrorsFound = true;
    1039              :         } else {
    1040              :             // Verify Curve Object, only legal type is BiQuadratic
    1041          186 :             ErrorsFound |= Curve::CheckCurveDims(state,
    1042           62 :                                                  thisDXCoil.EIRFTemp(1), // Curve index
    1043              :                                                  {2},                    // Valid dimensions
    1044              :                                                  RoutineName,            // Routine name
    1045              :                                                  CurrentModuleObject,    // Object Type
    1046              :                                                  thisDXCoil.Name,        // Object Name
    1047           62 :                                                  cAlphaFields(7));       // Field Name
    1048              : 
    1049           62 :             if (!ErrorsFound) {
    1050           62 :                 checkCurveIsNormalizedToOne(state,
    1051          186 :                                             std::string{RoutineName} + CurrentModuleObject,
    1052           62 :                                             thisDXCoil.Name,
    1053           62 :                                             thisDXCoil.EIRFTemp(1),
    1054           62 :                                             cAlphaFields(7),
    1055           62 :                                             Alphas(7),
    1056              :                                             RatedInletWetBulbTemp,
    1057              :                                             RatedOutdoorAirTemp);
    1058              :             }
    1059              :         }
    1060              : 
    1061           62 :         thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
    1062           62 :         if (thisDXCoil.EIRFFlow(1) == 0) {
    1063            0 :             if (lAlphaBlanks(8)) {
    1064            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1065            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
    1066              :             } else {
    1067            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1068            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
    1069              :             }
    1070            0 :             ErrorsFound = true;
    1071              :         } else {
    1072              :             // Verify Curve Object, only legal type is Quadratic
    1073          186 :             ErrorsFound |= Curve::CheckCurveDims(state,
    1074           62 :                                                  thisDXCoil.EIRFFlow(1), // Curve index
    1075              :                                                  {1},                    // Valid dimensions
    1076              :                                                  RoutineName,            // Routine name
    1077              :                                                  CurrentModuleObject,    // Object Type
    1078              :                                                  thisDXCoil.Name,        // Object Name
    1079           62 :                                                  cAlphaFields(8));       // Field Name
    1080              : 
    1081           62 :             if (!ErrorsFound) {
    1082           62 :                 checkCurveIsNormalizedToOne(
    1083          248 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
    1084              :             }
    1085              :         }
    1086              : 
    1087           62 :         thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
    1088           62 :         if (thisDXCoil.PLFFPLR(1) == 0) {
    1089            0 :             if (lAlphaBlanks(9)) {
    1090            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1091            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
    1092              :             } else {
    1093            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1094            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
    1095              :             }
    1096            0 :             ErrorsFound = true;
    1097              :         } else {
    1098              :             // Verify Curve Object, only legal types are Quadratic or Cubic
    1099          186 :             ErrorsFound |= Curve::CheckCurveDims(state,
    1100           62 :                                                  thisDXCoil.PLFFPLR(1), // Curve index
    1101              :                                                  {1},                   // Valid dimensions
    1102              :                                                  RoutineName,           // Routine name
    1103              :                                                  CurrentModuleObject,   // Object Type
    1104              :                                                  thisDXCoil.Name,       // Object Name
    1105           62 :                                                  cAlphaFields(9));      // Field Name
    1106              : 
    1107           62 :             if (!ErrorsFound) {
    1108              :                 //     Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    1109           62 :                 MinCurveVal = 999.0;
    1110           62 :                 MaxCurveVal = -999.0;
    1111           62 :                 CurveInput = 0.0;
    1112         6262 :                 while (CurveInput <= 1.0) {
    1113         6200 :                     CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
    1114         6200 :                     if (CurveVal < MinCurveVal) {
    1115           62 :                         MinCurveVal = CurveVal;
    1116           62 :                         MinCurvePLR = CurveInput;
    1117              :                     }
    1118         6200 :                     if (CurveVal > MaxCurveVal) {
    1119         4568 :                         MaxCurveVal = CurveVal;
    1120         4568 :                         MaxCurvePLR = CurveInput;
    1121              :                     }
    1122         6200 :                     CurveInput += 0.01;
    1123              :                 }
    1124           62 :                 if (MinCurveVal < 0.7) {
    1125            0 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1126            0 :                     ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFields(9), Alphas(9)));
    1127            0 :                     ShowContinueError(state,
    1128            0 :                                       format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    1129            0 :                     ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    1130            0 :                     Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
    1131              :                 }
    1132              : 
    1133           62 :                 if (MaxCurveVal > 1.0) {
    1134            2 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1135            2 :                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
    1136            4 :                     ShowContinueError(state,
    1137            4 :                                       format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    1138            4 :                     ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    1139            2 :                     Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
    1140              :                 }
    1141              :             }
    1142              :         }
    1143              : 
    1144              :         // Set minimum OAT for compressor operation
    1145           62 :         thisDXCoil.MinOATCompressor = Numbers(7);
    1146           62 :         if (NumNumbers < 6)
    1147            0 :             thisDXCoil.MinOATCompressor = minOATCompDXCooling; // input field is after min fields and won't default if field not included
    1148              : 
    1149           62 :         thisDXCoil.Twet_Rated(1) = Numbers(8);
    1150           62 :         thisDXCoil.Gamma_Rated(1) = Numbers(9);
    1151           62 :         thisDXCoil.MaxONOFFCyclesperHour(1) = Numbers(10);
    1152           62 :         thisDXCoil.LatentCapacityTimeConstant(1) = Numbers(11);
    1153              : 
    1154              :         // Numbers (7) through (11) must all be greater than zero to use the latent capacity degradation model
    1155           76 :         if ((Numbers(8) > 0.0 || Numbers(9) > 0.0 || Numbers(10) > 0.0 || Numbers(11) > 0.0) &&
    1156           14 :             (Numbers(8) <= 0.0 || Numbers(9) <= 0.0 || Numbers(10) <= 0.0 || Numbers(11) <= 0.0)) {
    1157            0 :             ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1158            0 :             ShowContinueError(state, "...At least one of the four input parameters for the latent capacity degradation model");
    1159            0 :             ShowContinueError(state, "...is set to zero. Therefore, the latent degradation model will not be used for this simulation.");
    1160              :         }
    1161              : 
    1162              :         // outdoor condenser node
    1163           62 :         if (lAlphaBlanks(10)) {
    1164           48 :             thisDXCoil.CondenserInletNodeNum(1) = 0;
    1165              :         } else {
    1166           28 :             thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
    1167           14 :                                                                     Alphas(10),
    1168              :                                                                     ErrorsFound,
    1169              :                                                                     DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
    1170           14 :                                                                     thisDXCoil.Name,
    1171              :                                                                     DataLoopNode::NodeFluidType::Air,
    1172              :                                                                     DataLoopNode::ConnectionType::OutsideAirReference,
    1173              :                                                                     NodeInputManager::CompFluidStream::Primary,
    1174              :                                                                     ObjectIsNotParent);
    1175              : 
    1176           14 :             if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
    1177            4 :                 ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1178            8 :                 ShowContinueError(
    1179              :                     state,
    1180            8 :                     format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(10), Alphas(10)));
    1181           12 :                 ShowContinueError(
    1182              :                     state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
    1183              :             }
    1184              :         }
    1185              : 
    1186           62 :         if ((Util::SameString(Alphas(11), "AirCooled")) || lAlphaBlanks(11)) {
    1187           48 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
    1188           14 :         } else if (Util::SameString(Alphas(11), "EvaporativelyCooled")) {
    1189           14 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
    1190           14 :             thisDXCoil.ReportEvapCondVars = true;
    1191              :         } else {
    1192            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1193            0 :             ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(11), Alphas(11)));
    1194            0 :             ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
    1195            0 :             ErrorsFound = true;
    1196              :         }
    1197              : 
    1198           62 :         thisDXCoil.EvapCondEffect(1) = Numbers(12);
    1199           62 :         if (thisDXCoil.EvapCondEffect(1) < 0.0 || thisDXCoil.EvapCondEffect(1) > 1.0) {
    1200            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1201            0 :             ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields(11)));
    1202            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(12)));
    1203            0 :             ErrorsFound = true;
    1204              :         }
    1205              : 
    1206           62 :         thisDXCoil.EvapCondAirFlow(1) = Numbers(13);
    1207           62 :         if (thisDXCoil.EvapCondAirFlow(1) < 0.0 && thisDXCoil.EvapCondAirFlow(1) != AutoSize) {
    1208            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1209            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(12)));
    1210            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(13)));
    1211            0 :             ErrorsFound = true;
    1212              :         }
    1213              : 
    1214           62 :         thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(14);
    1215           62 :         if (thisDXCoil.EvapCondPumpElecNomPower(1) < 0.0 && thisDXCoil.EvapCondPumpElecNomPower(1) != AutoSize) {
    1216            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1217            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(13)));
    1218            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(14)));
    1219            0 :             ErrorsFound = true;
    1220              :         }
    1221              : 
    1222              :         // Set crankcase heater capacity
    1223           62 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(15);
    1224           62 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    1225            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1226            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(14)));
    1227            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(15)));
    1228            0 :             ErrorsFound = true;
    1229              :         }
    1230              : 
    1231              :         // Set crankcase heater cutout temperature
    1232           62 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(16);
    1233              : 
    1234           62 :         if (thisDXCoil.RatedCOP(1) > 0.0) {
    1235           62 :             thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
    1236              :         }
    1237              : 
    1238              :         // A12, \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
    1239           62 :         if (!lAlphaBlanks(12)) {
    1240            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(12));
    1241            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    1242            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(12), Alphas(12)));
    1243            0 :                 ErrorsFound = true;
    1244              :             } else {
    1245            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    1246              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    1247              :                                                      {1},                                          // Valid dimensions
    1248              :                                                      RoutineName,                                  // Routine name
    1249              :                                                      CurrentModuleObject,                          // Object Type
    1250              :                                                      thisDXCoil.Name,                              // Object Name
    1251            2 :                                                      cAlphaFields(12));                            // Field Name
    1252              :             }
    1253              :         }
    1254              : 
    1255              :         // Get Water System tank connections
    1256              :         //  A13, \field Name of Water Storage Tank for Supply
    1257           62 :         thisDXCoil.EvapWaterSupplyName = Alphas(13);
    1258           62 :         if (lAlphaBlanks(13)) {
    1259           62 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
    1260              :         } else {
    1261            0 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
    1262            0 :             SetupTankDemandComponent(state,
    1263              :                                      thisDXCoil.Name,
    1264              :                                      CurrentModuleObject,
    1265              :                                      thisDXCoil.EvapWaterSupplyName,
    1266              :                                      ErrorsFound,
    1267            0 :                                      thisDXCoil.EvapWaterSupTankID,
    1268            0 :                                      thisDXCoil.EvapWaterTankDemandARRID);
    1269              :         }
    1270              : 
    1271              :         // A14; \field Name of Water Storage Tank for Condensate Collection
    1272           62 :         thisDXCoil.CondensateCollectName = Alphas(14);
    1273           62 :         if (lAlphaBlanks(14)) {
    1274           62 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    1275              :         } else {
    1276            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    1277            0 :             SetupTankSupplyComponent(state,
    1278              :                                      thisDXCoil.Name,
    1279              :                                      CurrentModuleObject,
    1280              :                                      thisDXCoil.CondensateCollectName,
    1281              :                                      ErrorsFound,
    1282            0 :                                      thisDXCoil.CondensateTankID,
    1283            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    1284              :         }
    1285              : 
    1286              :         //   Basin heater power as a function of temperature must be greater than or equal to 0
    1287           62 :         thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(17);
    1288           62 :         if (Numbers(17) < 0.0) {
    1289            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1290            0 :             ShowContinueError(state, format("...{} must be >= 0.0.", cNumericFields(16)));
    1291            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(17)));
    1292            0 :             ErrorsFound = true;
    1293              :         }
    1294              : 
    1295           62 :         thisDXCoil.BasinHeaterSetPointTemp = Numbers(18);
    1296           62 :         if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    1297            3 :             if (NumNumbers < 18) {
    1298            1 :                 thisDXCoil.BasinHeaterSetPointTemp = 2.0;
    1299              :             }
    1300            3 :             if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
    1301            0 :                 ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1302            0 :                 ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(17)));
    1303            0 :                 ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(18)));
    1304              :             }
    1305              :         }
    1306              : 
    1307           62 :         if (!lAlphaBlanks(15)) {
    1308            0 :             if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(15))) == nullptr) {
    1309            0 :                 ShowWarningItemNotFound(
    1310            0 :                     state, eoh, cAlphaFields(15), Alphas(15), "Basin heater will be available to operate throughout the simulation.");
    1311              :             }
    1312              :         }
    1313              : 
    1314           62 :         if (!lAlphaBlanks(16) && NumAlphas > 15) {
    1315            0 :             thisDXCoil.SHRFTemp(1) = GetCurveIndex(state, Alphas(16)); // convert curve name to number
    1316            0 :             if (thisDXCoil.SHRFTemp(1) == 0) {
    1317            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1318            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
    1319              :             } else {
    1320              :                 // Verify Curve Object, only legal type is BiQuadratic
    1321            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    1322            0 :                                                      thisDXCoil.SHRFTemp(1), // Curve index
    1323              :                                                      {2},                    // Valid dimensions
    1324              :                                                      RoutineName,            // Routine name
    1325              :                                                      CurrentModuleObject,    // Object Type
    1326              :                                                      thisDXCoil.Name,        // Object Name
    1327            0 :                                                      cAlphaFields(16));      // Field Name
    1328              :             }
    1329              :         }
    1330              : 
    1331           62 :         if (!lAlphaBlanks(17) && NumAlphas > 16) {
    1332            2 :             thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
    1333            2 :             if (thisDXCoil.SHRFTemp(1) == 0) {
    1334            2 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1335            2 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
    1336              :             } else {
    1337              :                 // Verify Curve Object, only legal type is Quadratic and Cubic
    1338            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    1339            0 :                                                      thisDXCoil.SHRFFlow(1), // Curve index
    1340              :                                                      {1},                    // Valid dimensions
    1341              :                                                      RoutineName,            // Routine name
    1342              :                                                      CurrentModuleObject,    // Object Type
    1343              :                                                      thisDXCoil.Name,        // Object Name
    1344            0 :                                                      cAlphaFields(17));      // Field Name
    1345              :             }
    1346              :         }
    1347              : 
    1348           62 :         if (thisDXCoil.SHRFTemp(1) > 0 && thisDXCoil.SHRFFlow(1) > 0) {
    1349            0 :             thisDXCoil.UserSHRCurveExists = true;
    1350              :         }
    1351              :         // get User Input flag for ASHRAE Standard 127 Standard Ratings Reporting
    1352           62 :         if (lAlphaBlanks(18)) {
    1353           62 :             thisDXCoil.ASHRAE127StdRprt = false;
    1354              :         } else {
    1355            0 :             if (Alphas(18) == "YES" || Alphas(18) == "Yes") {
    1356            0 :                 thisDXCoil.ASHRAE127StdRprt = true;
    1357              :             } else {
    1358            0 :                 thisDXCoil.ASHRAE127StdRprt = false;
    1359              :             }
    1360              :         }
    1361              :         // A19; \field Zone Name for Condenser Placement
    1362           62 :         if (!lAlphaBlanks(19) && NumAlphas > 18) {
    1363            0 :             thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(19), state.dataHeatBal->Zone);
    1364              : 
    1365            0 :             if (thisDXCoil.SecZonePtr > 0) {
    1366            0 :                 SetupZoneInternalGain(state,
    1367              :                                       thisDXCoil.SecZonePtr,
    1368              :                                       thisDXCoil.Name,
    1369              :                                       DataHeatBalance::IntGainType::SecCoolingDXCoilSingleSpeed,
    1370              :                                       &thisDXCoil.SecCoilSensibleHeatGainRate);
    1371            0 :                 thisDXCoil.IsSecondaryDXCoilInZone = true;
    1372              :             } else {
    1373            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1374            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(19), Alphas(19)));
    1375              :             }
    1376              :         }
    1377              : 
    1378              :     } // end of the Doe2 DX coil loop
    1379              : 
    1380          135 :     if (ErrorsFound) {
    1381            0 :         ShowFatalError(state,
    1382            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    1383              :     }
    1384              : 
    1385              :     // Loop over the Multimode DX Coils and get & load the data
    1386          135 :     CurrentModuleObject = "Coil:Cooling:DX:TwoStageWithHumidityControlMode";
    1387          137 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulModeCoils; ++DXCoilIndex) {
    1388              : 
    1389            2 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1390              :                                                                  CurrentModuleObject,
    1391              :                                                                  DXCoilIndex,
    1392              :                                                                  Alphas,
    1393              :                                                                  NumAlphas,
    1394              :                                                                  Numbers,
    1395              :                                                                  NumNumbers,
    1396              :                                                                  IOStatus,
    1397              :                                                                  lNumericBlanks,
    1398              :                                                                  lAlphaBlanks,
    1399              :                                                                  cAlphaFields,
    1400              :                                                                  cNumericFields);
    1401              : 
    1402            2 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    1403            2 :         ++DXCoilNum;
    1404              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    1405            2 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    1406              : 
    1407            2 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    1408            2 :         thisDXCoil.Name = Alphas(1);
    1409              :         // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
    1410            2 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
    1411            2 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
    1412            2 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    1413            2 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoStageWHumControl;
    1414            2 :         if (lAlphaBlanks(2)) {
    1415            2 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    1416            0 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    1417            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    1418            0 :             ErrorsFound = true;
    1419              :         }
    1420              : 
    1421            2 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    1422            2 :                                                  Alphas(3),
    1423              :                                                  ErrorsFound,
    1424              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
    1425            2 :                                                  Alphas(1),
    1426              :                                                  DataLoopNode::NodeFluidType::Air,
    1427              :                                                  DataLoopNode::ConnectionType::Inlet,
    1428              :                                                  NodeInputManager::CompFluidStream::Primary,
    1429              :                                                  ObjectIsNotParent);
    1430              : 
    1431            4 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    1432            2 :                                                   Alphas(4),
    1433              :                                                   ErrorsFound,
    1434              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
    1435            2 :                                                   Alphas(1),
    1436              :                                                   DataLoopNode::NodeFluidType::Air,
    1437              :                                                   DataLoopNode::ConnectionType::Outlet,
    1438              :                                                   NodeInputManager::CompFluidStream::Primary,
    1439              :                                                   ObjectIsNotParent);
    1440              : 
    1441            2 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    1442              : 
    1443              :         // A5; \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
    1444            2 :         if (!lAlphaBlanks(5)) {
    1445            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
    1446            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    1447            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
    1448            0 :                 ErrorsFound = true;
    1449              :             } else {
    1450            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    1451              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    1452              :                                                      {1},                                          // Valid dimensions
    1453              :                                                      RoutineName,                                  // Routine name
    1454              :                                                      CurrentModuleObject,                          // Object Type
    1455              :                                                      thisDXCoil.Name,                              // Object Name
    1456            2 :                                                      cAlphaFields(5));                             // Field Name
    1457              :             }
    1458              :         }
    1459              : 
    1460              :         // Set crankcase heater capacity
    1461            2 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(1);
    1462            2 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    1463            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1464            0 :             ShowContinueError(state, format("...{} must be >= 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
    1465            0 :             ErrorsFound = true;
    1466              :         }
    1467              : 
    1468              :         // Set crankcase heater cutout temperature
    1469            2 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(2);
    1470              : 
    1471              :         //  Number of capacity stages
    1472            2 :         thisDXCoil.NumCapacityStages = Numbers(3);
    1473              :         //  Check if requested number of capacity stages exceeds limits
    1474            2 :         if ((thisDXCoil.NumCapacityStages > MaxCapacityStages) || (thisDXCoil.NumCapacityStages < 1)) {
    1475            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1476            0 :             ShowContinueError(state, format("...illegal {} = {}", cNumericFields(3), thisDXCoil.NumCapacityStages));
    1477            0 :             ShowContinueError(state, format("...Valid range is 1 to {}", MaxCapacityStages));
    1478            0 :             ErrorsFound = true;
    1479              :         }
    1480              : 
    1481              :         //  Number of enhanced dehumidification modes
    1482            2 :         thisDXCoil.NumDehumidModes = Numbers(4);
    1483              :         //  Check if requested number of enhanced dehumidification modes exceeds limits
    1484            2 :         if ((thisDXCoil.NumDehumidModes > MaxDehumidModes) || (thisDXCoil.NumDehumidModes < 0)) {
    1485            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1486            0 :             ShowContinueError(state, format("...illegal {} = {}", cNumericFields(4), thisDXCoil.NumDehumidModes));
    1487            0 :             ShowContinueError(state, format("...Valid range is 0 to {}", MaxDehumidModes));
    1488            0 :             ErrorsFound = true;
    1489              :         }
    1490              : 
    1491              :         //  Set starting alpha index for coil performance inputs
    1492            2 :         AlphaIndex = 6;
    1493              :         // allocate performance modes for numeric field strings used for sizing routine
    1494            4 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(
    1495            2 :             thisDXCoil.NumDehumidModes * 2 + thisDXCoil.NumCapacityStages * 2); // not sure this math is correct, ask MW
    1496              : 
    1497              :         //  Loop through capacity stages and dehumidification modes
    1498            6 :         for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
    1499           12 :             for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
    1500              :                 //  Check if sufficient number of fields entered
    1501            8 :                 if ((AlphaIndex + 1) > NumAlphas) {
    1502            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1503            0 :                     ShowContinueError(state, "...not enough remaining fields for specified Number of Operating Modes.");
    1504            0 :                     ShowContinueError(state, "...Need additional Coil Performance Object Type and Coil Performance Object Name fields.");
    1505            0 :                     ErrorsFound = true;
    1506              :                 } else {
    1507            8 :                     PerfObjectType = Alphas(AlphaIndex);
    1508            8 :                     PerfObjectName = Alphas(AlphaIndex + 1);
    1509            8 :                     PerfModeNum = DehumidModeNum * 2 + CapacityStageNum;
    1510            8 :                     thisDXCoil.CoilPerformanceType(PerfModeNum) = PerfObjectType;
    1511            8 :                     if (Util::SameString(PerfObjectType, "CoilPerformance:DX:Cooling")) {
    1512            8 :                         thisDXCoil.CoilPerformanceType_Num(PerfModeNum) = HVAC::CoilPerfDX_CoolBypassEmpirical;
    1513              :                     } else {
    1514            0 :                         ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1515            0 :                         ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(AlphaIndex), PerfObjectType));
    1516            0 :                         ShowContinueError(state, "Must be \"CoilPerformance:DX:Cooling\".");
    1517            0 :                         ErrorsFound = true;
    1518              :                     }
    1519            8 :                     thisDXCoil.CoilPerformanceName(PerfModeNum) = PerfObjectName;
    1520              :                     // Get for CoilPerformance object
    1521            8 :                     PerfObjectNum = state.dataInputProcessing->inputProcessor->getObjectItemNum(state, PerfObjectType, PerfObjectName);
    1522            8 :                     if (PerfObjectNum > 0) {
    1523              : 
    1524            8 :                         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1525              :                                                                                  PerfObjectType,
    1526              :                                                                                  PerfObjectNum,
    1527              :                                                                                  Alphas2,
    1528              :                                                                                  NumAlphas2,
    1529              :                                                                                  Numbers2,
    1530              :                                                                                  NumNumbers2,
    1531              :                                                                                  IOStatus,
    1532              :                                                                                  lNumericBlanks2,
    1533              :                                                                                  lAlphaBlanks2,
    1534              :                                                                                  cAlphaFields2,
    1535              :                                                                                  cNumericFields2);
    1536              : 
    1537              :                         // allocate performance mode numeric field strings used for sizing routine
    1538            8 :                         state.dataDXCoils->DXCoilNumericFields(DXCoilNum)
    1539            8 :                             .PerfMode(PerfModeNum)
    1540            8 :                             .FieldNames.allocate(NumNumbers2); // use MaxNumbers here??
    1541            8 :                         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(PerfModeNum).FieldNames = cNumericFields2;
    1542              : 
    1543            8 :                         thisDXCoil.RatedTotCap(PerfModeNum) = Numbers2(1);
    1544            8 :                         thisDXCoil.RatedSHR(PerfModeNum) = Numbers2(2);
    1545            8 :                         thisDXCoil.RatedCOP(PerfModeNum) = Numbers2(3);
    1546              :                         // Rated flow is immediately adjusted for bypass fraction if not autosized
    1547            8 :                         thisDXCoil.BypassedFlowFrac(PerfModeNum) = Numbers2(5);
    1548            8 :                         thisDXCoil.RatedAirVolFlowRate(PerfModeNum) = Numbers2(4);
    1549            8 :                         if (thisDXCoil.RatedAirVolFlowRate(PerfModeNum) != AutoSize) {
    1550            0 :                             thisDXCoil.RatedAirVolFlowRate(PerfModeNum) *= (1.0 - thisDXCoil.BypassedFlowFrac(PerfModeNum));
    1551              :                         }
    1552              : 
    1553            8 :                         thisDXCoil.CCapFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(2)); // convert curve name to number
    1554            8 :                         if (thisDXCoil.CCapFTemp(PerfModeNum) == 0) {
    1555            0 :                             if (lAlphaBlanks2(2)) {
    1556            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1557            0 :                                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(2)));
    1558              :                             } else {
    1559            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1560            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(2), Alphas2(2)));
    1561              :                             }
    1562            0 :                             ErrorsFound = true;
    1563              :                         } else {
    1564              :                             // Verify Curve Object, only legal type is BiQuadratic
    1565           24 :                             ErrorsFound |= Curve::CheckCurveDims(state,
    1566            8 :                                                                  thisDXCoil.CCapFTemp(PerfModeNum), // Curve index
    1567              :                                                                  {2},                               // Valid dimensions
    1568              :                                                                  RoutineName,                       // Routine name
    1569              :                                                                  CurrentModuleObject,               // Object Type
    1570              :                                                                  thisDXCoil.Name,                   // Object Name
    1571            8 :                                                                  cAlphaFields2(2));                 // Field Name
    1572              : 
    1573            8 :                             if (!ErrorsFound) {
    1574            8 :                                 checkCurveIsNormalizedToOne(state,
    1575           24 :                                                             std::string{RoutineName} + CurrentModuleObject,
    1576            8 :                                                             thisDXCoil.Name,
    1577            8 :                                                             thisDXCoil.CCapFTemp(PerfModeNum),
    1578            8 :                                                             cAlphaFields2(2),
    1579            8 :                                                             Alphas2(2),
    1580              :                                                             RatedInletWetBulbTemp,
    1581              :                                                             RatedOutdoorAirTemp);
    1582              :                             }
    1583              :                         }
    1584              : 
    1585            8 :                         thisDXCoil.CCapFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(3)); // convert curve name to number
    1586            8 :                         if (thisDXCoil.CCapFFlow(PerfModeNum) == 0) {
    1587            0 :                             if (lAlphaBlanks2(3)) {
    1588            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1589            0 :                                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(3)));
    1590              :                             } else {
    1591            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1592            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(3), Alphas2(3)));
    1593              :                             }
    1594            0 :                             ErrorsFound = true;
    1595              :                         } else {
    1596              :                             // Verify Curve Object, only legal type is Quadratic
    1597           24 :                             ErrorsFound |= Curve::CheckCurveDims(state,
    1598            8 :                                                                  thisDXCoil.CCapFFlow(PerfModeNum), // Curve index
    1599              :                                                                  {1},                               // Valid dimensions
    1600              :                                                                  RoutineName,                       // Routine name
    1601              :                                                                  CurrentModuleObject,               // Object Type
    1602              :                                                                  thisDXCoil.Name,                   // Object Name
    1603            8 :                                                                  cAlphaFields2(3));                 // Field Name
    1604              : 
    1605            8 :                             if (!ErrorsFound) {
    1606            8 :                                 checkCurveIsNormalizedToOne(state,
    1607           24 :                                                             std::string{RoutineName} + CurrentModuleObject,
    1608            8 :                                                             thisDXCoil.Name,
    1609            8 :                                                             thisDXCoil.CCapFFlow(PerfModeNum),
    1610            8 :                                                             cAlphaFields2(3),
    1611            8 :                                                             Alphas2(3),
    1612              :                                                             1.0);
    1613              :                             }
    1614              :                         }
    1615              : 
    1616            8 :                         thisDXCoil.EIRFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(4)); // convert curve name to number
    1617            8 :                         if (thisDXCoil.EIRFTemp(PerfModeNum) == 0) {
    1618            0 :                             if (lAlphaBlanks2(4)) {
    1619            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1620            0 :                                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(4)));
    1621              :                             } else {
    1622            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1623            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(4), Alphas2(4)));
    1624              :                             }
    1625            0 :                             ErrorsFound = true;
    1626              :                         } else {
    1627              :                             // Verify Curve Object, only legal type is BiQuadratic
    1628           24 :                             ErrorsFound |= Curve::CheckCurveDims(state,
    1629            8 :                                                                  thisDXCoil.EIRFTemp(PerfModeNum), // Curve index
    1630              :                                                                  {2},                              // Valid dimensions
    1631              :                                                                  RoutineName,                      // Routine name
    1632              :                                                                  CurrentModuleObject,              // Object Type
    1633              :                                                                  thisDXCoil.Name,                  // Object Name
    1634            8 :                                                                  cAlphaFields2(4));                // Field Name
    1635              : 
    1636            8 :                             if (!ErrorsFound) {
    1637            8 :                                 checkCurveIsNormalizedToOne(state,
    1638           24 :                                                             std::string{RoutineName} + CurrentModuleObject,
    1639            8 :                                                             thisDXCoil.Name,
    1640            8 :                                                             thisDXCoil.EIRFTemp(PerfModeNum),
    1641            8 :                                                             cAlphaFields2(4),
    1642            8 :                                                             Alphas2(4),
    1643              :                                                             RatedInletWetBulbTemp,
    1644              :                                                             RatedOutdoorAirTemp);
    1645              :                             }
    1646              :                         }
    1647              : 
    1648            8 :                         thisDXCoil.EIRFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(5)); // convert curve name to number
    1649            8 :                         if (thisDXCoil.EIRFFlow(PerfModeNum) == 0) {
    1650            0 :                             if (lAlphaBlanks2(5)) {
    1651            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1652            0 :                                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(5)));
    1653              :                             } else {
    1654            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1655            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(5), Alphas2(5)));
    1656              :                             }
    1657            0 :                             ErrorsFound = true;
    1658              :                         } else {
    1659              :                             // Verify Curve Object, only legal type is Quadratic
    1660           24 :                             ErrorsFound |= Curve::CheckCurveDims(state,
    1661            8 :                                                                  thisDXCoil.EIRFFlow(PerfModeNum), // Curve index
    1662              :                                                                  {1},                              // Valid dimensions
    1663              :                                                                  RoutineName,                      // Routine name
    1664              :                                                                  CurrentModuleObject,              // Object Type
    1665              :                                                                  thisDXCoil.Name,                  // Object Name
    1666            8 :                                                                  cAlphaFields2(5));                // Field Name
    1667              : 
    1668            8 :                             if (!ErrorsFound) {
    1669            8 :                                 checkCurveIsNormalizedToOne(state,
    1670           24 :                                                             std::string{RoutineName} + CurrentModuleObject,
    1671            8 :                                                             thisDXCoil.Name,
    1672            8 :                                                             thisDXCoil.EIRFFlow(PerfModeNum),
    1673            8 :                                                             cAlphaFields2(5),
    1674            8 :                                                             Alphas2(5),
    1675              :                                                             1.0);
    1676              :                             }
    1677              :                         }
    1678              : 
    1679            8 :                         thisDXCoil.PLFFPLR(PerfModeNum) = GetCurveIndex(state, Alphas2(6)); // convert curve name to number
    1680            8 :                         if (thisDXCoil.PLFFPLR(PerfModeNum) == 0) {
    1681            0 :                             if (lAlphaBlanks2(6)) {
    1682            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1683            0 :                                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(6)));
    1684              :                             } else {
    1685            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1686            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(6), Alphas2(6)));
    1687              :                             }
    1688            0 :                             ErrorsFound = true;
    1689              :                         } else {
    1690              :                             // Verify Curve Object, only legal types are Quadratic or Cubic
    1691           24 :                             ErrorsFound |= Curve::CheckCurveDims(state,
    1692            8 :                                                                  thisDXCoil.PLFFPLR(PerfModeNum), // Curve index
    1693              :                                                                  {1},                             // Valid dimensions
    1694              :                                                                  RoutineName,                     // Routine name
    1695              :                                                                  CurrentModuleObject,             // Object Type
    1696              :                                                                  thisDXCoil.Name,                 // Object Name
    1697            8 :                                                                  cAlphaFields2(6));               // Field Name
    1698              : 
    1699            8 :                             if (!ErrorsFound) {
    1700              :                                 //             Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    1701            8 :                                 MinCurveVal = 999.0;
    1702            8 :                                 MaxCurveVal = -999.0;
    1703            8 :                                 CurveInput = 0.0;
    1704          808 :                                 while (CurveInput <= 1.0) {
    1705          800 :                                     CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(PerfModeNum), CurveInput);
    1706          800 :                                     if (CurveVal < MinCurveVal) {
    1707            8 :                                         MinCurveVal = CurveVal;
    1708            8 :                                         MinCurvePLR = CurveInput;
    1709              :                                     }
    1710          800 :                                     if (CurveVal > MaxCurveVal) {
    1711            8 :                                         MaxCurveVal = CurveVal;
    1712            8 :                                         MaxCurvePLR = CurveInput;
    1713              :                                     }
    1714          800 :                                     CurveInput += 0.01;
    1715              :                                 }
    1716            8 :                                 if (MinCurveVal < 0.7) {
    1717            0 :                                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1718            0 :                                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields2(6), Alphas2(6)));
    1719            0 :                                     ShowContinueError(
    1720              :                                         state,
    1721            0 :                                         format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    1722            0 :                                     ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    1723            0 :                                     Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 0.7);
    1724              :                                 }
    1725              : 
    1726            8 :                                 if (MaxCurveVal > 1.0) {
    1727            0 :                                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1728            0 :                                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields2(6), Alphas2(6)));
    1729            0 :                                     ShowContinueError(
    1730              :                                         state,
    1731            0 :                                         format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    1732            0 :                                     ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    1733            0 :                                     Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 1.0);
    1734              :                                 }
    1735              :                             }
    1736              :                         }
    1737              : 
    1738            8 :                         thisDXCoil.Twet_Rated(PerfModeNum) = Numbers2(6);
    1739            8 :                         thisDXCoil.Gamma_Rated(PerfModeNum) = Numbers2(7);
    1740            8 :                         thisDXCoil.MaxONOFFCyclesperHour(PerfModeNum) = Numbers2(8);
    1741            8 :                         thisDXCoil.LatentCapacityTimeConstant(PerfModeNum) = Numbers2(9);
    1742              :                         // Numbers2 (6) through (9) must all be greater than zero to use the latent capacity degradation model
    1743            8 :                         if ((Numbers2(6) > 0.0 || Numbers2(7) > 0.0 || Numbers2(8) > 0.0 || Numbers2(9) > 0.0) &&
    1744            0 :                             (Numbers2(6) <= 0.0 || Numbers2(7) <= 0.0 || Numbers2(8) <= 0.0 || Numbers2(9) <= 0.0)) {
    1745            0 :                             ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, PerfObjectType, PerfObjectName));
    1746            0 :                             ShowContinueError(state, "...At least one of the four input parameters for the latent capacity degradation model");
    1747            0 :                             ShowContinueError(state,
    1748              :                                               "...is set to zero. Therefore, the latent degradation model will not be used for this simulation.");
    1749              :                         }
    1750              : 
    1751              :                         // outdoor condenser node
    1752            8 :                         if (lAlphaBlanks2(7)) {
    1753            8 :                             thisDXCoil.CondenserInletNodeNum(PerfModeNum) = 0;
    1754              :                         } else {
    1755            0 :                             thisDXCoil.CondenserInletNodeNum(PerfModeNum) =
    1756            0 :                                 GetOnlySingleNode(state,
    1757            0 :                                                   Alphas2(7),
    1758              :                                                   ErrorsFound,
    1759            0 :                                                   (DataLoopNode::ConnectionObjectType)getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC,
    1760            0 :                                                                                                    Util::makeUPPER(PerfObjectType)),
    1761              :                                                   PerfObjectName,
    1762              :                                                   DataLoopNode::NodeFluidType::Air,
    1763              :                                                   DataLoopNode::ConnectionType::OutsideAirReference,
    1764              :                                                   NodeInputManager::CompFluidStream::Primary,
    1765              :                                                   ObjectIsNotParent);
    1766            0 :                             if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(PerfModeNum))) {
    1767            0 :                                 ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, PerfObjectType, PerfObjectName));
    1768            0 :                                 ShowContinueError(state, format("may not be valid {}=\"{}\".", cAlphaFields2(7), Alphas2(7)));
    1769            0 :                                 ShowContinueError(state, "node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
    1770            0 :                                 ShowContinueError(state,
    1771              :                                                   "This node needs to be included in an air system or the coil model will not be valid, and the "
    1772              :                                                   "simulation continues");
    1773              :                             }
    1774              :                         }
    1775            8 :                         if ((Util::SameString(Alphas2(8), "AirCooled")) || lAlphaBlanks2(8)) {
    1776            8 :                             thisDXCoil.CondenserType(PerfModeNum) = DataHeatBalance::RefrigCondenserType::Air;
    1777            0 :                         } else if (Util::SameString(Alphas2(8), "EvaporativelyCooled")) {
    1778            0 :                             thisDXCoil.CondenserType(PerfModeNum) = DataHeatBalance::RefrigCondenserType::Evap;
    1779            0 :                             thisDXCoil.ReportEvapCondVars = true;
    1780              :                         } else {
    1781            0 :                             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1782            0 :                             ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields2(8), Alphas2(8)));
    1783            0 :                             ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
    1784            0 :                             ErrorsFound = true;
    1785              :                         }
    1786              : 
    1787            8 :                         thisDXCoil.EvapCondEffect(PerfModeNum) = Numbers2(10);
    1788            8 :                         if (thisDXCoil.EvapCondEffect(PerfModeNum) < 0.0 || thisDXCoil.EvapCondEffect(PerfModeNum) > 1.0) {
    1789            0 :                             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1790            0 :                             ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields2(10)));
    1791            0 :                             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(10)));
    1792            0 :                             ErrorsFound = true;
    1793              :                         }
    1794              : 
    1795            8 :                         thisDXCoil.EvapCondAirFlow(PerfModeNum) = Numbers2(11);
    1796            8 :                         if (thisDXCoil.EvapCondAirFlow(PerfModeNum) < 0.0 && thisDXCoil.EvapCondAirFlow(PerfModeNum) != AutoSize) {
    1797            0 :                             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1798            0 :                             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields2(11)));
    1799            0 :                             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(11)));
    1800            0 :                             ErrorsFound = true;
    1801              :                         }
    1802              : 
    1803            8 :                         thisDXCoil.EvapCondPumpElecNomPower(PerfModeNum) = Numbers2(12);
    1804            8 :                         if (thisDXCoil.EvapCondPumpElecNomPower(PerfModeNum) < 0.0 && thisDXCoil.EvapCondAirFlow(PerfModeNum) != AutoSize) {
    1805            0 :                             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1806            0 :                             ShowContinueError(state, format("...{} cannot be less than zero.", cNumericFields2(12)));
    1807            0 :                             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(12)));
    1808            0 :                             ErrorsFound = true;
    1809              :                         }
    1810              : 
    1811            8 :                         thisDXCoil.RatedEIR(PerfModeNum) = 1.0 / thisDXCoil.RatedCOP(PerfModeNum);
    1812              : 
    1813              :                         // read in user specified SHR modifier curves
    1814            8 :                         if (!lAlphaBlanks2(9) && NumAlphas2 > 8) {
    1815            0 :                             thisDXCoil.SHRFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(9)); // convert curve name to number
    1816            0 :                             if (thisDXCoil.SHRFTemp(PerfModeNum) == 0) {
    1817            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1818            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(9), Alphas2(9)));
    1819              :                             } else {
    1820              :                                 // Verify Curve Object, only legal type is BiQuadratic
    1821            0 :                                 ErrorsFound |= Curve::CheckCurveDims(state,
    1822            0 :                                                                      thisDXCoil.SHRFTemp(PerfModeNum), // Curve index
    1823              :                                                                      {2},                              // Valid dimensions
    1824              :                                                                      RoutineName,                      // Routine name
    1825              :                                                                      CurrentModuleObject,              // Object Type
    1826              :                                                                      thisDXCoil.Name,                  // Object Name
    1827            0 :                                                                      cAlphaFields2(9));                // Field Name
    1828              :                             }
    1829              :                         }
    1830              : 
    1831            8 :                         if (!lAlphaBlanks2(10) && NumAlphas2 > 9) {
    1832            0 :                             thisDXCoil.SHRFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(10)); // convert curve name to number
    1833            0 :                             if (thisDXCoil.SHRFTemp(PerfModeNum) == 0) {
    1834            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1835            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(10), Alphas2(10)));
    1836              :                             } else {
    1837              :                                 // Verify Curve Object, only legal type is BiQuadratic
    1838            0 :                                 ErrorsFound |= Curve::CheckCurveDims(state,
    1839            0 :                                                                      thisDXCoil.SHRFFlow(PerfModeNum), // Curve index
    1840              :                                                                      {1},                              // Valid dimensions
    1841              :                                                                      RoutineName,                      // Routine name
    1842              :                                                                      CurrentModuleObject,              // Object Type
    1843              :                                                                      thisDXCoil.Name,                  // Object Name
    1844            0 :                                                                      cAlphaFields2(10));               // Field Name
    1845              :                             }
    1846              :                         }
    1847            8 :                         if (thisDXCoil.SHRFTemp(PerfModeNum) > 0 && thisDXCoil.SHRFFlow(PerfModeNum) > 0) {
    1848            0 :                             thisDXCoil.UserSHRCurveExists = true;
    1849              :                         } else {
    1850            8 :                             thisDXCoil.UserSHRCurveExists = false;
    1851              :                         }
    1852              : 
    1853              :                     } else { // invalid performance object
    1854            0 :                         ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1855            0 :                         ShowContinueError(state, format("... not found {}=\"{}\".", PerfObjectType, PerfObjectName));
    1856            0 :                         ErrorsFound = true;
    1857              :                     } // end of valid performance object check
    1858            8 :                     AlphaIndex += 2;
    1859              :                 } // end of sufficient number of fields entered check
    1860              :             }     // End of multimode DX capacity stages loop
    1861              :             // Warn if inputs entered for unused capacity stages
    1862            4 :             for (CapacityStageNum = (thisDXCoil.NumCapacityStages + 1); CapacityStageNum <= MaxCapacityStages; ++CapacityStageNum) {
    1863            0 :                 if ((AlphaIndex <= NumAlphas) && ((!Alphas(AlphaIndex).empty()) || (!Alphas(AlphaIndex + 1).empty()))) {
    1864            0 :                     ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1865            0 :                     ShowContinueError(state, format("...Capacity Stage {} not active. Therefore,{}", CapacityStageNum, cAlphaFields(AlphaIndex)));
    1866            0 :                     ShowContinueError(state, format("... and {} fields will be ignored.", cAlphaFields(AlphaIndex + 1)));
    1867              :                 }
    1868            0 :                 AlphaIndex += 2;
    1869              :             } // End of unused capacity stages loop
    1870              :         }     // End of multimode DX dehumidification modes loo
    1871              : 
    1872              :         // Get Water System tank connections
    1873              :         //  A14, \field Name of Water Storage Tank for Supply
    1874            2 :         thisDXCoil.EvapWaterSupplyName = Alphas(14);
    1875            2 :         if (lAlphaBlanks(14)) {
    1876            2 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
    1877              :         } else {
    1878            0 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
    1879            0 :             SetupTankDemandComponent(state,
    1880              :                                      thisDXCoil.Name,
    1881              :                                      CurrentModuleObject,
    1882              :                                      thisDXCoil.EvapWaterSupplyName,
    1883              :                                      ErrorsFound,
    1884            0 :                                      thisDXCoil.EvapWaterSupTankID,
    1885            0 :                                      thisDXCoil.EvapWaterTankDemandARRID);
    1886              :         }
    1887              : 
    1888              :         // A15; \field Name of Water Storage Tank for Condensate Collection
    1889            2 :         thisDXCoil.CondensateCollectName = Alphas(15);
    1890            2 :         if (lAlphaBlanks(15)) {
    1891            2 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    1892              :         } else {
    1893            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    1894            0 :             SetupTankSupplyComponent(state,
    1895              :                                      thisDXCoil.Name,
    1896              :                                      CurrentModuleObject,
    1897              :                                      thisDXCoil.CondensateCollectName,
    1898              :                                      ErrorsFound,
    1899            0 :                                      thisDXCoil.CondensateTankID,
    1900            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    1901              :         }
    1902              : 
    1903              :         // Set minimum OAT for compressor operation
    1904            2 :         thisDXCoil.MinOATCompressor = Numbers(5);
    1905            2 :         if (NumNumbers < 5)
    1906            0 :             thisDXCoil.MinOATCompressor = minOATCompDXCooling; // input field is after min fields and won't default if field not included
    1907              : 
    1908              :         // Basin heater power as a function of temperature must be greater than or equal to 0
    1909            2 :         thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(6);
    1910            2 :         if (Numbers(6) < 0.0) {
    1911            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1912            0 :             ShowContinueError(state, format("...{} must be >= 0.", cNumericFields(6)));
    1913            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(6)));
    1914            0 :             ErrorsFound = true;
    1915              :         }
    1916              : 
    1917            2 :         thisDXCoil.BasinHeaterSetPointTemp = Numbers(7);
    1918            2 :         if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    1919            0 :             if (NumNumbers < 7) {
    1920            0 :                 thisDXCoil.BasinHeaterSetPointTemp = 2.0;
    1921              :             }
    1922            0 :             if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
    1923            0 :                 ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1924            0 :                 ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(7)));
    1925            0 :                 ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(7)));
    1926              :             }
    1927              :         }
    1928              : 
    1929            2 :         if (!lAlphaBlanks(16)) {
    1930            0 :             if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(16))) == nullptr) {
    1931            0 :                 ShowWarningItemNotFound(
    1932            0 :                     state, eoh, cAlphaFields(16), Alphas(16), "Basin heater will be available to operate throughout the simulation.");
    1933              :             }
    1934              :         }
    1935              : 
    1936              :     } // end of the Multimode DX coil loop
    1937              : 
    1938          135 :     if (ErrorsFound) {
    1939            0 :         ShowFatalError(state,
    1940            0 :                        format("{}Errors found in getting {} input.  Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    1941              :     }
    1942              : 
    1943              :     //************* Read Heat Pump (DX Heating Coil) Input **********
    1944          135 :     CurrentModuleObject = "Coil:Heating:DX:SingleSpeed";
    1945          147 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXHeatingCoils; ++DXCoilIndex) {
    1946              : 
    1947           12 :         ++DXCoilNum;
    1948              : 
    1949           12 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1950              :                                                                  CurrentModuleObject,
    1951              :                                                                  DXCoilIndex,
    1952              :                                                                  Alphas,
    1953              :                                                                  NumAlphas,
    1954              :                                                                  Numbers,
    1955              :                                                                  NumNumbers,
    1956              :                                                                  IOStatus,
    1957              :                                                                  lNumericBlanks,
    1958              :                                                                  lAlphaBlanks,
    1959              :                                                                  cAlphaFields,
    1960              :                                                                  cNumericFields);
    1961              : 
    1962           12 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    1963              :         // allocate single performance mode for numeric field strings used for sizing routine
    1964           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    1965           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    1966           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    1967              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    1968           12 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    1969              : 
    1970           12 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    1971           12 :         thisDXCoil.Name = Alphas(1);
    1972           12 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    1973           12 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatingEmpirical;
    1974           12 :         if (lAlphaBlanks(2)) {
    1975            3 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    1976            9 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    1977            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    1978            0 :             ErrorsFound = true;
    1979              :         }
    1980              : 
    1981           12 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    1982           12 :                                                  Alphas(3),
    1983              :                                                  ErrorsFound,
    1984              :                                                  DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
    1985           12 :                                                  Alphas(1),
    1986              :                                                  DataLoopNode::NodeFluidType::Air,
    1987              :                                                  DataLoopNode::ConnectionType::Inlet,
    1988              :                                                  NodeInputManager::CompFluidStream::Primary,
    1989              :                                                  ObjectIsNotParent);
    1990              : 
    1991           24 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    1992           12 :                                                   Alphas(4),
    1993              :                                                   ErrorsFound,
    1994              :                                                   DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
    1995           12 :                                                   Alphas(1),
    1996              :                                                   DataLoopNode::NodeFluidType::Air,
    1997              :                                                   DataLoopNode::ConnectionType::Outlet,
    1998              :                                                   NodeInputManager::CompFluidStream::Primary,
    1999              :                                                   ObjectIsNotParent);
    2000              : 
    2001           12 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    2002              : 
    2003           12 :         thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
    2004           12 :         if (thisDXCoil.CCapFTemp(1) == 0) {
    2005            0 :             if (lAlphaBlanks(5)) {
    2006            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2007            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
    2008              :             } else {
    2009            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2010            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
    2011              :             }
    2012            0 :             ErrorsFound = true;
    2013              :         } else {
    2014              :             // only legal types are Quadratic, BiQuadratic and Cubic
    2015           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2016           12 :                                                  thisDXCoil.CCapFTemp(1), // Curve index
    2017              :                                                  {1, 2},                  // Valid dimensions  // MULTIPLECURVEDIMS
    2018              :                                                  RoutineName,             // Routine name
    2019              :                                                  CurrentModuleObject,     // Object Type
    2020              :                                                  thisDXCoil.Name,         // Object Name
    2021           12 :                                                  cAlphaFields(5));        // Field Name
    2022              : 
    2023           12 :             if (!ErrorsFound) {
    2024           12 :                 if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
    2025            7 :                     checkCurveIsNormalizedToOne(state,
    2026           21 :                                                 std::string{RoutineName} + CurrentModuleObject,
    2027            7 :                                                 thisDXCoil.Name,
    2028            7 :                                                 thisDXCoil.CCapFTemp(1),
    2029            7 :                                                 cAlphaFields(5),
    2030            7 :                                                 Alphas(5),
    2031              :                                                 RatedOutdoorAirTempHeat);
    2032              :                 } else {
    2033            5 :                     checkCurveIsNormalizedToOne(state,
    2034           15 :                                                 std::string{RoutineName} + CurrentModuleObject,
    2035            5 :                                                 thisDXCoil.Name,
    2036            5 :                                                 thisDXCoil.CCapFTemp(1),
    2037            5 :                                                 cAlphaFields(5),
    2038            5 :                                                 Alphas(5),
    2039              :                                                 RatedInletAirTempHeat,
    2040              :                                                 RatedOutdoorAirTempHeat);
    2041              :                 }
    2042              :             }
    2043              :         }
    2044              : 
    2045           12 :         thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
    2046           12 :         if (thisDXCoil.CCapFFlow(1) == 0) {
    2047            0 :             if (lAlphaBlanks(6)) {
    2048            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2049            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
    2050              :             } else {
    2051            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2052            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
    2053              :             }
    2054            0 :             ErrorsFound = true;
    2055              :         } else {
    2056              :             // Verify Curve Object, only legal type is Quadratic
    2057           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2058           12 :                                                  thisDXCoil.CCapFFlow(1), // Curve index
    2059              :                                                  {1},                     // Valid dimensions
    2060              :                                                  RoutineName,             // Routine name
    2061              :                                                  CurrentModuleObject,     // Object Type
    2062              :                                                  thisDXCoil.Name,         // Object Name
    2063           12 :                                                  cAlphaFields(6));        // Field Name
    2064              : 
    2065           12 :             if (!ErrorsFound) {
    2066           12 :                 checkCurveIsNormalizedToOne(
    2067           48 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
    2068              :             }
    2069              :         }
    2070              : 
    2071           12 :         thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
    2072           12 :         if (thisDXCoil.EIRFTemp(1) == 0) {
    2073            0 :             if (lAlphaBlanks(7)) {
    2074            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2075            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
    2076              :             } else {
    2077            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2078            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
    2079              :             }
    2080            0 :             ErrorsFound = true;
    2081              :         } else {
    2082              :             // only legal types are Quadratic, BiQuadratic and Cubic
    2083           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2084           12 :                                                  thisDXCoil.EIRFTemp(1), // Curve index
    2085              :                                                  {1, 2},                 // Valid dimensions  // MULTIPLECURVEDIMS
    2086              :                                                  RoutineName,            // Routine name
    2087              :                                                  CurrentModuleObject,    // Object Type
    2088              :                                                  thisDXCoil.Name,        // Object Name
    2089           12 :                                                  cAlphaFields(7));       // Field Name
    2090              : 
    2091           12 :             if (!ErrorsFound) {
    2092           12 :                 if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(1))->numDims == 1) {
    2093            7 :                     checkCurveIsNormalizedToOne(state,
    2094           21 :                                                 std::string{RoutineName} + CurrentModuleObject,
    2095            7 :                                                 thisDXCoil.Name,
    2096            7 :                                                 thisDXCoil.EIRFTemp(1),
    2097            7 :                                                 cAlphaFields(7),
    2098            7 :                                                 Alphas(7),
    2099              :                                                 RatedOutdoorAirTempHeat);
    2100              :                 } else {
    2101            5 :                     checkCurveIsNormalizedToOne(state,
    2102           15 :                                                 std::string{RoutineName} + CurrentModuleObject,
    2103            5 :                                                 thisDXCoil.Name,
    2104            5 :                                                 thisDXCoil.EIRFTemp(1),
    2105            5 :                                                 cAlphaFields(7),
    2106            5 :                                                 Alphas(7),
    2107              :                                                 RatedInletAirTempHeat,
    2108              :                                                 RatedOutdoorAirTempHeat);
    2109              :                 }
    2110              :             }
    2111              :         }
    2112              : 
    2113           12 :         thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
    2114           12 :         if (thisDXCoil.EIRFFlow(1) == 0) {
    2115            0 :             if (lAlphaBlanks(8)) {
    2116            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2117            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
    2118              :             } else {
    2119            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2120            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
    2121              :             }
    2122            0 :             ErrorsFound = true;
    2123              :         } else {
    2124              :             // Verify Curve Object, only legal type is Quadratic or Cubic
    2125           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2126           12 :                                                  thisDXCoil.EIRFFlow(1), // Curve index
    2127              :                                                  {1},                    // Valid dimensions
    2128              :                                                  RoutineName,            // Routine name
    2129              :                                                  CurrentModuleObject,    // Object Type
    2130              :                                                  thisDXCoil.Name,        // Object Name
    2131           12 :                                                  cAlphaFields(8));       // Field Name
    2132              : 
    2133           12 :             if (!ErrorsFound) {
    2134           12 :                 checkCurveIsNormalizedToOne(
    2135           48 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
    2136              :             }
    2137              :         }
    2138              : 
    2139           12 :         thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
    2140           12 :         if (thisDXCoil.PLFFPLR(1) == 0) {
    2141            0 :             if (lAlphaBlanks(9)) {
    2142            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2143            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
    2144              :             } else {
    2145            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2146            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
    2147              :             }
    2148            0 :             ErrorsFound = true;
    2149              :         } else {
    2150              :             // Verify Curve Object, only legal types are Quadratic or Cubic
    2151           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2152           12 :                                                  thisDXCoil.PLFFPLR(1), // Curve index
    2153              :                                                  {1},                   // Valid dimensions
    2154              :                                                  RoutineName,           // Routine name
    2155              :                                                  CurrentModuleObject,   // Object Type
    2156              :                                                  thisDXCoil.Name,       // Object Name
    2157           12 :                                                  cAlphaFields(9));      // Field Name
    2158              : 
    2159           12 :             if (!ErrorsFound) {
    2160              :                 //     Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    2161           12 :                 MinCurveVal = 999.0;
    2162           12 :                 MaxCurveVal = -999.0;
    2163           12 :                 CurveInput = 0.0;
    2164         1212 :                 while (CurveInput <= 1.0) {
    2165         1200 :                     CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
    2166         1200 :                     if (CurveVal < MinCurveVal) {
    2167           12 :                         MinCurveVal = CurveVal;
    2168           12 :                         MinCurvePLR = CurveInput;
    2169              :                     }
    2170         1200 :                     if (CurveVal > MaxCurveVal) {
    2171          854 :                         MaxCurveVal = CurveVal;
    2172          854 :                         MaxCurvePLR = CurveInput;
    2173              :                     }
    2174         1200 :                     CurveInput += 0.01;
    2175              :                 }
    2176           12 :                 if (MinCurveVal < 0.7) {
    2177            0 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2178            0 :                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
    2179            0 :                     ShowContinueError(state,
    2180            0 :                                       format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    2181            0 :                     ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    2182            0 :                     Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
    2183              :                 }
    2184              : 
    2185           12 :                 if (MaxCurveVal > 1.0) {
    2186            0 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2187            0 :                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
    2188            0 :                     ShowContinueError(state,
    2189            0 :                                       format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    2190            0 :                     ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    2191            0 :                     Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
    2192              :                 }
    2193              :             }
    2194              :         }
    2195              : 
    2196              :         // Only required for reverse cycle heat pumps
    2197           12 :         thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(10)); // convert curve name to number
    2198              :         // A11; \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
    2199           12 :         if (!lAlphaBlanks(11)) {
    2200            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
    2201            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    2202            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(11), Alphas(11)));
    2203            0 :                 ErrorsFound = true;
    2204              :             } else {
    2205            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2206              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    2207              :                                                      {1},                                          // Valid dimensions
    2208              :                                                      RoutineName,                                  // Routine name
    2209              :                                                      CurrentModuleObject,                          // Object Type
    2210              :                                                      thisDXCoil.Name,                              // Object Name
    2211            2 :                                                      cAlphaFields(11));                            // Field Name
    2212              :             }
    2213              :         }
    2214              : 
    2215           12 :         if (Util::SameString(Alphas(12), "ReverseCycle")) {
    2216              : 
    2217            3 :             if (thisDXCoil.DefrostEIRFT == 0) {
    2218            0 :                 if (lAlphaBlanks(10)) {
    2219            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2220            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(10)));
    2221            0 :                     ShowContinueError(state, format("...field is required because {} is \"ReverseCycle\".", cAlphaFields(12)));
    2222              :                 } else {
    2223            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2224            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
    2225              :                 }
    2226            0 :                 ErrorsFound = true;
    2227              :             } else {
    2228              :                 // Verify Curve Object, only legal type is BiQuadratic
    2229            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2230              :                                                      thisDXCoil.DefrostEIRFT, // Curve index
    2231              :                                                      {2},                     // Valid dimensions
    2232              :                                                      RoutineName,             // Routine name
    2233              :                                                      CurrentModuleObject,     // Object Type
    2234              :                                                      thisDXCoil.Name,         // Object Name
    2235            3 :                                                      cAlphaFields(10));       // Field Name
    2236              : 
    2237            3 :                 if (!ErrorsFound) {
    2238            3 :                     checkCurveIsNormalizedToOne(state,
    2239            9 :                                                 std::string{RoutineName} + CurrentModuleObject,
    2240            3 :                                                 thisDXCoil.Name,
    2241              :                                                 thisDXCoil.DefrostEIRFT,
    2242            3 :                                                 cAlphaFields(10),
    2243            3 :                                                 Alphas(10),
    2244              :                                                 RatedInletAirTempHeat,
    2245              :                                                 RatedOutdoorAirTempHeat);
    2246              :                 }
    2247              :             }
    2248              :         }
    2249              : 
    2250           12 :         if (Util::SameString(Alphas(12), "ReverseCycle")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
    2251           12 :         if (Util::SameString(Alphas(12), "Resistive")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
    2252              : 
    2253           12 :         if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
    2254            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2255            0 :             ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(12), Alphas(12)));
    2256            0 :             ShowContinueError(state, "...valid values for this field are ReverseCycle or Resistive.");
    2257            0 :             ErrorsFound = true;
    2258              :         }
    2259              : 
    2260           12 :         if (Util::SameString(Alphas(13), "Timed")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
    2261           12 :         if (Util::SameString(Alphas(13), "OnDemand")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
    2262           12 :         if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
    2263            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2264            0 :             ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(13), Alphas(13)));
    2265            0 :             ShowContinueError(state, "...valid values for this field are Timed or OnDemand.");
    2266            0 :             ErrorsFound = true;
    2267              :         }
    2268              : 
    2269           12 :         thisDXCoil.RatedSHR(1) = 1.0;
    2270           12 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    2271           12 :         thisDXCoil.RatedCOP(1) = Numbers(2);
    2272           12 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
    2273           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(4);
    2274           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(5);
    2275              : 
    2276              :         // Set minimum OAT for heat pump compressor operation
    2277           12 :         thisDXCoil.MinOATCompressor = Numbers(6);
    2278              : 
    2279           12 :         thisDXCoil.OATempCompressorOn = Numbers(7);
    2280              : 
    2281           12 :         if (lNumericBlanks(7) || lNumericBlanks(6)) { //??TBD:BPS 6 or 5 | 7 or 6
    2282           12 :             thisDXCoil.OATempCompressorOnOffBlank = true;
    2283              :         } else {
    2284            0 :             thisDXCoil.OATempCompressorOnOffBlank = false;
    2285              :         }
    2286              : 
    2287           12 :         if (thisDXCoil.OATempCompressorOn < thisDXCoil.MinOATCompressor) thisDXCoil.OATempCompressorOn = thisDXCoil.MinOATCompressor;
    2288              : 
    2289              :         // Set maximum outdoor temp for defrost to occur
    2290           12 :         thisDXCoil.MaxOATDefrost = Numbers(8);
    2291              : 
    2292              :         // Set crankcase heater capacity
    2293           12 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(9);
    2294           12 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    2295            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2296            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(8)));
    2297            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(9)));
    2298            0 :             ErrorsFound = true;
    2299              :         }
    2300              : 
    2301              :         // Set crankcase heater cutout temperature
    2302           12 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(10);
    2303              : 
    2304              :         // Set defrost time period
    2305           12 :         thisDXCoil.DefrostTime = Numbers(11);
    2306           12 :         if (thisDXCoil.DefrostTime == 0.0 && thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
    2307            0 :             ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2308            0 :             ShowContinueError(state, format("...{} = 0.0 for defrost control = TIMED.", cNumericFields(11)));
    2309              :         }
    2310              : 
    2311              :         // Set defrost capacity (for resistive defrost)
    2312           12 :         thisDXCoil.DefrostCapacity = Numbers(12);
    2313           12 :         if (thisDXCoil.DefrostCapacity == 0.0 && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
    2314            0 :             ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2315            0 :             ShowContinueError(state, format("...{} = 0.0 for defrost strategy = RESISTIVE.", cNumericFields(12)));
    2316              :         }
    2317              : 
    2318              :         // Set Region number for calculating HSPF
    2319           12 :         thisDXCoil.RegionNum = Numbers(13);
    2320              : 
    2321           12 :         if (lNumericBlanks(13)) {
    2322           11 :             thisDXCoil.RegionNum = 4;
    2323              :         }
    2324              : 
    2325           12 :         thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
    2326              : 
    2327              :         // A14 is optional evaporator node name
    2328           12 :         if (lAlphaBlanks(14)) {
    2329           12 :             thisDXCoil.CondenserInletNodeNum(1) = 0;
    2330              :         } else {
    2331            0 :             thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
    2332            0 :                                                                     Alphas(14),
    2333              :                                                                     ErrorsFound,
    2334              :                                                                     DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
    2335            0 :                                                                     thisDXCoil.Name,
    2336              :                                                                     DataLoopNode::NodeFluidType::Air,
    2337              :                                                                     DataLoopNode::ConnectionType::OutsideAirReference,
    2338              :                                                                     NodeInputManager::CompFluidStream::Primary,
    2339              :                                                                     ObjectIsNotParent);
    2340              :             // warn if not an outdoor node, but allow
    2341            0 :             if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
    2342            0 :                 ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2343            0 :                 ShowContinueError(
    2344              :                     state,
    2345            0 :                     format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(14), Alphas(14)));
    2346            0 :                 ShowContinueError(
    2347              :                     state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
    2348              :             }
    2349              :         }
    2350              : 
    2351              :         // A14, \field Zone Name for Evaporator Placement
    2352           12 :         if (!lAlphaBlanks(15) && NumAlphas > 14) {
    2353            0 :             thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(15), state.dataHeatBal->Zone);
    2354            0 :             if (thisDXCoil.SecZonePtr > 0) {
    2355            0 :                 SetupZoneInternalGain(state,
    2356              :                                       thisDXCoil.SecZonePtr,
    2357              :                                       thisDXCoil.Name,
    2358              :                                       DataHeatBalance::IntGainType::SecHeatingDXCoilSingleSpeed,
    2359              :                                       &thisDXCoil.SecCoilSensibleHeatRemovalRate,
    2360              :                                       nullptr,
    2361              :                                       nullptr,
    2362              :                                       &thisDXCoil.SecCoilLatentHeatRemovalRate);
    2363            0 :                 thisDXCoil.IsSecondaryDXCoilInZone = true;
    2364              :             } else {
    2365            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2366            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15), Alphas(15)));
    2367              :             }
    2368              :         }
    2369           12 :         if (thisDXCoil.SecZonePtr > 0) {
    2370              :             // N14, \field Secondary Coil Air Flow Rate
    2371            0 :             if (!lNumericBlanks(13)) {
    2372            0 :                 thisDXCoil.SecCoilAirFlow = Numbers(14);
    2373              :             }
    2374              :             // N15, \field Secondary Coil Fan Flow Scaling Factor
    2375            0 :             if (!lNumericBlanks(15)) {
    2376            0 :                 thisDXCoil.SecCoilAirFlowScalingFactor = Numbers(15);
    2377              :             }
    2378              :             // N16, \field Nominal Sensible Heat Ratio of Secondary Coil
    2379            0 :             if (!lNumericBlanks(16)) {
    2380            0 :                 thisDXCoil.SecCoilRatedSHR = Numbers(16);
    2381              :             } else {
    2382            0 :                 thisDXCoil.SecCoilRatedSHR = 1.0;
    2383              :             }
    2384              :             // A16, \field Sensible Heat Ratio Modifier Function of Temperature Curve Name
    2385            0 :             if (!lAlphaBlanks(16)) {
    2386            0 :                 thisDXCoil.SecCoilSHRFT = GetCurveIndex(state, Alphas(16));
    2387            0 :                 if (thisDXCoil.SecCoilSHRFT == 0) {
    2388            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2389            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
    2390              :                 }
    2391              :             }
    2392              :             // A17; \field Sensible Heat Ratio Function of Flow Fraction Curve Name
    2393            0 :             if (!lAlphaBlanks(17)) {
    2394            0 :                 thisDXCoil.SecCoilSHRFF = GetCurveIndex(state, Alphas(17));
    2395            0 :                 if (thisDXCoil.SecCoilSHRFF == 0) {
    2396            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2397            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
    2398              :                 }
    2399              :             }
    2400              :         }
    2401              : 
    2402              :     } // end of the DX heating coil loop
    2403              : 
    2404          135 :     if (ErrorsFound) {
    2405            0 :         ShowFatalError(state,
    2406            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    2407              :     }
    2408              : 
    2409          135 :     CurrentModuleObject = "Coil:Cooling:DX:TwoSpeed";
    2410          147 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoils; ++DXCoilIndex) {
    2411              : 
    2412           12 :         ++DXCoilNum;
    2413              : 
    2414           12 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    2415              :                                                                  CurrentModuleObject,
    2416              :                                                                  DXCoilIndex,
    2417              :                                                                  Alphas,
    2418              :                                                                  NumAlphas,
    2419              :                                                                  Numbers,
    2420              :                                                                  NumNumbers,
    2421              :                                                                  IOStatus,
    2422              :                                                                  lNumericBlanks,
    2423              :                                                                  lAlphaBlanks,
    2424              :                                                                  cAlphaFields,
    2425              :                                                                  cNumericFields);
    2426              : 
    2427           12 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    2428              : 
    2429              :         // allocate single performance mode for numeric field strings used for sizing routine
    2430           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    2431           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    2432           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    2433              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    2434           12 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    2435              : 
    2436           12 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    2437           12 :         thisDXCoil.Name = Alphas(1);
    2438              :         // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
    2439           12 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
    2440           12 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
    2441           12 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    2442           12 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoSpeed;
    2443           12 :         if (lAlphaBlanks(2)) {
    2444            2 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    2445           10 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    2446            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    2447            0 :             ErrorsFound = true;
    2448              :         }
    2449           12 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    2450           12 :         thisDXCoil.RatedSHR(1) = Numbers(2);
    2451           12 :         thisDXCoil.RatedCOP(1) = Numbers(3);
    2452           12 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
    2453              : 
    2454           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
    2455           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
    2456              : 
    2457           12 :         if (!lNumericBlanks(7)) {
    2458            5 :             thisDXCoil.InternalStaticPressureDrop = Numbers(7);
    2459            5 :             thisDXCoil.RateWithInternalStaticAndFanObject = true;
    2460              :         } else {
    2461            7 :             thisDXCoil.InternalStaticPressureDrop = -999.0;
    2462            7 :             thisDXCoil.RateWithInternalStaticAndFanObject = false;
    2463              :         }
    2464              : 
    2465           12 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    2466           12 :                                                  Alphas(3),
    2467              :                                                  ErrorsFound,
    2468              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
    2469           12 :                                                  Alphas(1),
    2470              :                                                  DataLoopNode::NodeFluidType::Air,
    2471              :                                                  DataLoopNode::ConnectionType::Inlet,
    2472              :                                                  NodeInputManager::CompFluidStream::Primary,
    2473              :                                                  ObjectIsNotParent);
    2474              : 
    2475           24 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    2476           12 :                                                   Alphas(4),
    2477              :                                                   ErrorsFound,
    2478              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
    2479           12 :                                                   Alphas(1),
    2480              :                                                   DataLoopNode::NodeFluidType::Air,
    2481              :                                                   DataLoopNode::ConnectionType::Outlet,
    2482              :                                                   NodeInputManager::CompFluidStream::Primary,
    2483              :                                                   ObjectIsNotParent);
    2484              : 
    2485           12 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    2486              : 
    2487           12 :         thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
    2488           12 :         if (thisDXCoil.CCapFTemp(1) == 0) {
    2489            0 :             if (lAlphaBlanks(5)) {
    2490            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2491            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
    2492              :             } else {
    2493            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2494            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
    2495              :             }
    2496            0 :             ErrorsFound = true;
    2497              :         } else {
    2498              :             // Verify Curve Object, only legal type is BiQuadratic
    2499           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2500           12 :                                                  thisDXCoil.CCapFTemp(1), // Curve index
    2501              :                                                  {2},                     // Valid dimensions
    2502              :                                                  RoutineName,             // Routine name
    2503              :                                                  CurrentModuleObject,     // Object Type
    2504              :                                                  thisDXCoil.Name,         // Object Name
    2505           12 :                                                  cAlphaFields(5));        // Field Name
    2506              : 
    2507           12 :             if (!ErrorsFound) {
    2508           12 :                 checkCurveIsNormalizedToOne(state,
    2509           36 :                                             std::string{RoutineName} + CurrentModuleObject,
    2510           12 :                                             thisDXCoil.Name,
    2511           12 :                                             thisDXCoil.CCapFTemp(1),
    2512           12 :                                             cAlphaFields(5),
    2513           12 :                                             Alphas(5),
    2514              :                                             RatedInletWetBulbTemp,
    2515              :                                             RatedOutdoorAirTemp);
    2516              :             }
    2517              :         }
    2518              : 
    2519           12 :         thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
    2520           12 :         if (thisDXCoil.CCapFFlow(1) == 0) {
    2521            0 :             if (lAlphaBlanks(6)) {
    2522            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2523            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
    2524              :             } else {
    2525            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2526            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
    2527              :             }
    2528            0 :             ErrorsFound = true;
    2529              :         } else {
    2530              :             // Verify Curve Object, only legal type is Quadratic
    2531           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2532           12 :                                                  thisDXCoil.CCapFFlow(1), // Curve index
    2533              :                                                  {1},                     // Valid dimensions
    2534              :                                                  RoutineName,             // Routine name
    2535              :                                                  CurrentModuleObject,     // Object Type
    2536              :                                                  thisDXCoil.Name,         // Object Name
    2537           12 :                                                  cAlphaFields(6));        // Field Name
    2538              : 
    2539           12 :             if (!ErrorsFound) {
    2540           12 :                 checkCurveIsNormalizedToOne(
    2541           48 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
    2542              :             }
    2543              :         }
    2544              : 
    2545           12 :         thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
    2546           12 :         if (thisDXCoil.EIRFTemp(1) == 0) {
    2547            0 :             if (lAlphaBlanks(7)) {
    2548            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2549            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
    2550              :             } else {
    2551            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2552            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
    2553              :             }
    2554            0 :             ErrorsFound = true;
    2555              :         } else {
    2556              :             // Verify Curve Object, only legal type is BiQuadratic
    2557           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2558           12 :                                                  thisDXCoil.EIRFTemp(1), // Curve index
    2559              :                                                  {2},                    // Valid dimensions
    2560              :                                                  RoutineName,            // Routine name
    2561              :                                                  CurrentModuleObject,    // Object Type
    2562              :                                                  thisDXCoil.Name,        // Object Name
    2563           12 :                                                  cAlphaFields(7));       // Field Name
    2564              : 
    2565           12 :             if (!ErrorsFound) {
    2566           12 :                 checkCurveIsNormalizedToOne(state,
    2567           36 :                                             std::string{RoutineName} + CurrentModuleObject,
    2568           12 :                                             thisDXCoil.Name,
    2569           12 :                                             thisDXCoil.EIRFTemp(1),
    2570           12 :                                             cAlphaFields(7),
    2571           12 :                                             Alphas(7),
    2572              :                                             RatedInletWetBulbTemp,
    2573              :                                             RatedOutdoorAirTemp);
    2574              :             }
    2575              :         }
    2576              : 
    2577           12 :         thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
    2578           12 :         if (thisDXCoil.EIRFFlow(1) == 0) {
    2579            0 :             if (lAlphaBlanks(8)) {
    2580            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2581            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
    2582              :             } else {
    2583            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2584            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
    2585              :             }
    2586            0 :             ErrorsFound = true;
    2587              :         } else {
    2588              :             // Verify Curve Object, only legal type is Quadratic
    2589           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2590           12 :                                                  thisDXCoil.EIRFFlow(1), // Curve index
    2591              :                                                  {1},                    // Valid dimensions
    2592              :                                                  RoutineName,            // Routine name
    2593              :                                                  CurrentModuleObject,    // Object Type
    2594              :                                                  thisDXCoil.Name,        // Object Name
    2595           12 :                                                  cAlphaFields(8));       // Field Name
    2596              : 
    2597           12 :             if (!ErrorsFound) {
    2598           12 :                 checkCurveIsNormalizedToOne(
    2599           48 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
    2600              :             }
    2601              :         }
    2602              : 
    2603           12 :         thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
    2604           12 :         if (thisDXCoil.PLFFPLR(1) == 0) {
    2605            0 :             if (lAlphaBlanks(9)) {
    2606            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2607            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
    2608              :             } else {
    2609            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2610            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
    2611              :             }
    2612            0 :             ErrorsFound = true;
    2613              :         } else {
    2614              :             // Verify Curve Object, only legal types are Quadratic or Cubic
    2615           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2616           12 :                                                  thisDXCoil.PLFFPLR(1), // Curve index
    2617              :                                                  {1},                   // Valid dimensions
    2618              :                                                  RoutineName,           // Routine name
    2619              :                                                  CurrentModuleObject,   // Object Type
    2620              :                                                  thisDXCoil.Name,       // Object Name
    2621           12 :                                                  cAlphaFields(9));      // Field Name
    2622              : 
    2623           12 :             if (!ErrorsFound) {
    2624              :                 //     Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    2625           12 :                 MinCurveVal = 999.0;
    2626           12 :                 MaxCurveVal = -999.0;
    2627           12 :                 CurveInput = 0.0;
    2628         1212 :                 while (CurveInput <= 1.0) {
    2629         1200 :                     CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
    2630         1200 :                     if (CurveVal < MinCurveVal) {
    2631           12 :                         MinCurveVal = CurveVal;
    2632           12 :                         MinCurvePLR = CurveInput;
    2633              :                     }
    2634         1200 :                     if (CurveVal > MaxCurveVal) {
    2635         1052 :                         MaxCurveVal = CurveVal;
    2636         1052 :                         MaxCurvePLR = CurveInput;
    2637              :                     }
    2638         1200 :                     CurveInput += 0.01;
    2639              :                 }
    2640           12 :                 if (MinCurveVal < 0.7) {
    2641            0 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2642            0 :                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
    2643            0 :                     ShowContinueError(state,
    2644            0 :                                       format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    2645            0 :                     ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    2646            0 :                     Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
    2647              :                 }
    2648              : 
    2649           12 :                 if (MaxCurveVal > 1.0) {
    2650            0 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2651            0 :                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
    2652            0 :                     ShowContinueError(state,
    2653            0 :                                       format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    2654            0 :                     ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    2655            0 :                     Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
    2656              :                 }
    2657              :             }
    2658              :         }
    2659              : 
    2660           12 :         thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
    2661              : 
    2662           12 :         thisDXCoil.RatedTotCap2 = Numbers(8);
    2663           12 :         thisDXCoil.RatedSHR2 = Numbers(9);
    2664           12 :         thisDXCoil.RatedCOP2 = Numbers(10);
    2665           12 :         thisDXCoil.RatedAirVolFlowRate2 = Numbers(11);
    2666              : 
    2667           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate_LowSpeed(1) = Numbers(12);
    2668           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate_2023_LowSpeed(1) = Numbers(13);
    2669              : 
    2670           12 :         if (lNumericBlanks(14)) {
    2671           11 :             thisDXCoil.MinOATCompressor = -25.0;
    2672              :         } else {
    2673            1 :             thisDXCoil.MinOATCompressor = Numbers(14);
    2674              :         }
    2675              : 
    2676           12 :         thisDXCoil.CCapFTemp2 = GetCurveIndex(state, Alphas(10)); // convert curve name to number
    2677           12 :         if (thisDXCoil.CCapFTemp2 == 0) {
    2678            0 :             if (lAlphaBlanks(10)) {
    2679            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2680            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(10)));
    2681              :             } else {
    2682            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2683            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
    2684              :             }
    2685            0 :             ErrorsFound = true;
    2686              :         } else {
    2687              :             // Verify Curve Object, only legal type is BiQuadratic
    2688           24 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2689              :                                                  thisDXCoil.CCapFTemp2, // Curve index
    2690              :                                                  {2},                   // Valid dimensions
    2691              :                                                  RoutineName,           // Routine name
    2692              :                                                  CurrentModuleObject,   // Object Type
    2693              :                                                  thisDXCoil.Name,       // Object Name
    2694           12 :                                                  cAlphaFields(10));     // Field Name
    2695              : 
    2696           12 :             if (!ErrorsFound) {
    2697           12 :                 checkCurveIsNormalizedToOne(state,
    2698           36 :                                             std::string{RoutineName} + CurrentModuleObject,
    2699           12 :                                             thisDXCoil.Name,
    2700              :                                             thisDXCoil.CCapFTemp2,
    2701           12 :                                             cAlphaFields(10),
    2702           12 :                                             Alphas(10),
    2703              :                                             RatedInletWetBulbTemp,
    2704              :                                             RatedOutdoorAirTemp);
    2705              :             }
    2706              :         }
    2707              : 
    2708           12 :         thisDXCoil.EIRFTemp2 = GetCurveIndex(state, Alphas(11)); // convert curve name to number
    2709           12 :         if (thisDXCoil.EIRFTemp2 == 0) {
    2710            0 :             if (lAlphaBlanks(11)) {
    2711            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2712            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(11)));
    2713              :             } else {
    2714            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2715            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
    2716              :             }
    2717            0 :             ErrorsFound = true;
    2718              :         } else {
    2719              :             // Verify Curve Object, only legal type is BiQuadratic
    2720           24 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2721              :                                                  thisDXCoil.EIRFTemp2, // Curve index
    2722              :                                                  {2},                  // Valid dimensions
    2723              :                                                  RoutineName,          // Routine name
    2724              :                                                  CurrentModuleObject,  // Object Type
    2725              :                                                  thisDXCoil.Name,      // Object Name
    2726           12 :                                                  cAlphaFields(11));    // Field Name
    2727              : 
    2728           12 :             if (!ErrorsFound) {
    2729           12 :                 checkCurveIsNormalizedToOne(state,
    2730           36 :                                             std::string{RoutineName} + CurrentModuleObject,
    2731           12 :                                             thisDXCoil.Name,
    2732              :                                             thisDXCoil.EIRFTemp2,
    2733           12 :                                             cAlphaFields(11),
    2734           12 :                                             Alphas(11),
    2735              :                                             RatedInletWetBulbTemp,
    2736              :                                             RatedOutdoorAirTemp);
    2737              :             }
    2738              :         }
    2739              : 
    2740              :         // outdoor condenser node
    2741           12 :         if (lAlphaBlanks(12)) {
    2742            6 :             thisDXCoil.CondenserInletNodeNum(1) = 0;
    2743              :         } else {
    2744           12 :             thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
    2745            6 :                                                                     Alphas(12),
    2746              :                                                                     ErrorsFound,
    2747              :                                                                     DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
    2748            6 :                                                                     thisDXCoil.Name,
    2749              :                                                                     DataLoopNode::NodeFluidType::Air,
    2750              :                                                                     DataLoopNode::ConnectionType::OutsideAirReference,
    2751              :                                                                     NodeInputManager::CompFluidStream::Primary,
    2752              :                                                                     ObjectIsNotParent);
    2753            6 :             if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
    2754            4 :                 ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2755            8 :                 ShowContinueError(
    2756              :                     state,
    2757            8 :                     format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(12), Alphas(12)));
    2758           12 :                 ShowContinueError(
    2759              :                     state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
    2760              :             }
    2761              :         }
    2762              : 
    2763           12 :         if ((Util::SameString(Alphas(13), "AirCooled")) || lAlphaBlanks(13)) {
    2764           10 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
    2765            2 :         } else if (Util::SameString(Alphas(13), "EvaporativelyCooled")) {
    2766            2 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
    2767            2 :             thisDXCoil.ReportEvapCondVars = true;
    2768              :         } else {
    2769            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2770            0 :             ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(13), Alphas(13)));
    2771            0 :             ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
    2772            0 :             ErrorsFound = true;
    2773              :         }
    2774              : 
    2775           12 :         thisDXCoil.EvapCondEffect(1) = Numbers(15);
    2776           12 :         if (thisDXCoil.EvapCondEffect(1) < 0.0 || thisDXCoil.EvapCondEffect(1) > 1.0) {
    2777            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2778            0 :             ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields(15)));
    2779            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(15)));
    2780            0 :             ErrorsFound = true;
    2781              :         }
    2782              : 
    2783           12 :         thisDXCoil.EvapCondAirFlow(1) = Numbers(16);
    2784           12 :         if (thisDXCoil.EvapCondAirFlow(1) < 0.0 && thisDXCoil.EvapCondAirFlow(1) != AutoSize) {
    2785            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2786            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(16)));
    2787            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(16)));
    2788            0 :             ErrorsFound = true;
    2789              :         }
    2790              : 
    2791           12 :         thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(17);
    2792           12 :         if (thisDXCoil.EvapCondPumpElecNomPower(1) < 0.0 && thisDXCoil.EvapCondPumpElecNomPower(1) != AutoSize) {
    2793            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2794            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(17)));
    2795            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(17)));
    2796            0 :             ErrorsFound = true;
    2797              :         }
    2798              : 
    2799           12 :         thisDXCoil.EvapCondEffect2 = Numbers(18);
    2800           12 :         if (thisDXCoil.EvapCondEffect2 < 0.0 || thisDXCoil.EvapCondEffect2 > 1.0) {
    2801            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2802            0 :             ShowContinueError(state, format("...{} cannot be cannot be < 0.0 or > 1.0.", cNumericFields(18)));
    2803            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(18)));
    2804            0 :             ErrorsFound = true;
    2805              :         }
    2806              : 
    2807           12 :         thisDXCoil.EvapCondAirFlow2 = Numbers(19);
    2808           12 :         if (thisDXCoil.EvapCondAirFlow2 < 0.0 && thisDXCoil.EvapCondAirFlow2 != AutoSize) {
    2809            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2810            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(19)));
    2811            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(19)));
    2812            0 :             ErrorsFound = true;
    2813              :         }
    2814              : 
    2815           12 :         thisDXCoil.EvapCondPumpElecNomPower2 = Numbers(20);
    2816           12 :         if (thisDXCoil.EvapCondPumpElecNomPower2 < 0.0 && thisDXCoil.EvapCondPumpElecNomPower2 != AutoSize) {
    2817            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2818            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(20)));
    2819            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(20)));
    2820            0 :             ErrorsFound = true;
    2821              :         }
    2822              : 
    2823           12 :         thisDXCoil.RatedEIR2 = 1.0 / thisDXCoil.RatedCOP2;
    2824              : 
    2825              :         // Get Water System tank connections
    2826              :         //  A14, \field Name of Water Storage Tank for Supply
    2827           12 :         thisDXCoil.EvapWaterSupplyName = Alphas(14);
    2828           12 :         if (lAlphaBlanks(14)) {
    2829           12 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
    2830              :         } else {
    2831            0 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
    2832            0 :             SetupTankDemandComponent(state,
    2833              :                                      thisDXCoil.Name,
    2834              :                                      CurrentModuleObject,
    2835              :                                      thisDXCoil.EvapWaterSupplyName,
    2836              :                                      ErrorsFound,
    2837            0 :                                      thisDXCoil.EvapWaterSupTankID,
    2838            0 :                                      thisDXCoil.EvapWaterTankDemandARRID);
    2839              :         }
    2840              : 
    2841              :         // A15; \field Name of Water Storage Tank for Condensate Collection
    2842           12 :         thisDXCoil.CondensateCollectName = Alphas(15);
    2843           12 :         if (lAlphaBlanks(15)) {
    2844           12 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    2845              :         } else {
    2846            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    2847            0 :             SetupTankSupplyComponent(state,
    2848              :                                      thisDXCoil.Name,
    2849              :                                      CurrentModuleObject,
    2850              :                                      thisDXCoil.CondensateCollectName,
    2851              :                                      ErrorsFound,
    2852            0 :                                      thisDXCoil.CondensateTankID,
    2853            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    2854              :         }
    2855              : 
    2856              :         // Basin heater power as a function of temperature must be greater than or equal to 0
    2857           12 :         thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(21);
    2858           12 :         if (Numbers(21) < 0.0) {
    2859            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2860            0 :             ShowContinueError(state, format("...{} must be >= 0.0.", cNumericFields(21)));
    2861            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(21)));
    2862            0 :             ErrorsFound = true;
    2863              :         }
    2864              : 
    2865           12 :         thisDXCoil.BasinHeaterSetPointTemp = Numbers(22);
    2866           12 :         if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    2867            4 :             if (NumNumbers < 22) {
    2868            0 :                 thisDXCoil.BasinHeaterSetPointTemp = 2.0;
    2869              :             }
    2870            4 :             if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
    2871            0 :                 ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2872            0 :                 ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(22)));
    2873            0 :                 ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(22)));
    2874              :             }
    2875              :         }
    2876              : 
    2877           12 :         if (!lAlphaBlanks(16)) {
    2878            1 :             if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(16))) == nullptr) {
    2879            2 :                 ShowWarningItemNotFound(
    2880            1 :                     state, eoh, cAlphaFields(16), Alphas(16), "Basin heater will be available to operate throughout the simulation.");
    2881              :             }
    2882              :         }
    2883              : 
    2884           12 :         if (!lAlphaBlanks(17) && NumAlphas > 16) {
    2885            0 :             thisDXCoil.SHRFTemp(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
    2886              :             // DXCoil(DXCoilNum)%SHRFTemp2 = DXCoil(DXCoilNum)%SHRFTemp(1)
    2887            0 :             if (thisDXCoil.SHRFTemp(1) == 0) {
    2888            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2889            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
    2890              :             } else {
    2891              :                 // Verify Curve Object, only legal type is BiQuadratic
    2892            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2893            0 :                                                      thisDXCoil.SHRFTemp(1), // Curve index
    2894              :                                                      {2},                    // Valid dimensions
    2895              :                                                      RoutineName,            // Routine name
    2896              :                                                      CurrentModuleObject,    // Object Type
    2897              :                                                      thisDXCoil.Name,        // Object Name
    2898            0 :                                                      cAlphaFields(17));      // Field Name
    2899              :             }
    2900              :         }
    2901              : 
    2902           12 :         if (!lAlphaBlanks(18) && NumAlphas > 17) {
    2903            0 :             thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(18)); // convert curve name to number
    2904              :             // DXCoil(DXCoilNum)%SHRFFlow2 = DXCoil(DXCoilNum)%SHRFFlow(1)
    2905            0 :             if (thisDXCoil.SHRFFlow(1) == 0) {
    2906            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2907            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(18), Alphas(18)));
    2908              :             } else {
    2909              :                 // Verify Curve Object, only legal type is BiQuadratic
    2910            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2911            0 :                                                      thisDXCoil.SHRFFlow(1), // Curve index
    2912              :                                                      {1},                    // Valid dimensions
    2913              :                                                      RoutineName,            // Routine name
    2914              :                                                      CurrentModuleObject,    // Object Type
    2915              :                                                      thisDXCoil.Name,        // Object Name
    2916            0 :                                                      cAlphaFields(18));      // Field Name
    2917              :             }
    2918              :         }
    2919              : 
    2920           12 :         if (!lAlphaBlanks(19) && NumAlphas > 18) {
    2921            0 :             thisDXCoil.SHRFTemp2 = GetCurveIndex(state, Alphas(19)); // convert curve name to number
    2922            0 :             if (thisDXCoil.SHRFTemp2 == 0) {
    2923            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2924            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(19), Alphas(19)));
    2925              :             } else {
    2926              :                 // Verify Curve Object, only legal type is BiQuadratic
    2927            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2928              :                                                      thisDXCoil.SHRFTemp2, // Curve index
    2929              :                                                      {2},                  // Valid dimensions
    2930              :                                                      RoutineName,          // Routine name
    2931              :                                                      CurrentModuleObject,  // Object Type
    2932              :                                                      thisDXCoil.Name,      // Object Name
    2933            0 :                                                      cAlphaFields(19));    // Field Name
    2934              :             }
    2935              :         }
    2936              : 
    2937           12 :         if (!lAlphaBlanks(20) && NumAlphas > 19) {
    2938            0 :             thisDXCoil.SHRFFlow2 = GetCurveIndex(state, Alphas(20)); // convert curve name to number
    2939            0 :             if (thisDXCoil.SHRFTemp2 == 0) {
    2940            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2941            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(20), Alphas(20)));
    2942              :             } else {
    2943              :                 // Verify Curve Object, only legal type is BiQuadratic
    2944            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2945              :                                                      thisDXCoil.SHRFFlow2, // Curve index
    2946              :                                                      {1},                  // Valid dimensions
    2947              :                                                      RoutineName,          // Routine name
    2948              :                                                      CurrentModuleObject,  // Object Type
    2949              :                                                      thisDXCoil.Name,      // Object Name
    2950            0 :                                                      cAlphaFields(20));    // Field Name
    2951              :             }
    2952              :         }
    2953           12 :         if (thisDXCoil.SHRFTemp(1) > 0 && thisDXCoil.SHRFFlow(1) > 0 && thisDXCoil.SHRFTemp2 > 0 && thisDXCoil.SHRFFlow2 > 0) {
    2954            0 :             thisDXCoil.UserSHRCurveExists = true;
    2955              :         } else {
    2956           12 :             thisDXCoil.UserSHRCurveExists = false;
    2957              :         }
    2958              :         // A21; \field Zone Name for Condenser Placement
    2959           12 :         if (!lAlphaBlanks(21) && NumAlphas > 20) {
    2960            0 :             thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(21), state.dataHeatBal->Zone);
    2961            0 :             if (thisDXCoil.SecZonePtr > 0) {
    2962            0 :                 SetupZoneInternalGain(state,
    2963              :                                       thisDXCoil.SecZonePtr,
    2964              :                                       thisDXCoil.Name,
    2965              :                                       DataHeatBalance::IntGainType::SecCoolingDXCoilTwoSpeed,
    2966              :                                       &thisDXCoil.SecCoilSensibleHeatGainRate);
    2967            0 :                 thisDXCoil.IsSecondaryDXCoilInZone = true;
    2968              :             } else {
    2969            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2970            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(21), Alphas(21)));
    2971              :             }
    2972              :         }
    2973              :     }
    2974              : 
    2975          135 :     if (ErrorsFound) {
    2976            0 :         ShowFatalError(state,
    2977            0 :                        format("{}Errors found in getting {} input.  Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    2978              :     }
    2979              : 
    2980              :     // Loop over the Pumped DX Water Heater Coils and get & load the data
    2981          135 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped);
    2982          144 :     for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils; ++DXHPWaterHeaterCoilNum) {
    2983              : 
    2984            9 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    2985              :                                                                  CurrentModuleObject,
    2986              :                                                                  DXHPWaterHeaterCoilNum,
    2987              :                                                                  Alphas,
    2988              :                                                                  NumAlphas,
    2989              :                                                                  Numbers,
    2990              :                                                                  NumNumbers,
    2991              :                                                                  IOStatus,
    2992              :                                                                  lNumericBlanks,
    2993              :                                                                  lAlphaBlanks,
    2994              :                                                                  cAlphaFields,
    2995              :                                                                  cNumericFields);
    2996              : 
    2997            9 :         ++DXCoilNum;
    2998              : 
    2999              :         // allocate single performance mode for numeric field strings used for sizing routine
    3000            9 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    3001            9 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    3002            9 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    3003              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    3004            9 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    3005              : 
    3006            9 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    3007            9 :         thisDXCoil.Name = Alphas(1);
    3008            9 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    3009            9 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterPumped;
    3010            9 :         thisDXCoil.availSched = Sched::GetScheduleAlwaysOff(state); // heat pump water heater DX coil has no schedule
    3011              : 
    3012              :         // Store the HPWH DX coil heating capacity in RatedTotCap2. After backing off pump and fan heat,
    3013              :         // move to RatedTotCap() for use by DX coil
    3014            9 :         thisDXCoil.RatedTotCap2 = Numbers(1);
    3015            9 :         if (thisDXCoil.RatedTotCap2 <= 0.0) {
    3016            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3017            0 :             ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
    3018            0 :             ErrorsFound = true;
    3019              :         }
    3020              : 
    3021            9 :         thisDXCoil.RatedCOP(1) = Numbers(2);
    3022            9 :         if (thisDXCoil.RatedCOP(1) <= 0.0) {
    3023            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3024            0 :             ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(2), Numbers(2)));
    3025            0 :             ErrorsFound = true;
    3026              :         }
    3027              : 
    3028            9 :         thisDXCoil.RatedSHR(1) = Numbers(3);
    3029            9 :         if (thisDXCoil.RatedSHR(1) <= 0.0 || thisDXCoil.RatedSHR(1) > 1.0) {
    3030            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3031            0 :             ShowContinueError(state, format("...{} must be > 0 and <= 1.  entered value=[{:.3T}].", cNumericFields(3), Numbers(3)));
    3032              : 
    3033            0 :             ErrorsFound = true;
    3034              :         }
    3035              : 
    3036            9 :         thisDXCoil.RatedInletDBTemp = Numbers(4);
    3037            9 :         if (thisDXCoil.RatedInletDBTemp <= 5.0) {
    3038            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3039            0 :             ShowContinueError(state, format("...{} must be > 5 {{C}}.  entered value=[{:.1T}].", cNumericFields(4), Numbers(4)));
    3040            0 :             ErrorsFound = true;
    3041              :         }
    3042              : 
    3043            9 :         thisDXCoil.RatedInletWBTemp = Numbers(5);
    3044            9 :         if (thisDXCoil.RatedInletWBTemp <= 5.0) {
    3045            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3046            0 :             ShowContinueError(state, format("...{} must be > 5 {{C}}.  entered value=[{:.1T}].", cNumericFields(5), Numbers(5)));
    3047            0 :             ErrorsFound = true;
    3048              :         }
    3049              : 
    3050            9 :         thisDXCoil.RatedInletWaterTemp = Numbers(6);
    3051            9 :         if (thisDXCoil.RatedInletWaterTemp <= 25.0) {
    3052            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3053            0 :             ShowContinueError(state, format("...{} must be > 25 {{C}}.  entered value=[{:.1T}].", cNumericFields(6), Numbers(6)));
    3054            0 :             ErrorsFound = true;
    3055              :         }
    3056              : 
    3057            9 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
    3058            9 :         if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
    3059            0 :             if (thisDXCoil.RatedAirVolFlowRate(1) <= 0.0) {
    3060            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3061            0 :                 ShowContinueError(state, format("...{} must be > 0.0.  entered value=[{:.3T}].", cNumericFields(7), Numbers(7)));
    3062            0 :                 ErrorsFound = true;
    3063              :             }
    3064              :         }
    3065              : 
    3066            9 :         thisDXCoil.RatedHPWHCondWaterFlow = Numbers(8);
    3067              :         // move to init
    3068            9 :         if (thisDXCoil.RatedHPWHCondWaterFlow != Constant::AutoCalculate) {
    3069            0 :             if (thisDXCoil.RatedHPWHCondWaterFlow <= 0.0) {
    3070            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3071            0 :                 ShowContinueError(state, format("...{} must be > 0.0  entered value=[{:.3T}].", cNumericFields(8), Numbers(8)));
    3072            0 :                 ErrorsFound = true;
    3073              :             }
    3074              :             //   check the range of flow rate to be >= 1 gpm/ton and <= 5 gpm/ton
    3075            0 :             if (thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2 < 1.79405e-8 ||
    3076            0 :                 thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2 > 8.97024e-8) {
    3077            0 :                 ShowWarningError(state, format("{}{}=\"{}\", outside range", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3078            0 :                 ShowContinueError(state,
    3079            0 :                                   format("...{} per watt of {} is outside the recommended range of >= 1.79405E-8 m3/s/W (0.083 gpm/MBH) and <= "
    3080              :                                          "8.97024E-8 m3/s/W (0.417 gpm/MBH).",
    3081              :                                          cNumericFields(8),
    3082              :                                          cNumericFields(1)));
    3083            0 :                 ShowContinueError(
    3084            0 :                     state, format("...Entered Flow rate per watt = [{:.10T}].", (thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2)));
    3085              :             }
    3086              :         }
    3087              : 
    3088            9 :         if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
    3089              :             //  initialized to TRUE on allocate
    3090            9 :             if (Util::SameString(Alphas(2), "No")) thisDXCoil.FanPowerIncludedInCOP = false;
    3091              :         } else {
    3092            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3093            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(2), Alphas(2)));
    3094            0 :             ShowContinueError(state, "Valid choices are Yes or No.");
    3095            0 :             ErrorsFound = true;
    3096              :         }
    3097              : 
    3098            9 :         if (Util::SameString(Alphas(3), "Yes") || Util::SameString(Alphas(3), "No")) {
    3099              :             //  initialized to FALSE on allocate
    3100            9 :             if (Util::SameString(Alphas(3), "Yes")) thisDXCoil.CondPumpPowerInCOP = true;
    3101              :         } else {
    3102            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3103            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(3), Alphas(3)));
    3104            0 :             ShowContinueError(state, "Valid choices are Yes or No.");
    3105            0 :             ErrorsFound = true;
    3106              :         }
    3107              : 
    3108            9 :         if (Util::SameString(Alphas(4), "Yes") || Util::SameString(Alphas(4), "No")) {
    3109              :             //  initialized to FALSE on allocate
    3110            9 :             if (Util::SameString(Alphas(4), "Yes")) thisDXCoil.CondPumpHeatInCapacity = true;
    3111              :         } else {
    3112            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3113            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(4), Alphas(4)));
    3114            0 :             ShowContinueError(state, "Valid choices are Yes or No.");
    3115            0 :             ErrorsFound = true;
    3116              :         }
    3117              : 
    3118            9 :         thisDXCoil.HPWHCondPumpElecNomPower = Numbers(9);
    3119            9 :         if (thisDXCoil.HPWHCondPumpElecNomPower < 0.0) {
    3120            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3121            0 :             ShowContinueError(state, format("...{} must be >= 0.0  entered value=[{:.3T}].", cNumericFields(9), Numbers(9)));
    3122            0 :             ErrorsFound = true;
    3123              :         }
    3124              : 
    3125            9 :         thisDXCoil.HPWHCondPumpFracToWater = Numbers(10);
    3126            9 :         if (thisDXCoil.HPWHCondPumpFracToWater <= 0.0 || thisDXCoil.HPWHCondPumpFracToWater > 1.0) {
    3127            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3128            0 :             ShowContinueError(state, format("...{} must be >= 0 and <= 1.  entered value=[{:.3T}].", cNumericFields(10), Numbers(10)));
    3129            0 :             ErrorsFound = true;
    3130              :         }
    3131              : 
    3132              :         // Air nodes
    3133            9 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    3134            9 :                                                  Alphas(5),
    3135              :                                                  ErrorsFound,
    3136              :                                                  DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
    3137            9 :                                                  Alphas(1),
    3138              :                                                  DataLoopNode::NodeFluidType::Air,
    3139              :                                                  DataLoopNode::ConnectionType::Inlet,
    3140              :                                                  NodeInputManager::CompFluidStream::Primary,
    3141              :                                                  ObjectIsNotParent);
    3142              : 
    3143           18 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    3144            9 :                                                   Alphas(6),
    3145              :                                                   ErrorsFound,
    3146              :                                                   DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
    3147            9 :                                                   Alphas(1),
    3148              :                                                   DataLoopNode::NodeFluidType::Air,
    3149              :                                                   DataLoopNode::ConnectionType::Outlet,
    3150              :                                                   NodeInputManager::CompFluidStream::Primary,
    3151              :                                                   ObjectIsNotParent);
    3152              : 
    3153            9 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(5), Alphas(6), "Air Nodes");
    3154              : 
    3155              :         // Check if the air inlet node is OA node, to justify whether the coil is placed in zone or not
    3156            9 :         thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
    3157              : 
    3158              :         // Water nodes
    3159            9 :         thisDXCoil.WaterInNode = GetOnlySingleNode(state,
    3160            9 :                                                    Alphas(7),
    3161              :                                                    ErrorsFound,
    3162              :                                                    DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
    3163            9 :                                                    Alphas(1),
    3164              :                                                    DataLoopNode::NodeFluidType::Water,
    3165              :                                                    DataLoopNode::ConnectionType::Inlet,
    3166              :                                                    NodeInputManager::CompFluidStream::Secondary,
    3167              :                                                    ObjectIsNotParent);
    3168              : 
    3169           18 :         thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
    3170            9 :                                                     Alphas(8),
    3171              :                                                     ErrorsFound,
    3172              :                                                     DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
    3173            9 :                                                     Alphas(1),
    3174              :                                                     DataLoopNode::NodeFluidType::Water,
    3175              :                                                     DataLoopNode::ConnectionType::Outlet,
    3176              :                                                     NodeInputManager::CompFluidStream::Secondary,
    3177              :                                                     ObjectIsNotParent);
    3178              : 
    3179            9 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(7), Alphas(8), "Water Nodes");
    3180              : 
    3181            9 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(11);
    3182            9 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    3183            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3184            0 :             ShowContinueError(state, format("...{} must be >= 0.0  entered value=[{:.1T}].", cNumericFields(11), Numbers(11)));
    3185            0 :             ErrorsFound = true;
    3186              :         }
    3187              : 
    3188            9 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(12);
    3189            9 :         if (thisDXCoil.MaxOATCrankcaseHeater < 0.0) {
    3190            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3191            0 :             ShowContinueError(state, format("...{} must be >= 0 {{C}}.  entered value=[{:.1T}].", cNumericFields(12), Numbers(12)));
    3192            0 :             ErrorsFound = true;
    3193              :         }
    3194              : 
    3195            9 :         if (!lAlphaBlanks(9)) {
    3196            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(9));
    3197            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    3198            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(9), Alphas(9)));
    3199            0 :                 ErrorsFound = true;
    3200              :             } else {
    3201            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3202              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    3203              :                                                      {1},                                          // Valid dimensions
    3204              :                                                      RoutineName,                                  // Routine name
    3205              :                                                      CurrentModuleObject,                          // Object Type
    3206              :                                                      thisDXCoil.Name,                              // Object Name
    3207            2 :                                                      cAlphaFields(9));                             // Field Name
    3208              :             }
    3209              :         }
    3210              : 
    3211            9 :         thisDXCoil.InletAirTemperatureType = static_cast<HVAC::OATType>(getEnumValue(HVAC::oatTypeNamesUC, Alphas(10)));
    3212              : 
    3213              :         // set rated inlet air temperature for curve object verification
    3214            9 :         if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
    3215            9 :             InletAirTemp = thisDXCoil.RatedInletWBTemp;
    3216              :         } else {
    3217            0 :             InletAirTemp = thisDXCoil.RatedInletDBTemp;
    3218              :         }
    3219              :         // set rated water temperature for curve object verification
    3220            9 :         InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
    3221              : 
    3222            9 :         if (!lAlphaBlanks(11)) {
    3223            9 :             thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(11));
    3224            9 :             if (thisDXCoil.HCapFTemp == 0) {
    3225            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3226            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
    3227            0 :                 ErrorsFound = true;
    3228              :             } else {
    3229              :                 // Verify Curve Object, only legal types are BiQuadratic or Cubic
    3230           18 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3231              :                                                      thisDXCoil.HCapFTemp, // Curve index
    3232              :                                                      {1, 2},               // Valid dimensions  // MULTIPLECURVEDIMS
    3233              :                                                      RoutineName,          // Routine name
    3234              :                                                      CurrentModuleObject,  // Object Type
    3235              :                                                      thisDXCoil.Name,      // Object Name
    3236            9 :                                                      cAlphaFields(11));    // Field Name
    3237              : 
    3238            9 :                 if (!ErrorsFound) {
    3239            9 :                     if (state.dataCurveManager->curves(thisDXCoil.HCapFTemp)->numDims == 1) {
    3240            2 :                         checkCurveIsNormalizedToOne(state,
    3241            6 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3242            2 :                                                     thisDXCoil.Name,
    3243              :                                                     thisDXCoil.HCapFTemp,
    3244            2 :                                                     cAlphaFields(11),
    3245            2 :                                                     Alphas(11),
    3246              :                                                     InletAirTemp);
    3247              :                     } else {
    3248            7 :                         checkCurveIsNormalizedToOne(state,
    3249           21 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3250            7 :                                                     thisDXCoil.Name,
    3251              :                                                     thisDXCoil.HCapFTemp,
    3252            7 :                                                     cAlphaFields(11),
    3253            7 :                                                     Alphas(11),
    3254              :                                                     InletAirTemp,
    3255              :                                                     InletWaterTemp);
    3256              :                     }
    3257              :                 }
    3258              :             }
    3259              :         }
    3260              : 
    3261            9 :         if (!lAlphaBlanks(12)) {
    3262            2 :             thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(12));
    3263            2 :             if (thisDXCoil.HCapFAirFlow == 0) {
    3264            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3265            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(12), Alphas(12)));
    3266            0 :                 ErrorsFound = true;
    3267              :             } else {
    3268              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3269            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3270              :                                                      thisDXCoil.HCapFAirFlow, // Curve index
    3271              :                                                      {1},                     // Valid dimensions
    3272              :                                                      RoutineName,             // Routine name
    3273              :                                                      CurrentModuleObject,     // Object Type
    3274              :                                                      thisDXCoil.Name,         // Object Name
    3275            2 :                                                      cAlphaFields(12));       // Field Name
    3276              : 
    3277            2 :                 if (!ErrorsFound) {
    3278            2 :                     checkCurveIsNormalizedToOne(state,
    3279            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3280            2 :                                                 thisDXCoil.Name,
    3281              :                                                 thisDXCoil.HCapFAirFlow,
    3282            2 :                                                 cAlphaFields(12),
    3283            2 :                                                 Alphas(12),
    3284              :                                                 1.0);
    3285              :                 }
    3286              :             }
    3287              :         }
    3288              : 
    3289            9 :         if (!lAlphaBlanks(13)) {
    3290            2 :             thisDXCoil.HCapFWaterFlow = GetCurveIndex(state, Alphas(13));
    3291            2 :             if (thisDXCoil.HCapFWaterFlow == 0) {
    3292            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3293            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(13), Alphas(13)));
    3294            0 :                 ErrorsFound = true;
    3295              :             } else {
    3296              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3297            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3298              :                                                      thisDXCoil.HCapFWaterFlow, // Curve index
    3299              :                                                      {1},                       // Valid dimensions
    3300              :                                                      RoutineName,               // Routine name
    3301              :                                                      CurrentModuleObject,       // Object Type
    3302              :                                                      thisDXCoil.Name,           // Object Name
    3303            2 :                                                      cAlphaFields(13));         // Field Name
    3304              : 
    3305            2 :                 if (!ErrorsFound) {
    3306            2 :                     checkCurveIsNormalizedToOne(state,
    3307            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3308            2 :                                                 thisDXCoil.Name,
    3309              :                                                 thisDXCoil.HCapFWaterFlow,
    3310            2 :                                                 cAlphaFields(13),
    3311            2 :                                                 Alphas(13),
    3312              :                                                 1.0);
    3313              :                 }
    3314              :             }
    3315              :         }
    3316              : 
    3317            9 :         if (!lAlphaBlanks(14)) {
    3318            9 :             thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(14));
    3319            9 :             if (thisDXCoil.HCOPFTemp == 0) {
    3320            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3321            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14), Alphas(14)));
    3322            0 :                 ErrorsFound = true;
    3323              :             } else {
    3324              :                 // Verify Curve Object, only legal types are BiQuadratic or Cubic
    3325           18 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3326              :                                                      thisDXCoil.HCOPFTemp, // Curve index
    3327              :                                                      {1, 2},               // Valid dimensions  // MULTIPLECURVEDIMS
    3328              :                                                      RoutineName,          // Routine name
    3329              :                                                      CurrentModuleObject,  // Object Type
    3330              :                                                      thisDXCoil.Name,      // Object Name
    3331            9 :                                                      cAlphaFields(14));    // Field Name
    3332              : 
    3333            9 :                 if (!ErrorsFound) {
    3334            9 :                     if (state.dataCurveManager->curves(thisDXCoil.HCOPFTemp)->numDims == 1) {
    3335            0 :                         checkCurveIsNormalizedToOne(state,
    3336            0 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3337            0 :                                                     thisDXCoil.Name,
    3338              :                                                     thisDXCoil.HCOPFTemp,
    3339            0 :                                                     cAlphaFields(14),
    3340            0 :                                                     Alphas(14),
    3341              :                                                     InletAirTemp);
    3342              :                     } else {
    3343            9 :                         checkCurveIsNormalizedToOne(state,
    3344           27 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3345            9 :                                                     thisDXCoil.Name,
    3346              :                                                     thisDXCoil.HCOPFTemp,
    3347            9 :                                                     cAlphaFields(14),
    3348            9 :                                                     Alphas(14),
    3349              :                                                     InletAirTemp,
    3350              :                                                     InletWaterTemp);
    3351              :                     }
    3352              :                 }
    3353              :             }
    3354              :         }
    3355              : 
    3356            9 :         if (!lAlphaBlanks(15)) {
    3357            2 :             thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(15));
    3358            2 :             if (thisDXCoil.HCOPFAirFlow == 0) {
    3359            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3360            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15), Alphas(15)));
    3361            0 :                 ErrorsFound = true;
    3362              :             } else {
    3363              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3364            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3365              :                                                      thisDXCoil.HCOPFAirFlow, // Curve index
    3366              :                                                      {1},                     // Valid dimensions
    3367              :                                                      RoutineName,             // Routine name
    3368              :                                                      CurrentModuleObject,     // Object Type
    3369              :                                                      thisDXCoil.Name,         // Object Name
    3370            2 :                                                      cAlphaFields(15));       // Field Name
    3371              : 
    3372            2 :                 if (!ErrorsFound) {
    3373            2 :                     checkCurveIsNormalizedToOne(state,
    3374            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3375            2 :                                                 thisDXCoil.Name,
    3376              :                                                 thisDXCoil.HCOPFAirFlow,
    3377            2 :                                                 cAlphaFields(15),
    3378            2 :                                                 Alphas(15),
    3379              :                                                 1.0);
    3380              :                 }
    3381              :             }
    3382              :         }
    3383              : 
    3384            9 :         if (!lAlphaBlanks(16)) {
    3385            2 :             thisDXCoil.HCOPFWaterFlow = GetCurveIndex(state, Alphas(16));
    3386            2 :             if (thisDXCoil.HCOPFWaterFlow == 0) {
    3387            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3388            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
    3389            0 :                 ErrorsFound = true;
    3390              :             } else {
    3391              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3392            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3393              :                                                      thisDXCoil.HCOPFWaterFlow, // Curve index
    3394              :                                                      {1},                       // Valid dimensions
    3395              :                                                      RoutineName,               // Routine name
    3396              :                                                      CurrentModuleObject,       // Object Type
    3397              :                                                      thisDXCoil.Name,           // Object Name
    3398            2 :                                                      cAlphaFields(16));         // Field Name
    3399              : 
    3400            2 :                 if (!ErrorsFound) {
    3401            2 :                     checkCurveIsNormalizedToOne(state,
    3402            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3403            2 :                                                 thisDXCoil.Name,
    3404              :                                                 thisDXCoil.HCOPFWaterFlow,
    3405            2 :                                                 cAlphaFields(16),
    3406            2 :                                                 Alphas(16),
    3407              :                                                 1.0);
    3408              :                 }
    3409              :             }
    3410              :         }
    3411              : 
    3412            9 :         if (!lAlphaBlanks(17)) {
    3413            9 :             thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(17));
    3414            9 :             if (thisDXCoil.PLFFPLR(1) == 0) {
    3415            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3416            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
    3417            0 :                 ErrorsFound = true;
    3418              :             } else {
    3419              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3420           27 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3421            9 :                                                      thisDXCoil.PLFFPLR(1), // Curve index
    3422              :                                                      {1},                   // Valid dimensions
    3423              :                                                      RoutineName,           // Routine name
    3424              :                                                      CurrentModuleObject,   // Object Type
    3425              :                                                      thisDXCoil.Name,       // Object Name
    3426            9 :                                                      cAlphaFields(17));     // Field Name
    3427              : 
    3428            9 :                 if (!ErrorsFound) {
    3429              :                     //       Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    3430            9 :                     MinCurveVal = 999.0;
    3431            9 :                     MaxCurveVal = -999.0;
    3432            9 :                     CurveInput = 0.0;
    3433          909 :                     while (CurveInput <= 1.0) {
    3434          900 :                         CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
    3435          900 :                         if (CurveVal < MinCurveVal) {
    3436            9 :                             MinCurveVal = CurveVal;
    3437            9 :                             MinCurvePLR = CurveInput;
    3438              :                         }
    3439          900 :                         if (CurveVal > MaxCurveVal) {
    3440          702 :                             MaxCurveVal = CurveVal;
    3441          702 :                             MaxCurvePLR = CurveInput;
    3442              :                         }
    3443          900 :                         CurveInput += 0.01;
    3444              :                     }
    3445            9 :                     if (MinCurveVal < 0.7) {
    3446            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3447            0 :                         ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(17), Alphas(17)));
    3448            0 :                         ShowContinueError(state,
    3449            0 :                                           format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    3450            0 :                         ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    3451            0 :                         Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
    3452              :                     }
    3453              : 
    3454            9 :                     if (MaxCurveVal > 1.0) {
    3455            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3456            0 :                         ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(17), Alphas(17)));
    3457            0 :                         ShowContinueError(state,
    3458            0 :                                           format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    3459            0 :                         ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    3460            0 :                         Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
    3461              :                     }
    3462              :                 }
    3463              :             }
    3464              :         }
    3465              : 
    3466              :         // assume compressor resides at the inlet to the DX Coil
    3467            9 :         thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
    3468              : 
    3469              :         // set condenser type as HPWH
    3470            9 :         thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
    3471              : 
    3472              :     } // end of the DX water heater coil loop
    3473              : 
    3474          135 :     if (ErrorsFound) {
    3475            0 :         ShowFatalError(state,
    3476            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    3477              :     }
    3478              :     // Loop over the Wrapped DX Water Heater Coils and get & load the data
    3479          135 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped);
    3480          142 :     for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils; ++DXHPWaterHeaterCoilNum) {
    3481              : 
    3482            7 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    3483              :                                                                  CurrentModuleObject,
    3484              :                                                                  DXHPWaterHeaterCoilNum,
    3485              :                                                                  Alphas,
    3486              :                                                                  NumAlphas,
    3487              :                                                                  Numbers,
    3488              :                                                                  NumNumbers,
    3489              :                                                                  IOStatus,
    3490              :                                                                  lNumericBlanks,
    3491              :                                                                  lAlphaBlanks,
    3492              :                                                                  cAlphaFields,
    3493              :                                                                  cNumericFields);
    3494              : 
    3495            7 :         ++DXCoilNum;
    3496              : 
    3497              :         // allocate single performance mode for numeric field strings used for sizing routine
    3498            7 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    3499            7 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    3500            7 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    3501              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    3502            7 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    3503              : 
    3504            7 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    3505            7 :         thisDXCoil.Name = Alphas(1);
    3506            7 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    3507            7 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterWrapped;
    3508            7 :         thisDXCoil.availSched = Sched::GetScheduleAlwaysOff(state); // heat pump water heater DX coil has no schedule
    3509              : 
    3510              :         // Store the HPWH DX coil heating capacity in RatedTotCap2. After backing off pump and fan heat,
    3511              :         // move to RatedTotCap() for use by DX coil
    3512            7 :         thisDXCoil.RatedTotCap2 = Numbers(1);
    3513            7 :         if (thisDXCoil.RatedTotCap2 <= 0.0) {
    3514            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3515            0 :             ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
    3516            0 :             ErrorsFound = true;
    3517              :         }
    3518              : 
    3519            7 :         thisDXCoil.RatedCOP(1) = Numbers(2);
    3520            7 :         if (thisDXCoil.RatedCOP(1) <= 0.0) {
    3521            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3522            0 :             ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(2), Numbers(2)));
    3523            0 :             ErrorsFound = true;
    3524              :         }
    3525              : 
    3526            7 :         thisDXCoil.RatedSHR(1) = Numbers(3);
    3527            7 :         if (thisDXCoil.RatedSHR(1) <= 0.0 || thisDXCoil.RatedSHR(1) > 1.0) {
    3528            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3529            0 :             ShowContinueError(state, format("...{} must be > 0 and <= 1.  entered value=[{:.3T}].", cNumericFields(3), Numbers(3)));
    3530              : 
    3531            0 :             ErrorsFound = true;
    3532              :         }
    3533              : 
    3534            7 :         thisDXCoil.RatedInletDBTemp = Numbers(4);
    3535            7 :         if (thisDXCoil.RatedInletDBTemp <= 5.0) {
    3536            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3537            0 :             ShowContinueError(state, format("...{} must be > 5 {{C}}.  entered value=[{:.1T}].", cNumericFields(4), Numbers(4)));
    3538            0 :             ErrorsFound = true;
    3539              :         }
    3540              : 
    3541            7 :         thisDXCoil.RatedInletWBTemp = Numbers(5);
    3542            7 :         if (thisDXCoil.RatedInletWBTemp <= 5.0) {
    3543            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3544            0 :             ShowContinueError(state, format("...{} must be > 5 {{C}}.  entered value=[{:.1T}].", cNumericFields(5), Numbers(5)));
    3545            0 :             ErrorsFound = true;
    3546              :         }
    3547              : 
    3548            7 :         thisDXCoil.RatedInletWaterTemp = Numbers(6);
    3549            7 :         if (thisDXCoil.RatedInletWaterTemp <= 25.0) {
    3550            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3551            0 :             ShowContinueError(state, format("...{} must be > 25 {{C}}.  entered value=[{:.1T}].", cNumericFields(6), Numbers(6)));
    3552            0 :             ErrorsFound = true;
    3553              :         }
    3554              : 
    3555            7 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
    3556            7 :         if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
    3557            7 :             if (thisDXCoil.RatedAirVolFlowRate(1) <= 0.0) {
    3558            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3559            0 :                 ShowContinueError(state, format("...{} must be > 0.0.  entered value=[{:.3T}].", cNumericFields(7), Numbers(7)));
    3560            0 :                 ErrorsFound = true;
    3561              :             }
    3562              :         }
    3563              : 
    3564            7 :         if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
    3565              :             //  initialized to TRUE on allocate
    3566            7 :             if (Util::SameString(Alphas(2), "No")) thisDXCoil.FanPowerIncludedInCOP = false;
    3567              :         } else {
    3568            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3569            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(2), Alphas(2)));
    3570            0 :             ShowContinueError(state, "Valid choices are Yes or No.");
    3571            0 :             ErrorsFound = true;
    3572              :         }
    3573              : 
    3574              :         // Air nodes
    3575            7 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    3576            7 :                                                  Alphas(3),
    3577              :                                                  ErrorsFound,
    3578              :                                                  DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
    3579            7 :                                                  Alphas(1),
    3580              :                                                  DataLoopNode::NodeFluidType::Air,
    3581              :                                                  DataLoopNode::ConnectionType::Inlet,
    3582              :                                                  NodeInputManager::CompFluidStream::Primary,
    3583              :                                                  ObjectIsNotParent);
    3584              : 
    3585           14 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    3586            7 :                                                   Alphas(4),
    3587              :                                                   ErrorsFound,
    3588              :                                                   DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
    3589            7 :                                                   Alphas(1),
    3590              :                                                   DataLoopNode::NodeFluidType::Air,
    3591              :                                                   DataLoopNode::ConnectionType::Outlet,
    3592              :                                                   NodeInputManager::CompFluidStream::Primary,
    3593              :                                                   ObjectIsNotParent);
    3594              : 
    3595            7 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    3596              : 
    3597              :         // Check if the air inlet node is OA node, to justify whether the coil is placed in zone or not
    3598            7 :         thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
    3599              : 
    3600            7 :         std::string const DummyCondenserInletName("DUMMY CONDENSER INLET " + thisDXCoil.Name);
    3601            7 :         std::string const DummyCondenserOutletName("DUMMY CONDENSER OUTLET " + thisDXCoil.Name);
    3602            7 :         thisDXCoil.WaterInNode = GetOnlySingleNode(state,
    3603              :                                                    DummyCondenserInletName,
    3604              :                                                    ErrorsFound,
    3605              :                                                    DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
    3606            7 :                                                    Alphas(1),
    3607              :                                                    DataLoopNode::NodeFluidType::Water,
    3608              :                                                    DataLoopNode::ConnectionType::Inlet,
    3609              :                                                    NodeInputManager::CompFluidStream::Secondary,
    3610              :                                                    ObjectIsNotParent);
    3611              : 
    3612           14 :         thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
    3613              :                                                     DummyCondenserOutletName,
    3614              :                                                     ErrorsFound,
    3615              :                                                     DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
    3616            7 :                                                     Alphas(1),
    3617              :                                                     DataLoopNode::NodeFluidType::Water,
    3618              :                                                     DataLoopNode::ConnectionType::Outlet,
    3619              :                                                     NodeInputManager::CompFluidStream::Secondary,
    3620              :                                                     ObjectIsNotParent);
    3621              : 
    3622            7 :         TestCompSet(state, CurrentModuleObject, Alphas(1), DummyCondenserInletName, DummyCondenserOutletName, "Water Nodes");
    3623              : 
    3624            7 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(8);
    3625            7 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    3626            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3627            0 :             ShowContinueError(state, format("...{} must be >= 0.0  entered value=[{:.1T}].", cNumericFields(8), Numbers(8)));
    3628            0 :             ErrorsFound = true;
    3629              :         }
    3630              : 
    3631            7 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(9);
    3632            7 :         if (thisDXCoil.MaxOATCrankcaseHeater < 0.0) {
    3633            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3634            0 :             ShowContinueError(state, format("...{} must be >= 0 {{C}}.  entered value=[{:.1T}].", cNumericFields(9), Numbers(9)));
    3635            0 :             ErrorsFound = true;
    3636              :         }
    3637              : 
    3638              :         // Coil:WaterHeating:AirToWaterHeatPump:Wrapped
    3639            7 :         if (!lAlphaBlanks(5)) {
    3640            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
    3641            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    3642            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
    3643            0 :                 ErrorsFound = true;
    3644              :             } else {
    3645            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3646              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    3647              :                                                      {1},                                          // Valid dimensions
    3648              :                                                      RoutineName,                                  // Routine name
    3649              :                                                      CurrentModuleObject,                          // Object Type
    3650              :                                                      thisDXCoil.Name,                              // Object Name
    3651            2 :                                                      cAlphaFields(5));                             // Field Name
    3652              :             }
    3653              :         }
    3654              : 
    3655            7 :         if (Util::SameString(Alphas(6), "DryBulbTemperature")) {
    3656            0 :             thisDXCoil.InletAirTemperatureType = HVAC::OATType::DryBulb;
    3657            7 :         } else if (Util::SameString(Alphas(6), "WetBulbTemperature")) {
    3658            7 :             thisDXCoil.InletAirTemperatureType = HVAC::OATType::WetBulb;
    3659              :         } else {
    3660              :             //   wrong temperature type selection
    3661            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3662            0 :             ShowContinueError(state, format("...{} must be DryBulbTemperature or WetBulbTemperature.", cAlphaFields(6)));
    3663            0 :             ShowContinueError(state, format("...entered value=\"{}\".", Alphas(6)));
    3664            0 :             ErrorsFound = true;
    3665              :         }
    3666              : 
    3667              :         // set rated inlet air temperature for curve object verification
    3668            7 :         if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
    3669            7 :             InletAirTemp = thisDXCoil.RatedInletWBTemp;
    3670              :         } else {
    3671            0 :             InletAirTemp = thisDXCoil.RatedInletDBTemp;
    3672              :         }
    3673              :         // set rated water temperature for curve object verification
    3674            7 :         InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
    3675              : 
    3676            7 :         if (!lAlphaBlanks(7)) {
    3677            7 :             thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(7));
    3678            7 :             if (thisDXCoil.HCapFTemp == 0) {
    3679            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3680            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
    3681            0 :                 ErrorsFound = true;
    3682              :             } else {
    3683              :                 // Verify Curve Object, only legal types are BiQuadratic or Cubic
    3684           14 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3685              :                                                      thisDXCoil.HCapFTemp, // Curve index
    3686              :                                                      {1, 2},               // Valid dimensions  // MULTIPLECURVEDIMS
    3687              :                                                      RoutineName,          // Routine name
    3688              :                                                      CurrentModuleObject,  // Object Type
    3689              :                                                      thisDXCoil.Name,      // Object Name
    3690            7 :                                                      cAlphaFields(7));     // Field Name
    3691              : 
    3692            7 :                 if (!ErrorsFound) {
    3693            7 :                     if (state.dataCurveManager->curves(thisDXCoil.HCapFTemp)->numDims == 1) {
    3694            0 :                         checkCurveIsNormalizedToOne(state,
    3695            0 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3696            0 :                                                     thisDXCoil.Name,
    3697              :                                                     thisDXCoil.HCapFTemp,
    3698            0 :                                                     cAlphaFields(7),
    3699            0 :                                                     Alphas(7),
    3700              :                                                     InletAirTemp);
    3701              :                     } else {
    3702            7 :                         checkCurveIsNormalizedToOne(state,
    3703           21 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3704            7 :                                                     thisDXCoil.Name,
    3705              :                                                     thisDXCoil.HCapFTemp,
    3706            7 :                                                     cAlphaFields(7),
    3707            7 :                                                     Alphas(7),
    3708              :                                                     InletAirTemp,
    3709              :                                                     InletWaterTemp);
    3710              :                     }
    3711              :                 }
    3712              :             }
    3713              :         }
    3714              : 
    3715            7 :         if (!lAlphaBlanks(8)) {
    3716            2 :             thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(8));
    3717            2 :             if (thisDXCoil.HCapFAirFlow == 0) {
    3718            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3719            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
    3720            0 :                 ErrorsFound = true;
    3721              :             } else {
    3722              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3723            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3724              :                                                      thisDXCoil.HCapFAirFlow, // Curve index
    3725              :                                                      {1},                     // Valid dimensions
    3726              :                                                      RoutineName,             // Routine name
    3727              :                                                      CurrentModuleObject,     // Object Type
    3728              :                                                      thisDXCoil.Name,         // Object Name
    3729            2 :                                                      cAlphaFields(8));        // Field Name
    3730              : 
    3731            2 :                 if (!ErrorsFound) {
    3732            2 :                     checkCurveIsNormalizedToOne(state,
    3733            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3734            2 :                                                 thisDXCoil.Name,
    3735              :                                                 thisDXCoil.HCapFAirFlow,
    3736            2 :                                                 cAlphaFields(8),
    3737            2 :                                                 Alphas(8),
    3738              :                                                 1.0);
    3739              :                 }
    3740              :             }
    3741              :         }
    3742              : 
    3743            7 :         if (!lAlphaBlanks(9)) {
    3744            7 :             thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(9));
    3745            7 :             if (thisDXCoil.HCOPFTemp == 0) {
    3746            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3747            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
    3748            0 :                 ErrorsFound = true;
    3749              :             } else {
    3750              :                 // Verify Curve Object, only legal types are BiQuadratic or Cubic
    3751           14 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3752              :                                                      thisDXCoil.HCOPFTemp, // Curve index
    3753              :                                                      {1, 2},               // Valid dimensions  // MULTIPLECURVEDIMS
    3754              :                                                      RoutineName,          // Routine name
    3755              :                                                      CurrentModuleObject,  // Object Type
    3756              :                                                      thisDXCoil.Name,      // Object Name
    3757            7 :                                                      cAlphaFields(9));     // Field Name
    3758              : 
    3759            7 :                 if (!ErrorsFound) {
    3760            7 :                     if (state.dataCurveManager->curves(thisDXCoil.HCOPFTemp)->numDims == 1) {
    3761            0 :                         checkCurveIsNormalizedToOne(state,
    3762            0 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3763            0 :                                                     thisDXCoil.Name,
    3764              :                                                     thisDXCoil.HCOPFTemp,
    3765            0 :                                                     cAlphaFields(9),
    3766            0 :                                                     Alphas(9),
    3767              :                                                     InletAirTemp);
    3768              :                     } else {
    3769            7 :                         checkCurveIsNormalizedToOne(state,
    3770           21 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3771            7 :                                                     thisDXCoil.Name,
    3772              :                                                     thisDXCoil.HCOPFTemp,
    3773            7 :                                                     cAlphaFields(9),
    3774            7 :                                                     Alphas(9),
    3775              :                                                     InletAirTemp,
    3776              :                                                     InletWaterTemp);
    3777              :                     }
    3778              :                 }
    3779              :             }
    3780              :         }
    3781              : 
    3782            7 :         if (!lAlphaBlanks(10)) {
    3783            2 :             thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(10));
    3784            2 :             if (thisDXCoil.HCOPFAirFlow == 0) {
    3785            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3786            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
    3787            0 :                 ErrorsFound = true;
    3788              :             } else {
    3789              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3790            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3791              :                                                      thisDXCoil.HCOPFAirFlow, // Curve index
    3792              :                                                      {1},                     // Valid dimensions
    3793              :                                                      RoutineName,             // Routine name
    3794              :                                                      CurrentModuleObject,     // Object Type
    3795              :                                                      thisDXCoil.Name,         // Object Name
    3796            2 :                                                      cAlphaFields(10));       // Field Name
    3797              : 
    3798            2 :                 if (!ErrorsFound) {
    3799            2 :                     checkCurveIsNormalizedToOne(state,
    3800            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3801            2 :                                                 thisDXCoil.Name,
    3802              :                                                 thisDXCoil.HCOPFAirFlow,
    3803            2 :                                                 cAlphaFields(10),
    3804            2 :                                                 Alphas(10),
    3805              :                                                 1.0);
    3806              :                 }
    3807              :             }
    3808              :         }
    3809              : 
    3810            7 :         if (!lAlphaBlanks(11)) {
    3811            4 :             thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(11));
    3812            4 :             if (thisDXCoil.PLFFPLR(1) == 0) {
    3813            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3814            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
    3815            0 :                 ErrorsFound = true;
    3816              :             } else {
    3817              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3818           12 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3819            4 :                                                      thisDXCoil.PLFFPLR(1), // Curve index
    3820              :                                                      {1},                   // Valid dimensions
    3821              :                                                      RoutineName,           // Routine name
    3822              :                                                      CurrentModuleObject,   // Object Type
    3823              :                                                      thisDXCoil.Name,       // Object Name
    3824            4 :                                                      cAlphaFields(11));     // Field Name
    3825              : 
    3826            4 :                 if (!ErrorsFound) {
    3827              :                     //       Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    3828            4 :                     MinCurveVal = 999.0;
    3829            4 :                     MaxCurveVal = -999.0;
    3830            4 :                     CurveInput = 0.0;
    3831          404 :                     while (CurveInput <= 1.0) {
    3832          400 :                         CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
    3833          400 :                         if (CurveVal < MinCurveVal) {
    3834            4 :                             MinCurveVal = CurveVal;
    3835            4 :                             MinCurvePLR = CurveInput;
    3836              :                         }
    3837          400 :                         if (CurveVal > MaxCurveVal) {
    3838            4 :                             MaxCurveVal = CurveVal;
    3839            4 :                             MaxCurvePLR = CurveInput;
    3840              :                         }
    3841          400 :                         CurveInput += 0.01;
    3842              :                     }
    3843            4 :                     if (MinCurveVal < 0.7) {
    3844            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3845            0 :                         ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(11), Alphas(11)));
    3846            0 :                         ShowContinueError(state,
    3847            0 :                                           format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    3848            0 :                         ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    3849            0 :                         Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
    3850              :                     }
    3851              : 
    3852            4 :                     if (MaxCurveVal > 1.0) {
    3853            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3854            0 :                         ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(11), Alphas(11)));
    3855            0 :                         ShowContinueError(state,
    3856            0 :                                           format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    3857            0 :                         ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    3858            0 :                         Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
    3859              :                     }
    3860              :                 }
    3861              :             }
    3862              :         }
    3863              : 
    3864              :         // assume compressor resides at the inlet to the DX Coil
    3865            7 :         thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
    3866              : 
    3867              :         // set condenser type as HPWH
    3868            7 :         thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
    3869              : 
    3870            7 :     } // end of the DX water heater wrapped coil loop
    3871              : 
    3872          135 :     if (ErrorsFound) {
    3873            0 :         ShowFatalError(state,
    3874            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    3875              :     }
    3876              : 
    3877              :     // DX Multispeed cooling coil
    3878          135 :     CurrentModuleObject = "Coil:Cooling:DX:MultiSpeed";
    3879          163 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoolCoils; ++DXCoilIndex) {
    3880              : 
    3881           28 :         ++DXCoilNum;
    3882              : 
    3883           28 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    3884              :                                                                  CurrentModuleObject,
    3885              :                                                                  DXCoilIndex,
    3886              :                                                                  Alphas,
    3887              :                                                                  NumAlphas,
    3888              :                                                                  Numbers,
    3889              :                                                                  NumNumbers,
    3890              :                                                                  IOStatus,
    3891              :                                                                  lNumericBlanks,
    3892              :                                                                  lAlphaBlanks,
    3893              :                                                                  cAlphaFields,
    3894              :                                                                  cNumericFields);
    3895              : 
    3896           28 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    3897              :         // allocate single performance mode for numeric field strings used for sizing routine (all fields are in this object)
    3898           28 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    3899           28 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    3900           28 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    3901              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    3902           28 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    3903              : 
    3904           28 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    3905           28 :         thisDXCoil.Name = Alphas(1);
    3906              :         // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
    3907           28 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
    3908           28 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
    3909           28 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    3910           28 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedCooling;
    3911           28 :         if (lAlphaBlanks(2)) {
    3912           18 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    3913           10 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    3914            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    3915            0 :             ErrorsFound = true;
    3916              :         }
    3917              : 
    3918           28 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    3919           28 :                                                  Alphas(3),
    3920              :                                                  ErrorsFound,
    3921              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
    3922           28 :                                                  Alphas(1),
    3923              :                                                  DataLoopNode::NodeFluidType::Air,
    3924              :                                                  DataLoopNode::ConnectionType::Inlet,
    3925              :                                                  NodeInputManager::CompFluidStream::Primary,
    3926              :                                                  ObjectIsNotParent);
    3927              : 
    3928           56 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    3929           28 :                                                   Alphas(4),
    3930              :                                                   ErrorsFound,
    3931              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
    3932           28 :                                                   Alphas(1),
    3933              :                                                   DataLoopNode::NodeFluidType::Air,
    3934              :                                                   DataLoopNode::ConnectionType::Outlet,
    3935              :                                                   NodeInputManager::CompFluidStream::Primary,
    3936              :                                                   ObjectIsNotParent);
    3937              : 
    3938           28 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    3939              : 
    3940              :         // outdoor condenser node
    3941           28 :         if (lAlphaBlanks(5)) {
    3942           15 :             thisDXCoil.CondenserInletNodeNum(1) = 0;
    3943              :         } else {
    3944           26 :             thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
    3945           13 :                                                                     Alphas(5),
    3946              :                                                                     ErrorsFound,
    3947              :                                                                     DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
    3948           13 :                                                                     thisDXCoil.Name,
    3949              :                                                                     DataLoopNode::NodeFluidType::Air,
    3950              :                                                                     DataLoopNode::ConnectionType::OutsideAirReference,
    3951              :                                                                     NodeInputManager::CompFluidStream::Primary,
    3952              :                                                                     ObjectIsNotParent);
    3953           13 :             if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
    3954            4 :                 ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3955            8 :                 ShowContinueError(
    3956            8 :                     state, format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(5), Alphas(5)));
    3957           12 :                 ShowContinueError(
    3958              :                     state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
    3959              :             }
    3960              :         }
    3961              : 
    3962           28 :         if ((Util::SameString(Alphas(6), "AirCooled")) || lAlphaBlanks(6)) {
    3963           28 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
    3964            0 :         } else if (Util::SameString(Alphas(6), "EvaporativelyCooled")) {
    3965            0 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
    3966            0 :             thisDXCoil.ReportEvapCondVars = true;
    3967              :         } else {
    3968            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3969            0 :             ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(6), Alphas(6)));
    3970            0 :             ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
    3971            0 :             ErrorsFound = true;
    3972              :         }
    3973              : 
    3974              :         // Get Water System tank connections
    3975              :         //  A8, \field Name of Water Storage Tank for Supply
    3976           28 :         thisDXCoil.EvapWaterSupplyName = Alphas(7);
    3977           28 :         if (lAlphaBlanks(7)) {
    3978           28 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
    3979              :         } else {
    3980            0 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
    3981            0 :             SetupTankDemandComponent(state,
    3982              :                                      thisDXCoil.Name,
    3983              :                                      CurrentModuleObject,
    3984              :                                      thisDXCoil.EvapWaterSupplyName,
    3985              :                                      ErrorsFound,
    3986            0 :                                      thisDXCoil.EvapWaterSupTankID,
    3987            0 :                                      thisDXCoil.EvapWaterTankDemandARRID);
    3988              :         }
    3989              : 
    3990              :         // A9; \field Name of Water Storage Tank for Condensate Collection
    3991           28 :         thisDXCoil.CondensateCollectName = Alphas(8);
    3992           28 :         if (lAlphaBlanks(8)) {
    3993           28 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    3994              :         } else {
    3995            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    3996            0 :             SetupTankSupplyComponent(state,
    3997              :                                      thisDXCoil.Name,
    3998              :                                      CurrentModuleObject,
    3999              :                                      thisDXCoil.CondensateCollectName,
    4000              :                                      ErrorsFound,
    4001            0 :                                      thisDXCoil.CondensateTankID,
    4002            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    4003              :         }
    4004              : 
    4005              :         // Set minimum OAT for compressor operation
    4006           28 :         thisDXCoil.MinOATCompressor = Numbers(1);
    4007              : 
    4008              :         // Set crankcase heater capacity
    4009           28 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(2);
    4010           28 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    4011            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4012            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(2)));
    4013            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(2)));
    4014            0 :             ErrorsFound = true;
    4015              :         }
    4016              : 
    4017              :         // Set crankcase heater cutout temperature
    4018           28 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(3);
    4019              : 
    4020           28 :         if (Util::SameString(Alphas(9), "Yes")) {
    4021            0 :             thisDXCoil.PLRImpact = true;
    4022           28 :         } else if (Util::SameString(Alphas(9), "No")) {
    4023           28 :             thisDXCoil.PLRImpact = false;
    4024              :         } else {
    4025            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4026            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(9), Alphas(9)));
    4027            0 :             ShowContinueError(state, "The allowed choices are Yes or No.");
    4028            0 :             ErrorsFound = true;
    4029              :         }
    4030              : 
    4031           28 :         if (Util::SameString(Alphas(10), "Yes")) {
    4032            0 :             thisDXCoil.LatentImpact = true;
    4033           28 :         } else if (Util::SameString(Alphas(10), "No")) {
    4034           28 :             thisDXCoil.LatentImpact = false;
    4035              :         } else {
    4036            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4037            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(10), Alphas(10)));
    4038            0 :             ShowContinueError(state, "The allowed choices are Yes or No.");
    4039            0 :             ErrorsFound = true;
    4040              :         }
    4041              : 
    4042              :         //   Basin heater power as a function of temperature must be greater than or equal to 0
    4043           28 :         thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(4);
    4044           28 :         if (Numbers(4) < 0.0) {
    4045            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4046            0 :             ShowContinueError(state, format("...{} must be >= 0.0, entered value=[{:.3T}].", cNumericFields(4), Numbers(4)));
    4047            0 :             ErrorsFound = true;
    4048              :         }
    4049              : 
    4050           28 :         thisDXCoil.BasinHeaterSetPointTemp = Numbers(5);
    4051           28 :         if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    4052            0 :             if (NumNumbers < 5) {
    4053            0 :                 thisDXCoil.BasinHeaterSetPointTemp = 2.0;
    4054              :             }
    4055            0 :             if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
    4056            0 :                 ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4057            0 :                 ShowContinueError(state, format("...{} is less than 2 {{C}}. Freezing could occur.", cNumericFields(5)));
    4058            0 :                 ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(5)));
    4059              :             }
    4060              :         }
    4061              : 
    4062           28 :         if (!lAlphaBlanks(11)) {
    4063            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
    4064            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    4065            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(11), Alphas(11)));
    4066            0 :                 ErrorsFound = true;
    4067              :             } else {
    4068            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4069              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    4070              :                                                      {1},                                          // Valid dimensions
    4071              :                                                      RoutineName,                                  // Routine name
    4072              :                                                      CurrentModuleObject,                          // Object Type
    4073              :                                                      thisDXCoil.Name,                              // Object Name
    4074            2 :                                                      cAlphaFields(11));                            // Field Name
    4075              :             }
    4076              :         }
    4077              : 
    4078           28 :         if (!lAlphaBlanks(12)) {
    4079            0 :             if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(12))) == nullptr) {
    4080            0 :                 ShowWarningItemNotFound(
    4081            0 :                     state, eoh, cAlphaFields(12), Alphas(12), "Basin heater will be available to operate throughout the simulation.");
    4082              :             }
    4083              :         }
    4084              : 
    4085              :         // A13; \field Fuel type, Validate fuel type input
    4086           28 :         thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(13)));
    4087              : 
    4088           28 :         thisDXCoil.NumOfSpeeds = Numbers(6); // Number of speeds
    4089           28 :         if (thisDXCoil.NumOfSpeeds < 2) {
    4090            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4091            0 :             ShowContinueError(state, format("...{} must be >= 2. entered number is {:.0T}", cNumericFields(6), Numbers(6)));
    4092            0 :             ErrorsFound = true;
    4093              :         }
    4094              : 
    4095              :         // Allocate arrays based on the number of speeds
    4096           28 :         thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
    4097           28 :         thisDXCoil.MSErrIndex = 0;
    4098           28 :         thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
    4099           28 :         thisDXCoil.MSRatedTotCapDes.allocate(thisDXCoil.NumOfSpeeds);
    4100           28 :         thisDXCoil.MSRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
    4101           28 :         thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
    4102           28 :         thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4103           28 :         thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4104           28 :         thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
    4105           28 :         thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
    4106           28 :         thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
    4107           28 :         thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
    4108           28 :         thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
    4109           28 :         thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
    4110           28 :         thisDXCoil.MSEvapCondEffect.allocate(thisDXCoil.NumOfSpeeds);
    4111           28 :         thisDXCoil.MSEvapCondAirFlow.allocate(thisDXCoil.NumOfSpeeds);
    4112           28 :         thisDXCoil.MSEvapCondPumpElecNomPower.allocate(thisDXCoil.NumOfSpeeds);
    4113           28 :         thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
    4114           28 :         thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
    4115           28 :         thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
    4116           28 :         thisDXCoil.MSTwet_Rated.allocate(thisDXCoil.NumOfSpeeds);
    4117           28 :         thisDXCoil.MSGamma_Rated.allocate(thisDXCoil.NumOfSpeeds);
    4118           28 :         thisDXCoil.MSMaxONOFFCyclesperHour.allocate(thisDXCoil.NumOfSpeeds);
    4119           28 :         thisDXCoil.MSLatentCapacityTimeConstant.allocate(thisDXCoil.NumOfSpeeds);
    4120           28 :         thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4121           28 :         thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
    4122              : 
    4123          107 :         for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
    4124           79 :             thisDXCoil.MSRatedTotCap(I) = Numbers(7 + (I - 1) * 14);
    4125           79 :             thisDXCoil.MSRatedSHR(I) = Numbers(8 + (I - 1) * 14);
    4126           79 :             thisDXCoil.MSRatedCOP(I) = Numbers(9 + (I - 1) * 14);
    4127           79 :             thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(10 + (I - 1) * 14);
    4128           79 :             thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(11 + (I - 1) * 14);
    4129           79 :             thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(12 + (I - 1) * 14);
    4130              : 
    4131           79 :             thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
    4132           79 :             if (thisDXCoil.MSCCapFTemp(I) == 0) {
    4133            0 :                 if (lAlphaBlanks(14 + (I - 1) * 6)) {
    4134            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4135            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(14 + (I - 1) * 6)));
    4136              :                 } else {
    4137            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4138            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14 + (I - 1) * 6), Alphas(14 + (I - 1) * 6)));
    4139              :                 }
    4140            0 :                 ErrorsFound = true;
    4141              :             } else {
    4142              :                 // Verify Curve Object, only legal type is BiQuadratic
    4143          237 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4144           79 :                                                      thisDXCoil.MSCCapFTemp(I),       // Curve index
    4145              :                                                      {2},                             // Valid dimensions
    4146              :                                                      RoutineName,                     // Routine name
    4147              :                                                      CurrentModuleObject,             // Object Type
    4148              :                                                      thisDXCoil.Name,                 // Object Name
    4149           79 :                                                      cAlphaFields(14 + (I - 1) * 6)); // Field Name
    4150              : 
    4151           79 :                 if (!ErrorsFound) {
    4152           76 :                     checkCurveIsNormalizedToOne(state,
    4153          228 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4154           76 :                                                 thisDXCoil.Name,
    4155           76 :                                                 thisDXCoil.MSCCapFTemp(I),
    4156           76 :                                                 cAlphaFields(14 + (I - 1) * 6),
    4157           76 :                                                 Alphas(14 + (I - 1) * 6),
    4158              :                                                 RatedInletWetBulbTemp,
    4159              :                                                 RatedOutdoorAirTemp);
    4160              :                 }
    4161              :             }
    4162              : 
    4163           79 :             thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
    4164           79 :             if (thisDXCoil.MSCCapFFlow(I) == 0) {
    4165            0 :                 if (lAlphaBlanks(15 + (I - 1) * 6)) {
    4166            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4167            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(15 + (I - 1) * 6)));
    4168              :                 } else {
    4169            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4170            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
    4171              :                 }
    4172            0 :                 ErrorsFound = true;
    4173              :             } else {
    4174              :                 // Verify Curve Object, only legal type is Quadratic
    4175          237 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4176           79 :                                                      thisDXCoil.MSCCapFFlow(I),       // Curve index
    4177              :                                                      {1},                             // Valid dimensions
    4178              :                                                      RoutineName,                     // Routine name
    4179              :                                                      CurrentModuleObject,             // Object Type
    4180              :                                                      thisDXCoil.Name,                 // Object Name
    4181           79 :                                                      cAlphaFields(15 + (I - 1) * 6)); // Field Name
    4182              : 
    4183           79 :                 if (!ErrorsFound) {
    4184           76 :                     checkCurveIsNormalizedToOne(state,
    4185          228 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4186           76 :                                                 thisDXCoil.Name,
    4187           76 :                                                 thisDXCoil.MSCCapFFlow(I),
    4188           76 :                                                 cAlphaFields(15 + (I - 1) * 6),
    4189           76 :                                                 Alphas(15 + (I - 1) * 6),
    4190              :                                                 1.0);
    4191              :                 }
    4192              :             }
    4193              : 
    4194           79 :             thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
    4195           79 :             if (thisDXCoil.MSEIRFTemp(I) == 0) {
    4196            0 :                 if (lAlphaBlanks(16 + (I - 1) * 6)) {
    4197            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4198            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(16 + (I - 1) * 6)));
    4199              :                 } else {
    4200            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4201            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16 + (I - 1) * 6), Alphas(16 + (I - 1) * 6)));
    4202              :                 }
    4203            0 :                 ErrorsFound = true;
    4204              :             } else {
    4205              :                 // Verify Curve Object, only legal type is BiQuadratic
    4206          237 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4207           79 :                                                      thisDXCoil.MSEIRFTemp(I),        // Curve index
    4208              :                                                      {2},                             // Valid dimensions
    4209              :                                                      RoutineName,                     // Routine name
    4210              :                                                      CurrentModuleObject,             // Object Type
    4211              :                                                      thisDXCoil.Name,                 // Object Name
    4212           79 :                                                      cAlphaFields(16 + (I - 1) * 6)); // Field Name
    4213              : 
    4214           79 :                 if (!ErrorsFound) {
    4215           76 :                     checkCurveIsNormalizedToOne(state,
    4216          228 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4217           76 :                                                 thisDXCoil.Name,
    4218           76 :                                                 thisDXCoil.MSEIRFTemp(I),
    4219           76 :                                                 cAlphaFields(16 + (I - 1) * 6),
    4220           76 :                                                 Alphas(16 + (I - 1) * 6),
    4221              :                                                 RatedInletWetBulbTemp,
    4222              :                                                 RatedOutdoorAirTemp);
    4223              :                 }
    4224              :             }
    4225              : 
    4226           79 :             thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(17 + (I - 1) * 6)); // convert curve name to number
    4227           79 :             if (thisDXCoil.MSEIRFFlow(I) == 0) {
    4228            0 :                 if (lAlphaBlanks(17 + (I - 1) * 6)) {
    4229            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4230            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(17 + (I - 1) * 6)));
    4231              :                 } else {
    4232            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4233            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17 + (I - 1) * 6), Alphas(17 + (I - 1) * 6)));
    4234              :                 }
    4235            0 :                 ErrorsFound = true;
    4236              :             } else {
    4237              :                 // Verify Curve Object, only legal type is Quadratic
    4238          237 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4239           79 :                                                      thisDXCoil.MSEIRFFlow(I),        // Curve index
    4240              :                                                      {1},                             // Valid dimensions
    4241              :                                                      RoutineName,                     // Routine name
    4242              :                                                      CurrentModuleObject,             // Object Type
    4243              :                                                      thisDXCoil.Name,                 // Object Name
    4244           79 :                                                      cAlphaFields(17 + (I - 1) * 6)); // Field Name
    4245              : 
    4246           79 :                 if (!ErrorsFound) {
    4247           76 :                     checkCurveIsNormalizedToOne(state,
    4248          228 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4249           76 :                                                 thisDXCoil.Name,
    4250           76 :                                                 thisDXCoil.MSEIRFFlow(I),
    4251           76 :                                                 cAlphaFields(17 + (I - 1) * 6),
    4252           76 :                                                 Alphas(17 + (I - 1) * 6),
    4253              :                                                 1.0);
    4254              :                 }
    4255              :             }
    4256              : 
    4257           79 :             thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(18 + (I - 1) * 6)); // convert curve name to number
    4258           79 :             if (thisDXCoil.MSPLFFPLR(I) == 0) {
    4259            4 :                 if (lAlphaBlanks(18 + (I - 1) * 6)) {
    4260            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4261            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(18 + (I - 1) * 6)));
    4262              :                 } else {
    4263            4 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4264            4 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(18 + (I - 1) * 6), Alphas(18 + (I - 1) * 6)));
    4265              :                 }
    4266            4 :                 ErrorsFound = true;
    4267              :             } else {
    4268              :                 // Verify Curve Object, only legal types are Quadratic or Cubic
    4269          225 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4270           75 :                                                      thisDXCoil.MSPLFFPLR(I),         // Curve index
    4271              :                                                      {1},                             // Valid dimensions
    4272              :                                                      RoutineName,                     // Routine name
    4273              :                                                      CurrentModuleObject,             // Object Type
    4274              :                                                      thisDXCoil.Name,                 // Object Name
    4275           75 :                                                      cAlphaFields(18 + (I - 1) * 6)); // Field Name
    4276              : 
    4277           75 :                 if (!ErrorsFound) {
    4278              :                     //       Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    4279           75 :                     MinCurveVal = 999.0;
    4280           75 :                     MaxCurveVal = -999.0;
    4281           75 :                     CurveInput = 0.0;
    4282         7575 :                     while (CurveInput <= 1.0) {
    4283         7500 :                         CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
    4284         7500 :                         if (CurveVal < MinCurveVal) {
    4285           75 :                             MinCurveVal = CurveVal;
    4286           75 :                             MinCurvePLR = CurveInput;
    4287              :                         }
    4288         7500 :                         if (CurveVal > MaxCurveVal) {
    4289         6256 :                             MaxCurveVal = CurveVal;
    4290         6256 :                             MaxCurvePLR = CurveInput;
    4291              :                         }
    4292         7500 :                         CurveInput += 0.01;
    4293              :                     }
    4294           75 :                     if (MinCurveVal < 0.7) {
    4295            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4296            0 :                         ShowContinueError(state,
    4297            0 :                                           format("...{} = {} has out of range value.", cAlphaFields2(18 + (I - 1) * 6), Alphas2(18 + (I - 1) * 6)));
    4298            0 :                         ShowContinueError(state,
    4299            0 :                                           format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    4300            0 :                         ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    4301            0 :                         Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 0.7);
    4302              :                     }
    4303              : 
    4304           75 :                     if (MaxCurveVal > 1.0) {
    4305            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4306            0 :                         ShowContinueError(state,
    4307            0 :                                           format("...{} = {} has out of range value.", cAlphaFields2(18 + (I - 1) * 6), Alphas2(18 + (I - 1) * 6)));
    4308            0 :                         ShowContinueError(state,
    4309            0 :                                           format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    4310            0 :                         ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    4311            0 :                         Curve::SetCurveOutputMaxValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 1.0);
    4312              :                     }
    4313              :                 }
    4314              :             }
    4315              : 
    4316              :             // read data for latent degradation
    4317           79 :             thisDXCoil.MSTwet_Rated(I) = Numbers(13 + (I - 1) * 14);
    4318           79 :             if (thisDXCoil.MSTwet_Rated(I) < 0.0) {
    4319            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4320            0 :                 ShowContinueError(
    4321            0 :                     state, format("...{} cannot be < 0.0, entered value=[{:.4T}].", cNumericFields(13 + (I - 1) * 14), thisDXCoil.MSTwet_Rated(I)));
    4322            0 :                 ErrorsFound = true;
    4323              :             }
    4324           79 :             thisDXCoil.MSGamma_Rated(I) = Numbers(14 + (I - 1) * 14);
    4325           79 :             if (thisDXCoil.MSGamma_Rated(I) < 0.0) {
    4326            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4327            0 :                 ShowContinueError(
    4328            0 :                     state, format("...{} cannot be < 0.0, entered value=[{:.4T}].", cNumericFields(14 + (I - 1) * 14), thisDXCoil.MSGamma_Rated(I)));
    4329            0 :                 ErrorsFound = true;
    4330              :             }
    4331           79 :             thisDXCoil.MSMaxONOFFCyclesperHour(I) = Numbers(15 + (I - 1) * 14);
    4332           79 :             if (thisDXCoil.Gamma_Rated(I) < 0.0) {
    4333            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4334            0 :                 ShowContinueError(state,
    4335            0 :                                   format("...{} cannot be < 0.0, entered value=[{:.2T}].",
    4336            0 :                                          cNumericFields(15 + (I - 1) * 14),
    4337              :                                          thisDXCoil.MSMaxONOFFCyclesperHour(I)));
    4338            0 :                 ErrorsFound = true;
    4339              :             }
    4340           79 :             thisDXCoil.MSLatentCapacityTimeConstant(I) = Numbers(16 + (I - 1) * 14);
    4341           79 :             if (thisDXCoil.Gamma_Rated(I) < 0.0) {
    4342            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4343            0 :                 ShowContinueError(state,
    4344            0 :                                   format("...{} cannot be < 0.0, entered value=[{:.2T}].",
    4345            0 :                                          cNumericFields(16 + (I - 1) * 14),
    4346              :                                          thisDXCoil.MSLatentCapacityTimeConstant(I)));
    4347            0 :                 ErrorsFound = true;
    4348              :             }
    4349              : 
    4350           79 :             thisDXCoil.MSWasteHeatFrac(I) = Numbers(17 + (I - 1) * 14);
    4351              : 
    4352              :             // Read waste heat modifier curve name
    4353           79 :             thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(19 + (I - 1) * 6)); // convert curve name to number
    4354           79 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
    4355           16 :                 if (thisDXCoil.MSWasteHeat(I) > 0) {
    4356              :                     // Verify Curve Object, only legal types are BiQuadratic
    4357           48 :                     ErrorsFound |= Curve::CheckCurveDims(state,
    4358           16 :                                                          thisDXCoil.MSWasteHeat(I),       // Curve index
    4359              :                                                          {2},                             // Valid dimensions
    4360              :                                                          RoutineName,                     // Routine name
    4361              :                                                          CurrentModuleObject,             // Object Type
    4362              :                                                          thisDXCoil.Name,                 // Object Name
    4363           16 :                                                          cAlphaFields(19 + (I - 1) * 6)); // Field Name
    4364              : 
    4365           16 :                     if (!ErrorsFound) {
    4366           16 :                         CurveVal = CurveValue(state, thisDXCoil.MSWasteHeat(I), RatedOutdoorAirTemp, RatedInletAirTemp);
    4367           16 :                         if (CurveVal > 1.10 || CurveVal < 0.90) {
    4368            0 :                             ShowWarningError(state, format("{}{}=\"{}\", curve values", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4369            0 :                             ShowContinueError(state, format("{} = {}", cAlphaFields(19 + (I - 1) * 6), Alphas(19 + (I - 1) * 6)));
    4370            0 :                             ShowContinueError(
    4371            0 :                                 state, format("...{} output is not equal to 1.0 (+ or - 10%) at rated conditions.", cAlphaFields(19 + (I - 1) * 6)));
    4372            0 :                             ShowContinueError(state, format("...Curve output at rated conditions = {:.3T}", CurveVal));
    4373              :                         }
    4374              :                     }
    4375              :                 }
    4376              :             }
    4377              : 
    4378           79 :             thisDXCoil.MSEvapCondEffect(I) = Numbers(18 + (I - 1) * 14);
    4379           79 :             if (thisDXCoil.MSEvapCondEffect(I) < 0.0 || thisDXCoil.MSEvapCondEffect(I) > 1.0) {
    4380            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4381            0 :                 ShowContinueError(
    4382              :                     state,
    4383            0 :                     format("...{} cannot be < 0.0 or > 1.0, entered value=[{:.3T}].", cNumericFields(18 + (I - 1) * 14), Numbers(18 + (I - 1) * 14)));
    4384            0 :                 ErrorsFound = true;
    4385              :             }
    4386              : 
    4387           79 :             thisDXCoil.MSEvapCondAirFlow(I) = Numbers(19 + (I - 1) * 14);
    4388           79 :             if (thisDXCoil.MSEvapCondAirFlow(I) < 0.0 && thisDXCoil.MSEvapCondAirFlow(I) != AutoSize) {
    4389            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4390            0 :                 ShowContinueError(
    4391            0 :                     state, format("...{} cannot be < 0.0, entered value=[{:.3T}].", cNumericFields(19 + (I - 1) * 14), Numbers(19 + (I - 1) * 14)));
    4392            0 :                 ErrorsFound = true;
    4393              :             }
    4394              : 
    4395           79 :             thisDXCoil.MSEvapCondPumpElecNomPower(I) = Numbers(20 + (I - 1) * 14);
    4396           79 :             if (thisDXCoil.MSEvapCondPumpElecNomPower(I) < 0.0 && thisDXCoil.MSEvapCondPumpElecNomPower(I) != AutoSize) {
    4397            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4398            0 :                 ShowContinueError(
    4399            0 :                     state, format("...{} cannot be < 0.0, entered value=[{:.3T}].", cNumericFields(20 + (I - 1) * 14), Numbers(20 + (I - 1) * 14)));
    4400            0 :                 ErrorsFound = true;
    4401              :             }
    4402              :         }
    4403              :         // A38; \field Zone Name for Condenser Placement
    4404           28 :         if (!lAlphaBlanks(38) && NumAlphas > 37) {
    4405            0 :             thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(38), state.dataHeatBal->Zone);
    4406            0 :             if (thisDXCoil.SecZonePtr > 0) {
    4407            0 :                 SetupZoneInternalGain(state,
    4408              :                                       thisDXCoil.SecZonePtr,
    4409              :                                       thisDXCoil.Name,
    4410              :                                       DataHeatBalance::IntGainType::SecCoolingDXCoilMultiSpeed,
    4411              :                                       &thisDXCoil.SecCoilSensibleHeatGainRate);
    4412            0 :                 thisDXCoil.IsSecondaryDXCoilInZone = true;
    4413              :             } else {
    4414            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4415            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(38), Alphas(38)));
    4416              :             }
    4417              :         }
    4418              :     }
    4419              : 
    4420          135 :     if (ErrorsFound) {
    4421            3 :         ShowFatalError(state,
    4422            3 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    4423              :     }
    4424              : 
    4425              :     // DX multispeed heating coil
    4426          134 :     CurrentModuleObject = "Coil:Heating:DX:MultiSpeed";
    4427          148 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedHeatCoils; ++DXCoilIndex) {
    4428              : 
    4429           14 :         ++DXCoilNum;
    4430              : 
    4431           14 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    4432              :                                                                  CurrentModuleObject,
    4433              :                                                                  DXCoilIndex,
    4434              :                                                                  Alphas,
    4435              :                                                                  NumAlphas,
    4436              :                                                                  Numbers,
    4437              :                                                                  NumNumbers,
    4438              :                                                                  IOStatus,
    4439              :                                                                  lNumericBlanks,
    4440              :                                                                  lAlphaBlanks,
    4441              :                                                                  cAlphaFields,
    4442              :                                                                  cNumericFields);
    4443              : 
    4444           14 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    4445              : 
    4446              :         // *** will have to circle back to this one to fix since the multispeed coil has all fields in this coil object ***
    4447              :         // allocate single performance mode for numeric field strings used for sizing routine
    4448           14 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    4449           14 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    4450           14 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    4451              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    4452           14 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    4453              : 
    4454           14 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    4455           14 :         thisDXCoil.Name = Alphas(1);
    4456              :         // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
    4457           14 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
    4458           14 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
    4459           14 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    4460           14 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedHeating;
    4461           14 :         if (lAlphaBlanks(2)) {
    4462            8 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    4463            6 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    4464            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    4465            0 :             ErrorsFound = true;
    4466              :         }
    4467              : 
    4468           14 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    4469           14 :                                                  Alphas(3),
    4470              :                                                  ErrorsFound,
    4471              :                                                  DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
    4472           14 :                                                  Alphas(1),
    4473              :                                                  DataLoopNode::NodeFluidType::Air,
    4474              :                                                  DataLoopNode::ConnectionType::Inlet,
    4475              :                                                  NodeInputManager::CompFluidStream::Primary,
    4476              :                                                  ObjectIsNotParent);
    4477              : 
    4478           28 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    4479           14 :                                                   Alphas(4),
    4480              :                                                   ErrorsFound,
    4481              :                                                   DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
    4482           14 :                                                   Alphas(1),
    4483              :                                                   DataLoopNode::NodeFluidType::Air,
    4484              :                                                   DataLoopNode::ConnectionType::Outlet,
    4485              :                                                   NodeInputManager::CompFluidStream::Primary,
    4486              :                                                   ObjectIsNotParent);
    4487              : 
    4488           14 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    4489              : 
    4490              :         // Set minimum OAT for heat pump compressor operation
    4491           14 :         thisDXCoil.MinOATCompressor = Numbers(1);
    4492              : 
    4493              :         // set Minimum Outdoor Dry-Bulb Temperature for Compressor Operation
    4494           14 :         thisDXCoil.OATempCompressorOn = Numbers(2);
    4495              :         // Set crankcase heater capacity
    4496           14 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(3);
    4497           14 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    4498            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4499            0 :             ShowContinueError(state, format("...{} cannot be < 0.0, entered value=[{:.2T}].", cNumericFields(3), Numbers(3)));
    4500            0 :             ErrorsFound = true;
    4501              :         }
    4502              : 
    4503              :         // Set crankcase heater cutout temperature
    4504           14 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(4);
    4505              : 
    4506           14 :         if (!lAlphaBlanks(5)) {
    4507            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
    4508            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    4509            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
    4510            0 :                 ErrorsFound = true;
    4511              :             } else {
    4512            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4513              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    4514              :                                                      {1},                                          // Valid dimensions
    4515              :                                                      RoutineName,                                  // Routine name
    4516              :                                                      CurrentModuleObject,                          // Object Type
    4517              :                                                      thisDXCoil.Name,                              // Object Name
    4518            2 :                                                      cAlphaFields(5));                             // Field Name
    4519              :             }
    4520              :         }
    4521              : 
    4522              :         // Only required for reverse cycle heat pumps
    4523           14 :         thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(6)); // convert curve name to number
    4524           14 :         if (Util::SameString(Alphas(7), "ReverseCycle")) {
    4525           13 :             if (thisDXCoil.DefrostEIRFT == 0) {
    4526            0 :                 if (lAlphaBlanks(6)) {
    4527            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4528            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
    4529              :                 } else {
    4530            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4531            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
    4532              :                 }
    4533            0 :                 ErrorsFound = true;
    4534              :             } else {
    4535              :                 // Verify Curve Object, only legal type is BiQuadratic
    4536           26 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4537              :                                                      thisDXCoil.DefrostEIRFT, // Curve index
    4538              :                                                      {2},                     // Valid dimensions
    4539              :                                                      RoutineName,             // Routine name
    4540              :                                                      CurrentModuleObject,     // Object Type
    4541              :                                                      thisDXCoil.Name,         // Object Name
    4542           13 :                                                      cAlphaFields(6));        // Field Name
    4543              : 
    4544           13 :                 if (!ErrorsFound) {
    4545           13 :                     checkCurveIsNormalizedToOne(state,
    4546           39 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4547           13 :                                                 thisDXCoil.Name,
    4548              :                                                 thisDXCoil.DefrostEIRFT,
    4549           13 :                                                 cAlphaFields(6),
    4550           13 :                                                 Alphas(6),
    4551              :                                                 RatedInletWetBulbTempHeat,
    4552              :                                                 RatedOutdoorAirTempHeat);
    4553              :                 }
    4554              :             }
    4555              :         }
    4556              : 
    4557           14 :         if (Util::SameString(Alphas(7), "ReverseCycle")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
    4558           14 :         if (Util::SameString(Alphas(7), "Resistive")) thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
    4559           14 :         if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
    4560            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4561            0 :             ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(7), Alphas(7)));
    4562            0 :             ShowContinueError(state, "...valid values for this field are ReverseCycle or Resistive.");
    4563            0 :             ErrorsFound = true;
    4564              :         }
    4565              : 
    4566           14 :         if (Util::SameString(Alphas(8), "Timed")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
    4567           14 :         if (Util::SameString(Alphas(8), "OnDemand")) thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
    4568           14 :         if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
    4569            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4570            0 :             ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(8), Alphas(8)));
    4571            0 :             ShowContinueError(state, "...valid values for this field are Timed or OnDemand.");
    4572            0 :             ErrorsFound = true;
    4573              :         }
    4574              : 
    4575              :         // Set maximum outdoor temp for defrost to occur
    4576           14 :         thisDXCoil.MaxOATDefrost = Numbers(5);
    4577              : 
    4578              :         // Set defrost time period
    4579           14 :         thisDXCoil.DefrostTime = Numbers(6);
    4580           14 :         if (thisDXCoil.DefrostTime == 0.0 && thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
    4581            0 :             ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4582            0 :             ShowContinueError(state, format("...{} = 0.0 for defrost control = TIMED.", cNumericFields(5)));
    4583              :         }
    4584              : 
    4585              :         // Set defrost capacity (for resistive defrost)
    4586           14 :         thisDXCoil.DefrostCapacity = Numbers(7);
    4587           14 :         if (thisDXCoil.DefrostCapacity == 0.0 && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
    4588            0 :             ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4589            0 :             ShowContinueError(state, format("...{} = 0.0 for defrost strategy = RESISTIVE.", cNumericFields(7)));
    4590              :         }
    4591              : 
    4592           14 :         if (Util::SameString(Alphas(9), "Yes")) {
    4593            0 :             thisDXCoil.PLRImpact = true;
    4594           14 :         } else if (Util::SameString(Alphas(9), "No")) {
    4595           14 :             thisDXCoil.PLRImpact = false;
    4596              :         } else {
    4597            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4598            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(9), Alphas(9)));
    4599            0 :             ShowContinueError(state, "The allowed choices are Yes or No.");
    4600            0 :             ErrorsFound = true;
    4601              :         }
    4602              : 
    4603              :         // A10; \field Fuel type, Validate fuel type input
    4604           14 :         thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(10)));
    4605              : 
    4606           14 :         thisDXCoil.RegionNum = Numbers(8);   // Region Number for HSPF Calc
    4607           14 :         thisDXCoil.NumOfSpeeds = Numbers(9); // Number of speeds
    4608           14 :         if (thisDXCoil.NumOfSpeeds < 2) {
    4609            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4610            0 :             ShowContinueError(state, format("...{} must be >= 2. entered number is {:.0T}", cNumericFields(9), Numbers(9)));
    4611            0 :             ErrorsFound = true;
    4612              :         }
    4613              : 
    4614              :         // Allocate arrays based on the number of speeds
    4615           14 :         thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
    4616           14 :         thisDXCoil.MSErrIndex = 0;
    4617           14 :         thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
    4618           14 :         thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
    4619           14 :         thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4620           14 :         thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4621           14 :         thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
    4622           14 :         thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
    4623           14 :         thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
    4624           14 :         thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
    4625           14 :         thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
    4626           14 :         thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
    4627           14 :         thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
    4628           14 :         thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
    4629           14 :         thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
    4630           14 :         thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4631           14 :         thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
    4632           14 :         thisDXCoil.MSSecCoilSHRFT.allocate(thisDXCoil.NumOfSpeeds);
    4633           14 :         thisDXCoil.MSSecCoilSHRFF.allocate(thisDXCoil.NumOfSpeeds);
    4634           14 :         thisDXCoil.MSSecCoilAirFlow.allocate(thisDXCoil.NumOfSpeeds);
    4635           14 :         thisDXCoil.MSSecCoilAirFlowScalingFactor.allocate(thisDXCoil.NumOfSpeeds);
    4636           14 :         thisDXCoil.MSSecCoilRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
    4637              : 
    4638           14 :         thisDXCoil.RatedSHR(1) = 1.0;
    4639              : 
    4640           48 :         for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
    4641           34 :             thisDXCoil.MSRatedTotCap(I) = Numbers(10 + (I - 1) * 6);
    4642           34 :             thisDXCoil.MSRatedCOP(I) = Numbers(11 + (I - 1) * 6);
    4643           34 :             thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(12 + (I - 1) * 6);
    4644           34 :             thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(13 + (I - 1) * 6);
    4645           34 :             thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(14 + (I - 1) * 6);
    4646           34 :             thisDXCoil.MSWasteHeatFrac(I) = Numbers(15 + (I - 1) * 6);
    4647              : 
    4648           34 :             thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(11 + (I - 1) * 6)); // convert curve name to number
    4649           34 :             if (thisDXCoil.MSCCapFTemp(I) == 0) {
    4650            0 :                 ShowSevereError(state,
    4651            0 :                                 format("{}, \"{}\" {} not found:{}",
    4652              :                                        CurrentModuleObject,
    4653            0 :                                        thisDXCoil.Name,
    4654            0 :                                        cAlphaFields(11 + (I - 1) * 6),
    4655            0 :                                        Alphas(11 + (I - 1) * 6)));
    4656            0 :                 ErrorsFound = true;
    4657              :             } else {
    4658              :                 // only legal types are Quadratic, BiQuadratic and Cubic
    4659          102 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4660           34 :                                                      thisDXCoil.MSCCapFTemp(I),       // Curve index
    4661              :                                                      {1, 2},                          // Valid dimensions  // MULTIPLECURVEDIMS
    4662              :                                                      RoutineName,                     // Routine name
    4663              :                                                      CurrentModuleObject,             // Object Type
    4664              :                                                      thisDXCoil.Name,                 // Object Name
    4665           34 :                                                      cAlphaFields(11 + (I - 1) * 6)); // Field Name
    4666              : 
    4667           34 :                 if (!ErrorsFound) {
    4668           34 :                     if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(I))->numDims == 1) {
    4669            8 :                         checkCurveIsNormalizedToOne(state,
    4670           24 :                                                     std::string{RoutineName} + CurrentModuleObject,
    4671            8 :                                                     thisDXCoil.Name,
    4672            8 :                                                     thisDXCoil.MSCCapFTemp(I),
    4673            8 :                                                     cAlphaFields(11 + (I - 1) * 6),
    4674            8 :                                                     Alphas(11 + (I - 1) * 6),
    4675              :                                                     RatedOutdoorAirTempHeat);
    4676              :                     } else {
    4677           26 :                         checkCurveIsNormalizedToOne(state,
    4678           78 :                                                     std::string{RoutineName} + CurrentModuleObject,
    4679           26 :                                                     thisDXCoil.Name,
    4680           26 :                                                     thisDXCoil.MSCCapFTemp(I),
    4681           26 :                                                     cAlphaFields(11 + (I - 1) * 6),
    4682           26 :                                                     Alphas(11 + (I - 1) * 6),
    4683              :                                                     RatedInletAirTempHeat,
    4684              :                                                     RatedOutdoorAirTempHeat);
    4685              :                     }
    4686              :                 }
    4687              :             }
    4688              : 
    4689           34 :             thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(12 + (I - 1) * 6)); // convert curve name to number
    4690           34 :             if (thisDXCoil.MSCCapFFlow(I) == 0) {
    4691            0 :                 if (lAlphaBlanks(12 + (I - 1) * 6)) {
    4692            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4693            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(12 + (I - 1) * 6)));
    4694              :                 } else {
    4695            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4696            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(12 + (I - 1) * 6), Alphas(12 + (I - 1) * 6)));
    4697              :                 }
    4698            0 :                 ErrorsFound = true;
    4699              :             } else {
    4700              :                 // Verify Curve Object, only legal type is Quadratic
    4701          102 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4702           34 :                                                      thisDXCoil.MSCCapFFlow(I),       // Curve index
    4703              :                                                      {1},                             // Valid dimensions
    4704              :                                                      RoutineName,                     // Routine name
    4705              :                                                      CurrentModuleObject,             // Object Type
    4706              :                                                      thisDXCoil.Name,                 // Object Name
    4707           34 :                                                      cAlphaFields(12 + (I - 1) * 6)); // Field Name
    4708              : 
    4709           34 :                 if (!ErrorsFound) {
    4710           34 :                     checkCurveIsNormalizedToOne(state,
    4711          102 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4712           34 :                                                 thisDXCoil.Name,
    4713           34 :                                                 thisDXCoil.MSCCapFFlow(I),
    4714           34 :                                                 cAlphaFields(12 + (I - 1) * 6),
    4715           34 :                                                 Alphas(12 + (I - 1) * 6),
    4716              :                                                 1.0);
    4717              :                 }
    4718              :             }
    4719              : 
    4720           34 :             thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(13 + (I - 1) * 6)); // convert curve name to number
    4721           34 :             if (thisDXCoil.MSEIRFTemp(I) == 0) {
    4722            0 :                 if (lAlphaBlanks(13 + (I - 1) * 6)) {
    4723            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4724            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(13 + (I - 1) * 6)));
    4725              :                 } else {
    4726            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4727            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(13 + (I - 1) * 6), Alphas(13 + (I - 1) * 6)));
    4728              :                 }
    4729            0 :                 ErrorsFound = true;
    4730              :             } else {
    4731              :                 // only legal types are Quadratic, BiQuadratic and Cubic
    4732          102 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4733           34 :                                                      thisDXCoil.MSEIRFTemp(I),        // Curve index
    4734              :                                                      {1, 2},                          // Valid dimensions  // MULTIPLECURVEDIMS
    4735              :                                                      RoutineName,                     // Routine name
    4736              :                                                      CurrentModuleObject,             // Object Type
    4737              :                                                      thisDXCoil.Name,                 // Object Name
    4738           34 :                                                      cAlphaFields(13 + (I - 1) * 6)); // Field Name
    4739              : 
    4740           34 :                 if (!ErrorsFound) {
    4741           34 :                     if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(I))->numDims == 1) {
    4742            8 :                         checkCurveIsNormalizedToOne(state,
    4743           24 :                                                     std::string{RoutineName} + CurrentModuleObject,
    4744            8 :                                                     thisDXCoil.Name,
    4745            8 :                                                     thisDXCoil.MSEIRFTemp(I),
    4746            8 :                                                     cAlphaFields(13 + (I - 1) * 6),
    4747            8 :                                                     Alphas(13 + (I - 1) * 6),
    4748              :                                                     RatedOutdoorAirTempHeat);
    4749              :                     } else {
    4750           26 :                         checkCurveIsNormalizedToOne(state,
    4751           78 :                                                     std::string{RoutineName} + CurrentModuleObject,
    4752           26 :                                                     thisDXCoil.Name,
    4753           26 :                                                     thisDXCoil.MSEIRFTemp(I),
    4754           26 :                                                     cAlphaFields(13 + (I - 1) * 6),
    4755           26 :                                                     Alphas(13 + (I - 1) * 6),
    4756              :                                                     RatedInletAirTempHeat,
    4757              :                                                     RatedOutdoorAirTempHeat);
    4758              :                     }
    4759              :                 }
    4760              :             }
    4761              : 
    4762           34 :             thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
    4763           34 :             if (thisDXCoil.MSEIRFFlow(I) == 0) {
    4764            0 :                 if (lAlphaBlanks(14 + (I - 1) * 6)) {
    4765            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4766            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(14 + (I - 1) * 6)));
    4767              :                 } else {
    4768            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4769            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14 + (I - 1) * 6), Alphas(14 + (I - 1) * 6)));
    4770              :                 }
    4771            0 :                 ErrorsFound = true;
    4772              :             } else {
    4773              :                 // Verify Curve Object, only legal type is Quadratic
    4774          102 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4775           34 :                                                      thisDXCoil.MSEIRFFlow(I),        // Curve index
    4776              :                                                      {1},                             // Valid dimensions
    4777              :                                                      RoutineName,                     // Routine name
    4778              :                                                      CurrentModuleObject,             // Object Type
    4779              :                                                      thisDXCoil.Name,                 // Object Name
    4780           34 :                                                      cAlphaFields(14 + (I - 1) * 6)); // Field Name
    4781              : 
    4782           34 :                 if (!ErrorsFound) {
    4783           34 :                     checkCurveIsNormalizedToOne(state,
    4784          102 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4785           34 :                                                 thisDXCoil.Name,
    4786           34 :                                                 thisDXCoil.MSEIRFFlow(I),
    4787           34 :                                                 cAlphaFields(14 + (I - 1) * 6),
    4788           34 :                                                 Alphas(14 + (I - 1) * 6),
    4789              :                                                 1.0);
    4790              :                 }
    4791              :             }
    4792              : 
    4793           34 :             thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
    4794           34 :             if (thisDXCoil.MSPLFFPLR(I) == 0) {
    4795            0 :                 if (lAlphaBlanks(15 + (I - 1) * 6)) {
    4796            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4797            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(15 + (I - 1) * 6)));
    4798              :                 } else {
    4799            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4800            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
    4801              :                 }
    4802            0 :                 ErrorsFound = true;
    4803              :             } else {
    4804              :                 // Verify Curve Object, only legal types are Quadratic or Cubic
    4805          102 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4806           34 :                                                      thisDXCoil.MSPLFFPLR(I),         // Curve index
    4807              :                                                      {1},                             // Valid dimensions
    4808              :                                                      RoutineName,                     // Routine name
    4809              :                                                      CurrentModuleObject,             // Object Type
    4810              :                                                      thisDXCoil.Name,                 // Object Name
    4811           34 :                                                      cAlphaFields(15 + (I - 1) * 6)); // Field Name
    4812              : 
    4813           34 :                 if (!ErrorsFound) {
    4814              :                     //       Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    4815           34 :                     MinCurveVal = 999.0;
    4816           34 :                     MaxCurveVal = -999.0;
    4817           34 :                     CurveInput = 0.0;
    4818         3434 :                     while (CurveInput <= 1.0) {
    4819         3400 :                         CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
    4820         3400 :                         if (CurveVal < MinCurveVal) {
    4821           34 :                             MinCurveVal = CurveVal;
    4822           34 :                             MinCurvePLR = CurveInput;
    4823              :                         }
    4824         3400 :                         if (CurveVal > MaxCurveVal) {
    4825         2944 :                             MaxCurveVal = CurveVal;
    4826         2944 :                             MaxCurvePLR = CurveInput;
    4827              :                         }
    4828         3400 :                         CurveInput += 0.01;
    4829              :                     }
    4830           34 :                     if (MinCurveVal < 0.7) {
    4831            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4832            0 :                         ShowContinueError(state,
    4833            0 :                                           format("...{} = {} has out of range value.", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
    4834            0 :                         ShowContinueError(state,
    4835            0 :                                           format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    4836            0 :                         ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    4837            0 :                         Curve::SetCurveOutputMinValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 0.7);
    4838              :                     }
    4839              : 
    4840           34 :                     if (MaxCurveVal > 1.0) {
    4841            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4842            0 :                         ShowContinueError(state,
    4843            0 :                                           format("...{} = {} has out of range value.", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
    4844            0 :                         ShowContinueError(state,
    4845            0 :                                           format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    4846            0 :                         ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    4847            0 :                         Curve::SetCurveOutputMaxValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 1.0);
    4848              :                     }
    4849              :                 }
    4850              :             }
    4851              : 
    4852              :             // Read waste heat modifier curve name
    4853           34 :             thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
    4854           34 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
    4855           12 :                 if (thisDXCoil.MSWasteHeat(I) > 0) {
    4856              :                     // Verify Curve Object, only legal types are BiQuadratic
    4857           24 :                     ErrorsFound |= Curve::CheckCurveDims(state,
    4858            8 :                                                          thisDXCoil.MSWasteHeat(I),       // Curve index
    4859              :                                                          {2},                             // Valid dimensions
    4860              :                                                          RoutineName,                     // Routine name
    4861              :                                                          CurrentModuleObject,             // Object Type
    4862              :                                                          thisDXCoil.Name,                 // Object Name
    4863            8 :                                                          cAlphaFields(16 + (I - 1) * 6)); // Field Name
    4864              : 
    4865            8 :                     if (!ErrorsFound) {
    4866            8 :                         checkCurveIsNormalizedToOne(state,
    4867           24 :                                                     std::string{RoutineName} + CurrentModuleObject,
    4868            8 :                                                     thisDXCoil.Name,
    4869            8 :                                                     thisDXCoil.MSWasteHeat(I),
    4870            8 :                                                     cAlphaFields(16 + (I - 1) * 6),
    4871            8 :                                                     Alphas(16 + (I - 1) * 6),
    4872              :                                                     RatedOutdoorAirTempHeat,
    4873              :                                                     RatedInletAirTempHeat);
    4874              :                     }
    4875              :                 }
    4876              :             }
    4877              :         }
    4878              :         // A35; \field Zone Name for Condenser Placement
    4879           14 :         if (!lAlphaBlanks(35) && NumAlphas > 34) {
    4880            0 :             thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(35), state.dataHeatBal->Zone);
    4881            0 :             if (thisDXCoil.SecZonePtr > 0) {
    4882            0 :                 SetupZoneInternalGain(state,
    4883              :                                       thisDXCoil.SecZonePtr,
    4884              :                                       thisDXCoil.Name,
    4885              :                                       DataHeatBalance::IntGainType::SecHeatingDXCoilMultiSpeed,
    4886              :                                       &thisDXCoil.SecCoilSensibleHeatRemovalRate,
    4887              :                                       nullptr,
    4888              :                                       nullptr,
    4889              :                                       &thisDXCoil.SecCoilLatentHeatRemovalRate);
    4890            0 :                 thisDXCoil.IsSecondaryDXCoilInZone = true;
    4891              :             } else {
    4892            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4893            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(35), Alphas(35)));
    4894              :             }
    4895              :         }
    4896           14 :         if (thisDXCoil.SecZonePtr > 0) {
    4897            0 :             for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
    4898            0 :                 thisDXCoil.MSSecCoilAirFlow(I) = Numbers(34 + (I - 1) * 3);
    4899            0 :                 thisDXCoil.MSSecCoilAirFlowScalingFactor(I) = Numbers(35 + (I - 1) * 3);
    4900            0 :                 thisDXCoil.MSSecCoilRatedSHR(I) = Numbers(36 + (I - 1) * 3);
    4901              :                 // Read SHR modifier curve function of temperature
    4902            0 :                 if (!lAlphaBlanks(36 + (I - 1) * 2)) {
    4903            0 :                     thisDXCoil.MSSecCoilSHRFT(I) = GetCurveIndex(state, Alphas(36 + (I - 1) * 2)); // convert curve name to number
    4904            0 :                     if (thisDXCoil.MSSecCoilSHRFT(I) == 0) {
    4905            0 :                         ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4906            0 :                         ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(36 + (I - 1) * 2), Alphas(36 + (I - 1) * 2)));
    4907              :                     }
    4908              :                 }
    4909              :                 // Read SHR modifier curve function of flow fraction
    4910            0 :                 if (!lAlphaBlanks(36 + (I - 1) * 2)) {
    4911            0 :                     thisDXCoil.MSSecCoilSHRFF(I) = GetCurveIndex(state, Alphas(36 + (I - 1) * 2)); // convert curve name to number
    4912            0 :                     if (thisDXCoil.MSSecCoilSHRFF(I) == 0) {
    4913            0 :                         ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4914            0 :                         ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(36 + (I - 1) * 2), Alphas(36 + (I - 1) * 2)));
    4915              :                     }
    4916              :                 }
    4917              :             }
    4918              :         }
    4919              :     }
    4920              : 
    4921              :     // Loop over the VRF Cooling Coils and get & load the data
    4922          134 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling);
    4923          158 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingCoils; ++DXCoilIndex) {
    4924              : 
    4925           24 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    4926              :                                                                  CurrentModuleObject,
    4927              :                                                                  DXCoilIndex,
    4928              :                                                                  Alphas,
    4929              :                                                                  NumAlphas,
    4930              :                                                                  Numbers,
    4931              :                                                                  NumNumbers,
    4932              :                                                                  IOStatus,
    4933              :                                                                  lNumericBlanks,
    4934              :                                                                  lAlphaBlanks,
    4935              :                                                                  cAlphaFields,
    4936              :                                                                  cNumericFields);
    4937              : 
    4938           24 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    4939              : 
    4940           24 :         ++DXCoilNum;
    4941              : 
    4942              :         // allocate single performance mode for numeric field strings used for sizing routine
    4943           24 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    4944           24 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    4945           24 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    4946              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    4947           24 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    4948              : 
    4949           24 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    4950           24 :         thisDXCoil.Name = Alphas(1);
    4951           24 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    4952           24 :         thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Cooling;
    4953              : 
    4954           24 :         if (lAlphaBlanks(2)) {
    4955            2 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    4956           22 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    4957            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    4958            0 :             ErrorsFound = true;
    4959              :         }
    4960           24 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    4961           24 :         thisDXCoil.RatedSHR(1) = Numbers(2);
    4962           24 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
    4963              : 
    4964           24 :         thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(3));
    4965              :         // Verify Curve Object, only legal type is Linear, Quadratic, Cubic, or BiQuadratic
    4966           72 :         ErrorsFound |= Curve::CheckCurveDims(state,
    4967           24 :                                              thisDXCoil.CCapFTemp(1), // Curve index
    4968              :                                              {1, 2},                  // Valid dimensions  // MULTIPLECURVEDIMS
    4969              :                                              RoutineName,             // Routine name
    4970              :                                              CurrentModuleObject,     // Object Type
    4971              :                                              thisDXCoil.Name,         // Object Name
    4972           24 :                                              cAlphaFields(3));        // Field Name
    4973              : 
    4974           24 :         if (!ErrorsFound) {
    4975           24 :             if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
    4976           23 :                 checkCurveIsNormalizedToOne(state,
    4977           69 :                                             std::string{RoutineName} + CurrentModuleObject,
    4978           23 :                                             thisDXCoil.Name,
    4979           23 :                                             thisDXCoil.CCapFTemp(1),
    4980           23 :                                             cAlphaFields(3),
    4981           23 :                                             Alphas(3),
    4982              :                                             RatedInletWetBulbTemp);
    4983              :             } else {
    4984            1 :                 checkCurveIsNormalizedToOne(state,
    4985            3 :                                             std::string{RoutineName} + CurrentModuleObject,
    4986            1 :                                             thisDXCoil.Name,
    4987            1 :                                             thisDXCoil.CCapFTemp(1),
    4988            1 :                                             cAlphaFields(3),
    4989            1 :                                             Alphas(3),
    4990              :                                             RatedInletWetBulbTemp,
    4991              :                                             RatedOutdoorAirTemp);
    4992              :             }
    4993              :         }
    4994              : 
    4995           24 :         thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(4)); // convert curve name to number
    4996           24 :         if (thisDXCoil.CCapFFlow(1) == 0) {
    4997            0 :             if (lAlphaBlanks(4)) {
    4998            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4999            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(4)));
    5000              :             } else {
    5001            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5002            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(4), Alphas(4)));
    5003              :             }
    5004            0 :             ErrorsFound = true;
    5005              :         } else {
    5006              :             // Verify Curve Object, only legal type is Linear, Quadratic or Cubic
    5007           72 :             ErrorsFound |= Curve::CheckCurveDims(state,
    5008           24 :                                                  thisDXCoil.CCapFFlow(1), // Curve index
    5009              :                                                  {1},                     // Valid dimensions
    5010              :                                                  RoutineName,             // Routine name
    5011              :                                                  CurrentModuleObject,     // Object Type
    5012              :                                                  thisDXCoil.Name,         // Object Name
    5013           24 :                                                  cAlphaFields(4));        // Field Name
    5014              : 
    5015           24 :             if (!ErrorsFound) {
    5016           24 :                 checkCurveIsNormalizedToOne(
    5017           96 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(4), Alphas(4), 1.0);
    5018              :             }
    5019              :         }
    5020              : 
    5021           24 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    5022           24 :                                                  Alphas(5),
    5023              :                                                  ErrorsFound,
    5024              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
    5025           24 :                                                  Alphas(1),
    5026              :                                                  DataLoopNode::NodeFluidType::Air,
    5027              :                                                  DataLoopNode::ConnectionType::Inlet,
    5028              :                                                  NodeInputManager::CompFluidStream::Primary,
    5029              :                                                  ObjectIsNotParent);
    5030              : 
    5031           48 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    5032           24 :                                                   Alphas(6),
    5033              :                                                   ErrorsFound,
    5034              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
    5035           24 :                                                   Alphas(1),
    5036              :                                                   DataLoopNode::NodeFluidType::Air,
    5037              :                                                   DataLoopNode::ConnectionType::Outlet,
    5038              :                                                   NodeInputManager::CompFluidStream::Primary,
    5039              :                                                   ObjectIsNotParent);
    5040              : 
    5041           24 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(5), Alphas(6), "Air Nodes");
    5042              : 
    5043           24 :         thisDXCoil.CondensateCollectName = Alphas(7);
    5044           24 :         if (lAlphaBlanks(7)) {
    5045           24 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    5046              :         } else {
    5047            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    5048            0 :             SetupTankSupplyComponent(state,
    5049              :                                      thisDXCoil.Name,
    5050              :                                      CurrentModuleObject,
    5051              :                                      thisDXCoil.CondensateCollectName,
    5052              :                                      ErrorsFound,
    5053            0 :                                      thisDXCoil.CondensateTankID,
    5054            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    5055              :         }
    5056              :     }
    5057              : 
    5058          134 :     if (ErrorsFound) {
    5059            0 :         ShowFatalError(state,
    5060            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    5061              :     }
    5062              : 
    5063              :     // Loop over the VRF Heating Coils and get & load the data
    5064          134 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating);
    5065          157 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingCoils; ++DXCoilIndex) {
    5066              : 
    5067           23 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    5068              :                                                                  CurrentModuleObject,
    5069              :                                                                  DXCoilIndex,
    5070              :                                                                  Alphas,
    5071              :                                                                  NumAlphas,
    5072              :                                                                  Numbers,
    5073              :                                                                  NumNumbers,
    5074              :                                                                  IOStatus,
    5075              :                                                                  lNumericBlanks,
    5076              :                                                                  lAlphaBlanks,
    5077              :                                                                  cAlphaFields,
    5078              :                                                                  cNumericFields);
    5079              : 
    5080           23 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    5081           23 :         ++DXCoilNum;
    5082              : 
    5083              :         // allocate single performance mode for numeric field strings used for sizing routine
    5084           23 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    5085           23 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    5086           23 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    5087              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    5088           23 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    5089              : 
    5090           23 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    5091           23 :         thisDXCoil.Name = Alphas(1);
    5092           23 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    5093           23 :         thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Heating;
    5094           23 :         if (lAlphaBlanks(2)) {
    5095            2 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    5096           21 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    5097            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    5098            0 :             ErrorsFound = true;
    5099              :         }
    5100           23 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    5101           23 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(2);
    5102              : 
    5103           23 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    5104           23 :                                                  Alphas(3),
    5105              :                                                  ErrorsFound,
    5106              :                                                  DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
    5107           23 :                                                  Alphas(1),
    5108              :                                                  DataLoopNode::NodeFluidType::Air,
    5109              :                                                  DataLoopNode::ConnectionType::Inlet,
    5110              :                                                  NodeInputManager::CompFluidStream::Primary,
    5111              :                                                  ObjectIsNotParent);
    5112              : 
    5113           46 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    5114           23 :                                                   Alphas(4),
    5115              :                                                   ErrorsFound,
    5116              :                                                   DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
    5117           23 :                                                   Alphas(1),
    5118              :                                                   DataLoopNode::NodeFluidType::Air,
    5119              :                                                   DataLoopNode::ConnectionType::Outlet,
    5120              :                                                   NodeInputManager::CompFluidStream::Primary,
    5121              :                                                   ObjectIsNotParent);
    5122              : 
    5123           23 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    5124              : 
    5125           23 :         thisDXCoil.CCapFTemp = GetCurveIndex(state, Alphas(5));
    5126           23 :         if (thisDXCoil.CCapFTemp(1) == 0) {
    5127            0 :             if (lAlphaBlanks(5)) {
    5128            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5129            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
    5130              :             } else {
    5131            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5132            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
    5133              :             }
    5134            0 :             ErrorsFound = true;
    5135              :         } else {
    5136           69 :             ErrorsFound |= Curve::CheckCurveDims(state,
    5137           23 :                                                  thisDXCoil.CCapFTemp(1), // Curve index
    5138              :                                                  {1, 2},                  // Valid dimensions  // MULTIPLECURVEDIMS
    5139              :                                                  RoutineName,             // Routine name
    5140              :                                                  CurrentModuleObject,     // Object Type
    5141              :                                                  thisDXCoil.Name,         // Object Name
    5142           23 :                                                  cAlphaFields(5));        // Field Name
    5143              : 
    5144           23 :             if (!ErrorsFound) {
    5145           23 :                 if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
    5146           23 :                     checkCurveIsNormalizedToOne(state,
    5147           69 :                                                 std::string{RoutineName} + CurrentModuleObject,
    5148           23 :                                                 thisDXCoil.Name,
    5149           23 :                                                 thisDXCoil.CCapFTemp(1),
    5150           23 :                                                 cAlphaFields(5),
    5151           23 :                                                 Alphas(5),
    5152              :                                                 RatedInletAirTempHeat);
    5153              :                 } else {
    5154              :                     // Can't check this here, don't know if using outdoor dry-bulb or outdoor wet-bulb temp as input. Make this check in VRF TU
    5155              :                     // GetInput.
    5156              :                 }
    5157              :             }
    5158              :         }
    5159              : 
    5160           23 :         thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
    5161           23 :         if (thisDXCoil.CCapFFlow(1) == 0) {
    5162            0 :             if (lAlphaBlanks(6)) {
    5163            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5164            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
    5165              :             } else {
    5166            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5167            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
    5168              :             }
    5169            0 :             ErrorsFound = true;
    5170              :         } else {
    5171              :             // Verify Curve Object, only legal type is Quadratic
    5172           69 :             ErrorsFound |= Curve::CheckCurveDims(state,
    5173           23 :                                                  thisDXCoil.CCapFFlow(1), // Curve index
    5174              :                                                  {1},                     // Valid dimensions
    5175              :                                                  RoutineName,             // Routine name
    5176              :                                                  CurrentModuleObject,     // Object Type
    5177              :                                                  thisDXCoil.Name,         // Object Name
    5178           23 :                                                  cAlphaFields(6));        // Field Name
    5179              : 
    5180           23 :             if (!ErrorsFound) {
    5181           23 :                 checkCurveIsNormalizedToOne(
    5182           92 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
    5183              :             }
    5184              :         }
    5185              :     }
    5186              : 
    5187          134 :     if (ErrorsFound) {
    5188            0 :         ShowFatalError(state,
    5189            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    5190              :     }
    5191              : 
    5192              :     // Loop over the VRF Cooling Coils for VRF FluidTCtrl Model_zrp 2015
    5193          134 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling);
    5194          146 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils; ++DXCoilIndex) {
    5195              : 
    5196           12 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    5197              :                                                                  CurrentModuleObject,
    5198              :                                                                  DXCoilIndex,
    5199              :                                                                  Alphas,
    5200              :                                                                  NumAlphas,
    5201              :                                                                  Numbers,
    5202              :                                                                  NumNumbers,
    5203              :                                                                  IOStatus,
    5204              :                                                                  lNumericBlanks,
    5205              :                                                                  lAlphaBlanks,
    5206              :                                                                  cAlphaFields,
    5207              :                                                                  cNumericFields);
    5208              : 
    5209           12 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    5210           12 :         ++DXCoilNum;
    5211              : 
    5212              :         // allocate single performance mode for numeric field strings used for sizing routine
    5213           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    5214           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    5215           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    5216              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    5217           12 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    5218              : 
    5219           12 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    5220           12 :         thisDXCoil.Name = Alphas(1);
    5221           12 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    5222           12 :         thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Cooling;
    5223           12 :         if (lAlphaBlanks(2)) {
    5224            3 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    5225            9 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    5226            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    5227            0 :             ErrorsFound = true;
    5228              :         }
    5229              : 
    5230           12 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    5231           12 :                                                  Alphas(3),
    5232              :                                                  ErrorsFound,
    5233              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
    5234           12 :                                                  Alphas(1),
    5235              :                                                  DataLoopNode::NodeFluidType::Air,
    5236              :                                                  DataLoopNode::ConnectionType::Inlet,
    5237              :                                                  NodeInputManager::CompFluidStream::Primary,
    5238              :                                                  ObjectIsNotParent);
    5239           24 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    5240           12 :                                                   Alphas(4),
    5241              :                                                   ErrorsFound,
    5242              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
    5243           12 :                                                   Alphas(1),
    5244              :                                                   DataLoopNode::NodeFluidType::Air,
    5245              :                                                   DataLoopNode::ConnectionType::Outlet,
    5246              :                                                   NodeInputManager::CompFluidStream::Primary,
    5247              :                                                   ObjectIsNotParent);
    5248           12 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    5249              : 
    5250           12 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    5251           12 :         thisDXCoil.RatedSHR(1) = Numbers(2);
    5252           12 :         thisDXCoil.SH = Numbers(3);
    5253              :         // @@ DXCoil( DXCoilNum ).RateBFVRFIUEvap = 0.0592; there will be a new field for this, which will be handled in a separate issue to
    5254              :         // update VRF-HP idd. It is not handled here to avoid transition issues for VRF-HP.
    5255              : 
    5256           12 :         int indexSHCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
    5257              :         // Verify curve name and type
    5258           12 :         if (indexSHCurve == 0) {
    5259            0 :             if (lAlphaBlanks(5)) {
    5260            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5261            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
    5262              :             } else {
    5263            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5264            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
    5265              :             }
    5266            0 :             ErrorsFound = true;
    5267              :         } else {
    5268              :             {
    5269           12 :                 if (state.dataCurveManager->curves(indexSHCurve)->curveType == Curve::CurveType::Quadratic) {
    5270           12 :                     thisDXCoil.C1Te = state.dataCurveManager->curves(indexSHCurve)->coeff[0];
    5271           12 :                     thisDXCoil.C2Te = state.dataCurveManager->curves(indexSHCurve)->coeff[1];
    5272           12 :                     thisDXCoil.C3Te = state.dataCurveManager->curves(indexSHCurve)->coeff[2];
    5273              : 
    5274              :                 } else {
    5275            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5276            0 :                     ShowContinueError(state,
    5277            0 :                                       format("...illegal {} type for this object = {}",
    5278              :                                              cAlphaFields(5),
    5279            0 :                                              Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexSHCurve)->curveType)]));
    5280            0 :                     ShowContinueError(state, "... Curve type must be Quadratic.");
    5281            0 :                     ErrorsFound = true;
    5282              :                 }
    5283              :             }
    5284              :         }
    5285              : 
    5286           12 :         thisDXCoil.CondensateCollectName = Alphas(6);
    5287           12 :         if (lAlphaBlanks(6)) {
    5288           12 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    5289              :         } else {
    5290            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    5291            0 :             SetupTankSupplyComponent(state,
    5292              :                                      thisDXCoil.Name,
    5293              :                                      CurrentModuleObject,
    5294              :                                      thisDXCoil.CondensateCollectName,
    5295              :                                      ErrorsFound,
    5296            0 :                                      thisDXCoil.CondensateTankID,
    5297            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    5298              :         }
    5299              :     }
    5300              : 
    5301          134 :     if (ErrorsFound) {
    5302            0 :         ShowFatalError(state,
    5303            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    5304              :     }
    5305              : 
    5306              :     // Loop over the VRF Heating Coils for VRF FluidTCtrl Model_zrp 2015
    5307          134 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating);
    5308          145 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils; ++DXCoilIndex) {
    5309              : 
    5310           11 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    5311              :                                                                  CurrentModuleObject,
    5312              :                                                                  DXCoilIndex,
    5313              :                                                                  Alphas,
    5314              :                                                                  NumAlphas,
    5315              :                                                                  Numbers,
    5316              :                                                                  NumNumbers,
    5317              :                                                                  IOStatus,
    5318              :                                                                  lNumericBlanks,
    5319              :                                                                  lAlphaBlanks,
    5320              :                                                                  cAlphaFields,
    5321              :                                                                  cNumericFields);
    5322              : 
    5323           11 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    5324           11 :         ++DXCoilNum;
    5325              : 
    5326              :         // allocate single performance mode for numeric field strings used for sizing routine
    5327           11 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    5328           11 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    5329           11 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    5330              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    5331           11 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    5332              : 
    5333           11 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    5334           11 :         thisDXCoil.Name = Alphas(1);
    5335           11 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    5336           11 :         thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Heating;
    5337           11 :         if (lAlphaBlanks(2)) {
    5338            2 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    5339            9 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    5340            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    5341            0 :             ErrorsFound = true;
    5342              :         }
    5343              : 
    5344           11 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    5345           11 :                                                  Alphas(3),
    5346              :                                                  ErrorsFound,
    5347              :                                                  DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
    5348           11 :                                                  Alphas(1),
    5349              :                                                  DataLoopNode::NodeFluidType::Air,
    5350              :                                                  DataLoopNode::ConnectionType::Inlet,
    5351              :                                                  NodeInputManager::CompFluidStream::Primary,
    5352              :                                                  ObjectIsNotParent);
    5353           22 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    5354           11 :                                                   Alphas(4),
    5355              :                                                   ErrorsFound,
    5356              :                                                   DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
    5357           11 :                                                   Alphas(1),
    5358              :                                                   DataLoopNode::NodeFluidType::Air,
    5359              :                                                   DataLoopNode::ConnectionType::Outlet,
    5360              :                                                   NodeInputManager::CompFluidStream::Primary,
    5361              :                                                   ObjectIsNotParent);
    5362           11 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    5363              : 
    5364           11 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    5365           11 :         thisDXCoil.SC = Numbers(2);
    5366              :         //@@ DXCoil( DXCoilNum ).RateBFVRFIUCond = 0.136;
    5367              : 
    5368           11 :         int indexSCCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
    5369              :         // Verify curve name and type
    5370           11 :         if (indexSCCurve == 0) {
    5371            0 :             if (lAlphaBlanks(5)) {
    5372            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5373            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
    5374              :             } else {
    5375            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5376            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
    5377              :             }
    5378            0 :             ErrorsFound = true;
    5379              :         } else {
    5380              :             {
    5381           11 :                 if (state.dataCurveManager->curves(indexSCCurve)->curveType == Curve::CurveType::Quadratic) {
    5382           11 :                     thisDXCoil.C1Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[0];
    5383           11 :                     thisDXCoil.C2Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[1];
    5384           11 :                     thisDXCoil.C3Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[2];
    5385              : 
    5386              :                 } else {
    5387            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5388            0 :                     ShowContinueError(state,
    5389            0 :                                       format("...illegal {} type for this object = {}",
    5390              :                                              cAlphaFields(5),
    5391            0 :                                              Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexSCCurve)->curveType)]));
    5392            0 :                     ShowContinueError(state, "... Curve type must be Quadratic.");
    5393            0 :                     ErrorsFound = true;
    5394              :                 }
    5395              :             }
    5396              :         }
    5397              :     }
    5398              : 
    5399          134 :     if (ErrorsFound) {
    5400            0 :         ShowFatalError(state,
    5401            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    5402              :     }
    5403              : 
    5404          349 :     for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDXCoils; ++DXCoilNum) {
    5405              : 
    5406          215 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    5407              : 
    5408          215 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    5409              :             // Setup Report Variables for Cooling Equipment
    5410              :             // CurrentModuleObject='Coil:Cooling:DX:SingleSpeed/Coil:Cooling:DX:TwoStageWithHumidityControlMode'
    5411          128 :             SetupOutputVariable(state,
    5412              :                                 "Cooling Coil Total Cooling Rate",
    5413              :                                 Constant::Units::W,
    5414           64 :                                 thisDXCoil.TotalCoolingEnergyRate,
    5415              :                                 OutputProcessor::TimeStepType::System,
    5416              :                                 OutputProcessor::StoreType::Average,
    5417           64 :                                 thisDXCoil.Name);
    5418          128 :             SetupOutputVariable(state,
    5419              :                                 "Cooling Coil Total Cooling Energy",
    5420              :                                 Constant::Units::J,
    5421           64 :                                 thisDXCoil.TotalCoolingEnergy,
    5422              :                                 OutputProcessor::TimeStepType::System,
    5423              :                                 OutputProcessor::StoreType::Sum,
    5424           64 :                                 thisDXCoil.Name,
    5425              :                                 Constant::eResource::EnergyTransfer,
    5426              :                                 OutputProcessor::Group::HVAC,
    5427              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    5428          128 :             SetupOutputVariable(state,
    5429              :                                 "Cooling Coil Sensible Cooling Rate",
    5430              :                                 Constant::Units::W,
    5431           64 :                                 thisDXCoil.SensCoolingEnergyRate,
    5432              :                                 OutputProcessor::TimeStepType::System,
    5433              :                                 OutputProcessor::StoreType::Average,
    5434           64 :                                 thisDXCoil.Name);
    5435          128 :             SetupOutputVariable(state,
    5436              :                                 "Cooling Coil Sensible Cooling Energy",
    5437              :                                 Constant::Units::J,
    5438           64 :                                 thisDXCoil.SensCoolingEnergy,
    5439              :                                 OutputProcessor::TimeStepType::System,
    5440              :                                 OutputProcessor::StoreType::Sum,
    5441           64 :                                 thisDXCoil.Name);
    5442          128 :             SetupOutputVariable(state,
    5443              :                                 "Cooling Coil Latent Cooling Rate",
    5444              :                                 Constant::Units::W,
    5445           64 :                                 thisDXCoil.LatCoolingEnergyRate,
    5446              :                                 OutputProcessor::TimeStepType::System,
    5447              :                                 OutputProcessor::StoreType::Average,
    5448           64 :                                 thisDXCoil.Name);
    5449          128 :             SetupOutputVariable(state,
    5450              :                                 "Cooling Coil Latent Cooling Energy",
    5451              :                                 Constant::Units::J,
    5452           64 :                                 thisDXCoil.LatCoolingEnergy,
    5453              :                                 OutputProcessor::TimeStepType::System,
    5454              :                                 OutputProcessor::StoreType::Sum,
    5455           64 :                                 thisDXCoil.Name);
    5456          128 :             SetupOutputVariable(state,
    5457              :                                 "Cooling Coil Electricity Rate",
    5458              :                                 Constant::Units::W,
    5459           64 :                                 thisDXCoil.ElecCoolingPower,
    5460              :                                 OutputProcessor::TimeStepType::System,
    5461              :                                 OutputProcessor::StoreType::Average,
    5462           64 :                                 thisDXCoil.Name);
    5463          128 :             SetupOutputVariable(state,
    5464              :                                 "Cooling Coil Electricity Energy",
    5465              :                                 Constant::Units::J,
    5466           64 :                                 thisDXCoil.ElecCoolingConsumption,
    5467              :                                 OutputProcessor::TimeStepType::System,
    5468              :                                 OutputProcessor::StoreType::Sum,
    5469           64 :                                 thisDXCoil.Name,
    5470              :                                 Constant::eResource::Electricity,
    5471              :                                 OutputProcessor::Group::HVAC,
    5472              :                                 OutputProcessor::EndUseCat::Cooling);
    5473          128 :             SetupOutputVariable(state,
    5474              :                                 "Cooling Coil Runtime Fraction",
    5475              :                                 Constant::Units::None,
    5476           64 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    5477              :                                 OutputProcessor::TimeStepType::System,
    5478              :                                 OutputProcessor::StoreType::Average,
    5479           64 :                                 thisDXCoil.Name);
    5480           64 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
    5481            0 :                 SetupOutputVariable(state,
    5482              :                                     "Secondary Coil Heat Rejection Rate",
    5483              :                                     Constant::Units::W,
    5484            0 :                                     thisDXCoil.SecCoilSensibleHeatGainRate,
    5485              :                                     OutputProcessor::TimeStepType::System,
    5486              :                                     OutputProcessor::StoreType::Average,
    5487            0 :                                     thisDXCoil.Name);
    5488              :             }
    5489              : 
    5490              :             // do we report these even if no storage tank?
    5491           64 :             if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
    5492            0 :                 SetupOutputVariable(state,
    5493              :                                     "Cooling Coil Condensate Volume Flow Rate",
    5494              :                                     Constant::Units::m3_s,
    5495            0 :                                     thisDXCoil.CondensateVdot,
    5496              :                                     OutputProcessor::TimeStepType::System,
    5497              :                                     OutputProcessor::StoreType::Average,
    5498            0 :                                     thisDXCoil.Name);
    5499            0 :                 SetupOutputVariable(state,
    5500              :                                     "Cooling Coil Condensate Volume",
    5501              :                                     Constant::Units::m3,
    5502            0 :                                     thisDXCoil.CondensateVol,
    5503              :                                     OutputProcessor::TimeStepType::System,
    5504              :                                     OutputProcessor::StoreType::Sum,
    5505            0 :                                     thisDXCoil.Name,
    5506              :                                     Constant::eResource::OnSiteWater,
    5507              :                                     OutputProcessor::Group::HVAC,
    5508              :                                     OutputProcessor::EndUseCat::Condensate);
    5509              :             }
    5510              : 
    5511           64 :             if (thisDXCoil.ReportEvapCondVars) {
    5512           28 :                 SetupOutputVariable(state,
    5513              :                                     "Cooling Coil Condenser Inlet Temperature",
    5514              :                                     Constant::Units::C,
    5515           14 :                                     thisDXCoil.CondInletTemp,
    5516              :                                     OutputProcessor::TimeStepType::System,
    5517              :                                     OutputProcessor::StoreType::Average,
    5518           14 :                                     thisDXCoil.Name);
    5519           28 :                 SetupOutputVariable(state,
    5520              :                                     "Cooling Coil Evaporative Condenser Water Volume",
    5521              :                                     Constant::Units::m3,
    5522           14 :                                     thisDXCoil.EvapWaterConsump,
    5523              :                                     OutputProcessor::TimeStepType::System,
    5524              :                                     OutputProcessor::StoreType::Sum,
    5525           14 :                                     thisDXCoil.Name,
    5526              :                                     Constant::eResource::Water,
    5527              :                                     OutputProcessor::Group::HVAC,
    5528              :                                     OutputProcessor::EndUseCat::Cooling);
    5529           28 :                 SetupOutputVariable(state,
    5530              :                                     "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
    5531              :                                     Constant::Units::m3,
    5532           14 :                                     thisDXCoil.EvapWaterConsump,
    5533              :                                     OutputProcessor::TimeStepType::System,
    5534              :                                     OutputProcessor::StoreType::Sum,
    5535           14 :                                     thisDXCoil.Name,
    5536              :                                     Constant::eResource::MainsWater,
    5537              :                                     OutputProcessor::Group::HVAC,
    5538              :                                     OutputProcessor::EndUseCat::Cooling);
    5539           28 :                 SetupOutputVariable(state,
    5540              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Rate",
    5541              :                                     Constant::Units::W,
    5542           14 :                                     thisDXCoil.EvapCondPumpElecPower,
    5543              :                                     OutputProcessor::TimeStepType::System,
    5544              :                                     OutputProcessor::StoreType::Average,
    5545           14 :                                     thisDXCoil.Name);
    5546           28 :                 SetupOutputVariable(state,
    5547              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Energy",
    5548              :                                     Constant::Units::J,
    5549           14 :                                     thisDXCoil.EvapCondPumpElecConsumption,
    5550              :                                     OutputProcessor::TimeStepType::System,
    5551              :                                     OutputProcessor::StoreType::Sum,
    5552           14 :                                     thisDXCoil.Name,
    5553              :                                     Constant::eResource::Electricity,
    5554              :                                     OutputProcessor::Group::HVAC,
    5555              :                                     OutputProcessor::EndUseCat::Cooling);
    5556           14 :                 if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    5557            6 :                     SetupOutputVariable(state,
    5558              :                                         "Cooling Coil Basin Heater Electricity Rate",
    5559              :                                         Constant::Units::W,
    5560            3 :                                         thisDXCoil.BasinHeaterPower,
    5561              :                                         OutputProcessor::TimeStepType::System,
    5562              :                                         OutputProcessor::StoreType::Average,
    5563            3 :                                         thisDXCoil.Name);
    5564            6 :                     SetupOutputVariable(state,
    5565              :                                         "Cooling Coil Basin Heater Electricity Energy",
    5566              :                                         Constant::Units::J,
    5567            3 :                                         thisDXCoil.BasinHeaterConsumption,
    5568              :                                         OutputProcessor::TimeStepType::System,
    5569              :                                         OutputProcessor::StoreType::Sum,
    5570            3 :                                         thisDXCoil.Name,
    5571              :                                         Constant::eResource::Electricity,
    5572              :                                         OutputProcessor::Group::HVAC,
    5573              :                                         OutputProcessor::EndUseCat::Cooling);
    5574              :                 }
    5575              :             }
    5576              : 
    5577           64 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    5578              :                 // Setup Report Variables for Cooling Equipment
    5579              :                 // CurrentModuleObject='Cooling:DX:TwoStageWithHumidityControlMode'
    5580            4 :                 SetupOutputVariable(state,
    5581              :                                     "Cooling Coil Stage 2 Runtime Fraction",
    5582              :                                     Constant::Units::None,
    5583            2 :                                     thisDXCoil.CoolingCoilStg2RuntimeFrac,
    5584              :                                     OutputProcessor::TimeStepType::System,
    5585              :                                     OutputProcessor::StoreType::Average,
    5586            2 :                                     thisDXCoil.Name);
    5587            2 :                 SetupOutputVariable(state,
    5588              :                                     "Cooling Coil Dehumidification Mode",
    5589              :                                     Constant::Units::None,
    5590            2 :                                     (int &)thisDXCoil.DehumidificationMode,
    5591              :                                     OutputProcessor::TimeStepType::System,
    5592              :                                     OutputProcessor::StoreType::Average,
    5593            2 :                                     thisDXCoil.Name);
    5594              :             }
    5595              : 
    5596              :         }
    5597              : 
    5598          151 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
    5599              :             // Setup Report Variables for Heating Equipment
    5600              :             // CurrentModuleObject='Coil:Heating:DX:SingleSpeed'
    5601           24 :             SetupOutputVariable(state,
    5602              :                                 "Heating Coil Heating Rate",
    5603              :                                 Constant::Units::W,
    5604           12 :                                 thisDXCoil.TotalHeatingEnergyRate,
    5605              :                                 OutputProcessor::TimeStepType::System,
    5606              :                                 OutputProcessor::StoreType::Average,
    5607           12 :                                 thisDXCoil.Name);
    5608           24 :             SetupOutputVariable(state,
    5609              :                                 "Heating Coil Heating Energy",
    5610              :                                 Constant::Units::J,
    5611           12 :                                 thisDXCoil.TotalHeatingEnergy,
    5612              :                                 OutputProcessor::TimeStepType::System,
    5613              :                                 OutputProcessor::StoreType::Sum,
    5614           12 :                                 thisDXCoil.Name,
    5615              :                                 Constant::eResource::EnergyTransfer,
    5616              :                                 OutputProcessor::Group::HVAC,
    5617              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    5618           24 :             SetupOutputVariable(state,
    5619              :                                 "Heating Coil Electricity Rate",
    5620              :                                 Constant::Units::W,
    5621           12 :                                 thisDXCoil.ElecHeatingPower,
    5622              :                                 OutputProcessor::TimeStepType::System,
    5623              :                                 OutputProcessor::StoreType::Average,
    5624           12 :                                 thisDXCoil.Name);
    5625           24 :             SetupOutputVariable(state,
    5626              :                                 "Heating Coil Electricity Energy",
    5627              :                                 Constant::Units::J,
    5628           12 :                                 thisDXCoil.ElecHeatingConsumption,
    5629              :                                 OutputProcessor::TimeStepType::System,
    5630              :                                 OutputProcessor::StoreType::Sum,
    5631           12 :                                 thisDXCoil.Name,
    5632              :                                 Constant::eResource::Electricity,
    5633              :                                 OutputProcessor::Group::HVAC,
    5634              :                                 OutputProcessor::EndUseCat::Heating);
    5635           24 :             SetupOutputVariable(state,
    5636              :                                 "Heating Coil Defrost Electricity Rate",
    5637              :                                 Constant::Units::W,
    5638           12 :                                 thisDXCoil.DefrostPower,
    5639              :                                 OutputProcessor::TimeStepType::System,
    5640              :                                 OutputProcessor::StoreType::Average,
    5641           12 :                                 thisDXCoil.Name);
    5642           24 :             SetupOutputVariable(state,
    5643              :                                 "Heating Coil Defrost Electricity Energy",
    5644              :                                 Constant::Units::J,
    5645           12 :                                 thisDXCoil.DefrostConsumption,
    5646              :                                 OutputProcessor::TimeStepType::System,
    5647              :                                 OutputProcessor::StoreType::Sum,
    5648           12 :                                 thisDXCoil.Name,
    5649              :                                 Constant::eResource::Electricity,
    5650              :                                 OutputProcessor::Group::HVAC,
    5651              :                                 OutputProcessor::EndUseCat::Heating);
    5652           24 :             SetupOutputVariable(state,
    5653              :                                 "Heating Coil Crankcase Heater Electricity Rate",
    5654              :                                 Constant::Units::W,
    5655           12 :                                 thisDXCoil.CrankcaseHeaterPower,
    5656              :                                 OutputProcessor::TimeStepType::System,
    5657              :                                 OutputProcessor::StoreType::Average,
    5658           12 :                                 thisDXCoil.Name);
    5659           24 :             SetupOutputVariable(state,
    5660              :                                 "Heating Coil Crankcase Heater Electricity Energy",
    5661              :                                 Constant::Units::J,
    5662           12 :                                 thisDXCoil.CrankcaseHeaterConsumption,
    5663              :                                 OutputProcessor::TimeStepType::System,
    5664              :                                 OutputProcessor::StoreType::Sum,
    5665           12 :                                 thisDXCoil.Name,
    5666              :                                 Constant::eResource::Electricity,
    5667              :                                 OutputProcessor::Group::HVAC,
    5668              :                                 OutputProcessor::EndUseCat::Heating);
    5669           24 :             SetupOutputVariable(state,
    5670              :                                 "Heating Coil Runtime Fraction",
    5671              :                                 Constant::Units::None,
    5672           12 :                                 thisDXCoil.HeatingCoilRuntimeFraction,
    5673              :                                 OutputProcessor::TimeStepType::System,
    5674              :                                 OutputProcessor::StoreType::Average,
    5675           12 :                                 thisDXCoil.Name);
    5676           12 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
    5677            0 :                 SetupOutputVariable(state,
    5678              :                                     "Secondary Coil Total Heat Removal Rate",
    5679              :                                     Constant::Units::W,
    5680            0 :                                     thisDXCoil.SecCoilTotalHeatRemovalRate,
    5681              :                                     OutputProcessor::TimeStepType::System,
    5682              :                                     OutputProcessor::StoreType::Average,
    5683            0 :                                     thisDXCoil.Name);
    5684            0 :                 SetupOutputVariable(state,
    5685              :                                     "Secondary Coil Sensible Heat Removal Rate",
    5686              :                                     Constant::Units::W,
    5687            0 :                                     thisDXCoil.SecCoilSensibleHeatRemovalRate,
    5688              :                                     OutputProcessor::TimeStepType::System,
    5689              :                                     OutputProcessor::StoreType::Average,
    5690            0 :                                     thisDXCoil.Name);
    5691            0 :                 SetupOutputVariable(state,
    5692              :                                     "Secondary Coil Latent Heat Removal Rate",
    5693              :                                     Constant::Units::W,
    5694            0 :                                     thisDXCoil.SecCoilLatentHeatRemovalRate,
    5695              :                                     OutputProcessor::TimeStepType::System,
    5696              :                                     OutputProcessor::StoreType::Average,
    5697            0 :                                     thisDXCoil.Name);
    5698            0 :                 SetupOutputVariable(state,
    5699              :                                     "Secondary Coil Sensible Heat Ratio",
    5700              :                                     Constant::Units::None,
    5701            0 :                                     thisDXCoil.SecCoilSHR,
    5702              :                                     OutputProcessor::TimeStepType::System,
    5703              :                                     OutputProcessor::StoreType::Average,
    5704            0 :                                     thisDXCoil.Name);
    5705            0 :                 SetupOutputVariable(state,
    5706              :                                     "Secondary Coil Compressor Part Load Ratio",
    5707              :                                     Constant::Units::None,
    5708            0 :                                     thisDXCoil.CompressorPartLoadRatio,
    5709              :                                     OutputProcessor::TimeStepType::System,
    5710              :                                     OutputProcessor::StoreType::Average,
    5711            0 :                                     thisDXCoil.Name);
    5712              :             }
    5713           12 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    5714            0 :                 SetupEMSActuator(state,
    5715              :                                  thisDXCoil.DXCoilType,
    5716              :                                  thisDXCoil.Name,
    5717              :                                  "Frost Heating Capacity Multiplier",
    5718              :                                  "[]",
    5719            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
    5720            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
    5721              : 
    5722            0 :                 SetupEMSActuator(state,
    5723              :                                  thisDXCoil.DXCoilType,
    5724              :                                  thisDXCoil.Name,
    5725              :                                  "Frost Heating Input Power Multiplier",
    5726              :                                  "[]",
    5727            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
    5728            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
    5729              :             }
    5730              :         }
    5731              : 
    5732          139 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    5733              :             // Setup Report Variables for Cooling Equipment
    5734              :             // CurrentModuleObject='Coil:Cooling:DX:TwoSpeed'
    5735           24 :             SetupOutputVariable(state,
    5736              :                                 "Cooling Coil Total Cooling Rate",
    5737              :                                 Constant::Units::W,
    5738           12 :                                 thisDXCoil.TotalCoolingEnergyRate,
    5739              :                                 OutputProcessor::TimeStepType::System,
    5740              :                                 OutputProcessor::StoreType::Average,
    5741           12 :                                 thisDXCoil.Name);
    5742           24 :             SetupOutputVariable(state,
    5743              :                                 "Cooling Coil Total Cooling Energy",
    5744              :                                 Constant::Units::J,
    5745           12 :                                 thisDXCoil.TotalCoolingEnergy,
    5746              :                                 OutputProcessor::TimeStepType::System,
    5747              :                                 OutputProcessor::StoreType::Sum,
    5748           12 :                                 thisDXCoil.Name,
    5749              :                                 Constant::eResource::EnergyTransfer,
    5750              :                                 OutputProcessor::Group::HVAC,
    5751              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    5752           24 :             SetupOutputVariable(state,
    5753              :                                 "Cooling Coil Sensible Cooling Rate",
    5754              :                                 Constant::Units::W,
    5755           12 :                                 thisDXCoil.SensCoolingEnergyRate,
    5756              :                                 OutputProcessor::TimeStepType::System,
    5757              :                                 OutputProcessor::StoreType::Average,
    5758           12 :                                 thisDXCoil.Name);
    5759           24 :             SetupOutputVariable(state,
    5760              :                                 "Cooling Coil Sensible Cooling Energy",
    5761              :                                 Constant::Units::J,
    5762           12 :                                 thisDXCoil.SensCoolingEnergy,
    5763              :                                 OutputProcessor::TimeStepType::System,
    5764              :                                 OutputProcessor::StoreType::Sum,
    5765           12 :                                 thisDXCoil.Name);
    5766           24 :             SetupOutputVariable(state,
    5767              :                                 "Cooling Coil Latent Cooling Rate",
    5768              :                                 Constant::Units::W,
    5769           12 :                                 thisDXCoil.LatCoolingEnergyRate,
    5770              :                                 OutputProcessor::TimeStepType::System,
    5771              :                                 OutputProcessor::StoreType::Average,
    5772           12 :                                 thisDXCoil.Name);
    5773           24 :             SetupOutputVariable(state,
    5774              :                                 "Cooling Coil Latent Cooling Energy",
    5775              :                                 Constant::Units::J,
    5776           12 :                                 thisDXCoil.LatCoolingEnergy,
    5777              :                                 OutputProcessor::TimeStepType::System,
    5778              :                                 OutputProcessor::StoreType::Sum,
    5779           12 :                                 thisDXCoil.Name);
    5780           24 :             SetupOutputVariable(state,
    5781              :                                 "Cooling Coil Electricity Rate",
    5782              :                                 Constant::Units::W,
    5783           12 :                                 thisDXCoil.ElecCoolingPower,
    5784              :                                 OutputProcessor::TimeStepType::System,
    5785              :                                 OutputProcessor::StoreType::Average,
    5786           12 :                                 thisDXCoil.Name);
    5787           24 :             SetupOutputVariable(state,
    5788              :                                 "Cooling Coil Electricity Energy",
    5789              :                                 Constant::Units::J,
    5790           12 :                                 thisDXCoil.ElecCoolingConsumption,
    5791              :                                 OutputProcessor::TimeStepType::System,
    5792              :                                 OutputProcessor::StoreType::Sum,
    5793           12 :                                 thisDXCoil.Name,
    5794              :                                 Constant::eResource::Electricity,
    5795              :                                 OutputProcessor::Group::HVAC,
    5796              :                                 OutputProcessor::EndUseCat::Cooling);
    5797           24 :             SetupOutputVariable(state,
    5798              :                                 "Cooling Coil Runtime Fraction",
    5799              :                                 Constant::Units::None,
    5800           12 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    5801              :                                 OutputProcessor::TimeStepType::System,
    5802              :                                 OutputProcessor::StoreType::Average,
    5803           12 :                                 thisDXCoil.Name);
    5804           12 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
    5805            0 :                 SetupOutputVariable(state,
    5806              :                                     "Secondary Coil Heat Rejection Rate",
    5807              :                                     Constant::Units::W,
    5808            0 :                                     thisDXCoil.SecCoilSensibleHeatGainRate,
    5809              :                                     OutputProcessor::TimeStepType::System,
    5810              :                                     OutputProcessor::StoreType::Average,
    5811            0 :                                     thisDXCoil.Name);
    5812              :             }
    5813              : 
    5814           12 :             if (thisDXCoil.ReportEvapCondVars) {
    5815            4 :                 SetupOutputVariable(state,
    5816              :                                     "Cooling Coil Condenser Inlet Temperature",
    5817              :                                     Constant::Units::C,
    5818            2 :                                     thisDXCoil.CondInletTemp,
    5819              :                                     OutputProcessor::TimeStepType::System,
    5820              :                                     OutputProcessor::StoreType::Average,
    5821            2 :                                     thisDXCoil.Name);
    5822            4 :                 SetupOutputVariable(state,
    5823              :                                     "Cooling Coil Evaporative Condenser Water Volume",
    5824              :                                     Constant::Units::m3,
    5825            2 :                                     thisDXCoil.EvapWaterConsump,
    5826              :                                     OutputProcessor::TimeStepType::System,
    5827              :                                     OutputProcessor::StoreType::Sum,
    5828            2 :                                     thisDXCoil.Name,
    5829              :                                     Constant::eResource::Water,
    5830              :                                     OutputProcessor::Group::HVAC,
    5831              :                                     OutputProcessor::EndUseCat::Cooling);
    5832            4 :                 SetupOutputVariable(state,
    5833              :                                     "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
    5834              :                                     Constant::Units::m3,
    5835            2 :                                     thisDXCoil.EvapWaterConsump,
    5836              :                                     OutputProcessor::TimeStepType::System,
    5837              :                                     OutputProcessor::StoreType::Sum,
    5838            2 :                                     thisDXCoil.Name,
    5839              :                                     Constant::eResource::MainsWater,
    5840              :                                     OutputProcessor::Group::HVAC,
    5841              :                                     OutputProcessor::EndUseCat::Cooling);
    5842            4 :                 SetupOutputVariable(state,
    5843              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Rate",
    5844              :                                     Constant::Units::W,
    5845            2 :                                     thisDXCoil.EvapCondPumpElecPower,
    5846              :                                     OutputProcessor::TimeStepType::System,
    5847              :                                     OutputProcessor::StoreType::Average,
    5848            2 :                                     thisDXCoil.Name);
    5849            4 :                 SetupOutputVariable(state,
    5850              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Energy",
    5851              :                                     Constant::Units::J,
    5852            2 :                                     thisDXCoil.EvapCondPumpElecConsumption,
    5853              :                                     OutputProcessor::TimeStepType::System,
    5854              :                                     OutputProcessor::StoreType::Sum,
    5855            2 :                                     thisDXCoil.Name,
    5856              :                                     Constant::eResource::Electricity,
    5857              :                                     OutputProcessor::Group::HVAC,
    5858              :                                     OutputProcessor::EndUseCat::Cooling);
    5859            2 :                 if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    5860            2 :                     SetupOutputVariable(state,
    5861              :                                         "Cooling Coil Basin Heater Electricity Rate",
    5862              :                                         Constant::Units::W,
    5863            1 :                                         thisDXCoil.BasinHeaterPower,
    5864              :                                         OutputProcessor::TimeStepType::System,
    5865              :                                         OutputProcessor::StoreType::Average,
    5866            1 :                                         thisDXCoil.Name);
    5867            2 :                     SetupOutputVariable(state,
    5868              :                                         "Cooling Coil Basin Heater Electricity Energy",
    5869              :                                         Constant::Units::J,
    5870            1 :                                         thisDXCoil.BasinHeaterConsumption,
    5871              :                                         OutputProcessor::TimeStepType::System,
    5872              :                                         OutputProcessor::StoreType::Sum,
    5873            1 :                                         thisDXCoil.Name,
    5874              :                                         Constant::eResource::Electricity,
    5875              :                                         OutputProcessor::Group::HVAC,
    5876              :                                         OutputProcessor::EndUseCat::Cooling);
    5877              :                 }
    5878              :             }
    5879              : 
    5880              :         }
    5881              : 
    5882          127 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    5883          118 :                  thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    5884              :             // Setup Report Variables for Cooling Equipment
    5885              :             // CurrentModuleObject='Coil:WaterHeating:AirToWaterHeatPump:Pumped'
    5886              :             // or 'Coil:WaterHeating:AirToWaterHeatPump:Wrapped'
    5887           32 :             SetupOutputVariable(state,
    5888              :                                 "Cooling Coil Total Cooling Rate",
    5889              :                                 Constant::Units::W,
    5890           16 :                                 thisDXCoil.TotalCoolingEnergyRate,
    5891              :                                 OutputProcessor::TimeStepType::System,
    5892              :                                 OutputProcessor::StoreType::Average,
    5893           16 :                                 thisDXCoil.Name);
    5894              : 
    5895           16 :             if (thisDXCoil.IsDXCoilInZone) {
    5896           32 :                 SetupOutputVariable(state,
    5897              :                                     "Cooling Coil Total Cooling Energy",
    5898              :                                     Constant::Units::J,
    5899           16 :                                     thisDXCoil.TotalCoolingEnergy,
    5900              :                                     OutputProcessor::TimeStepType::System,
    5901              :                                     OutputProcessor::StoreType::Sum,
    5902           16 :                                     thisDXCoil.Name,
    5903              :                                     Constant::eResource::EnergyTransfer,
    5904              :                                     OutputProcessor::Group::HVAC,
    5905              :                                     OutputProcessor::EndUseCat::CoolingCoils);
    5906              :             } else {
    5907            0 :                 SetupOutputVariable(state,
    5908              :                                     "Cooling Coil Total Cooling Energy",
    5909              :                                     Constant::Units::J,
    5910            0 :                                     thisDXCoil.TotalCoolingEnergy,
    5911              :                                     OutputProcessor::TimeStepType::System,
    5912              :                                     OutputProcessor::StoreType::Sum,
    5913            0 :                                     thisDXCoil.Name);
    5914              :             }
    5915              : 
    5916           32 :             SetupOutputVariable(state,
    5917              :                                 "Cooling Coil Sensible Cooling Rate",
    5918              :                                 Constant::Units::W,
    5919           16 :                                 thisDXCoil.SensCoolingEnergyRate,
    5920              :                                 OutputProcessor::TimeStepType::System,
    5921              :                                 OutputProcessor::StoreType::Average,
    5922           16 :                                 thisDXCoil.Name);
    5923           32 :             SetupOutputVariable(state,
    5924              :                                 "Cooling Coil Sensible Cooling Energy",
    5925              :                                 Constant::Units::J,
    5926           16 :                                 thisDXCoil.SensCoolingEnergy,
    5927              :                                 OutputProcessor::TimeStepType::System,
    5928              :                                 OutputProcessor::StoreType::Sum,
    5929           16 :                                 thisDXCoil.Name);
    5930           32 :             SetupOutputVariable(state,
    5931              :                                 "Cooling Coil Latent Cooling Rate",
    5932              :                                 Constant::Units::W,
    5933           16 :                                 thisDXCoil.LatCoolingEnergyRate,
    5934              :                                 OutputProcessor::TimeStepType::System,
    5935              :                                 OutputProcessor::StoreType::Average,
    5936           16 :                                 thisDXCoil.Name);
    5937           32 :             SetupOutputVariable(state,
    5938              :                                 "Cooling Coil Latent Cooling Energy",
    5939              :                                 Constant::Units::J,
    5940           16 :                                 thisDXCoil.LatCoolingEnergy,
    5941              :                                 OutputProcessor::TimeStepType::System,
    5942              :                                 OutputProcessor::StoreType::Sum,
    5943           16 :                                 thisDXCoil.Name);
    5944           32 :             SetupOutputVariable(state,
    5945              :                                 "Cooling Coil Runtime Fraction",
    5946              :                                 Constant::Units::None,
    5947           16 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    5948              :                                 OutputProcessor::TimeStepType::System,
    5949              :                                 OutputProcessor::StoreType::Average,
    5950           16 :                                 thisDXCoil.Name);
    5951              : 
    5952           16 :             if (thisDXCoil.ReportCoolingCoilCrankcasePower) {
    5953           32 :                 SetupOutputVariable(state,
    5954              :                                     "Cooling Coil Crankcase Heater Electricity Rate",
    5955              :                                     Constant::Units::W,
    5956           16 :                                     thisDXCoil.CrankcaseHeaterPower,
    5957              :                                     OutputProcessor::TimeStepType::System,
    5958              :                                     OutputProcessor::StoreType::Average,
    5959           16 :                                     thisDXCoil.Name);
    5960           32 :                 SetupOutputVariable(state,
    5961              :                                     "Cooling Coil Crankcase Heater Electricity Energy",
    5962              :                                     Constant::Units::J,
    5963           16 :                                     thisDXCoil.CrankcaseHeaterConsumption,
    5964              :                                     OutputProcessor::TimeStepType::System,
    5965              :                                     OutputProcessor::StoreType::Sum,
    5966           16 :                                     thisDXCoil.Name,
    5967              :                                     Constant::eResource::Electricity,
    5968              :                                     OutputProcessor::Group::Plant,
    5969              :                                     OutputProcessor::EndUseCat::WaterSystem); // DHW
    5970              :             }
    5971              : 
    5972              :             // new report variables for a HP water heater DX coil
    5973           32 :             SetupOutputVariable(state,
    5974              :                                 "Cooling Coil Total Water Heating Rate",
    5975              :                                 Constant::Units::W,
    5976           16 :                                 thisDXCoil.TotalHeatingEnergyRate,
    5977              :                                 OutputProcessor::TimeStepType::System,
    5978              :                                 OutputProcessor::StoreType::Average,
    5979           16 :                                 thisDXCoil.Name);
    5980           32 :             SetupOutputVariable(state,
    5981              :                                 "Cooling Coil Total Water Heating Energy",
    5982              :                                 Constant::Units::J,
    5983           16 :                                 thisDXCoil.TotalHeatingEnergy,
    5984              :                                 OutputProcessor::TimeStepType::System,
    5985              :                                 OutputProcessor::StoreType::Sum,
    5986           16 :                                 thisDXCoil.Name); //, &
    5987              :             //                           ResourceTypeKey='ENERGYTRANSFER',EndUseKey='HEATING',GroupKey='Plant')
    5988           32 :             SetupOutputVariable(state,
    5989              :                                 "Cooling Coil Water Heating Electricity Rate",
    5990              :                                 Constant::Units::W,
    5991           16 :                                 thisDXCoil.ElecWaterHeatingPower,
    5992              :                                 OutputProcessor::TimeStepType::System,
    5993              :                                 OutputProcessor::StoreType::Average,
    5994           16 :                                 thisDXCoil.Name);
    5995           32 :             SetupOutputVariable(state,
    5996              :                                 "Cooling Coil Water Heating Electricity Energy",
    5997              :                                 Constant::Units::J,
    5998           16 :                                 thisDXCoil.ElecWaterHeatingConsumption,
    5999              :                                 OutputProcessor::TimeStepType::System,
    6000              :                                 OutputProcessor::StoreType::Sum,
    6001           16 :                                 thisDXCoil.Name,
    6002              :                                 Constant::eResource::Electricity,
    6003              :                                 OutputProcessor::Group::Plant,
    6004              :                                 OutputProcessor::EndUseCat::WaterSystem); // DHW
    6005              :         }
    6006              : 
    6007          111 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
    6008              :             // Setup Report Variables for Cooling Equipment:
    6009              :             // CurrentModuleObject='Coil:Cooling:DX:MultiSpeed'
    6010           54 :             SetupOutputVariable(state,
    6011              :                                 "Cooling Coil Total Cooling Rate",
    6012              :                                 Constant::Units::W,
    6013           27 :                                 thisDXCoil.TotalCoolingEnergyRate,
    6014              :                                 OutputProcessor::TimeStepType::System,
    6015              :                                 OutputProcessor::StoreType::Average,
    6016           27 :                                 thisDXCoil.Name);
    6017           54 :             SetupOutputVariable(state,
    6018              :                                 "Cooling Coil Total Cooling Energy",
    6019              :                                 Constant::Units::J,
    6020           27 :                                 thisDXCoil.TotalCoolingEnergy,
    6021              :                                 OutputProcessor::TimeStepType::System,
    6022              :                                 OutputProcessor::StoreType::Sum,
    6023           27 :                                 thisDXCoil.Name,
    6024              :                                 Constant::eResource::EnergyTransfer,
    6025              :                                 OutputProcessor::Group::HVAC,
    6026              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    6027           54 :             SetupOutputVariable(state,
    6028              :                                 "Cooling Coil Sensible Cooling Rate",
    6029              :                                 Constant::Units::W,
    6030           27 :                                 thisDXCoil.SensCoolingEnergyRate,
    6031              :                                 OutputProcessor::TimeStepType::System,
    6032              :                                 OutputProcessor::StoreType::Average,
    6033           27 :                                 thisDXCoil.Name);
    6034           54 :             SetupOutputVariable(state,
    6035              :                                 "Cooling Coil Sensible Cooling Energy",
    6036              :                                 Constant::Units::J,
    6037           27 :                                 thisDXCoil.SensCoolingEnergy,
    6038              :                                 OutputProcessor::TimeStepType::System,
    6039              :                                 OutputProcessor::StoreType::Sum,
    6040           27 :                                 thisDXCoil.Name);
    6041           54 :             SetupOutputVariable(state,
    6042              :                                 "Cooling Coil Latent Cooling Rate",
    6043              :                                 Constant::Units::W,
    6044           27 :                                 thisDXCoil.LatCoolingEnergyRate,
    6045              :                                 OutputProcessor::TimeStepType::System,
    6046              :                                 OutputProcessor::StoreType::Average,
    6047           27 :                                 thisDXCoil.Name);
    6048           54 :             SetupOutputVariable(state,
    6049              :                                 "Cooling Coil Latent Cooling Energy",
    6050              :                                 Constant::Units::J,
    6051           27 :                                 thisDXCoil.LatCoolingEnergy,
    6052              :                                 OutputProcessor::TimeStepType::System,
    6053              :                                 OutputProcessor::StoreType::Sum,
    6054           27 :                                 thisDXCoil.Name);
    6055           54 :             SetupOutputVariable(state,
    6056              :                                 "Cooling Coil Electricity Rate",
    6057              :                                 Constant::Units::W,
    6058           27 :                                 thisDXCoil.ElecCoolingPower,
    6059              :                                 OutputProcessor::TimeStepType::System,
    6060              :                                 OutputProcessor::StoreType::Average,
    6061           27 :                                 thisDXCoil.Name);
    6062           54 :             SetupOutputVariable(state,
    6063              :                                 "Cooling Coil Electricity Energy",
    6064              :                                 Constant::Units::J,
    6065           27 :                                 thisDXCoil.ElecCoolingConsumption,
    6066              :                                 OutputProcessor::TimeStepType::System,
    6067              :                                 OutputProcessor::StoreType::Sum,
    6068           27 :                                 thisDXCoil.Name,
    6069              :                                 Constant::eResource::Electricity,
    6070              :                                 OutputProcessor::Group::HVAC,
    6071              :                                 OutputProcessor::EndUseCat::Cooling);
    6072              : 
    6073           27 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
    6074            4 :                 std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
    6075           12 :                 SetupOutputVariable(state,
    6076            8 :                                     format("Cooling Coil {} Rate", sFuelType),
    6077              :                                     Constant::Units::W,
    6078            4 :                                     thisDXCoil.FuelUsed,
    6079              :                                     OutputProcessor::TimeStepType::System,
    6080              :                                     OutputProcessor::StoreType::Average,
    6081            4 :                                     thisDXCoil.Name);
    6082           12 :                 SetupOutputVariable(state,
    6083            8 :                                     format("Cooling Coil {} Energy", sFuelType),
    6084              :                                     Constant::Units::J,
    6085            4 :                                     thisDXCoil.FuelConsumed,
    6086              :                                     OutputProcessor::TimeStepType::System,
    6087              :                                     OutputProcessor::StoreType::Sum,
    6088            4 :                                     thisDXCoil.Name,
    6089            4 :                                     Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
    6090              :                                     OutputProcessor::Group::HVAC,
    6091              :                                     OutputProcessor::EndUseCat::Cooling);
    6092              :             }
    6093              : 
    6094           54 :             SetupOutputVariable(state,
    6095              :                                 "Cooling Coil Runtime Fraction",
    6096              :                                 Constant::Units::None,
    6097           27 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    6098              :                                 OutputProcessor::TimeStepType::System,
    6099              :                                 OutputProcessor::StoreType::Average,
    6100           27 :                                 thisDXCoil.Name);
    6101              : 
    6102           27 :             if (thisDXCoil.ReportEvapCondVars) {
    6103            0 :                 SetupOutputVariable(state,
    6104              :                                     "Cooling Coil Condenser Inlet Temperature",
    6105              :                                     Constant::Units::C,
    6106            0 :                                     thisDXCoil.CondInletTemp,
    6107              :                                     OutputProcessor::TimeStepType::System,
    6108              :                                     OutputProcessor::StoreType::Average,
    6109            0 :                                     thisDXCoil.Name);
    6110            0 :                 SetupOutputVariable(state,
    6111              :                                     "Cooling Coil Evaporative Condenser Water Volume",
    6112              :                                     Constant::Units::m3,
    6113            0 :                                     thisDXCoil.EvapWaterConsump,
    6114              :                                     OutputProcessor::TimeStepType::System,
    6115              :                                     OutputProcessor::StoreType::Sum,
    6116            0 :                                     thisDXCoil.Name,
    6117              :                                     Constant::eResource::Water,
    6118              :                                     OutputProcessor::Group::HVAC,
    6119              :                                     OutputProcessor::EndUseCat::Cooling);
    6120            0 :                 SetupOutputVariable(state,
    6121              :                                     "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
    6122              :                                     Constant::Units::m3,
    6123            0 :                                     thisDXCoil.EvapWaterConsump,
    6124              :                                     OutputProcessor::TimeStepType::System,
    6125              :                                     OutputProcessor::StoreType::Sum,
    6126            0 :                                     thisDXCoil.Name,
    6127              :                                     Constant::eResource::MainsWater,
    6128              :                                     OutputProcessor::Group::HVAC,
    6129              :                                     OutputProcessor::EndUseCat::Cooling);
    6130            0 :                 SetupOutputVariable(state,
    6131              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Rate",
    6132              :                                     Constant::Units::W,
    6133            0 :                                     thisDXCoil.EvapCondPumpElecPower,
    6134              :                                     OutputProcessor::TimeStepType::System,
    6135              :                                     OutputProcessor::StoreType::Average,
    6136            0 :                                     thisDXCoil.Name);
    6137            0 :                 SetupOutputVariable(state,
    6138              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Energy",
    6139              :                                     Constant::Units::J,
    6140            0 :                                     thisDXCoil.EvapCondPumpElecConsumption,
    6141              :                                     OutputProcessor::TimeStepType::System,
    6142              :                                     OutputProcessor::StoreType::Sum,
    6143            0 :                                     thisDXCoil.Name,
    6144              :                                     Constant::eResource::Electricity,
    6145              :                                     OutputProcessor::Group::HVAC,
    6146              :                                     OutputProcessor::EndUseCat::Cooling);
    6147            0 :                 if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    6148            0 :                     SetupOutputVariable(state,
    6149              :                                         "Cooling Coil Basin Heater Electricity Rate",
    6150              :                                         Constant::Units::W,
    6151            0 :                                         thisDXCoil.BasinHeaterPower,
    6152              :                                         OutputProcessor::TimeStepType::System,
    6153              :                                         OutputProcessor::StoreType::Average,
    6154            0 :                                         thisDXCoil.Name);
    6155            0 :                     SetupOutputVariable(state,
    6156              :                                         "Cooling Coil Basin Heater Electricity Energy",
    6157              :                                         Constant::Units::J,
    6158            0 :                                         thisDXCoil.BasinHeaterConsumption,
    6159              :                                         OutputProcessor::TimeStepType::System,
    6160              :                                         OutputProcessor::StoreType::Sum,
    6161            0 :                                         thisDXCoil.Name,
    6162              :                                         Constant::eResource::Electricity,
    6163              :                                         OutputProcessor::Group::HVAC,
    6164              :                                         OutputProcessor::EndUseCat::Cooling);
    6165              :                 }
    6166              :             }
    6167           27 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
    6168            0 :                 SetupOutputVariable(state,
    6169              :                                     "Secondary Coil Heat Rejection Rate",
    6170              :                                     Constant::Units::W,
    6171            0 :                                     thisDXCoil.SecCoilSensibleHeatGainRate,
    6172              :                                     OutputProcessor::TimeStepType::System,
    6173              :                                     OutputProcessor::StoreType::Average,
    6174            0 :                                     thisDXCoil.Name);
    6175              :             }
    6176              : 
    6177              :         }
    6178              : 
    6179           84 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    6180              :             // Setup Report Variables for Heating Equipment:
    6181              :             // CurrentModuleObject='Coil:Heating:DX:MultiSpeed'
    6182           28 :             SetupOutputVariable(state,
    6183              :                                 "Heating Coil Heating Rate",
    6184              :                                 Constant::Units::W,
    6185           14 :                                 thisDXCoil.TotalHeatingEnergyRate,
    6186              :                                 OutputProcessor::TimeStepType::System,
    6187              :                                 OutputProcessor::StoreType::Average,
    6188           14 :                                 thisDXCoil.Name);
    6189           28 :             SetupOutputVariable(state,
    6190              :                                 "Heating Coil Heating Energy",
    6191              :                                 Constant::Units::J,
    6192           14 :                                 thisDXCoil.TotalHeatingEnergy,
    6193              :                                 OutputProcessor::TimeStepType::System,
    6194              :                                 OutputProcessor::StoreType::Sum,
    6195           14 :                                 thisDXCoil.Name,
    6196              :                                 Constant::eResource::EnergyTransfer,
    6197              :                                 OutputProcessor::Group::HVAC,
    6198              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    6199           28 :             SetupOutputVariable(state,
    6200              :                                 "Heating Coil Electricity Rate",
    6201              :                                 Constant::Units::W,
    6202           14 :                                 thisDXCoil.ElecHeatingPower,
    6203              :                                 OutputProcessor::TimeStepType::System,
    6204              :                                 OutputProcessor::StoreType::Average,
    6205           14 :                                 thisDXCoil.Name);
    6206           28 :             SetupOutputVariable(state,
    6207              :                                 "Heating Coil Electricity Energy",
    6208              :                                 Constant::Units::J,
    6209           14 :                                 thisDXCoil.ElecHeatingConsumption,
    6210              :                                 OutputProcessor::TimeStepType::System,
    6211              :                                 OutputProcessor::StoreType::Sum,
    6212           14 :                                 thisDXCoil.Name,
    6213              :                                 Constant::eResource::Electricity,
    6214              :                                 OutputProcessor::Group::HVAC,
    6215              :                                 OutputProcessor::EndUseCat::Heating);
    6216              : 
    6217           14 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
    6218            3 :                 std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
    6219            9 :                 SetupOutputVariable(state,
    6220            6 :                                     format("Heating Coil {} Rate", sFuelType),
    6221              :                                     Constant::Units::W,
    6222            3 :                                     thisDXCoil.FuelUsed,
    6223              :                                     OutputProcessor::TimeStepType::System,
    6224              :                                     OutputProcessor::StoreType::Average,
    6225            3 :                                     thisDXCoil.Name);
    6226            9 :                 SetupOutputVariable(state,
    6227            6 :                                     format("Heating Coil {} Energy", sFuelType),
    6228              :                                     Constant::Units::J,
    6229            3 :                                     thisDXCoil.FuelConsumed,
    6230              :                                     OutputProcessor::TimeStepType::System,
    6231              :                                     OutputProcessor::StoreType::Sum,
    6232            3 :                                     thisDXCoil.Name,
    6233            3 :                                     Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
    6234              :                                     OutputProcessor::Group::HVAC,
    6235              :                                     OutputProcessor::EndUseCat::HeatingCoils);
    6236              :             }
    6237              : 
    6238           14 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
    6239            2 :                 std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
    6240            6 :                 SetupOutputVariable(state,
    6241            4 :                                     format("Heating Coil Defrost {} Rate", sFuelType),
    6242              :                                     Constant::Units::W,
    6243            2 :                                     thisDXCoil.DefrostPower,
    6244              :                                     OutputProcessor::TimeStepType::System,
    6245              :                                     OutputProcessor::StoreType::Average,
    6246            2 :                                     thisDXCoil.Name);
    6247            6 :                 SetupOutputVariable(state,
    6248            4 :                                     format("Heating Coil Defrost {} Energy", sFuelType),
    6249              :                                     Constant::Units::J,
    6250            2 :                                     thisDXCoil.DefrostConsumption,
    6251              :                                     OutputProcessor::TimeStepType::System,
    6252              :                                     OutputProcessor::StoreType::Sum,
    6253            2 :                                     thisDXCoil.Name,
    6254            2 :                                     Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
    6255              :                                     OutputProcessor::Group::HVAC,
    6256              :                                     OutputProcessor::EndUseCat::Heating);
    6257            2 :             } else {
    6258           24 :                 SetupOutputVariable(state,
    6259              :                                     "Heating Coil Defrost Electricity Rate",
    6260              :                                     Constant::Units::W,
    6261           12 :                                     thisDXCoil.DefrostPower,
    6262              :                                     OutputProcessor::TimeStepType::System,
    6263              :                                     OutputProcessor::StoreType::Average,
    6264           12 :                                     thisDXCoil.Name);
    6265           24 :                 SetupOutputVariable(state,
    6266              :                                     "Heating Coil Defrost Electricity Energy",
    6267              :                                     Constant::Units::J,
    6268           12 :                                     thisDXCoil.DefrostConsumption,
    6269              :                                     OutputProcessor::TimeStepType::System,
    6270              :                                     OutputProcessor::StoreType::Sum,
    6271           12 :                                     thisDXCoil.Name,
    6272              :                                     Constant::eResource::Electricity,
    6273              :                                     OutputProcessor::Group::HVAC,
    6274              :                                     OutputProcessor::EndUseCat::Heating);
    6275              :             }
    6276              : 
    6277           28 :             SetupOutputVariable(state,
    6278              :                                 "Heating Coil Crankcase Heater Electricity Rate",
    6279              :                                 Constant::Units::W,
    6280           14 :                                 thisDXCoil.CrankcaseHeaterPower,
    6281              :                                 OutputProcessor::TimeStepType::System,
    6282              :                                 OutputProcessor::StoreType::Average,
    6283           14 :                                 thisDXCoil.Name);
    6284           28 :             SetupOutputVariable(state,
    6285              :                                 "Heating Coil Crankcase Heater Electricity Energy",
    6286              :                                 Constant::Units::J,
    6287           14 :                                 thisDXCoil.CrankcaseHeaterConsumption,
    6288              :                                 OutputProcessor::TimeStepType::System,
    6289              :                                 OutputProcessor::StoreType::Sum,
    6290           14 :                                 thisDXCoil.Name,
    6291              :                                 Constant::eResource::Electricity,
    6292              :                                 OutputProcessor::Group::HVAC,
    6293              :                                 OutputProcessor::EndUseCat::Heating);
    6294           28 :             SetupOutputVariable(state,
    6295              :                                 "Heating Coil Runtime Fraction",
    6296              :                                 Constant::Units::None,
    6297           14 :                                 thisDXCoil.HeatingCoilRuntimeFraction,
    6298              :                                 OutputProcessor::TimeStepType::System,
    6299              :                                 OutputProcessor::StoreType::Average,
    6300           14 :                                 thisDXCoil.Name);
    6301              : 
    6302           14 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
    6303            0 :                 SetupOutputVariable(state,
    6304              :                                     "Secondary Coil Total Heat Removal Rate",
    6305              :                                     Constant::Units::W,
    6306            0 :                                     thisDXCoil.SecCoilTotalHeatRemovalRate,
    6307              :                                     OutputProcessor::TimeStepType::System,
    6308              :                                     OutputProcessor::StoreType::Average,
    6309            0 :                                     thisDXCoil.Name);
    6310            0 :                 SetupOutputVariable(state,
    6311              :                                     "Secondary Coil Sensible Heat Removal Rate",
    6312              :                                     Constant::Units::W,
    6313            0 :                                     thisDXCoil.SecCoilSensibleHeatRemovalRate,
    6314              :                                     OutputProcessor::TimeStepType::System,
    6315              :                                     OutputProcessor::StoreType::Average,
    6316            0 :                                     thisDXCoil.Name);
    6317            0 :                 SetupOutputVariable(state,
    6318              :                                     "Secondary Coil Latent Heat Removal Rate",
    6319              :                                     Constant::Units::W,
    6320            0 :                                     thisDXCoil.SecCoilLatentHeatRemovalRate,
    6321              :                                     OutputProcessor::TimeStepType::System,
    6322              :                                     OutputProcessor::StoreType::Average,
    6323            0 :                                     thisDXCoil.Name);
    6324            0 :                 SetupOutputVariable(state,
    6325              :                                     "Secondary Coil Sensible Heat Ratio",
    6326              :                                     Constant::Units::None,
    6327            0 :                                     thisDXCoil.SecCoilSHR,
    6328              :                                     OutputProcessor::TimeStepType::System,
    6329              :                                     OutputProcessor::StoreType::Average,
    6330            0 :                                     thisDXCoil.Name);
    6331              :             }
    6332              : 
    6333           14 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    6334            0 :                 SetupEMSActuator(state,
    6335              :                                  thisDXCoil.DXCoilType,
    6336              :                                  thisDXCoil.Name,
    6337              :                                  "Frost Heating Capacity Multiplier",
    6338              :                                  "[]",
    6339            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
    6340            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
    6341              : 
    6342            0 :                 SetupEMSActuator(state,
    6343              :                                  thisDXCoil.DXCoilType,
    6344              :                                  thisDXCoil.Name,
    6345              :                                  "Frost Heating Input Power Multiplier",
    6346              :                                  "[]",
    6347            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
    6348            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
    6349              :             }
    6350              :         }
    6351              : 
    6352              :         // VRF cooling coil report variables
    6353           70 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
    6354              :             // Setup Report Variables for Cooling Equipment:
    6355              :             // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow
    6356           48 :             SetupOutputVariable(state,
    6357              :                                 "Cooling Coil Total Cooling Rate",
    6358              :                                 Constant::Units::W,
    6359           24 :                                 thisDXCoil.TotalCoolingEnergyRate,
    6360              :                                 OutputProcessor::TimeStepType::System,
    6361              :                                 OutputProcessor::StoreType::Average,
    6362           24 :                                 thisDXCoil.Name);
    6363           48 :             SetupOutputVariable(state,
    6364              :                                 "Cooling Coil Total Cooling Energy",
    6365              :                                 Constant::Units::J,
    6366           24 :                                 thisDXCoil.TotalCoolingEnergy,
    6367              :                                 OutputProcessor::TimeStepType::System,
    6368              :                                 OutputProcessor::StoreType::Sum,
    6369           24 :                                 thisDXCoil.Name,
    6370              :                                 Constant::eResource::EnergyTransfer,
    6371              :                                 OutputProcessor::Group::HVAC,
    6372              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    6373           48 :             SetupOutputVariable(state,
    6374              :                                 "Cooling Coil Sensible Cooling Rate",
    6375              :                                 Constant::Units::W,
    6376           24 :                                 thisDXCoil.SensCoolingEnergyRate,
    6377              :                                 OutputProcessor::TimeStepType::System,
    6378              :                                 OutputProcessor::StoreType::Average,
    6379           24 :                                 thisDXCoil.Name);
    6380           48 :             SetupOutputVariable(state,
    6381              :                                 "Cooling Coil Sensible Cooling Energy",
    6382              :                                 Constant::Units::J,
    6383           24 :                                 thisDXCoil.SensCoolingEnergy,
    6384              :                                 OutputProcessor::TimeStepType::System,
    6385              :                                 OutputProcessor::StoreType::Sum,
    6386           24 :                                 thisDXCoil.Name);
    6387           48 :             SetupOutputVariable(state,
    6388              :                                 "Cooling Coil Latent Cooling Rate",
    6389              :                                 Constant::Units::W,
    6390           24 :                                 thisDXCoil.LatCoolingEnergyRate,
    6391              :                                 OutputProcessor::TimeStepType::System,
    6392              :                                 OutputProcessor::StoreType::Average,
    6393           24 :                                 thisDXCoil.Name);
    6394           48 :             SetupOutputVariable(state,
    6395              :                                 "Cooling Coil Latent Cooling Energy",
    6396              :                                 Constant::Units::J,
    6397           24 :                                 thisDXCoil.LatCoolingEnergy,
    6398              :                                 OutputProcessor::TimeStepType::System,
    6399              :                                 OutputProcessor::StoreType::Sum,
    6400           24 :                                 thisDXCoil.Name);
    6401           48 :             SetupOutputVariable(state,
    6402              :                                 "Cooling Coil Runtime Fraction",
    6403              :                                 Constant::Units::None,
    6404           24 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    6405              :                                 OutputProcessor::TimeStepType::System,
    6406              :                                 OutputProcessor::StoreType::Average,
    6407           24 :                                 thisDXCoil.Name);
    6408           24 :             if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
    6409            0 :                 SetupOutputVariable(state,
    6410              :                                     "Cooling Coil Condensate Volume Flow Rate",
    6411              :                                     Constant::Units::m3_s,
    6412            0 :                                     thisDXCoil.CondensateVdot,
    6413              :                                     OutputProcessor::TimeStepType::System,
    6414              :                                     OutputProcessor::StoreType::Average,
    6415            0 :                                     thisDXCoil.Name);
    6416            0 :                 SetupOutputVariable(state,
    6417              :                                     "Cooling Coil Condensate Volume",
    6418              :                                     Constant::Units::m3,
    6419            0 :                                     thisDXCoil.CondensateVol,
    6420              :                                     OutputProcessor::TimeStepType::System,
    6421              :                                     OutputProcessor::StoreType::Sum,
    6422            0 :                                     thisDXCoil.Name,
    6423              :                                     Constant::eResource::OnSiteWater,
    6424              :                                     OutputProcessor::Group::HVAC,
    6425              :                                     OutputProcessor::EndUseCat::Condensate);
    6426              :             }
    6427              :         }
    6428              : 
    6429              :         // VRF heating coil report variables
    6430           46 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
    6431              :             // Setup Report Variables for Heating Equipment:
    6432              :             // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow
    6433           46 :             SetupOutputVariable(state,
    6434              :                                 "Heating Coil Heating Rate",
    6435              :                                 Constant::Units::W,
    6436           23 :                                 thisDXCoil.TotalHeatingEnergyRate,
    6437              :                                 OutputProcessor::TimeStepType::System,
    6438              :                                 OutputProcessor::StoreType::Average,
    6439           23 :                                 thisDXCoil.Name);
    6440           46 :             SetupOutputVariable(state,
    6441              :                                 "Heating Coil Heating Energy",
    6442              :                                 Constant::Units::J,
    6443           23 :                                 thisDXCoil.TotalHeatingEnergy,
    6444              :                                 OutputProcessor::TimeStepType::System,
    6445              :                                 OutputProcessor::StoreType::Sum,
    6446           23 :                                 thisDXCoil.Name,
    6447              :                                 Constant::eResource::EnergyTransfer,
    6448              :                                 OutputProcessor::Group::HVAC,
    6449              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    6450           46 :             SetupOutputVariable(state,
    6451              :                                 "Heating Coil Runtime Fraction",
    6452              :                                 Constant::Units::None,
    6453           23 :                                 thisDXCoil.HeatingCoilRuntimeFraction,
    6454              :                                 OutputProcessor::TimeStepType::System,
    6455              :                                 OutputProcessor::StoreType::Average,
    6456           23 :                                 thisDXCoil.Name);
    6457              : 
    6458           23 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    6459            0 :                 SetupEMSActuator(state,
    6460              :                                  thisDXCoil.DXCoilType,
    6461              :                                  thisDXCoil.Name,
    6462              :                                  "Frost Heating Capacity Multiplier",
    6463              :                                  "[]",
    6464            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
    6465            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
    6466              : 
    6467            0 :                 SetupEMSActuator(state,
    6468              :                                  thisDXCoil.DXCoilType,
    6469              :                                  thisDXCoil.Name,
    6470              :                                  "Frost Heating Input Power Multiplier",
    6471              :                                  "[]",
    6472            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
    6473            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
    6474              :             }
    6475              :         }
    6476              : 
    6477              :         // VRF cooling coil for FluidTCtrl, report variables
    6478           23 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    6479              :             // Setup Report Variables for Cooling Equipment:
    6480              :             // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl
    6481           24 :             SetupOutputVariable(state,
    6482              :                                 "Cooling Coil Total Cooling Rate",
    6483              :                                 Constant::Units::W,
    6484           12 :                                 thisDXCoil.TotalCoolingEnergyRate,
    6485              :                                 OutputProcessor::TimeStepType::System,
    6486              :                                 OutputProcessor::StoreType::Average,
    6487           12 :                                 thisDXCoil.Name);
    6488           24 :             SetupOutputVariable(state,
    6489              :                                 "Cooling Coil Total Cooling Energy",
    6490              :                                 Constant::Units::J,
    6491           12 :                                 thisDXCoil.TotalCoolingEnergy,
    6492              :                                 OutputProcessor::TimeStepType::System,
    6493              :                                 OutputProcessor::StoreType::Sum,
    6494           12 :                                 thisDXCoil.Name,
    6495              :                                 Constant::eResource::EnergyTransfer,
    6496              :                                 OutputProcessor::Group::HVAC,
    6497              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    6498           24 :             SetupOutputVariable(state,
    6499              :                                 "Cooling Coil Sensible Cooling Rate",
    6500              :                                 Constant::Units::W,
    6501           12 :                                 thisDXCoil.SensCoolingEnergyRate,
    6502              :                                 OutputProcessor::TimeStepType::System,
    6503              :                                 OutputProcessor::StoreType::Average,
    6504           12 :                                 thisDXCoil.Name);
    6505           24 :             SetupOutputVariable(state,
    6506              :                                 "Cooling Coil Sensible Cooling Energy",
    6507              :                                 Constant::Units::J,
    6508           12 :                                 thisDXCoil.SensCoolingEnergy,
    6509              :                                 OutputProcessor::TimeStepType::System,
    6510              :                                 OutputProcessor::StoreType::Sum,
    6511           12 :                                 thisDXCoil.Name);
    6512           24 :             SetupOutputVariable(state,
    6513              :                                 "Cooling Coil Latent Cooling Rate",
    6514              :                                 Constant::Units::W,
    6515           12 :                                 thisDXCoil.LatCoolingEnergyRate,
    6516              :                                 OutputProcessor::TimeStepType::System,
    6517              :                                 OutputProcessor::StoreType::Average,
    6518           12 :                                 thisDXCoil.Name);
    6519           24 :             SetupOutputVariable(state,
    6520              :                                 "Cooling Coil Latent Cooling Energy",
    6521              :                                 Constant::Units::J,
    6522           12 :                                 thisDXCoil.LatCoolingEnergy,
    6523              :                                 OutputProcessor::TimeStepType::System,
    6524              :                                 OutputProcessor::StoreType::Sum,
    6525           12 :                                 thisDXCoil.Name);
    6526           24 :             SetupOutputVariable(state,
    6527              :                                 "Cooling Coil Runtime Fraction",
    6528              :                                 Constant::Units::None,
    6529           12 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    6530              :                                 OutputProcessor::TimeStepType::System,
    6531              :                                 OutputProcessor::StoreType::Average,
    6532           12 :                                 thisDXCoil.Name);
    6533              :             // Followings for VRF_FluidTCtrl Only
    6534           24 :             SetupOutputVariable(state,
    6535              :                                 "Cooling Coil VRF Evaporating Temperature",
    6536              :                                 Constant::Units::C,
    6537           12 :                                 thisDXCoil.EvaporatingTemp,
    6538              :                                 OutputProcessor::TimeStepType::System,
    6539              :                                 OutputProcessor::StoreType::Average,
    6540           12 :                                 thisDXCoil.Name);
    6541           24 :             SetupOutputVariable(state,
    6542              :                                 "Cooling Coil VRF Super Heating Degrees",
    6543              :                                 Constant::Units::C,
    6544           12 :                                 thisDXCoil.ActualSH,
    6545              :                                 OutputProcessor::TimeStepType::System,
    6546              :                                 OutputProcessor::StoreType::Average,
    6547           12 :                                 thisDXCoil.Name);
    6548              : 
    6549           12 :             if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
    6550            0 :                 SetupOutputVariable(state,
    6551              :                                     "Cooling Coil Condensate Volume Flow Rate",
    6552              :                                     Constant::Units::m3_s,
    6553            0 :                                     thisDXCoil.CondensateVdot,
    6554              :                                     OutputProcessor::TimeStepType::System,
    6555              :                                     OutputProcessor::StoreType::Average,
    6556            0 :                                     thisDXCoil.Name);
    6557            0 :                 SetupOutputVariable(state,
    6558              :                                     "Cooling Coil Condensate Volume",
    6559              :                                     Constant::Units::m3,
    6560            0 :                                     thisDXCoil.CondensateVol,
    6561              :                                     OutputProcessor::TimeStepType::System,
    6562              :                                     OutputProcessor::StoreType::Sum,
    6563            0 :                                     thisDXCoil.Name,
    6564              :                                     Constant::eResource::OnSiteWater,
    6565              :                                     OutputProcessor::Group::HVAC,
    6566              :                                     OutputProcessor::EndUseCat::Condensate);
    6567              :             }
    6568              :         }
    6569              : 
    6570              :         // VRF heating coil for FluidTCtrl, report variables
    6571           11 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    6572              :             // Setup Report Variables for Heating Equipment:
    6573              :             // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl
    6574           22 :             SetupOutputVariable(state,
    6575              :                                 "Heating Coil Heating Rate",
    6576              :                                 Constant::Units::W,
    6577           11 :                                 thisDXCoil.TotalHeatingEnergyRate,
    6578              :                                 OutputProcessor::TimeStepType::System,
    6579              :                                 OutputProcessor::StoreType::Average,
    6580           11 :                                 thisDXCoil.Name);
    6581           22 :             SetupOutputVariable(state,
    6582              :                                 "Heating Coil Heating Energy",
    6583              :                                 Constant::Units::J,
    6584           11 :                                 thisDXCoil.TotalHeatingEnergy,
    6585              :                                 OutputProcessor::TimeStepType::System,
    6586              :                                 OutputProcessor::StoreType::Sum,
    6587           11 :                                 thisDXCoil.Name,
    6588              :                                 Constant::eResource::EnergyTransfer,
    6589              :                                 OutputProcessor::Group::HVAC,
    6590              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    6591           22 :             SetupOutputVariable(state,
    6592              :                                 "Heating Coil Runtime Fraction",
    6593              :                                 Constant::Units::None,
    6594           11 :                                 thisDXCoil.HeatingCoilRuntimeFraction,
    6595              :                                 OutputProcessor::TimeStepType::System,
    6596              :                                 OutputProcessor::StoreType::Average,
    6597           11 :                                 thisDXCoil.Name);
    6598              :             // Followings for VRF_FluidTCtrl Only
    6599           22 :             SetupOutputVariable(state,
    6600              :                                 "Heating Coil VRF Condensing Temperature",
    6601              :                                 Constant::Units::C,
    6602           11 :                                 thisDXCoil.CondensingTemp,
    6603              :                                 OutputProcessor::TimeStepType::System,
    6604              :                                 OutputProcessor::StoreType::Average,
    6605           11 :                                 thisDXCoil.Name);
    6606           22 :             SetupOutputVariable(state,
    6607              :                                 "Heating Coil VRF Subcooling Degrees",
    6608              :                                 Constant::Units::C,
    6609           11 :                                 thisDXCoil.ActualSC,
    6610              :                                 OutputProcessor::TimeStepType::System,
    6611              :                                 OutputProcessor::StoreType::Average,
    6612           11 :                                 thisDXCoil.Name);
    6613              :         }
    6614              :     }
    6615              : 
    6616          134 :     if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    6617              :         // setup EMS sizing actuators for single speed DX
    6618            0 :         for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilNum) {
    6619              : 
    6620            0 :             auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    6621              : 
    6622            0 :             SetupEMSActuator(state,
    6623              :                              "Coil:Cooling:DX:SingleSpeed",
    6624              :                              thisDXCoil.Name,
    6625              :                              "Autosized Rated Air Flow Rate",
    6626              :                              "[m3/s]",
    6627              :                              thisDXCoil.RatedAirVolFlowRateEMSOverrideON(1),
    6628            0 :                              thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(1));
    6629              : 
    6630            0 :             SetupEMSActuator(state,
    6631              :                              "Coil:Cooling:DX:SingleSpeed",
    6632              :                              thisDXCoil.Name,
    6633              :                              "Autosized Rated Sensible Heat Ratio",
    6634              :                              "[W/W]",
    6635              :                              thisDXCoil.RatedSHREMSOverrideOn(1),
    6636            0 :                              thisDXCoil.RatedSHREMSOverrideValue(1));
    6637              : 
    6638            0 :             SetupEMSActuator(state,
    6639              :                              "Coil:Cooling:DX:SingleSpeed",
    6640              :                              thisDXCoil.Name,
    6641              :                              "Autosized Rated Total Cooling Capacity",
    6642              :                              "[W]",
    6643              :                              thisDXCoil.RatedTotCapEMSOverrideOn(1),
    6644            0 :                              thisDXCoil.RatedTotCapEMSOverrideValue(1));
    6645              :         }
    6646              :     }
    6647          134 :     Alphas.deallocate();
    6648          134 :     cAlphaFields.deallocate();
    6649          134 :     cNumericFields.deallocate();
    6650          134 :     Numbers.deallocate();
    6651          134 :     lAlphaBlanks.deallocate();
    6652          134 :     lNumericBlanks.deallocate();
    6653              : 
    6654          134 :     Alphas2.deallocate();
    6655          134 :     cAlphaFields2.deallocate();
    6656          134 :     cNumericFields2.deallocate();
    6657          134 :     Numbers2.deallocate();
    6658          134 :     lAlphaBlanks2.deallocate();
    6659          134 :     lNumericBlanks2.deallocate();
    6660              :     bool anyEMSRan;
    6661          134 :     ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyEMSRan, ObjexxFCL::Optional_int_const());
    6662          149 : }
    6663              : 
    6664       539063 : void InitDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current DX coil unit being simulated
    6665              : {
    6666              : 
    6667              :     // SUBROUTINE INFORMATION:
    6668              :     //       AUTHOR         Fred Buhl
    6669              :     //       DATE WRITTEN   May 2000
    6670              :     //                      Feb 2005, M. J. Witte, GARD Analytics, Inc. Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
    6671              :     //                      Jul 2005, R. Raustad, FSEC. Add new coil type COIL:DX:HEATPUMPWATERHEATER
    6672              :     //                      Jun 2007, L. Gu, FSEC. Add new coil type COIL:DX:MULTISPEED:COOLING and HEATING
    6673              :     //                      Aug 2015, R. Zhang, LBNL. Add new coil types for VRF_FluidTCtrl
    6674              : 
    6675              :     // PURPOSE OF THIS SUBROUTINE:
    6676              :     // This subroutine is for initializations of DX Coil Components.
    6677              : 
    6678              :     // METHODOLOGY EMPLOYED:
    6679              :     // Uses the status flags to trigger initializations.
    6680              : 
    6681              :     // SUBROUTINE PARAMETER DEFINITIONS:
    6682       539063 :     constexpr Real64 SmallDifferenceTest(0.00000001);
    6683              :     static constexpr std::string_view RoutineName("InitDXCoil");
    6684              : 
    6685              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6686              :     Real64 RatedHeatPumpIndoorAirTemp; // Indoor dry-bulb temperature to heat pump evaporator at rated conditions [C]
    6687              :     Real64 RatedHeatPumpIndoorHumRat;  // Inlet humidity ratio to heat pump evaporator at rated conditions [kgWater/kgDryAir]
    6688              :     Real64 RatedVolFlowPerRatedTotCap; // Rated Air Volume Flow Rate divided by Rated Total Capacity [m3/s-W)
    6689              :     Real64 HPInletAirHumRat;           // Rated inlet air humidity ratio for heat pump water heater [kgWater/kgDryAir]
    6690       539063 :     bool ErrorsFound(false);           // TRUE when errors found
    6691              :     int CapacityStageNum;              // Loop index for 1,Number of capacity stages
    6692              :     int DehumidModeNum;                // Loop index for 1,Number of enhanced dehumidification modes
    6693              :     int Mode;                          // Performance mode for MultiMode DX coil; Always 1 for other coil types
    6694              :     int DXCoilNumTemp;                 // Counter for crankcase heater report variable DO loop
    6695              :     int AirInletNode;                  // Air inlet node number
    6696              :     int SpeedNum;                      // Speed number for multispeed coils
    6697              : 
    6698       539063 :     if (state.dataDXCoils->MyOneTimeFlag) {
    6699              :         // initialize the environment and sizing flags
    6700           68 :         state.dataDXCoils->MyEnvrnFlag.dimension(state.dataDXCoils->NumDXCoils, true);
    6701           68 :         state.dataDXCoils->MySizeFlag.dimension(state.dataDXCoils->NumDXCoils, true);
    6702           68 :         state.dataDXCoils->MyOneTimeFlag = false;
    6703              :     }
    6704              : 
    6705       539063 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    6706              : 
    6707              :     // if "ISHundredPercentDOASDXCoil" =.TRUE., then set coil as 100% DOAS dx coil
    6708       539063 :     state.dataHVACGlobal->DXCT = (thisDXCoil.ISHundredPercentDOASDXCoil) ? HVAC::DXCoilType::DOAS : HVAC::DXCoilType::Regular;
    6709              : 
    6710      1617030 :     if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    6711       539224 :          thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
    6712          161 :         state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
    6713              : 
    6714            4 :         SizeDXCoil(state, DXCoilNum);
    6715              : 
    6716            4 :         RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(1) / thisDXCoil.RatedTotCap2;
    6717            8 :         if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    6718            4 :             ((RatedVolFlowPerRatedTotCap - HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    6719            0 :             ShowWarningError(state,
    6720            0 :                              format("{} \"{}\": Rated air volume flow rate per watt of rated total water heating capacity is out of range",
    6721            0 :                                     thisDXCoil.DXCoilType,
    6722            0 :                                     thisDXCoil.Name));
    6723            0 :             ShowContinueError(state,
    6724            0 :                               format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    6725              :                                      "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
    6726            0 :                                      HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    6727              :                                      RatedVolFlowPerRatedTotCap,
    6728            0 :                                      HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    6729              :         }
    6730              :         HPInletAirHumRat =
    6731            4 :             PsyWFnTdbTwbPb(state, thisDXCoil.RatedInletDBTemp, thisDXCoil.RatedInletWBTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
    6732            4 :         state.dataHVACGlobal->HPWHInletDBTemp = thisDXCoil.RatedInletDBTemp;
    6733            4 :         state.dataHVACGlobal->HPWHInletWBTemp = thisDXCoil.RatedInletWBTemp;
    6734            8 :         thisDXCoil.RatedAirMassFlowRate(1) =
    6735            4 :             thisDXCoil.RatedAirVolFlowRate(1) *
    6736            4 :             PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, thisDXCoil.RatedInletDBTemp, HPInletAirHumRat, RoutineName);
    6737              :         //   get rated coil bypass factor excluding fan heat
    6738              : 
    6739              :         //   call CalcHPWHDXCoil to determine DXCoil%RatedTotCap(1) for rated CBF calculation below
    6740            4 :         CalcHPWHDXCoil(state, DXCoilNum, 1.0);
    6741            4 :         if (state.dataDXCoils->MySizeFlag(DXCoilNum)) {
    6742            4 :             SizeDXCoil(state, DXCoilNum);
    6743            4 :             state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
    6744              :         }
    6745              : 
    6746            4 :         thisDXCoil.RatedCBF(1) = CalcCBF(state,
    6747            4 :                                          thisDXCoil.DXCoilType,
    6748            4 :                                          thisDXCoil.Name,
    6749              :                                          thisDXCoil.RatedInletDBTemp,
    6750              :                                          HPInletAirHumRat,
    6751            4 :                                          thisDXCoil.RatedTotCap(1),
    6752            4 :                                          thisDXCoil.RatedAirVolFlowRate(1),
    6753            4 :                                          thisDXCoil.RatedSHR(1),
    6754              :                                          true);
    6755            4 :         state.dataDXCoils->MyEnvrnFlag(DXCoilNum) = false;
    6756              :     }
    6757              : 
    6758       539513 :     if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) &&
    6759          450 :         state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
    6760           15 :         if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
    6761            4 :             if (thisDXCoil.MSHPHeatRecActive) {
    6762            5 :                 for (SpeedNum = 1; SpeedNum <= thisDXCoil.NumOfSpeeds; ++SpeedNum) {
    6763            4 :                     if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
    6764            0 :                         ShowWarningError(
    6765              :                             state,
    6766            0 :                             format("GetDXCoils:{}. The value of Waste Heat Function of Temperature Curve is assumed to be 1. Simulation continues. ",
    6767            0 :                                    thisDXCoil.Name));
    6768            0 :                         break;
    6769              :                     }
    6770              :                 }
    6771              :             }
    6772              :         }
    6773           15 :         state.dataDXCoils->MyEnvrnFlag(DXCoilNum) = false;
    6774              :     }
    6775              : 
    6776              :     // Find the companion upstream coil (DX cooling coil) that is used with DX heating coils (HP AC units only)
    6777       539063 :     if (thisDXCoil.FindCompanionUpStreamCoil) {
    6778          135 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    6779           40 :             thisDXCoil.CompanionUpstreamDXCoil = GetHPCoolingCoilIndex(state, thisDXCoil.DXCoilType, thisDXCoil.Name, DXCoilNum);
    6780           40 :             if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
    6781            9 :                 state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).ReportCoolingCoilCrankcasePower = false;
    6782            9 :                 thisDXCoil.FindCompanionUpStreamCoil = false;
    6783              :                 //       Copy condenser node number from DX cooling coil when used with a companion DX heating coil
    6784           45 :                 for (Mode = 1; Mode <= MaxModes; ++Mode) {
    6785           36 :                     thisDXCoil.CondenserInletNodeNum(Mode) =
    6786           36 :                         state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CondenserInletNodeNum(Mode);
    6787              :                 }
    6788              :             }
    6789              :         } else {
    6790           95 :             thisDXCoil.FindCompanionUpStreamCoil = false;
    6791              :         }
    6792              :     } // IF(DXCoil(DXCoilNum)%FindCompanionUpStreamCoil)THEN
    6793              : 
    6794              :     // CR7308 - Wait for zone and air loop equipment to be simulated, then print out report variables
    6795       539063 :     if (state.dataDXCoils->CrankcaseHeaterReportVarFlag) {
    6796         1258 :         if (state.dataAirLoop->AirLoopInputsFilled) {
    6797              :             //     Set report variables for DX cooling coils that will have a crankcase heater (all DX coils not used in a HP AC unit)
    6798           90 :             for (DXCoilNumTemp = 1; DXCoilNumTemp <= state.dataDXCoils->NumDXCoils; ++DXCoilNumTemp) {
    6799           60 :                 if ((state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) ||
    6800          103 :                     (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) ||
    6801           43 :                     (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling)) {
    6802           18 :                     if (state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower) {
    6803           32 :                         SetupOutputVariable(state,
    6804              :                                             "Cooling Coil Crankcase Heater Electricity Rate",
    6805              :                                             Constant::Units::W,
    6806           16 :                                             state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterPower,
    6807              :                                             OutputProcessor::TimeStepType::System,
    6808              :                                             OutputProcessor::StoreType::Average,
    6809           16 :                                             state.dataDXCoils->DXCoil(DXCoilNumTemp).Name);
    6810           32 :                         SetupOutputVariable(state,
    6811              :                                             "Cooling Coil Crankcase Heater Electricity Energy",
    6812              :                                             Constant::Units::J,
    6813           16 :                                             state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterConsumption,
    6814              :                                             OutputProcessor::TimeStepType::System,
    6815              :                                             OutputProcessor::StoreType::Sum,
    6816           16 :                                             state.dataDXCoils->DXCoil(DXCoilNumTemp).Name,
    6817              :                                             Constant::eResource::Electricity,
    6818              :                                             OutputProcessor::Group::HVAC,
    6819              :                                             OutputProcessor::EndUseCat::Cooling);
    6820           16 :                         state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower = false;
    6821              :                     }
    6822              :                 }
    6823              :             }
    6824           30 :             state.dataDXCoils->CrankcaseHeaterReportVarFlag = false;
    6825              :         } //(AirLoopInputsFilled)THEN
    6826              :     }     //(CrankcaseHeaterReportVarFlag)THEN
    6827              : 
    6828       539063 :     if (!state.dataGlobal->SysSizingCalc && state.dataDXCoils->MySizeFlag(DXCoilNum)) {
    6829              :         // for each coil, do the sizing once.
    6830           69 :         SizeDXCoil(state, DXCoilNum);
    6831           69 :         state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
    6832              : 
    6833           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
    6834           35 :             thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    6835              : 
    6836           47 :             Mode = 1;
    6837              :             // Check for zero capacity or zero max flow rate
    6838           47 :             if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
    6839            0 :                 ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
    6840            0 :                 ErrorsFound = true;
    6841              :             }
    6842           47 :             if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
    6843            0 :                 ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
    6844            0 :                 ErrorsFound = true;
    6845              :             }
    6846           47 :             if (ErrorsFound) {
    6847            0 :                 ShowFatalError(state, "Preceding condition causes termination.");
    6848              :             }
    6849              : 
    6850              :             // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    6851           47 :             if (thisDXCoil.DXCoilType_Num !=
    6852              :                 HVAC::CoilVRF_FluidTCtrl_Cooling) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
    6853           41 :                 RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
    6854           82 :                 if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    6855           41 :                     ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    6856            2 :                     ShowWarningError(state,
    6857            2 :                                      format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range.",
    6858            1 :                                             thisDXCoil.DXCoilType,
    6859            1 :                                             thisDXCoil.Name));
    6860            2 :                     ShowContinueError(state,
    6861            2 :                                       format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    6862              :                                              "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
    6863            1 :                                              HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    6864              :                                              RatedVolFlowPerRatedTotCap,
    6865            1 :                                              HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    6866              :                 }
    6867              :             }
    6868              : 
    6869           94 :             thisDXCoil.RatedAirMassFlowRate(Mode) =
    6870           47 :                 thisDXCoil.RatedAirVolFlowRate(Mode) *
    6871           47 :                 PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
    6872              :             // get high speed rated coil bypass factor
    6873           47 :             thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
    6874           47 :                                                 thisDXCoil.DXCoilType,
    6875           47 :                                                 thisDXCoil.Name,
    6876              :                                                 RatedInletAirTemp,
    6877              :                                                 RatedInletAirHumRat,
    6878           47 :                                                 thisDXCoil.RatedTotCap(Mode),
    6879           47 :                                                 thisDXCoil.RatedAirVolFlowRate(Mode),
    6880           47 :                                                 thisDXCoil.RatedSHR(Mode));
    6881              : 
    6882              :             // call coil model with everything set at rating point
    6883           47 :             thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
    6884           47 :             thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
    6885           47 :             thisDXCoil.InletAirTemp = RatedInletAirTemp;
    6886              :             Real64 tempInletAirHumRat =
    6887           47 :                 Psychrometrics::PsyWFnTdbTwbPb(state, RatedInletAirTemp, RatedInletWetBulbTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
    6888              :             // DXCoil( DXCoilNum ).InletAirHumRat = RatedInletAirHumRat; // this seems inconsistent with dry bulb and wetbulb, filed NREL issue
    6889              :             // #5934  Real64 tempInletAirWetBulb = Psychrometrics::PsyTwbFnTdbWPb( RatedInletAirTemp, RatedInletAirHumRat,
    6890              :             // DataEnvironment::StdPressureSeaLevel );
    6891           47 :             thisDXCoil.InletAirHumRat = tempInletAirHumRat;
    6892           47 :             thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTemp, tempInletAirHumRat);
    6893              : 
    6894              :             // store environment data fill back in after rating point calc is over
    6895           47 :             Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
    6896           47 :             Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
    6897           47 :             Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
    6898           47 :             Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
    6899           47 :             Real64 ratedOutdoorAirWetBulb = 23.9; // from I/O ref. more precise value?
    6900           47 :             state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTemp;
    6901           47 :             state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
    6902           47 :             state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
    6903           94 :             state.dataEnvrn->OutHumRat =
    6904           47 :                 Psychrometrics::PsyWFnTdbTwbPb(state, RatedOutdoorAirTemp, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
    6905           47 :             if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
    6906           14 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTemp;
    6907           14 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
    6908           14 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
    6909              :             }
    6910              : 
    6911              :             // calculate coil model at rating point
    6912           47 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
    6913           31 :                 CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, _, 1.0);
    6914           16 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    6915            3 :                 CalcMultiSpeedDXCoil(state, DXCoilNum, 1.0, 1.0);
    6916           13 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
    6917            7 :                 CalcVRFCoolingCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _, _);
    6918            6 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    6919            6 :                 CalcVRFCoolingCoil_FluidTCtrl(
    6920              :                     state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _, Constant::MaxCap);
    6921              :             }
    6922              : 
    6923              :             // coil outlets
    6924           47 :             Real64 RatedOutletWetBulb(0.0);
    6925           47 :             RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
    6926              :                 state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
    6927              : 
    6928           47 :             state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
    6929              :                 state,
    6930           47 :                 thisDXCoil.Name,
    6931           47 :                 thisDXCoil.DXCoilType,
    6932              :                 thisDXCoil.TotalCoolingEnergyRate, // this is the report variable
    6933              :                 thisDXCoil.SensCoolingEnergyRate,  // this is the report variable
    6934              :                 thisDXCoil.InletAirMassFlowRate,
    6935              :                 thisDXCoil.InletAirTemp,
    6936              :                 thisDXCoil.InletAirHumRat,
    6937              :                 RatedInletWetBulbTemp,
    6938              :                 thisDXCoil.OutletAirTemp,
    6939              :                 thisDXCoil.OutletAirHumRat,
    6940              :                 RatedOutletWetBulb,
    6941              :                 RatedOutdoorAirTemp,
    6942              :                 ratedOutdoorAirWetBulb,
    6943           47 :                 thisDXCoil.RatedCBF(Mode),
    6944              :                 -999.0); // coil effectiveness not define for DX
    6945              : 
    6946              :             // now replace the outdoor air conditions set above for one time rating point calc
    6947           47 :             state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
    6948           47 :             state.dataEnvrn->OutHumRat = holdOutHumRat;
    6949           47 :             state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
    6950           47 :             state.dataEnvrn->OutBaroPress = holdOutBaroPress;
    6951              :         }
    6952              : 
    6953           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    6954            0 :             for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
    6955            0 :                 for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
    6956            0 :                     Mode = DehumidModeNum * 2 + CapacityStageNum;
    6957              :                     // Check for zero capacity or zero max flow rate
    6958            0 :                     if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
    6959            0 :                         ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
    6960            0 :                         ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
    6961            0 :                         ErrorsFound = true;
    6962              :                     }
    6963            0 :                     if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
    6964            0 :                         ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
    6965            0 :                         ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
    6966            0 :                         ErrorsFound = true;
    6967              :                     }
    6968            0 :                     if (ErrorsFound) {
    6969            0 :                         ShowFatalError(state, "Preceding condition causes termination.");
    6970              :                     }
    6971              :                     // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    6972            0 :                     RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
    6973            0 :                     if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    6974            0 :                         ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    6975            0 :                         ShowWarningError(
    6976              :                             state,
    6977            0 :                             format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range.",
    6978            0 :                                    thisDXCoil.DXCoilType,
    6979            0 :                                    thisDXCoil.Name));
    6980            0 :                         ShowContinueError(state,
    6981            0 :                                           format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    6982              :                                                  "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
    6983            0 :                                                  HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    6984              :                                                  RatedVolFlowPerRatedTotCap,
    6985            0 :                                                  HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    6986            0 :                         ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
    6987              :                     }
    6988            0 :                     thisDXCoil.RatedAirMassFlowRate(Mode) =
    6989            0 :                         thisDXCoil.RatedAirVolFlowRate(Mode) *
    6990            0 :                         PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
    6991              :                     // get rated coil bypass factor
    6992            0 :                     thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
    6993            0 :                                                         thisDXCoil.CoilPerformanceType(Mode),
    6994            0 :                                                         thisDXCoil.CoilPerformanceName(Mode),
    6995              :                                                         RatedInletAirTemp,
    6996              :                                                         RatedInletAirHumRat,
    6997            0 :                                                         thisDXCoil.RatedTotCap(Mode),
    6998            0 :                                                         thisDXCoil.RatedAirVolFlowRate(Mode),
    6999            0 :                                                         thisDXCoil.RatedSHR(Mode));
    7000              :                 } // End capacity stages loop
    7001              :             }     // End dehumidification modes loop
    7002              :         }
    7003              : 
    7004           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
    7005           58 :             thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    7006              : 
    7007           17 :             Mode = 1;
    7008           17 :             if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
    7009            0 :                 ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
    7010            0 :                 ErrorsFound = true;
    7011              :             }
    7012           17 :             if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
    7013            0 :                 ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
    7014            0 :                 ErrorsFound = true;
    7015              :             }
    7016           17 :             if (ErrorsFound) {
    7017            0 :                 ShowFatalError(state, "Preceding condition causes termination.");
    7018              :             }
    7019           17 :             RatedHeatPumpIndoorAirTemp = 21.11;  // 21.11C or 70F
    7020           17 :             RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
    7021           34 :             thisDXCoil.RatedAirMassFlowRate(Mode) =
    7022           17 :                 thisDXCoil.RatedAirVolFlowRate(Mode) *
    7023           17 :                 PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
    7024              : 
    7025              :             // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    7026           17 :             if (thisDXCoil.DXCoilType_Num !=
    7027              :                 HVAC::CoilVRF_FluidTCtrl_Heating) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
    7028           11 :                 RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
    7029           22 :                 if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    7030           11 :                     ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    7031            2 :                     ShowWarningError(state,
    7032            2 :                                      format("Sizing: {} {}: Rated air volume flow rate per watt of rated total heating capacity is out of range.",
    7033            1 :                                             thisDXCoil.DXCoilType,
    7034            1 :                                             thisDXCoil.Name));
    7035            2 :                     ShowContinueError(state,
    7036            2 :                                       format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    7037              :                                              "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
    7038            1 :                                              HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    7039              :                                              RatedVolFlowPerRatedTotCap,
    7040            1 :                                              HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    7041              :                 }
    7042              :             }
    7043              : 
    7044              :             // call coil model with everything set at rating point
    7045           17 :             thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
    7046           17 :             thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
    7047              : 
    7048           17 :             thisDXCoil.InletAirTemp = RatedInletAirTempHeat;
    7049           17 :             Real64 tempInletAirHumRat = Psychrometrics::PsyWFnTdbTwbPb(
    7050              :                 state, RatedInletAirTempHeat, RatedInletWetBulbTempHeat, DataEnvironment::StdPressureSeaLevel, RoutineName);
    7051           17 :             thisDXCoil.InletAirHumRat = tempInletAirHumRat;
    7052           17 :             thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTempHeat, tempInletAirHumRat);
    7053              : 
    7054              :             // store environment data fill back in after rating point calc is over
    7055           17 :             Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
    7056           17 :             Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
    7057           17 :             Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
    7058           17 :             Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
    7059              : 
    7060           17 :             state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTempHeat;
    7061              : 
    7062           17 :             Real64 ratedOutdoorAirWetBulb = 6.11; // from I/O ref. more precise value?
    7063           17 :             state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
    7064           17 :             state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
    7065           17 :             state.dataEnvrn->OutHumRat = Psychrometrics::PsyWFnTdbTwbPb(
    7066              :                 state, RatedOutdoorAirTempHeat, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
    7067              : 
    7068           17 :             if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
    7069            6 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTempHeat;
    7070            6 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
    7071            6 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
    7072              :             }
    7073              : 
    7074              :             // calculate coil model at rating point
    7075           17 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
    7076            4 :                 CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, 1.0);
    7077           13 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
    7078            7 :                 CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
    7079            6 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    7080            6 :                 CalcVRFHeatingCoil_FluidTCtrl(state, HVAC::CompressorOp::On, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
    7081              :             }
    7082              :             // coil outlets
    7083           17 :             Real64 RatedOutletWetBulb(0.0);
    7084           17 :             RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
    7085              :                 state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
    7086              : 
    7087           17 :             state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
    7088              :                 state,
    7089           17 :                 thisDXCoil.Name,
    7090           17 :                 thisDXCoil.DXCoilType,
    7091              :                 thisDXCoil.TotalHeatingEnergyRate, // this is the report variable
    7092              :                 thisDXCoil.TotalHeatingEnergyRate, // this is the report variable
    7093              :                 thisDXCoil.InletAirMassFlowRate,
    7094              :                 thisDXCoil.InletAirTemp,
    7095              :                 thisDXCoil.InletAirHumRat,
    7096              :                 RatedInletWetBulbTempHeat,
    7097              :                 thisDXCoil.OutletAirTemp,
    7098              :                 thisDXCoil.OutletAirHumRat,
    7099              :                 RatedOutletWetBulb,
    7100              :                 RatedOutdoorAirTempHeat,
    7101              :                 ratedOutdoorAirWetBulb,
    7102           17 :                 thisDXCoil.RatedCBF(Mode),
    7103              :                 -999.0); // coil effectiveness not define for DX
    7104              : 
    7105              :             // now replace the outdoor air conditions set above for one time rating point calc
    7106           17 :             state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
    7107           17 :             state.dataEnvrn->OutHumRat = holdOutHumRat;
    7108           17 :             state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
    7109           17 :             state.dataEnvrn->OutBaroPress = holdOutBaroPress;
    7110              :         }
    7111              : 
    7112           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7113              :             // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    7114            3 :             RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate2 / thisDXCoil.RatedTotCap2;
    7115            6 :             if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    7116            3 :                 ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    7117            0 :                 ShowWarningError(state,
    7118            0 :                                  format("Coil:Cooling:DX:TwoSpeed \"{}\": At low speed rated air volume flow rate per watt of rated total cooling "
    7119              :                                         "capacity is out of range.",
    7120            0 :                                         thisDXCoil.Name));
    7121            0 :                 ShowContinueError(state,
    7122            0 :                                   format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    7123              :                                          "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
    7124            0 :                                          HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    7125              :                                          RatedVolFlowPerRatedTotCap,
    7126            0 :                                          HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    7127              :             }
    7128              : 
    7129            3 :             thisDXCoil.RatedAirMassFlowRate2 =
    7130            6 :                 thisDXCoil.RatedAirVolFlowRate2 *
    7131            3 :                 PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
    7132              :             // get low speed rated coil bypass factor
    7133            6 :             thisDXCoil.RatedCBF2 = CalcCBF(state,
    7134            3 :                                            thisDXCoil.DXCoilType,
    7135            3 :                                            thisDXCoil.Name,
    7136              :                                            RatedInletAirTemp,
    7137              :                                            RatedInletAirHumRat,
    7138              :                                            thisDXCoil.RatedTotCap2,
    7139              :                                            thisDXCoil.RatedAirVolFlowRate2,
    7140              :                                            thisDXCoil.RatedSHR2);
    7141              : 
    7142              :             // call for standard ratings for two-speed DX coil
    7143            3 :             if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air) {
    7144            2 :                 CalcTwoSpeedDXCoilStandardRating(state, DXCoilNum);
    7145              :             }
    7146              :         }
    7147              : 
    7148              :         // Multispeed Cooling
    7149           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
    7150           16 :             for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    7151              :                 // Check for zero capacity or zero max flow rate
    7152           11 :                 if (thisDXCoil.MSRatedTotCap(Mode) <= 0.0) {
    7153            0 :                     ShowSevereError(state,
    7154            0 :                                     format("Sizing: {} {} has zero rated total capacity at speed {}", thisDXCoil.DXCoilType, thisDXCoil.Name, Mode));
    7155            0 :                     ErrorsFound = true;
    7156              :                 }
    7157           11 :                 if (thisDXCoil.MSRatedAirVolFlowRate(Mode) <= 0.0) {
    7158            0 :                     ShowSevereError(state,
    7159            0 :                                     format("Sizing: {} {} has zero rated air flow rate at speed {}", thisDXCoil.DXCoilType, thisDXCoil.Name, Mode));
    7160            0 :                     ErrorsFound = true;
    7161              :                 }
    7162           11 :                 if (ErrorsFound) {
    7163            0 :                     ShowFatalError(state, "Preceding condition causes termination.");
    7164              :                 }
    7165              :                 // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    7166           11 :                 RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
    7167           22 :                 if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    7168           11 :                     ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    7169            0 :                     ShowWarningError(
    7170              :                         state,
    7171            0 :                         format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range at speed {}",
    7172            0 :                                thisDXCoil.DXCoilType,
    7173            0 :                                thisDXCoil.Name,
    7174              :                                Mode));
    7175            0 :                     ShowContinueError(state,
    7176            0 :                                       format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    7177              :                                              "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
    7178            0 :                                              HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    7179              :                                              RatedVolFlowPerRatedTotCap,
    7180            0 :                                              HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    7181              :                 }
    7182           22 :                 thisDXCoil.MSRatedAirMassFlowRate(Mode) =
    7183           11 :                     thisDXCoil.MSRatedAirVolFlowRate(Mode) *
    7184           11 :                     PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
    7185              :                 // get high speed rated coil bypass factor
    7186           11 :                 thisDXCoil.MSRatedCBF(Mode) = CalcCBF(state,
    7187           11 :                                                       thisDXCoil.DXCoilType,
    7188           11 :                                                       thisDXCoil.Name,
    7189              :                                                       RatedInletAirTemp,
    7190              :                                                       RatedInletAirHumRat,
    7191           11 :                                                       thisDXCoil.MSRatedTotCap(Mode),
    7192           11 :                                                       thisDXCoil.MSRatedAirVolFlowRate(Mode),
    7193           11 :                                                       thisDXCoil.MSRatedSHR(Mode));
    7194              :             }
    7195              :         }
    7196              : 
    7197              :         // Multispeed Heating
    7198           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    7199            0 :             RatedHeatPumpIndoorAirTemp = 21.11;  // 21.11C or 70F
    7200            0 :             RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
    7201            0 :             for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    7202              : 
    7203            0 :                 thisDXCoil.MSRatedAirMassFlowRate(Mode) =
    7204            0 :                     thisDXCoil.MSRatedAirVolFlowRate(Mode) *
    7205            0 :                     PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
    7206              :                 // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    7207            0 :                 RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
    7208            0 :                 if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    7209            0 :                     ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    7210            0 :                     ShowWarningError(state,
    7211            0 :                                      format("Coil:Heating:DX:MultiSpeed {}: Rated air volume flow rate per watt of rated total heating capacity "
    7212              :                                             "is out of range at speed {}",
    7213            0 :                                             thisDXCoil.Name,
    7214              :                                             Mode));
    7215            0 :                     ShowContinueError(state,
    7216            0 :                                       format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    7217              :                                              "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
    7218            0 :                                              HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    7219              :                                              RatedVolFlowPerRatedTotCap,
    7220            0 :                                              HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    7221              :                 }
    7222              :             }
    7223              :         }
    7224              : 
    7225              :         // store fan info for coil
    7226           69 :         state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
    7227           69 :             state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType, thisDXCoil.SupplyFanIndex);
    7228              :     }
    7229              : 
    7230       539063 :     AirInletNode = thisDXCoil.AirInNode;
    7231              : 
    7232              :     // Each iteration, load the coil data structure with the inlet conditions
    7233              : 
    7234       539063 :     thisDXCoil.InletAirMassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
    7235       539063 :     thisDXCoil.InletAirMassFlowRateMax =
    7236       539063 :         max(state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax, state.dataLoopNodes->Node(AirInletNode).MassFlowRate);
    7237       539063 :     thisDXCoil.InletAirTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
    7238       539063 :     thisDXCoil.InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
    7239       539063 :     thisDXCoil.InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
    7240              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    7241              :     //  DXCoil(DXCoilNum)%InletAirPressure        = Node(AirInletNode)%Press
    7242              : 
    7243       539063 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    7244       128165 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
    7245            0 :             thisDXCoil.EvapInletWetBulb = PsyTwbFnTdbWPb(state,
    7246            0 :                                                          state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).ZT,
    7247            0 :                                                          state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).airHumRat,
    7248            0 :                                                          state.dataEnvrn->OutBaroPress,
    7249              :                                                          RoutineName);
    7250              :         }
    7251              :     }
    7252              : 
    7253       539063 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    7254          161 :         thisDXCoil.TotalHeatingEnergyRate = 0.0;
    7255          161 :         thisDXCoil.ElecWaterHeatingPower = 0.0;
    7256              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    7257              :         //  DXCoil(DXCoilNum)%InletAirPressure         = StdBaroPress
    7258              : 
    7259              :         //   HPWH's that use an inlet air temperature schedule also need to have a valid barometric pressure
    7260              :         //   The DX Coil used in HPWH's does not know if it is using a scheduled inlet temperature so check the node pressure
    7261          161 :         if (thisDXCoil.CondenserInletNodeNum(1) > 0) {
    7262          161 :             if (state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press == 0.0) {
    7263            2 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press = state.dataEnvrn->StdBaroPress;
    7264              :             }
    7265              :         }
    7266              :     }
    7267       539063 :     thisDXCoil.BasinHeaterPower = 0.0;
    7268              : 
    7269       539063 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
    7270            0 :         thisDXCoil.CompressorPartLoadRatio = 0.0;
    7271            0 :         thisDXCoil.SecCoilSensibleHeatGainRate = 0.0;
    7272            0 :         thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
    7273            0 :         thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
    7274            0 :         thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
    7275              :     }
    7276       539063 : }
    7277              : 
    7278           96 : void SizeDXCoil(EnergyPlusData &state, int const DXCoilNum)
    7279              : {
    7280              : 
    7281              :     // SUBROUTINE INFORMATION:
    7282              :     //       AUTHOR         Fred Buhl
    7283              :     //       DATE WRITTEN   January 2002
    7284              :     //                      Feb 2005, M. J. Witte, GARD Analytics, Inc. Add new coil type COIL:DX:MultiMode:CoolingEmpirical.
    7285              :     //                      Jul 2005, R. Raustad, FSEC. Add new coil type COIL:DX:HEATPUMPWATERHEATER
    7286              :     //                      Jun 2007, L. Gu, FSEC. Add new coil type COIL:DX:MULTISPEED:COOLING and HEATING
    7287              :     //                      Jan 2011, B. Griffith, NREL. add EMS overrides for autosized fields
    7288              :     //                      Aug 2013, D. Kang. add component sizing table entries
    7289              :     //                      May 2014, R. Raustad, FSEC. moved sizing calculations to common routine
    7290              :     //                      Aug 2015, R. Zhang, LBNL. Add new coil types for VRF_FluidTCtrl
    7291              :     //       RE-ENGINEERED  na
    7292              : 
    7293              :     // PURPOSE OF THIS SUBROUTINE:
    7294              :     // This subroutine is for sizing DX Coil components for which nominal capacity and air flow rate
    7295              :     // have not been specified in the input.
    7296              : 
    7297              :     // METHODOLOGY EMPLOYED:
    7298              :     // Obtains cooling capacities and air flow rates from the zone or system sizing arrays.
    7299              : 
    7300              :     // Using/Aliasing
    7301              :     using namespace DataSizing;
    7302              :     using Curve::CurveValue;
    7303              : 
    7304              :     using namespace OutputReportPredefined;
    7305              :     using StandardRatings::CalcDXCoilStandardRating;
    7306              : 
    7307              :     // SUBROUTINE PARAMETER DEFINITIONS:
    7308              :     static constexpr std::string_view RoutineName("SizeDXCoil");
    7309              : 
    7310              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    7311              :     Real64 CoilInTemp;       // DX coil inlet temperature
    7312              :     int CapacityStageNum;    // Loop index for 1,Number of capacity stages
    7313              :     int DehumidModeNum;      // Loop index for 1,Number of enhanced dehumidification modes
    7314              :     int Mode;                // Operating mode for MultiMode DX coil; Always 1 for other coil types
    7315              :     int NumOfSpeedCompanion; // Number of speed for a companion cooling coil (Multispeed HO heating coil only
    7316           96 :     std::string equipName;
    7317              :     Real64 DefrostCapacityDes;             // Design defrost heater capacity for reporting
    7318              :     Real64 DefrostCapacityUser;            // Hard-sized defrost heater capacity for reporting
    7319              :     Real64 MSRatedAirVolFlowRateDes;       // Design multispeed rated air volume flow rate for reporting
    7320              :     Real64 MSRatedTotCapDesAtMaxSpeed;     // Design multispeed rated total capacity for reporting (at maximum speed)
    7321              :     Real64 MSRatedSHRDes;                  // Design multispeed rated SHR for reporting
    7322              :     Real64 MSEvapCondAirFlowDes;           // Design evaporative condenser air flow for reporting
    7323              :     Real64 MSEvapCondAirFlowUser;          // Hard-sized evaporative condenser air flow for reporting
    7324              :     Real64 MSEvapCondPumpElecNomPowerDes;  // Design evaporative condenser pump rated power consumption for reporting
    7325              :     Real64 MSEvapCondPumpElecNomPowerUser; // Hard-sized evaporative condenser pump rated power consumption for reporting
    7326              :     bool HardSizeNoDesRun;                 // Indicator to a hard-sized field with no design sizing data
    7327              :     bool IsAutoSize;                       // Indicator to autosize for reporting
    7328              :     bool SizingDesRunThisAirSys;           // true if a particular air system had a Sizing:System object and system sizing done
    7329              :     bool SizingDesRunThisZone;             // true if a particular zone had a Sizing:Zone object and zone sizing was done
    7330           96 :     std::string CompName;                  // component name
    7331           96 :     std::string CompType;                  // component type
    7332           96 :     std::string SizingString;              // input field sizing description (e.g., Nominal Capacity)
    7333           96 :     bool bPRINT = true;                    // TRUE if sizing is reported to output (eio)
    7334              :     Real64 TempSize;                       // autosized value of coil input field
    7335           96 :     int FieldNum = 2;                      // IDD numeric field number where input field description is found
    7336              :     bool PrintFlag;                        // TRUE when sizing information is reported in the eio file
    7337              :     bool SizeSecDXCoil;                    // if true do sizing calculation for secondary coil
    7338              :     Real64 SecCoilAirFlowDes;              // Design secondary DX coil air flow for reporting
    7339              :     Real64 SecCoilAirFlowUser;             // Hard-sized secondary DX coil air flow for reporting
    7340              : 
    7341              :     // Initiate all reporting variables
    7342           96 :     if (state.dataSize->SysSizingRunDone || state.dataSize->ZoneSizingRunDone) {
    7343           72 :         HardSizeNoDesRun = false;
    7344              :     } else {
    7345           24 :         HardSizeNoDesRun = true;
    7346              :     }
    7347              : 
    7348           96 :     if (state.dataSize->CurSysNum > 0) {
    7349           38 :         CheckThisAirSystemForSizing(state, state.dataSize->CurSysNum, SizingDesRunThisAirSys);
    7350              :     } else {
    7351           58 :         SizingDesRunThisAirSys = false;
    7352              :     }
    7353           96 :     if (state.dataSize->CurZoneEqNum > 0) {
    7354           43 :         CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
    7355              :     } else {
    7356           53 :         SizingDesRunThisZone = false;
    7357              :     }
    7358              : 
    7359           96 :     IsAutoSize = false;
    7360           96 :     SizeSecDXCoil = false;
    7361           96 :     MSRatedTotCapDesAtMaxSpeed = 0.0;
    7362           96 :     DefrostCapacityDes = 0.0;
    7363           96 :     DefrostCapacityUser = 0.0;
    7364           96 :     MSRatedAirVolFlowRateDes = 0.0;
    7365           96 :     MSRatedSHRDes = 0.0;
    7366           96 :     MSEvapCondAirFlowDes = 0.0;
    7367           96 :     MSEvapCondAirFlowUser = 0.0;
    7368           96 :     MSEvapCondPumpElecNomPowerDes = 0.0;
    7369           96 :     MSEvapCondPumpElecNomPowerUser = 0.0;
    7370           96 :     SecCoilAirFlowDes = 0.0;
    7371           96 :     SecCoilAirFlowUser = 0.0;
    7372              : 
    7373              :     // Sizer classes
    7374           96 :     CoolingSHRSizer sizerCoolingSHR;
    7375           96 :     bool ErrorsFound = false;
    7376              : 
    7377           96 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    7378              : 
    7379              :     // NOTE: we are sizing COIL:DX:HeatingEmpirical on the COOLING load. Thus the cooling and
    7380              :     // and heating capacities of a DX heat pump system will be identical. In real life the AHRI
    7381              :     // heating and cooling capacities are close but not identical.
    7382          192 :     for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
    7383          192 :         for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
    7384           96 :             Mode = DehumidModeNum * 2 + CapacityStageNum;
    7385           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    7386           90 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    7387            8 :                 if (thisDXCoil.RatedAirVolFlowRate(1) == Constant::AutoCalculate) {
    7388              :                     // report autocalculated sizing
    7389            3 :                     PrintFlag = true;
    7390            3 :                     CompName = thisDXCoil.Name;
    7391            3 :                     CompType = thisDXCoil.DXCoilType;
    7392              :                     // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00005035
    7393            3 :                     state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
    7394            3 :                     state.dataSize->DataFractionUsedForSizing = 0.00005035;
    7395            3 :                     TempSize = AutoSize;
    7396            3 :                     AutoCalculateSizer sizerHPRatedAirVolFlow;
    7397            3 :                     std::string stringOverride = "Rated Evaporator Air Flow Rate [m3/s]";
    7398            3 :                     if (state.dataGlobal->isEpJSON) stringOverride = "rated_evaporator_air_flow_rate [m3/s]";
    7399            3 :                     sizerHPRatedAirVolFlow.overrideSizingString(stringOverride);
    7400            3 :                     sizerHPRatedAirVolFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7401            3 :                     thisDXCoil.RatedAirVolFlowRate(1) = sizerHPRatedAirVolFlow.size(state, TempSize, ErrorsFound);
    7402            3 :                     PrintFlag = false;
    7403            3 :                 }
    7404              : 
    7405            8 :                 if (thisDXCoil.RatedHPWHCondWaterFlow == Constant::AutoCalculate) {
    7406              :                     // report autocalculated sizing
    7407            3 :                     PrintFlag = true;
    7408            3 :                     CompName = thisDXCoil.Name;
    7409            3 :                     CompType = thisDXCoil.DXCoilType;
    7410              :                     // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00000004487
    7411            3 :                     state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
    7412            3 :                     state.dataSize->DataFractionUsedForSizing = 0.00000004487;
    7413            3 :                     TempSize = AutoSize;
    7414            3 :                     AutoCalculateSizer sizerHPWHCondWaterFlow;
    7415            3 :                     std::string stringOverride = "Rated Condenser Water Flow Rate [m3/s]";
    7416            3 :                     if (state.dataGlobal->isEpJSON) stringOverride = "rated_condenser_water_flow_rate [m3/s]";
    7417            3 :                     sizerHPWHCondWaterFlow.overrideSizingString(stringOverride);
    7418            3 :                     sizerHPWHCondWaterFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7419            3 :                     thisDXCoil.RatedHPWHCondWaterFlow = sizerHPWHCondWaterFlow.size(state, TempSize, ErrorsFound);
    7420            3 :                     PrintFlag = false;
    7421            3 :                 }
    7422            8 :             } else {
    7423           88 :                 PrintFlag = true;
    7424           88 :                 FieldNum = 0;
    7425           88 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    7426            0 :                     CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
    7427            0 :                     FieldNum = 4;
    7428            0 :                     state.dataSize->DataBypassFrac = thisDXCoil.BypassedFlowFrac(Mode);
    7429           88 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
    7430            5 :                     CompName = thisDXCoil.Name;
    7431            5 :                     FieldNum = 3;
    7432              :                     // doesn't look like this is needed for air flow sizing, only for heating capacity sizing
    7433           10 :                     state.dataSize->DataCoolCoilCap =
    7434            5 :                         state.dataSize->DXCoolCap; // pass global variable used only for heat pumps (i.e., DX cooling and heating coils)
    7435            5 :                     if ((thisDXCoil.IsSecondaryDXCoilInZone) &&
    7436            0 :                         (thisDXCoil.CondenserType(1) ==
    7437              :                          DataHeatBalance::RefrigCondenserType::Air)) { // secondary DX coil in secondary zone is specified
    7438            0 :                         SizeSecDXCoil = true;
    7439              :                     }
    7440           83 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
    7441            7 :                     CompName = thisDXCoil.Name;
    7442            7 :                     FieldNum = 2;
    7443           76 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
    7444            7 :                     CompName = thisDXCoil.Name;
    7445            7 :                     FieldNum = 3;
    7446           69 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    7447            6 :                     CompName = thisDXCoil.Name;
    7448           63 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    7449            6 :                     CompName = thisDXCoil.Name;
    7450           57 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
    7451           10 :                     thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
    7452           10 :                     CompName = thisDXCoil.Name;
    7453           10 :                     PrintFlag = false;
    7454           47 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    7455            7 :                     thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
    7456            7 :                     CompName = thisDXCoil.Name;
    7457            7 :                     PrintFlag = false;
    7458              :                 } else {
    7459           40 :                     CompName = thisDXCoil.Name;
    7460           40 :                     FieldNum = 4;
    7461              :                 }
    7462              : 
    7463           88 :                 TempSize = thisDXCoil.RatedAirVolFlowRate(Mode);
    7464           88 :                 if (FieldNum > 0) {
    7465           59 :                     SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
    7466              :                 } else {
    7467           29 :                     SizingString = "Rated Air Flow Rate [m3/s]";
    7468              :                 }
    7469           88 :                 CompType = thisDXCoil.DXCoilType;
    7470           88 :                 state.dataSize->DataIsDXCoil = true;
    7471           88 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
    7472           88 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
    7473           88 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating ||
    7474           75 :                     thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
    7475           25 :                     bool errorsFound = false;
    7476           25 :                     HeatingAirFlowSizer sizingHeatingAirFlow;
    7477           25 :                     sizingHeatingAirFlow.overrideSizingString(SizingString);
    7478              :                     // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    7479           25 :                     sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7480           25 :                     thisDXCoil.RatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
    7481           25 :                 } else {
    7482           63 :                     bool errorsFound = false;
    7483           63 :                     CoolingAirFlowSizer sizingCoolingAirFlow;
    7484           63 :                     sizingCoolingAirFlow.overrideSizingString(SizingString);
    7485              :                     // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    7486           63 :                     sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7487           63 :                     thisDXCoil.RatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    7488           63 :                 }
    7489           88 :                 state.dataSize->DataIsDXCoil = false;
    7490           88 :                 state.dataSize->DataEMSOverrideON = false;
    7491           88 :                 state.dataSize->DataEMSOverride = 0.0;
    7492           88 :                 state.dataSize->DataBypassFrac = 0.0;
    7493              :             }
    7494              : 
    7495           96 :             state.dataSize->DataFlowUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
    7496              :             // get autosized air flow for capacity calc's if capacity is not autosized
    7497              :             // *** RAR this if block is a last minute addition to correct capacity reporting when not autosized and a sizing run is done. Test
    7498              :             // suite was not run with this code included. *** The question here is if the autosized air flow rate or the user specified air flow
    7499              :             // rate should be used to calculate capacity removing this for now until more is known
    7500              :             //                if ( DXCoil( DXCoilNum ).RatedTotCap( Mode ) != AutoSize && ( ( SysSizingRunDone && CurSysNum > 0 ) ||
    7501              :             //(  ZoneSizingRunDone && CurZoneEqNum > 0 ) ) ) {                     if ( DXCoil( DXCoilNum ).DXCoilType_Num ==
    7502              :             // HVAC::CoilDX_CoolingTwoStageWHumControl ) {                         SizingMethod = CoolingAirflowSizing;
    7503              :             //                        DataBypassFrac = DXCoil ( DXCoilNum ).BypassedFlowFrac ( Mode );
    7504              :             //                    } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical ) {
    7505              :             //                        SizingMethod = HeatingAirflowSizing;
    7506              :             ////                        DataCoolCoilCap = DXCoolCap; // pass global variable used only for heat pumps (i.e.,
    7507              :             /// DX  cooling  and  heating coils)
    7508              :             //                    } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilVRF_Heating ) {
    7509              :             //                        SizingMethod = HeatingAirflowSizing;
    7510              :             //                    } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilVRF_Cooling ) {
    7511              :             //                        SizingMethod = CoolingAirflowSizing;
    7512              :             //                    } else {
    7513              :             //                        SizingMethod = CoolingAirflowSizing;
    7514              :             //                    }
    7515              :             //                    CompName = DXCoil( DXCoilNum ).Name;
    7516              :             //                    TempSize = AutoSize;
    7517              :             //                    SizingString.clear(); // don't care
    7518              :             //                    CompType = DXCoil( DXCoilNum ).DXCoilType;
    7519              :             //                    DataIsDXCoil = true;
    7520              :             //                    DataEMSOverrideON = DXCoil ( DXCoilNum ).RatedAirVolFlowRateEMSOverrideON ( Mode );
    7521              :             //                    DataEMSOverride = DXCoil( DXCoilNum ).RatedAirVolFlowRateEMSOverrideValue( Mode );
    7522              :             //                  CoolingAirFlowSizer sizingCoolingAirFlow;
    7523              :             //                  sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    7524              :             //                  sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    7525              :             //                  DataAirFlowUsedForSizing = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    7526              :             //                    DataIsDXCoil = false; // don't need this and next 2, they are just overwritten below. Delete
    7527              :             // on  next  pass so testing will show problems if any.                     DataEMSOverrideON = false;
    7528              :             //                    DataEMSOverride = 0.0;
    7529              :             //                    DataBypassFrac = 0.0;
    7530              :             //                }
    7531           96 :             PrintFlag = true;
    7532           96 :             state.dataSize->DataTotCapCurveIndex = thisDXCoil.CCapFTemp(Mode);
    7533           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    7534            0 :                 CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
    7535            0 :                 FieldNum = 1;
    7536            0 :                 TempSize = thisDXCoil.RatedTotCap(Mode);
    7537            0 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7538           96 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
    7539           84 :                        thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    7540           18 :                 CompName = thisDXCoil.Name;
    7541           18 :                 FieldNum = 1;
    7542           18 :                 TempSize = thisDXCoil.RatedTotCap(Mode);
    7543           18 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7544           18 :                 state.dataSize->DataCoolCoilCap = state.dataSize->DXCoolCap;
    7545           78 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    7546           72 :                        thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    7547            8 :                 CompName = thisDXCoil.Name;
    7548            8 :                 FieldNum = 1;
    7549            8 :                 TempSize = thisDXCoil.RatedTotCap(Mode);
    7550            8 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7551            8 :                 PrintFlag = false;
    7552            8 :                 state.dataLoopNodes->Node(thisDXCoil.WaterInNode).Temp =
    7553            8 :                     thisDXCoil.RatedInletWaterTemp; // set the rated water inlet node for HPWHs for use in CalcHPWHDXCoil
    7554           70 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    7555            6 :                 CompName = thisDXCoil.Name;
    7556            6 :                 FieldNum = 1;
    7557            6 :                 TempSize = thisDXCoil.RatedTotCap(Mode);
    7558            6 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7559            6 :                 if (state.dataSize->CurZoneEqNum > 0) {
    7560            6 :                     CoilInTemp =
    7561            6 :                         state.dataSize->ZoneSizingRunDone ? state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp : 26;
    7562              :                 } else {
    7563            0 :                     if (state.dataSize->CurOASysNum > 0) {
    7564            0 :                         CoilInTemp =
    7565            0 :                             state.dataSize->SysSizingRunDone ? state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).OutTempAtCoolPeak : 32;
    7566              :                     } else {
    7567            0 :                         CoilInTemp =
    7568            0 :                             state.dataSize->SysSizingRunDone ? state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).MixTempAtCoolPeak : 26;
    7569              :                     }
    7570              :                 }
    7571            6 :                 CalcVRFCoilCapModFac(state, 0, _, CompName, CoilInTemp, _, _, _, state.dataSize->DataTotCapCurveValue);
    7572           64 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
    7573           10 :                 CompName = thisDXCoil.Name;
    7574           10 :                 FieldNum = 7 + (thisDXCoil.NumOfSpeeds - 1) * 13;
    7575           10 :                 state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
    7576           10 :                 TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
    7577           10 :                 PrintFlag = false;
    7578           10 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7579           54 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    7580            7 :                 CompName = thisDXCoil.Name;
    7581            7 :                 FieldNum = 10 + (thisDXCoil.NumOfSpeeds - 1) * 6;
    7582            7 :                 state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
    7583            7 :                 TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
    7584            7 :                 PrintFlag = false;
    7585            7 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7586              :             } else {
    7587           47 :                 CompName = thisDXCoil.Name;
    7588           47 :                 FieldNum = 1;
    7589           47 :                 TempSize = thisDXCoil.RatedTotCap(Mode);
    7590           47 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7591              :             }
    7592           96 :             CompType = thisDXCoil.DXCoilType;
    7593           96 :             state.dataSize->DataIsDXCoil = true;
    7594           96 :             state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    7595           96 :             state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    7596           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical ||
    7597           84 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    7598           25 :                 HeatingCapacitySizer sizerHeatingCapacity;
    7599           25 :                 sizerHeatingCapacity.overrideSizingString(SizingString);
    7600           25 :                 sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7601           25 :                 thisDXCoil.RatedTotCap(Mode) = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    7602           25 :             } else {
    7603           71 :                 CoolingCapacitySizer sizerCoolingCapacity;
    7604           71 :                 sizerCoolingCapacity.overrideSizingString(SizingString);
    7605           71 :                 sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7606           71 :                 thisDXCoil.RatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    7607           71 :             }
    7608           96 :             state.dataSize->DataIsDXCoil = false;
    7609           96 :             state.dataSize->DataFlowUsedForSizing = 0.0;
    7610           96 :             state.dataSize->DataCoolCoilCap = 0.0;
    7611           96 :             state.dataSize->DataTotCapCurveIndex = 0;
    7612           96 :             state.dataSize->DataEMSOverrideON = false;
    7613           96 :             state.dataSize->DataEMSOverride = 0.0;
    7614           96 :             state.dataSize->DataConstantUsedForSizing = 0.0;
    7615           96 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    7616           96 :             state.dataSize->DataTotCapCurveValue = 0.0;
    7617              : 
    7618              :             // Cooling coil capacity
    7619           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
    7620           56 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
    7621           49 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    7622           53 :                 state.dataSize->DXCoolCap = thisDXCoil.RatedTotCap(Mode);
    7623              :             }
    7624              : 
    7625              :             // Sizing DX cooling coil SHR
    7626           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
    7627           56 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
    7628           49 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    7629              : 
    7630           53 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    7631            0 :                     CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
    7632              :                 } else {
    7633           53 :                     CompName = thisDXCoil.Name;
    7634              :                 }
    7635           53 :                 CompType = thisDXCoil.DXCoilType;
    7636           53 :                 TempSize = thisDXCoil.RatedSHR(Mode);
    7637           53 :                 state.dataSize->DataDXSpeedNum = Mode;
    7638           53 :                 state.dataSize->DataFlowUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
    7639           53 :                 state.dataSize->DataCapacityUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7640           53 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
    7641           53 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
    7642           53 :                 bool ErrorsFound = false;
    7643           53 :                 sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7644           53 :                 thisDXCoil.RatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
    7645           53 :                 state.dataSize->DataDXSpeedNum = 0;
    7646           53 :                 state.dataSize->DataFlowUsedForSizing = 0.0;
    7647           53 :                 state.dataSize->DataCapacityUsedForSizing = 0.0;
    7648           53 :                 state.dataSize->DataEMSOverrideON = false;
    7649           53 :                 state.dataSize->DataEMSOverride = 0.0;
    7650              : 
    7651              :             } // End of Rated SHR
    7652              : 
    7653              :             // Sizing evaporator condenser air flow
    7654           98 :             if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow(Mode) != 0.0 &&
    7655            2 :                 (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
    7656            0 :                  thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    7657              : 
    7658            2 :                 AutoCalculateSizer sizerEvapCondAirFlow;
    7659            2 :                 std::string stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
    7660            2 :                 if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
    7661            2 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    7662            0 :                     CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
    7663              :                 } else {
    7664            2 :                     CompName = thisDXCoil.Name;
    7665            2 :                     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7666            1 :                         stringOverride = "High Speed Evaporative Condenser Air Flow Rate [m3/s]";
    7667            1 :                         if (state.dataGlobal->isEpJSON) stringOverride = "high_speed_evaporative_condenser_air_flow_rate [m3/s]";
    7668              :                     } else {
    7669            1 :                         stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
    7670            1 :                         if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
    7671              :                     }
    7672              :                 }
    7673            2 :                 CompType = thisDXCoil.DXCoilType;
    7674              :                 // Auto-size condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
    7675            2 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7676            2 :                 state.dataSize->DataFractionUsedForSizing = 0.000114;
    7677            2 :                 TempSize = thisDXCoil.EvapCondAirFlow(Mode);
    7678            2 :                 sizerEvapCondAirFlow.overrideSizingString(stringOverride);
    7679            2 :                 sizerEvapCondAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7680            2 :                 thisDXCoil.EvapCondAirFlow(Mode) = sizerEvapCondAirFlow.size(state, TempSize, ErrorsFound);
    7681            2 :             }
    7682              : 
    7683           96 :             if (SizeSecDXCoil) { // autosize secondary coil air flow rate for AirCooled condenser type
    7684            0 :                 IsAutoSize = false;
    7685            0 :                 if (thisDXCoil.SecCoilAirFlow == AutoSize) {
    7686            0 :                     IsAutoSize = true;
    7687              :                 }
    7688              :                 // Autosize Primary Coil Air Flow * Secondary Coil Scaling Factor
    7689            0 :                 SecCoilAirFlowDes = thisDXCoil.RatedAirVolFlowRate(1) * thisDXCoil.SecCoilAirFlowScalingFactor;
    7690            0 :                 if (IsAutoSize) {
    7691            0 :                     thisDXCoil.SecCoilAirFlow = SecCoilAirFlowDes;
    7692            0 :                     BaseSizer::reportSizerOutput(
    7693              :                         state, thisDXCoil.DXCoilType, thisDXCoil.Name, "Design Size Secondary Coil Air Flow Rate [m3/s]", SecCoilAirFlowDes);
    7694              :                 } else {
    7695            0 :                     if (thisDXCoil.SecCoilAirFlow > 0.0 && SecCoilAirFlowDes > 0.0 && !HardSizeNoDesRun) {
    7696            0 :                         SecCoilAirFlowUser = thisDXCoil.SecCoilAirFlow;
    7697            0 :                         BaseSizer::reportSizerOutput(state,
    7698              :                                                      thisDXCoil.DXCoilType,
    7699              :                                                      thisDXCoil.Name,
    7700              :                                                      "Design Size Secondary Coil Air Flow Rate [m3/s]",
    7701              :                                                      SecCoilAirFlowDes,
    7702              :                                                      "User-Specified Secondary Coil Air Flow Rate [m3/s]",
    7703              :                                                      SecCoilAirFlowUser);
    7704            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    7705            0 :                             if ((std::abs(SecCoilAirFlowDes - SecCoilAirFlowUser) / SecCoilAirFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
    7706            0 :                                 ShowMessage(
    7707              :                                     state,
    7708            0 :                                     format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
    7709            0 :                                 ShowContinueError(state, format("User-Specified Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowUser));
    7710            0 :                                 ShowContinueError(
    7711            0 :                                     state, format("differs from Design Size Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowDes));
    7712            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    7713            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    7714              :                             }
    7715              :                         }
    7716              :                     }
    7717              :                 }
    7718              :             }
    7719              : 
    7720              :             // Sizing evaporative condenser air flow 2
    7721           96 :             PrintFlag = true;
    7722           97 :             if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow2 != 0.0 &&
    7723            1 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7724            1 :                 CompName = thisDXCoil.Name;
    7725            1 :                 FieldNum = 15; // Low Speed Evaporative Condenser Air Flow Rate
    7726            1 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
    7727            1 :                 CompType = thisDXCoil.DXCoilType;
    7728              :                 // Autosize low speed condenser air flow to 1/3 Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
    7729            1 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7730            1 :                 state.dataSize->DataFractionUsedForSizing = 0.000114 * 0.3333;
    7731            1 :                 TempSize = thisDXCoil.EvapCondAirFlow2;
    7732            1 :                 AutoCalculateSizer sizerEvapCondAirFlow2;
    7733            1 :                 std::string stringOverride = "Low Speed Evaporative Condenser Air Flow Rate [m3/s]";
    7734            1 :                 if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_evaporative_condenser_air_flow_rate [m3/s]";
    7735            1 :                 sizerEvapCondAirFlow2.overrideSizingString(stringOverride);
    7736            1 :                 sizerEvapCondAirFlow2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7737            1 :                 thisDXCoil.EvapCondAirFlow2 = sizerEvapCondAirFlow2.size(state, TempSize, ErrorsFound);
    7738            1 :             }
    7739              : 
    7740              :             // Sizing evaporative condenser pump electric nominal power
    7741          108 :             if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower(Mode) != 0.0 &&
    7742           12 :                 (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
    7743            0 :                  thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    7744              : 
    7745           12 :                 AutoCalculateSizer sizerEvapCondPumpPower;
    7746           12 :                 std::string stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
    7747           12 :                 if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
    7748           12 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    7749            0 :                     CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
    7750              :                 } else {
    7751           12 :                     CompName = thisDXCoil.Name;
    7752           12 :                     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7753            1 :                         stringOverride = "High Speed Evaporative Condenser Pump Rated Power Consumption [W]";
    7754            1 :                         if (state.dataGlobal->isEpJSON) stringOverride = "high_speed_evaporative_condenser_pump_rated_power_consumption [W]";
    7755              :                     } else {
    7756           11 :                         stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
    7757           11 :                         if (state.dataGlobal->isEpJSON) stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
    7758              :                     }
    7759              :                 }
    7760           12 :                 CompType = thisDXCoil.DXCoilType;
    7761              :                 // Autosize high speed evap condenser pump power to Total Capacity * 0.004266 w/w (15 w/ton)
    7762           12 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7763           12 :                 state.dataSize->DataFractionUsedForSizing = 0.004266;
    7764           12 :                 TempSize = thisDXCoil.EvapCondPumpElecNomPower(Mode);
    7765           12 :                 sizerEvapCondPumpPower.overrideSizingString(stringOverride);
    7766           12 :                 sizerEvapCondPumpPower.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7767           12 :                 thisDXCoil.EvapCondPumpElecNomPower(Mode) = sizerEvapCondPumpPower.size(state, TempSize, ErrorsFound);
    7768           12 :             }
    7769              : 
    7770              :             // Sizing low speed evaporative condenser pump electric nominal power
    7771           97 :             if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower2 != 0.0 &&
    7772            1 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7773            1 :                 CompName = thisDXCoil.Name;
    7774            1 :                 CompType = thisDXCoil.DXCoilType;
    7775              :                 // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
    7776            1 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7777            1 :                 state.dataSize->DataFractionUsedForSizing = 0.004266 * 0.3333;
    7778            1 :                 TempSize = thisDXCoil.EvapCondPumpElecNomPower2;
    7779            1 :                 AutoCalculateSizer sizerEvapCondPumpPower2;
    7780            1 :                 std::string stringOverride = "Low Speed Evaporative Condenser Pump Rated Power Consumption [W]";
    7781            1 :                 if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_evaporative_condenser_pump_rated_power_consumption [W]";
    7782            1 :                 sizerEvapCondPumpPower2.overrideSizingString(stringOverride);
    7783            1 :                 sizerEvapCondPumpPower2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7784            1 :                 thisDXCoil.EvapCondPumpElecNomPower2 = sizerEvapCondPumpPower2.size(state, TempSize, ErrorsFound);
    7785            1 :             }
    7786              : 
    7787              :             //                // Sizing rated low speed air flow rate
    7788           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7789            4 :                 CompName = thisDXCoil.Name;
    7790            4 :                 CompType = thisDXCoil.DXCoilType;
    7791              :                 // Autosize low speed air flow rate to 1/3 high speed air flow rate
    7792            4 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
    7793            4 :                 state.dataSize->DataFractionUsedForSizing = 0.3333;
    7794            4 :                 TempSize = thisDXCoil.RatedAirVolFlowRate2;
    7795            4 :                 AutoCalculateSizer sizerLowSpdAirFlow;
    7796            4 :                 std::string stringOverride = "Low Speed Rated Air Flow Rate [m3/s]";
    7797            4 :                 if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_rated_air_flow_rate [m3/s]";
    7798            4 :                 sizerLowSpdAirFlow.overrideSizingString(stringOverride);
    7799            4 :                 sizerLowSpdAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7800            4 :                 thisDXCoil.RatedAirVolFlowRate2 = sizerLowSpdAirFlow.size(state, TempSize, ErrorsFound);
    7801            4 :             }
    7802              : 
    7803              :             //                // Sizing rated low speed total cooling capacity
    7804           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7805            4 :                 CompName = thisDXCoil.Name;
    7806            4 :                 CompType = thisDXCoil.DXCoilType;
    7807              :                 // Autosize low speed capacity to 1/3 high speed capacity
    7808            4 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7809            4 :                 state.dataSize->DataFractionUsedForSizing = 0.3333;
    7810            4 :                 TempSize = thisDXCoil.RatedTotCap2;
    7811            4 :                 AutoCalculateSizer sizerLowSpdCap;
    7812            4 :                 std::string stringOverride = "Low Speed Gross Rated Total Cooling Capacity [W]";
    7813            4 :                 if (state.dataGlobal->isEpJSON) stringOverride = "low_speed_gross_rated_total_cooling_capacity [W]";
    7814            4 :                 sizerLowSpdCap.overrideSizingString(stringOverride);
    7815            4 :                 sizerLowSpdCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7816            4 :                 thisDXCoil.RatedTotCap2 = sizerLowSpdCap.size(state, TempSize, ErrorsFound);
    7817            4 :             }
    7818              : 
    7819           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7820            4 :                 if (thisDXCoil.EvapCondAirFlow2 > thisDXCoil.EvapCondAirFlow(Mode)) {
    7821            0 :                     ShowSevereError(
    7822              :                         state,
    7823            0 :                         format("SizeDXCoil: {} {}, Evaporative Condenser low speed air flow must be less than or equal to high speed air flow.",
    7824            0 :                                thisDXCoil.DXCoilType,
    7825            0 :                                thisDXCoil.Name));
    7826            0 :                     ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.EvapCondAirFlow2, thisDXCoil.EvapCondAirFlow(Mode)));
    7827            0 :                     ShowFatalError(state, "Preceding conditions cause termination.");
    7828              :                 }
    7829              : 
    7830            4 :                 if (thisDXCoil.EvapCondPumpElecNomPower2 > thisDXCoil.EvapCondPumpElecNomPower(Mode)) {
    7831            0 :                     ShowSevereError(
    7832              :                         state,
    7833            0 :                         format("SizeDXCoil: {} {}, Evaporative Condenser low speed pump power must be less than or equal to high speed pump power.",
    7834            0 :                                thisDXCoil.DXCoilType,
    7835            0 :                                thisDXCoil.Name));
    7836            0 :                     ShowContinueError(
    7837            0 :                         state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.EvapCondPumpElecNomPower2, thisDXCoil.EvapCondPumpElecNomPower(Mode)));
    7838            0 :                     ShowFatalError(state, "Preceding conditions cause termination.");
    7839              :                 }
    7840              : 
    7841            4 :                 if (thisDXCoil.RatedTotCap2 > thisDXCoil.RatedTotCap(Mode)) {
    7842            0 :                     ShowSevereError(state,
    7843            0 :                                     format("SizeDXCoil: {} {}, Rated Total Cooling Capacity, Low Speed must be less than or equal to Rated Total "
    7844              :                                            "Cooling Capacity, High Speed.",
    7845            0 :                                            thisDXCoil.DXCoilType,
    7846            0 :                                            thisDXCoil.Name));
    7847            0 :                     ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.RatedTotCap2, thisDXCoil.RatedTotCap(Mode)));
    7848            0 :                     ShowFatalError(state, "Preceding conditions cause termination.");
    7849              :                 }
    7850              : 
    7851            4 :                 if (thisDXCoil.RatedAirVolFlowRate2 > thisDXCoil.RatedAirVolFlowRate(Mode)) {
    7852            0 :                     ShowFatalError(state,
    7853            0 :                                    format("SizeDXCoil: {} {}, Rated Air Volume Flow Rate, low speed must be less than or equal to Rated Air Volume "
    7854              :                                           "Flow Rate, high speed.",
    7855            0 :                                           thisDXCoil.DXCoilType,
    7856            0 :                                           thisDXCoil.Name));
    7857            0 :                     ShowContinueError(state,
    7858            0 :                                       format("Instead, {:.2R} > {:.2R}", thisDXCoil.RatedAirVolFlowRate2, thisDXCoil.RatedAirVolFlowRate(Mode)));
    7859            0 :                     ShowFatalError(state, "Preceding conditions cause termination.");
    7860              :                 }
    7861              :             }
    7862              : 
    7863              :             //                // Sizing rated low speed SHR2
    7864           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7865            4 :                 CompName = thisDXCoil.Name;
    7866            4 :                 FieldNum = 7;
    7867            4 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum);
    7868            4 :                 CompType = thisDXCoil.DXCoilType;
    7869              :                 // Autosize low speed SHR to be the same as high speed SHR
    7870            4 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedSHR(Mode);
    7871            4 :                 state.dataSize->DataFractionUsedForSizing = 1.0;
    7872            4 :                 state.dataSize->DataDXSpeedNum = 2; // refers to low speed in sizer
    7873            4 :                 bool ErrorsFound = false;
    7874            4 :                 TempSize = thisDXCoil.RatedSHR2;
    7875            4 :                 sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7876            4 :                 thisDXCoil.RatedSHR2 = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
    7877            4 :                 state.dataSize->DataConstantUsedForSizing = 0.0;
    7878            4 :                 state.dataSize->DataFractionUsedForSizing = 0.0;
    7879            4 :                 state.dataSize->DataDXSpeedNum = 0;
    7880              :             }
    7881              : 
    7882              :             //                // Sizing resistive defrost heater capacity
    7883           96 :             if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating &&
    7884           83 :                 thisDXCoil.DXCoilType_Num != HVAC::CoilDX_MultiSpeedHeating) {
    7885              :                 // IF (DXCoil(DXCoilNum)%DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating .OR. &
    7886              :                 //    DXCoil(DXCoilNum)%DXCoilType_Num == Coil_HeatingAirToAirVariableSpeed) THEN
    7887           76 :                 if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
    7888            3 :                     CompName = thisDXCoil.Name;
    7889            3 :                     CompType = thisDXCoil.DXCoilType;
    7890              :                     // Autosize low speed capacity to 1/3 high speed capacity
    7891            3 :                     state.dataSize->DataConstantUsedForSizing = state.dataSize->DXCoolCap;
    7892            3 :                     state.dataSize->DataFractionUsedForSizing = 1.0;
    7893            3 :                     TempSize = thisDXCoil.DefrostCapacity;
    7894            3 :                     AutoCalculateSizer sizerResDefCap;
    7895            3 :                     std::string stringOverride = "Resistive Defrost Heater Capacity [W]";
    7896            3 :                     if (state.dataGlobal->isEpJSON) stringOverride = "resistive_defrost_heater_capacity [W]";
    7897            3 :                     sizerResDefCap.overrideSizingString(stringOverride);
    7898            3 :                     sizerResDefCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7899            3 :                     thisDXCoil.DefrostCapacity = sizerResDefCap.size(state, TempSize, ErrorsFound);
    7900            3 :                 } else {
    7901           73 :                     thisDXCoil.DefrostCapacity = 0.0;
    7902              :                 }
    7903              :             }
    7904              : 
    7905              :         } // End capacity stages loop
    7906              :     }     // End dehumidification modes loop
    7907              : 
    7908              :     // Autosizing for multispeed cooling coil
    7909           96 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
    7910              :         // flow rate autosize
    7911           31 :         for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    7912              :             // Sizing multispeed air volume flow rate
    7913           21 :             IsAutoSize = false;
    7914           21 :             if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
    7915           15 :                 IsAutoSize = true;
    7916              :             }
    7917           21 :             state.dataSize->DataIsDXCoil = true;
    7918           21 :             CompName = thisDXCoil.Name;
    7919           21 :             CompType = thisDXCoil.DXCoilType;
    7920           21 :             if (Mode == thisDXCoil.NumOfSpeeds) {
    7921           10 :                 FieldNum = 10 + (Mode - 1) * 14;
    7922           10 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
    7923           10 :                 TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    7924           10 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
    7925           10 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
    7926           10 :                 bool errorsFound = false;
    7927           10 :                 CoolingAirFlowSizer sizingCoolingAirFlow;
    7928           10 :                 sizingCoolingAirFlow.overrideSizingString(SizingString);
    7929              :                 // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    7930           10 :                 sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7931           10 :                 TempSize = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    7932           10 :                 thisDXCoil.MSRatedAirVolFlowRate(Mode) = TempSize;
    7933           10 :                 state.dataSize->DataEMSOverrideON = false;
    7934           10 :                 state.dataSize->DataEMSOverride = 0.0;
    7935           10 :                 if (!IsAutoSize && !HardSizeNoDesRun) {
    7936            1 :                     TempSize = AutoSize;
    7937            1 :                     bPRINT = false;
    7938            1 :                     sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    7939            1 :                     MSRatedAirVolFlowRateDes = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    7940            1 :                     bPRINT = true;
    7941              :                 }
    7942           10 :                 if (IsAutoSize) {
    7943            7 :                     MSRatedAirVolFlowRateDes = TempSize;
    7944              :                 }
    7945           10 :             } else {
    7946           11 :                 FieldNum = 10 + (Mode - 1) * 14;
    7947           11 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
    7948           11 :                 if (IsAutoSize || !HardSizeNoDesRun) {
    7949              :                     // Autosize low speed flow to fraction of the highest speed flow
    7950            9 :                     state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
    7951            9 :                     if (!IsAutoSize && !HardSizeNoDesRun) state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
    7952            9 :                     state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
    7953              :                 }
    7954           11 :                 TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    7955           11 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
    7956           11 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
    7957           11 :                 bool errorsFound = false;
    7958           11 :                 CoolingAirFlowSizer sizingCoolingAirFlow;
    7959           11 :                 sizingCoolingAirFlow.overrideSizingString(SizingString);
    7960           11 :                 sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    7961           11 :                 thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    7962           11 :             }
    7963           21 :             state.dataSize->DataEMSOverride = 0.0;
    7964           21 :             state.dataSize->DataEMSOverrideON = false;
    7965           21 :             state.dataSize->DataIsDXCoil = false;
    7966           21 :             state.dataSize->DataTotCapCurveIndex = 0;
    7967           21 :             state.dataSize->DataConstantUsedForSizing = 0.0;
    7968           21 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    7969              :         }
    7970              : 
    7971              :         // Ensure flow rate at lower speed must be lower or equal to the flow rate at higher speed. Otherwise, a severe error is issued.
    7972           21 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    7973           11 :             if (thisDXCoil.MSRatedAirVolFlowRate(Mode) > thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)) {
    7974            0 :                 ShowWarningError(state,
    7975            0 :                                  format("SizeDXCoil: {} {}, Speed {} Rated Air Flow Rate must be less than or equal to Speed {} Rated Air Flow Rate.",
    7976            0 :                                         thisDXCoil.DXCoilType,
    7977            0 :                                         thisDXCoil.Name,
    7978              :                                         Mode,
    7979            0 :                                         Mode + 1));
    7980            0 :                 ShowContinueError(
    7981            0 :                     state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedAirVolFlowRate(Mode), thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)));
    7982            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    7983              :             }
    7984              :         }
    7985              : 
    7986              :         // Sizing multispeed rated total cooling capacity
    7987           31 :         for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    7988           21 :             IsAutoSize = false;
    7989           21 :             if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
    7990           15 :                 IsAutoSize = true;
    7991              :             }
    7992           21 :             CompName = thisDXCoil.Name;
    7993           21 :             CompType = thisDXCoil.DXCoilType;
    7994           21 :             state.dataSize->DataIsDXCoil = true;
    7995           21 :             state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
    7996           21 :             if (Mode == thisDXCoil.NumOfSpeeds) {
    7997           10 :                 PrintFlag = true;
    7998           10 :                 state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    7999           10 :                 FieldNum = 7 + (Mode - 1) * 14;
    8000           10 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
    8001           10 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    8002           10 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    8003           10 :                 MSRatedTotCapDesAtMaxSpeed = thisDXCoil.MSRatedTotCap(Mode);
    8004           10 :                 if (!HardSizeNoDesRun) {
    8005            8 :                     PrintFlag = false;
    8006            8 :                     TempSize = DataSizing::AutoSize;
    8007              :                     // Auto-size capacity at the highest speed
    8008            8 :                     CoolingCapacitySizer sizerCoolingCapacity;
    8009            8 :                     sizerCoolingCapacity.overrideSizingString(SizingString);
    8010            8 :                     sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8011            8 :                     TempSize = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    8012            8 :                     state.dataSize->DataConstantUsedForSizing = TempSize;
    8013            8 :                     state.dataSize->DataFractionUsedForSizing = 1.0;
    8014            8 :                     MSRatedTotCapDesAtMaxSpeed = TempSize;
    8015            8 :                     thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
    8016            8 :                     PrintFlag = true;
    8017            8 :                 }
    8018           10 :                 TempSize = thisDXCoil.MSRatedTotCap(Mode);
    8019           10 :                 CoolingCapacitySizer sizerCoolingCapacity2;
    8020           10 :                 sizerCoolingCapacity2.overrideSizingString(SizingString);
    8021           10 :                 sizerCoolingCapacity2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8022           10 :                 TempSize = sizerCoolingCapacity2.size(state, TempSize, ErrorsFound);
    8023           10 :                 thisDXCoil.MSRatedTotCap(Mode) = TempSize;
    8024           10 :                 if (IsAutoSize) {
    8025            7 :                     MSRatedTotCapDesAtMaxSpeed = TempSize;
    8026            7 :                     thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
    8027              :                 }
    8028           10 :             } else {
    8029              :                 // cooling capacity at lower speeds
    8030           11 :                 PrintFlag = true;
    8031           11 :                 FieldNum = 7 + (Mode - 1) * 14;
    8032           11 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
    8033           11 :                 if (IsAutoSize || !HardSizeNoDesRun) {
    8034              :                     // autosize low speed capacity to fraction of the highest speed capacity
    8035            9 :                     if (!HardSizeNoDesRun) {
    8036            9 :                         state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
    8037              :                     } else {
    8038            0 :                         state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
    8039              :                     }
    8040            9 :                     state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
    8041            9 :                     thisDXCoil.MSRatedTotCapDes(Mode) = state.dataSize->DataConstantUsedForSizing * state.dataSize->DataFractionUsedForSizing;
    8042              :                 }
    8043           11 :                 TempSize = thisDXCoil.MSRatedTotCap(Mode);
    8044           11 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    8045           11 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    8046           11 :                 CoolingCapacitySizer sizerCoolingCapacity;
    8047           11 :                 sizerCoolingCapacity.overrideSizingString(SizingString);
    8048           11 :                 sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8049           11 :                 thisDXCoil.MSRatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    8050           11 :             }
    8051           21 :             state.dataSize->DataEMSOverride = 0.0;
    8052           21 :             state.dataSize->DataEMSOverrideON = false;
    8053           21 :             state.dataSize->DataIsDXCoil = false;
    8054           21 :             state.dataSize->DataCoolCoilCap = 0.0;
    8055           21 :             state.dataSize->DataTotCapCurveIndex = 0;
    8056           21 :             state.dataSize->DataConstantUsedForSizing = 0.0;
    8057           21 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    8058              :         }
    8059              : 
    8060              :         // Ensure capacity at lower speed must be lower or equal to the capacity at higher speed.
    8061           21 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    8062           11 :             if (thisDXCoil.MSRatedTotCap(Mode) > thisDXCoil.MSRatedTotCap(Mode + 1)) {
    8063            0 :                 ShowWarningError(state,
    8064            0 :                                  format("SizeDXCoil: {} {}, Speed {} Rated Total Cooling Capacity must be less than or equal to Speed {} Rated "
    8065              :                                         "Total Cooling Capacity.",
    8066            0 :                                         thisDXCoil.DXCoilType,
    8067            0 :                                         thisDXCoil.Name,
    8068              :                                         Mode,
    8069            0 :                                         Mode + 1));
    8070            0 :                 ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedTotCap(Mode), thisDXCoil.MSRatedTotCap(Mode + 1)));
    8071            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    8072              :             }
    8073              :         }
    8074              : 
    8075              :         // Rated SHR
    8076           31 :         for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    8077           21 :             IsAutoSize = false;
    8078           21 :             if (thisDXCoil.MSRatedSHR(Mode) == AutoSize) {
    8079           15 :                 IsAutoSize = true;
    8080              :             }
    8081           21 :             if (Mode == thisDXCoil.NumOfSpeeds) {
    8082           10 :                 CompType = thisDXCoil.DXCoilType;
    8083           10 :                 CompName = thisDXCoil.Name;
    8084           10 :                 TempSize = thisDXCoil.MSRatedSHR(Mode);
    8085           10 :                 state.dataSize->DataFlowUsedForSizing = MSRatedAirVolFlowRateDes;
    8086           10 :                 state.dataSize->DataCapacityUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
    8087           10 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
    8088           10 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
    8089           10 :                 bool ErrorsFound = false;
    8090           10 :                 state.dataSize->DataDXSpeedNum = Mode;
    8091           10 :                 sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8092           10 :                 thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
    8093              :                 // added for rated sensible cooling capacity estimate for html reporting, issue #7381
    8094           10 :                 thisDXCoil.RatedSHR(1) = thisDXCoil.MSRatedSHR(Mode);
    8095              :                 // design SHR value at the maximum speed calculated above was supposed to be used for all speeds
    8096              :                 // Now user specified SHR value is used when the SHR field is not autosized and design day run is
    8097              :                 // set to yes unless the code below is commented out
    8098           10 :                 MSRatedSHRDes = thisDXCoil.MSRatedSHR(Mode);
    8099              :             } else {
    8100           11 :                 TempSize = thisDXCoil.MSRatedSHR(Mode);
    8101           11 :                 bool ErrorsFound = false;
    8102           11 :                 state.dataSize->DataDXSpeedNum = Mode;
    8103           11 :                 state.dataSize->DataFractionUsedForSizing = MSRatedSHRDes;
    8104           11 :                 state.dataSize->DataConstantUsedForSizing = 1.0;
    8105           11 :                 sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8106           11 :                 thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
    8107              :             }
    8108              :         }
    8109           10 :         state.dataSize->DataFlowUsedForSizing = 0.0;
    8110           10 :         state.dataSize->DataCapacityUsedForSizing = 0.0;
    8111           10 :         state.dataSize->DataEMSOverrideON = false;
    8112           10 :         state.dataSize->DataEMSOverride = 0.0;
    8113           10 :         state.dataSize->DataDXSpeedNum = 0;
    8114           10 :         state.dataSize->DataFractionUsedForSizing = 0.0;
    8115           10 :         state.dataSize->DataConstantUsedForSizing = 0.0;
    8116              : 
    8117              :         // Rated Evaporative condenser airflow rates
    8118           31 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    8119           21 :             IsAutoSize = false;
    8120           21 :             if (thisDXCoil.MSEvapCondAirFlow(Mode) == AutoSize) {
    8121           16 :                 IsAutoSize = true;
    8122              :             }
    8123           21 :             if (IsAutoSize || !HardSizeNoDesRun) {
    8124              :                 // Autosize condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
    8125           21 :                 MSEvapCondAirFlowDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.000114;
    8126              :             } else {
    8127              :                 // this is done to duplicate any existing calc method
    8128            0 :                 MSEvapCondAirFlowDes = thisDXCoil.MSRatedTotCap(Mode) * 0.000114;
    8129              :             }
    8130           21 :             if (IsAutoSize) {
    8131           16 :                 thisDXCoil.MSEvapCondAirFlow(Mode) = MSEvapCondAirFlowDes;
    8132           48 :                 BaseSizer::reportSizerOutput(state,
    8133              :                                              thisDXCoil.DXCoilType,
    8134              :                                              thisDXCoil.Name,
    8135           32 :                                              format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
    8136              :                                              MSEvapCondAirFlowDes);
    8137              :             } else {
    8138            5 :                 if (thisDXCoil.MSEvapCondAirFlow(Mode) > 0.0 && MSEvapCondAirFlowDes > 0.0 && !HardSizeNoDesRun) {
    8139            2 :                     MSEvapCondAirFlowUser = thisDXCoil.MSEvapCondAirFlow(Mode);
    8140            6 :                     BaseSizer::reportSizerOutput(state,
    8141              :                                                  thisDXCoil.DXCoilType,
    8142              :                                                  thisDXCoil.Name,
    8143            4 :                                                  format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
    8144              :                                                  MSEvapCondAirFlowDes,
    8145            4 :                                                  format("User-Specified Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
    8146              :                                                  MSEvapCondAirFlowUser);
    8147            2 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    8148            0 :                         if ((std::abs(MSEvapCondAirFlowDes - MSEvapCondAirFlowUser) / MSEvapCondAirFlowUser) >
    8149            0 :                             state.dataSize->AutoVsHardSizingThreshold) {
    8150            0 :                             ShowMessage(
    8151            0 :                                 state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
    8152            0 :                             ShowContinueError(state,
    8153            0 :                                               format("User-Specified Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", MSEvapCondAirFlowUser));
    8154            0 :                             ShowContinueError(
    8155            0 :                                 state, format("differs from Design Size Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", MSEvapCondAirFlowDes));
    8156            0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    8157            0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    8158              :                         }
    8159              :                     }
    8160              :                 }
    8161              :             }
    8162              :         }
    8163              : 
    8164              :         // Ensure evaporative condenser airflow rate at lower speed must be lower or equal to one at higher speed.
    8165           21 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    8166           11 :             if (thisDXCoil.MSEvapCondAirFlow(Mode) > thisDXCoil.MSEvapCondAirFlow(Mode + 1)) {
    8167            0 :                 ShowWarningError(state,
    8168            0 :                                  format("SizeDXCoil: {} {}, Speed {} Evaporative Condenser Air Flow Rate must be less than or equal to Speed {} "
    8169              :                                         "Evaporative Condenser Air Flow Rate.",
    8170            0 :                                         thisDXCoil.DXCoilType,
    8171            0 :                                         thisDXCoil.Name,
    8172              :                                         Mode,
    8173            0 :                                         Mode + 1));
    8174            0 :                 ShowContinueError(state,
    8175            0 :                                   format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSEvapCondAirFlow(Mode), thisDXCoil.MSEvapCondAirFlow(Mode + 1)));
    8176            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    8177              :             }
    8178              :         }
    8179              : 
    8180              :         // Sizing multispeed rated evaporative condenser pump power
    8181           31 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    8182           21 :             IsAutoSize = false;
    8183           21 :             if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) == AutoSize) {
    8184           16 :                 IsAutoSize = true;
    8185              :             }
    8186              : 
    8187           21 :             if (IsAutoSize || !HardSizeNoDesRun) {
    8188              :                 // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
    8189           21 :                 MSEvapCondPumpElecNomPowerDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.004266;
    8190              :             } else {
    8191              :                 // this is done to duplicate any existing calc method
    8192            0 :                 MSEvapCondPumpElecNomPowerDes = thisDXCoil.MSRatedTotCap(Mode) * 0.004266;
    8193              :             }
    8194              :             // Design Size data is always available
    8195           21 :             if (IsAutoSize) {
    8196           16 :                 thisDXCoil.MSEvapCondPumpElecNomPower(Mode) = MSEvapCondPumpElecNomPowerDes;
    8197           48 :                 BaseSizer::reportSizerOutput(state,
    8198              :                                              thisDXCoil.DXCoilType,
    8199              :                                              thisDXCoil.Name,
    8200           32 :                                              format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
    8201              :                                              MSEvapCondPumpElecNomPowerDes);
    8202              :             } else {
    8203            5 :                 if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) > 0.0 && MSEvapCondPumpElecNomPowerDes > 0.0 && !HardSizeNoDesRun) {
    8204            2 :                     MSEvapCondPumpElecNomPowerUser = thisDXCoil.MSEvapCondPumpElecNomPower(Mode);
    8205            6 :                     BaseSizer::reportSizerOutput(state,
    8206              :                                                  thisDXCoil.DXCoilType,
    8207              :                                                  thisDXCoil.Name,
    8208            4 :                                                  format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
    8209              :                                                  MSEvapCondPumpElecNomPowerDes,
    8210            4 :                                                  format("User-Specified Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
    8211              :                                                  MSEvapCondPumpElecNomPowerUser);
    8212            2 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    8213            0 :                         if ((std::abs(MSEvapCondPumpElecNomPowerDes - MSEvapCondPumpElecNomPowerUser) / MSEvapCondPumpElecNomPowerUser) >
    8214            0 :                             state.dataSize->AutoVsHardSizingThreshold) {
    8215            0 :                             ShowMessage(
    8216            0 :                                 state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
    8217            0 :                             ShowContinueError(state,
    8218            0 :                                               format("User-Specified Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
    8219              :                                                      MSEvapCondPumpElecNomPowerUser));
    8220            0 :                             ShowContinueError(state,
    8221            0 :                                               format("differs from Design Size Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
    8222              :                                                      MSEvapCondPumpElecNomPowerDes));
    8223            0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    8224            0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    8225              :                         }
    8226              :                     }
    8227              :                 }
    8228              :             }
    8229              :         }
    8230              : 
    8231              :         // Ensure evaporative condenser pump power at lower speed must be lower or equal to one at higher speed.
    8232           21 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    8233           11 :             if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) > thisDXCoil.MSEvapCondPumpElecNomPower(Mode + 1)) {
    8234            0 :                 ShowWarningError(state,
    8235            0 :                                  format("SizeDXCoil: {} {}, Speed {} Rated Evaporative Condenser Pump Power Consumption must be less than or "
    8236              :                                         "equal to Speed {} Rated Evaporative Condenser Pump Power Consumption.",
    8237            0 :                                         thisDXCoil.DXCoilType,
    8238            0 :                                         thisDXCoil.Name,
    8239              :                                         Mode,
    8240            0 :                                         Mode + 1));
    8241            0 :                 ShowContinueError(
    8242              :                     state,
    8243            0 :                     format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSEvapCondPumpElecNomPower(Mode), thisDXCoil.MSEvapCondPumpElecNomPower(Mode + 1)));
    8244            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    8245              :             }
    8246              :         }
    8247              :     }
    8248              : 
    8249              :     // Autosizing for multispeed heating coil
    8250           96 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    8251              :         // flow rate autosize
    8252           23 :         for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    8253           16 :             IsAutoSize = false;
    8254           16 :             if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
    8255           12 :                 IsAutoSize = true;
    8256              :             }
    8257           16 :             state.dataSize->DataIsDXCoil = true;
    8258           16 :             CompName = thisDXCoil.Name;
    8259           16 :             CompType = thisDXCoil.DXCoilType;
    8260              :             // Sizing rated air flow rate
    8261           16 :             if (Mode == thisDXCoil.NumOfSpeeds) {
    8262            7 :                 FieldNum = 12 + (Mode - 1) * 6;
    8263            7 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
    8264            7 :                 TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    8265            7 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
    8266            7 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
    8267            7 :                 bool errorsFound = false;
    8268            7 :                 HeatingAirFlowSizer sizingHeatingAirFlow;
    8269            7 :                 sizingHeatingAirFlow.overrideSizingString(SizingString);
    8270              :                 // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    8271            7 :                 sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    8272            7 :                 thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
    8273            7 :                 if (!IsAutoSize && !HardSizeNoDesRun) {
    8274            0 :                     TempSize = AutoSize;
    8275            0 :                     bPRINT = false;
    8276            0 :                     errorsFound = false;
    8277            0 :                     HeatingAirFlowSizer sizingHeatingAirFlow2;
    8278            0 :                     sizingHeatingAirFlow2.overrideSizingString(SizingString);
    8279              :                     // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    8280            0 :                     sizingHeatingAirFlow2.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    8281            0 :                     MSRatedAirVolFlowRateDes = sizingHeatingAirFlow2.size(state, TempSize, errorsFound);
    8282            0 :                     bPRINT = true;
    8283            0 :                 }
    8284            7 :             } else {
    8285            9 :                 FieldNum = 12 + (Mode - 1) * 6;
    8286            9 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
    8287            9 :                 if (IsAutoSize || !HardSizeNoDesRun) {
    8288              :                     // Auto-size low speed flow to fraction of the highest speed capacity
    8289            7 :                     state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
    8290            7 :                     if (!IsAutoSize && !HardSizeNoDesRun) state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
    8291            7 :                     state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
    8292              :                 }
    8293            9 :                 TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    8294            9 :                 bool errorsFound = false;
    8295            9 :                 HeatingAirFlowSizer sizingHeatingAirFlow;
    8296            9 :                 sizingHeatingAirFlow.overrideSizingString(SizingString);
    8297              :                 // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    8298            9 :                 sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    8299            9 :                 thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
    8300            9 :             }
    8301           16 :             state.dataSize->DataEMSOverride = 0.0;
    8302           16 :             state.dataSize->DataEMSOverrideON = false;
    8303           16 :             state.dataSize->DataIsDXCoil = false;
    8304           16 :             state.dataSize->DataTotCapCurveIndex = 0;
    8305           16 :             state.dataSize->DataConstantUsedForSizing = 0.0;
    8306           16 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    8307              :         }
    8308              : 
    8309              :         // Ensure flow rate at lower speed must be lower or equal to the flow rate at higher speed. Otherwise, a severe error is issued.
    8310           16 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    8311            9 :             if (thisDXCoil.MSRatedAirVolFlowRate(Mode) > thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)) {
    8312            0 :                 ShowWarningError(state,
    8313            0 :                                  format("SizeDXCoil: {} {}, Speed {} Rated Air Flow Rate must be less than or equal to Speed {} Rated Air Flow Rate.",
    8314            0 :                                         thisDXCoil.DXCoilType,
    8315            0 :                                         thisDXCoil.Name,
    8316              :                                         Mode,
    8317            0 :                                         Mode + 1));
    8318            0 :                 ShowContinueError(
    8319            0 :                     state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedAirVolFlowRate(Mode), thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)));
    8320            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    8321              :             }
    8322              :         }
    8323              :         // Rated Secondary Coil Airflow Rates for AirCooled condenser type
    8324            7 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
    8325            0 :             for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    8326            0 :                 IsAutoSize = false;
    8327            0 :                 if (thisDXCoil.MSSecCoilAirFlow(Mode) == AutoSize) {
    8328            0 :                     IsAutoSize = true;
    8329              :                 }
    8330              :                 // Autosize Primary Coil air flow * Secondary Coil Scaling Factor
    8331            0 :                 SecCoilAirFlowDes = thisDXCoil.MSRatedAirVolFlowRate(Mode) * thisDXCoil.MSSecCoilAirFlowScalingFactor(Mode);
    8332            0 :                 if (IsAutoSize) {
    8333            0 :                     thisDXCoil.MSSecCoilAirFlow(Mode) = SecCoilAirFlowDes;
    8334            0 :                     BaseSizer::reportSizerOutput(state,
    8335              :                                                  thisDXCoil.DXCoilType,
    8336              :                                                  thisDXCoil.Name,
    8337            0 :                                                  format("Design Size Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
    8338              :                                                  SecCoilAirFlowDes);
    8339              :                 } else {
    8340            0 :                     if (thisDXCoil.MSSecCoilAirFlow(Mode) > 0.0 && SecCoilAirFlowDes > 0.0 && !HardSizeNoDesRun) {
    8341            0 :                         SecCoilAirFlowUser = thisDXCoil.MSSecCoilAirFlow(Mode);
    8342            0 :                         BaseSizer::reportSizerOutput(state,
    8343              :                                                      thisDXCoil.DXCoilType,
    8344              :                                                      thisDXCoil.Name,
    8345            0 :                                                      format("Design Size Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
    8346              :                                                      SecCoilAirFlowDes,
    8347            0 :                                                      format("User-Specified Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
    8348              :                                                      SecCoilAirFlowUser);
    8349            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    8350            0 :                             if ((std::abs(SecCoilAirFlowDes - SecCoilAirFlowUser) / SecCoilAirFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
    8351            0 :                                 ShowMessage(
    8352              :                                     state,
    8353            0 :                                     format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
    8354            0 :                                 ShowContinueError(state, format("User-Specified Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowUser));
    8355            0 :                                 ShowContinueError(
    8356            0 :                                     state, format("differs from Design Size Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowDes));
    8357            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    8358            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    8359              :                             }
    8360              :                         }
    8361              :                     }
    8362              :                 }
    8363              :             }
    8364              :         }
    8365              : 
    8366              :         // Sizing rated total heating capacity
    8367           23 :         for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    8368           16 :             IsAutoSize = false;
    8369           16 :             if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
    8370           12 :                 IsAutoSize = true;
    8371              :             }
    8372           16 :             state.dataSize->DataIsDXCoil = true;
    8373           16 :             CompName = thisDXCoil.Name;
    8374           16 :             CompType = thisDXCoil.DXCoilType;
    8375           16 :             if (Mode == thisDXCoil.NumOfSpeeds) {
    8376            7 :                 state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    8377            7 :                 FieldNum = 10 + (Mode - 1) * 6;
    8378            7 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
    8379            7 :                 state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
    8380            7 :                 if (IsAutoSize || !HardSizeNoDesRun) {
    8381              :                     // Heating capacity is assumed to be equal to the cooling capacity
    8382            5 :                     PrintFlag = false;
    8383            5 :                     state.dataSize->DataFractionUsedForSizing = 1.0;
    8384            5 :                     if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
    8385            1 :                         NumOfSpeedCompanion = state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).NumOfSpeeds;
    8386            1 :                         state.dataSize->DataConstantUsedForSizing =
    8387            1 :                             state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).MSRatedTotCapDes(NumOfSpeedCompanion);
    8388              :                     } else {
    8389            4 :                         state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(1); // sized above
    8390              :                     }
    8391            5 :                     TempSize = DataSizing::AutoSize;
    8392            5 :                     state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    8393            5 :                     state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    8394            5 :                     HeatingCapacitySizer sizerHeatingCapacity;
    8395            5 :                     sizerHeatingCapacity.overrideSizingString(SizingString);
    8396            5 :                     sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8397            5 :                     MSRatedTotCapDesAtMaxSpeed = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    8398            5 :                     state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
    8399            5 :                     state.dataSize->DataFractionUsedForSizing = 1.0;
    8400            5 :                 }
    8401            7 :                 PrintFlag = true;
    8402            7 :                 TempSize = thisDXCoil.MSRatedTotCap(Mode);
    8403            7 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    8404            7 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    8405            7 :                 HeatingCapacitySizer sizerHeatingCapacity;
    8406            7 :                 sizerHeatingCapacity.overrideSizingString(SizingString);
    8407            7 :                 sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8408            7 :                 TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    8409            7 :                 thisDXCoil.MSRatedTotCap(Mode) = TempSize;
    8410            7 :                 if (IsAutoSize) {
    8411            5 :                     MSRatedTotCapDesAtMaxSpeed = TempSize;
    8412              :                 }
    8413            7 :             } else {
    8414            9 :                 PrintFlag = true;
    8415            9 :                 FieldNum = 10 + (Mode - 1) * 6;
    8416            9 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
    8417            9 :                 if (IsAutoSize || !HardSizeNoDesRun) {
    8418              :                     // autosize low speed capacity to fraction of the highest speed capacity
    8419            7 :                     if (!HardSizeNoDesRun) {
    8420            7 :                         state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
    8421              :                     } else {
    8422            0 :                         state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
    8423              :                     }
    8424            7 :                     state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
    8425              :                 }
    8426            9 :                 TempSize = thisDXCoil.MSRatedTotCap(Mode);
    8427            9 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    8428            9 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    8429            9 :                 HeatingCapacitySizer sizerHeatingCapacity;
    8430            9 :                 sizerHeatingCapacity.overrideSizingString(SizingString);
    8431            9 :                 sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8432            9 :                 TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    8433            9 :                 thisDXCoil.MSRatedTotCap(Mode) = TempSize;
    8434            9 :             }
    8435           16 :             PrintFlag = false;
    8436           16 :             state.dataSize->DataEMSOverrideON = false;
    8437           16 :             state.dataSize->DataEMSOverride = 0.0;
    8438           16 :             state.dataSize->DataIsDXCoil = false;
    8439           16 :             state.dataSize->DataFlowUsedForSizing = 0.0;
    8440           16 :             state.dataSize->DataCoolCoilCap = 0.0;
    8441           16 :             state.dataSize->DataTotCapCurveIndex = 0;
    8442           16 :             state.dataSize->DataConstantUsedForSizing = 0.0;
    8443           16 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    8444              :         }
    8445              :         // Ensure capacity at lower speed must be lower or equal to the capacity at higher speed.
    8446           16 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    8447            9 :             if (thisDXCoil.MSRatedTotCap(Mode) > thisDXCoil.MSRatedTotCap(Mode + 1)) {
    8448            0 :                 ShowWarningError(state,
    8449            0 :                                  format("SizeDXCoil: {} {}, Speed {} Rated Total Heating Capacity must be less than or equal to Speed {} Rated "
    8450              :                                         "Total Heating Capacity.",
    8451            0 :                                         thisDXCoil.DXCoilType,
    8452            0 :                                         thisDXCoil.Name,
    8453              :                                         Mode,
    8454            0 :                                         Mode + 1));
    8455            0 :                 ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedTotCap(Mode), thisDXCoil.MSRatedTotCap(Mode + 1)));
    8456            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    8457              :             }
    8458              :         }
    8459              : 
    8460              :         // Resistive Defrost Heater Capacity = capacity at the first stage
    8461              :         // Sizing defrost heater capacity
    8462            7 :         IsAutoSize = false;
    8463            7 :         if (thisDXCoil.DefrostCapacity == AutoSize) {
    8464            6 :             IsAutoSize = true;
    8465              :         }
    8466            7 :         if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
    8467            2 :             DefrostCapacityDes = thisDXCoil.MSRatedTotCap(1);
    8468              :         } else {
    8469            5 :             DefrostCapacityDes = 0.0;
    8470              :         }
    8471            7 :         if (IsAutoSize) {
    8472            6 :             thisDXCoil.DefrostCapacity = DefrostCapacityDes;
    8473            6 :             BaseSizer::reportSizerOutput(
    8474              :                 state, thisDXCoil.DXCoilType, thisDXCoil.Name, "Design Size Resistive Defrost Heater Capacity", DefrostCapacityDes);
    8475              :         } else {
    8476            1 :             if (thisDXCoil.DefrostCapacity > 0.0 && DefrostCapacityDes > 0.0 && !HardSizeNoDesRun) {
    8477            0 :                 DefrostCapacityUser = thisDXCoil.DefrostCapacity;
    8478            0 :                 BaseSizer::reportSizerOutput(state,
    8479              :                                              thisDXCoil.DXCoilType,
    8480              :                                              thisDXCoil.Name,
    8481              :                                              "Design Size Resistive Defrost Heater Capacity",
    8482              :                                              DefrostCapacityDes,
    8483              :                                              "User-Specified Resistive Defrost Heater Capacity",
    8484              :                                              DefrostCapacityUser);
    8485            0 :                 if (state.dataGlobal->DisplayExtraWarnings) {
    8486            0 :                     if ((std::abs(DefrostCapacityDes - DefrostCapacityUser) / DefrostCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
    8487            0 :                         ShowWarningMessage(
    8488            0 :                             state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
    8489            0 :                         ShowContinueError(state, format("User-Specified Resistive Defrost Heater Capacity of {:.2R}[W]", DefrostCapacityUser));
    8490            0 :                         ShowContinueError(state,
    8491            0 :                                           format("differs from Design Size Resistive Defrost Heater Capacity of {:.2R}[W]", DefrostCapacityDes));
    8492            0 :                         ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    8493            0 :                         ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    8494              :                     }
    8495              :                 }
    8496              :             }
    8497              :         }
    8498              :     }
    8499              : 
    8500              :     // Call routine that computes AHRI certified rating for single-speed DX Coils
    8501          228 :     if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed &&
    8502           36 :          (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
    8503          192 :           thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) ||
    8504           60 :         thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
    8505           82 :         CalcDXCoilStandardRating(state,
    8506           41 :                                  thisDXCoil.Name,
    8507           41 :                                  thisDXCoil.DXCoilType,
    8508              :                                  thisDXCoil.DXCoilType_Num,
    8509              :                                  1,
    8510           41 :                                  thisDXCoil.RatedTotCap(1),
    8511           41 :                                  thisDXCoil.RatedCOP(1),
    8512           41 :                                  thisDXCoil.CCapFFlow(1),
    8513           41 :                                  thisDXCoil.CCapFTemp(1),
    8514           41 :                                  thisDXCoil.EIRFFlow(1),
    8515           41 :                                  thisDXCoil.EIRFTemp(1),
    8516           41 :                                  thisDXCoil.PLFFPLR(1),
    8517           41 :                                  thisDXCoil.RatedAirVolFlowRate(1),
    8518           41 :                                  thisDXCoil.FanPowerPerEvapAirFlowRate(1),
    8519           41 :                                  thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1),
    8520           41 :                                  thisDXCoil.CondenserType,
    8521           41 :                                  thisDXCoil.RegionNum,
    8522           41 :                                  thisDXCoil.MinOATCompressor,
    8523           41 :                                  thisDXCoil.OATempCompressorOn,
    8524           41 :                                  thisDXCoil.OATempCompressorOnOffBlank,
    8525           41 :                                  thisDXCoil.DefrostControl,
    8526           41 :                                  thisDXCoil.ASHRAE127StdRprt);
    8527              :     }
    8528              :     // Call routine that computes AHRI certified rating for multi-speed DX cooling Coils
    8529           96 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    8530           68 :         CalcDXCoilStandardRating(state,
    8531           17 :                                  thisDXCoil.Name,
    8532           17 :                                  thisDXCoil.DXCoilType,
    8533              :                                  thisDXCoil.DXCoilType_Num,
    8534              :                                  thisDXCoil.NumOfSpeeds,
    8535              :                                  thisDXCoil.MSRatedTotCap,
    8536              :                                  thisDXCoil.MSRatedCOP,
    8537              :                                  thisDXCoil.MSCCapFFlow,
    8538              :                                  thisDXCoil.MSCCapFTemp,
    8539              :                                  thisDXCoil.MSEIRFFlow,
    8540              :                                  thisDXCoil.MSEIRFTemp,
    8541              :                                  thisDXCoil.MSPLFFPLR,
    8542              :                                  thisDXCoil.MSRatedAirVolFlowRate,
    8543              :                                  thisDXCoil.MSFanPowerPerEvapAirFlowRate,
    8544              :                                  thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023,
    8545           17 :                                  thisDXCoil.CondenserType,
    8546           17 :                                  thisDXCoil.RegionNum,
    8547           17 :                                  thisDXCoil.MinOATCompressor,
    8548           17 :                                  thisDXCoil.OATempCompressorOn,
    8549           17 :                                  thisDXCoil.OATempCompressorOnOffBlank,
    8550           17 :                                  thisDXCoil.DefrostControl,
    8551           34 :                                  ObjexxFCL::Optional_bool_const());
    8552              :     }
    8553              : 
    8554           98 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed && (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
    8555            2 :                                                                       thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) {
    8556            8 :         StandardRatings::CalcTwoSpeedDXCoilRating(state,
    8557            4 :                                                   thisDXCoil.Name,
    8558            4 :                                                   thisDXCoil.DXCoilType,
    8559              :                                                   thisDXCoil.DXCoilType_Num,
    8560              :                                                   thisDXCoil.RatedTotCap,
    8561              :                                                   thisDXCoil.RatedTotCap2,
    8562              :                                                   thisDXCoil.RatedCOP,
    8563              :                                                   thisDXCoil.RatedCOP2,
    8564              :                                                   thisDXCoil.CCapFFlow, // High Speed
    8565              :                                                   thisDXCoil.CCapFTemp,
    8566              :                                                   thisDXCoil.CCapFTemp2,
    8567              :                                                   thisDXCoil.EIRFFlow, // High Speed
    8568              :                                                   thisDXCoil.EIRFTemp,
    8569              :                                                   thisDXCoil.EIRFTemp2,
    8570              :                                                   thisDXCoil.RatedAirVolFlowRate,
    8571              :                                                   thisDXCoil.RatedAirVolFlowRate2,
    8572              :                                                   thisDXCoil.FanPowerPerEvapAirFlowRate_2023,
    8573              :                                                   thisDXCoil.FanPowerPerEvapAirFlowRate_2023_LowSpeed,
    8574            4 :                                                   thisDXCoil.CondenserType,
    8575            4 :                                                   thisDXCoil.PLFFPLR(1));
    8576              :     }
    8577              : 
    8578              :     // create predefined report entries
    8579           96 :     equipName = thisDXCoil.Name;
    8580              :     // put tables for cooling and heating separate
    8581           96 :     switch (thisDXCoil.DXCoilType_Num) {
    8582           50 :     case HVAC::CoilDX_CoolingSingleSpeed:
    8583              :     case HVAC::CoilDX_CoolingTwoSpeed:
    8584              :     case HVAC::CoilDX_CoolingTwoStageWHumControl:
    8585              :     case HVAC::CoilDX_MultiSpeedCooling: {
    8586           50 :         PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilType, equipName, thisDXCoil.DXCoilType);
    8587           50 :         if (thisDXCoil.NumOfSpeeds == 0) {
    8588           40 :             if (thisDXCoil.NumCapacityStages == 1) {
    8589           40 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(1));
    8590           80 :                 PreDefTableEntry(
    8591           40 :                     state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
    8592           80 :                 PreDefTableEntry(state,
    8593           40 :                                  state.dataOutRptPredefined->pdchCoolCoilLatCap,
    8594              :                                  equipName,
    8595           40 :                                  thisDXCoil.RatedTotCap(1) - thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
    8596           40 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(1));
    8597           40 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(1));
    8598              :             } else {
    8599            0 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(2));
    8600            0 :                 PreDefTableEntry(
    8601            0 :                     state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
    8602            0 :                 PreDefTableEntry(state,
    8603            0 :                                  state.dataOutRptPredefined->pdchCoolCoilLatCap,
    8604              :                                  equipName,
    8605            0 :                                  thisDXCoil.RatedTotCap(2) - thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
    8606            0 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(2));
    8607            0 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(2));
    8608              :             }
    8609              :         } else {
    8610           31 :             for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    8611           21 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
    8612           42 :                 PreDefTableEntry(
    8613           21 :                     state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
    8614           42 :                 PreDefTableEntry(state,
    8615           21 :                                  state.dataOutRptPredefined->pdchCoolCoilLatCap,
    8616              :                                  equipName,
    8617           21 :                                  thisDXCoil.MSRatedTotCap(Mode) - thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
    8618           21 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.MSRatedSHR(Mode));
    8619           21 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
    8620              :             }
    8621              :         }
    8622          100 :         addFootNoteSubTable(state,
    8623           50 :                             state.dataOutRptPredefined->pdstCoolCoil,
    8624              :                             "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
    8625           50 :     } break;
    8626           20 :     case HVAC::CoilDX_HeatingEmpirical:
    8627              :     case HVAC::CoilDX_MultiSpeedHeating:
    8628              :     case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
    8629              :     case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
    8630           20 :         PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, equipName, thisDXCoil.DXCoilType);
    8631           20 :         if (thisDXCoil.NumOfSpeeds == 0) {
    8632           13 :             if (thisDXCoil.NumCapacityStages == 1) {
    8633           13 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.RatedTotCap(1));
    8634           13 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.RatedCOP(1));
    8635              :             } else {
    8636            0 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.RatedTotCap(2));
    8637            0 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.RatedCOP(2));
    8638              :             }
    8639              :         } else {
    8640           23 :             for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    8641           16 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
    8642           16 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
    8643              :             }
    8644              :         }
    8645           40 :         addFootNoteSubTable(state,
    8646           20 :                             state.dataOutRptPredefined->pdstHeatCoil,
    8647              :                             "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
    8648              : 
    8649              :         // std 229 existing table DX Heating coil new reporting variables
    8650           40 :         OutputReportPredefined::PreDefTableEntry(
    8651           20 :             state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp, equipName, thisDXCoil.MinOATCompressor);
    8652           40 :         OutputReportPredefined::PreDefTableEntry(state,
    8653           20 :                                                  state.dataOutRptPredefined->pdchDXHeatCoilAirloopName,
    8654              :                                                  equipName,
    8655           60 :                                                  thisDXCoil.AirLoopNum > 0 ? state.dataAirSystemsData->PrimaryAirSystems(thisDXCoil.AirLoopNum).Name
    8656              :                                                                            : "N/A");
    8657              :         // std 229 existing table DX Heating coil 2023 AHRI new reporting variables
    8658           40 :         OutputReportPredefined::PreDefTableEntry(
    8659           20 :             state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp_2023, equipName, thisDXCoil.MinOATCompressor);
    8660           40 :         OutputReportPredefined::PreDefTableEntry(state,
    8661           20 :                                                  state.dataOutRptPredefined->pdchDXHeatCoilAirloopName_2023,
    8662              :                                                  equipName,
    8663           60 :                                                  thisDXCoil.AirLoopNum > 0 ? state.dataAirSystemsData->PrimaryAirSystems(thisDXCoil.AirLoopNum).Name
    8664              :                                                                            : "N/A");
    8665           20 :     } break;
    8666           26 :     default:
    8667           26 :         break;
    8668              :     }
    8669           96 : }
    8670              : 
    8671          178 : void CalcHPWHDXCoil(EnergyPlusData &state,
    8672              :                     int const DXCoilNum,       // the number of the DX coil to be simulated
    8673              :                     Real64 const PartLoadRatio // sensible water heating load / full load sensible water heating capacity
    8674              : )
    8675              : {
    8676              : 
    8677              :     // SUBROUTINE INFORMATION:
    8678              :     //       AUTHOR         Richard Raustad
    8679              :     //       DATE WRITTEN   May 2005
    8680              : 
    8681              :     // PURPOSE OF THIS SUBROUTINE:
    8682              :     // Calculates the gross cooling capacity of a heat pump water heater evaporator and
    8683              :     // heating capacity of the condenser coil given the rated heating capacity and COP.
    8684              : 
    8685              :     // METHODOLOGY EMPLOYED:
    8686              :     // The routine requires the user to enter the total heating capacity and COP for the
    8687              :     // heat pump water heater along with logicals defining if fan and condenser pump are included.
    8688              :     // Since manufacturer's can rate their HPWH equipment with or without including condenser
    8689              :     // pump heat, this information is required to accurately determine the condenser's leaving
    8690              :     // water temperature. In addition, knowledge of the fan heat is required to back into
    8691              :     // a compressor COP.
    8692              : 
    8693              :     // Using/Aliasing
    8694              :     using Curve::CurveValue;
    8695              : 
    8696              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    8697              :     Real64 RatedHeatingCapacity;     // Water heating rated capacity with or without condenser water pump heat (W)
    8698              :     Real64 RatedHeatingCOP;          // Water heating rated COP with or without evap fan and cond water pump heat (W/W)
    8699              :     Real64 OperatingHeatingCapacity; // Water heating operating capacity including the impact of capacity and COP curves (W)
    8700              :     Real64 OperatingHeatingCOP;      // Water heating operating COP including the impact of capacity and COP curves (W/W)
    8701              :     Real64 OperatingHeatingPower;    // Water heating operating Power (W)
    8702              :     Real64 CompressorPower;          // Power consumed by compressor only (W)
    8703              : 
    8704              :     Real64 TotalTankHeatingCapacity; // Water heating capacity corrected for condenser water pump heat (W)
    8705              :     Real64 TankHeatingCOP;           // Water heating COP corrected for fan and condenser water pump power (W/W)
    8706              :     // (these previous 2 variables also include the impact of capacity and COP curves)
    8707              :     Real64 EvapCoolingCapacity;   // Air cooling capacity corrected for evap fan and cond water pump heat (W)
    8708              :     Real64 InletWaterTemp;        // Condenser water inlet temperature (C)
    8709              :     Real64 OutletWaterTemp;       // Condenser water outlet temperature (C)
    8710              :     Real64 EvapInletMassFlowRate; // Evaporator air inlet mass flow rate (m3/s)
    8711              :     Real64 CondInletMassFlowRate; // Condenser water inlet mass flow rate (m3/s)
    8712              :     Real64 CpWater;               // Specific heat of condenser inlet water (J/Kg/k)
    8713              :     Real64 InletAirTemp;          // HPWH inlet air temperature (dry-bulb or wet-bulb) (C)
    8714              :     Real64 HeatCapFTemp;          // Output of HPWH Heating Capacity as a Function of Temperature curve
    8715              :     Real64 HeatCapFAirFlow;       // Output of HPWH Heating Capacity as a Function of Air Flow Rate Ratio curve
    8716              :     Real64 HeatCapFWaterFlow;     // Output of HPWH Heating Capacity as a Function of Water Flow Rate Ratio curve
    8717              :     Real64 HeatCOPFTemp;          // Output of HPWH COP as a Function of Temperature curve
    8718              :     Real64 HeatCOPFAirFlow;       // Output of HPWH COP as a Function of Air Flow Rate Ratio curve
    8719              :     Real64 HeatCOPFWaterFlow;     // Output of HPWH COP as a Function of Water Flow Rate Ratio curve
    8720              :     Real64 AirFlowRateRatio;      // Ratio of evaporator inlet air mass flow rate to rated mass flow rate
    8721              :     Real64 WaterFlowRateRatio;    // Ratio of evaporator inlet water mass flow rate to rated mass flow rate
    8722              :     Real64 PartLoadFraction;      // Output of Part Load Fraction as a Function of Part Load Ratio curve
    8723              :     Real64 PumpHeatToWater;       // Amount of pump heat attributed to heating water
    8724              :     Real64 HPRTF;                 // Heat pump run time fraction
    8725              : 
    8726              :     // References to Coil and Node struct
    8727          178 :     DXCoilData &Coil = state.dataDXCoils->DXCoil(DXCoilNum);
    8728          178 :     NodeData &AirInletNode = state.dataLoopNodes->Node(Coil.AirInNode);
    8729          178 :     NodeData &WaterInletNode = state.dataLoopNodes->Node(Coil.WaterInNode);
    8730          178 :     NodeData &WaterOutletNode = state.dataLoopNodes->Node(Coil.WaterOutNode);
    8731              : 
    8732              :     // If heat pump water heater is OFF, set outlet to inlet and RETURN
    8733              :     // Also set the heating energy rate to zero
    8734          178 :     if (PartLoadRatio == 0.0) {
    8735            8 :         WaterOutletNode = WaterInletNode;
    8736            8 :         Coil.TotalHeatingEnergyRate = 0.0;
    8737            8 :         return;
    8738              :     } else {
    8739          170 :         RatedHeatingCapacity = Coil.RatedTotCap2;
    8740          170 :         RatedHeatingCOP = Coil.RatedCOP(1);
    8741          170 :         InletWaterTemp = WaterInletNode.Temp;
    8742          170 :         CondInletMassFlowRate = WaterInletNode.MassFlowRate / PartLoadRatio;
    8743          170 :         EvapInletMassFlowRate = AirInletNode.MassFlowRate / PartLoadRatio;
    8744          170 :         CpWater = CPHW(InletWaterTemp);
    8745          170 :         CompressorPower = 0.0;
    8746          170 :         OperatingHeatingPower = 0.0;
    8747          170 :         TankHeatingCOP = 0.0;
    8748              :     }
    8749              : 
    8750              :     // determine inlet air temperature type for curve objects
    8751          170 :     if (Coil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
    8752          170 :         InletAirTemp = state.dataHVACGlobal->HPWHInletWBTemp;
    8753              :     } else {
    8754            0 :         InletAirTemp = state.dataHVACGlobal->HPWHInletDBTemp;
    8755              :     }
    8756              : 
    8757              :     // get output of Heating Capacity and Heating COP curves (curves default to 1 if user has not specified curve name)
    8758          170 :     if (Coil.HCapFTemp > 0) {
    8759          170 :         if (state.dataCurveManager->curves(Coil.HCapFTemp)->numDims == 1) {
    8760            0 :             HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp);
    8761              :         } else {
    8762          170 :             HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp, InletWaterTemp);
    8763              :         }
    8764              :         //   Warn user if curve output goes negative
    8765          170 :         if (HeatCapFTemp < 0.0) {
    8766            0 :             if (Coil.HCapFTempErrorIndex == 0) {
    8767            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8768            0 :                 ShowContinueError(
    8769            0 :                     state, format(" HPWH Heating Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", HeatCapFTemp));
    8770            0 :                 if (state.dataCurveManager->curves(Coil.HCapFTemp)->numDims == 2) {
    8771            0 :                     ShowContinueError(
    8772              :                         state,
    8773            0 :                         format(" Negative value occurs using an inlet air temperature of {:.1T} and an inlet water temperature of {:.1T}.",
    8774              :                                InletAirTemp,
    8775              :                                InletWaterTemp));
    8776              :                 } else {
    8777            0 :                     ShowContinueError(state, format(" Negative value occurs using an inlet air temperature of {:.1T}.", InletAirTemp));
    8778              :                 }
    8779            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8780              :             }
    8781            0 :             ShowRecurringWarningErrorAtEnd(
    8782              :                 state,
    8783            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8784              :                     "\": HPWH Heating Capacity Modifier curve (function of temperature) output is negative warning continues...",
    8785            0 :                 Coil.HCapFTempErrorIndex,
    8786              :                 HeatCapFTemp,
    8787              :                 HeatCapFTemp,
    8788              :                 _,
    8789              :                 "[C]",
    8790              :                 "[C]");
    8791            0 :             HeatCapFTemp = 0.0;
    8792              :         }
    8793              :     } else {
    8794            0 :         HeatCapFTemp = 1.0;
    8795              :     }
    8796              : 
    8797          170 :     if (Coil.HCOPFTemp > 0) {
    8798          170 :         if (state.dataCurveManager->curves(Coil.HCOPFTemp)->numDims == 1) {
    8799            0 :             HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp);
    8800              :         } else {
    8801          170 :             HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp, InletWaterTemp);
    8802              :         }
    8803              :         //   Warn user if curve output goes negative
    8804          170 :         if (HeatCOPFTemp < 0.0) {
    8805            0 :             if (Coil.HCOPFTempErrorIndex == 0) {
    8806            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8807            0 :                 ShowContinueError(state,
    8808            0 :                                   format(" HPWH Heating COP Modifier curve (function of temperature) output is negative ({:.3T}).", HeatCOPFTemp));
    8809            0 :                 if (state.dataCurveManager->curves(Coil.HCOPFTemp)->numDims == 2) {
    8810            0 :                     ShowContinueError(
    8811              :                         state,
    8812            0 :                         format(" Negative value occurs using an inlet air temperature of {:.1T} and an inlet water temperature of {:.1T}.",
    8813              :                                InletAirTemp,
    8814              :                                InletWaterTemp));
    8815              :                 } else {
    8816            0 :                     ShowContinueError(state, format(" Negative value occurs using an inlet air temperature of {:.1T}.", InletAirTemp));
    8817              :                 }
    8818            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8819              :             }
    8820            0 :             ShowRecurringWarningErrorAtEnd(
    8821              :                 state,
    8822            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8823              :                     "\": HPWH Heating COP Modifier curve (function of temperature) output is negative warning continues...",
    8824            0 :                 Coil.HCOPFTempErrorIndex,
    8825              :                 HeatCOPFTemp,
    8826              :                 HeatCOPFTemp,
    8827              :                 _,
    8828              :                 "[C]",
    8829              :                 "[C]");
    8830            0 :             HeatCOPFTemp = 0.0;
    8831              :         }
    8832              :     } else {
    8833            0 :         HeatCOPFTemp = 1.0;
    8834              :     }
    8835              : 
    8836          170 :     if (Coil.HCapFAirFlow > 0) {
    8837            0 :         AirFlowRateRatio = EvapInletMassFlowRate / (Coil.RatedAirMassFlowRate(1));
    8838            0 :         HeatCapFAirFlow = CurveValue(state, Coil.HCapFAirFlow, AirFlowRateRatio);
    8839              :         //   Warn user if curve output goes negative
    8840            0 :         if (HeatCapFAirFlow < 0.0) {
    8841            0 :             if (Coil.HCapFAirFlowErrorIndex == 0) {
    8842            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8843            0 :                 ShowContinueError(
    8844              :                     state,
    8845            0 :                     format(" HPWH Heating Capacity Modifier curve (function of air flow fraction) output is negative ({:.3T}).", HeatCapFAirFlow));
    8846            0 :                 ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirFlowRateRatio));
    8847            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8848              :             }
    8849            0 :             ShowRecurringWarningErrorAtEnd(
    8850              :                 state,
    8851            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8852              :                     "\": HPWH Heating Capacity Modifier curve (function of air flow fraction) output is negative warning continues...",
    8853            0 :                 Coil.HCapFAirFlowErrorIndex,
    8854              :                 HeatCapFAirFlow,
    8855              :                 HeatCapFAirFlow);
    8856            0 :             HeatCapFAirFlow = 0.0;
    8857              :         }
    8858              :     } else {
    8859          170 :         HeatCapFAirFlow = 1.0;
    8860              :     }
    8861              : 
    8862          170 :     if (Coil.HCOPFAirFlow > 0) {
    8863            0 :         AirFlowRateRatio = EvapInletMassFlowRate / (Coil.RatedAirMassFlowRate(1));
    8864            0 :         HeatCOPFAirFlow = CurveValue(state, Coil.HCOPFAirFlow, AirFlowRateRatio);
    8865              :         //   Warn user if curve output goes negative
    8866            0 :         if (HeatCOPFAirFlow < 0.0) {
    8867            0 :             if (Coil.HCOPFAirFlowErrorIndex == 0) {
    8868            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8869            0 :                 ShowContinueError(
    8870            0 :                     state, format(" HPWH Heating COP Modifier curve (function of air flow fraction) output is negative ({:.3T}).", HeatCOPFAirFlow));
    8871            0 :                 ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirFlowRateRatio));
    8872            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8873              :             }
    8874            0 :             ShowRecurringWarningErrorAtEnd(
    8875              :                 state,
    8876            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8877              :                     "\": HPWH Heating COP Modifier curve (function of air flow fraction) output is negative warning continues...",
    8878            0 :                 Coil.HCOPFAirFlowErrorIndex,
    8879              :                 HeatCOPFAirFlow,
    8880              :                 HeatCOPFAirFlow);
    8881            0 :             HeatCOPFAirFlow = 0.0;
    8882              :         }
    8883              :     } else {
    8884          170 :         HeatCOPFAirFlow = 1.0;
    8885              :     }
    8886              : 
    8887          170 :     if (Coil.HCapFWaterFlow > 0) {
    8888            0 :         WaterFlowRateRatio = CondInletMassFlowRate / (Coil.RatedHPWHCondWaterFlow * RhoH2O(InletWaterTemp));
    8889            0 :         HeatCapFWaterFlow = CurveValue(state, Coil.HCapFWaterFlow, WaterFlowRateRatio);
    8890              :         //   Warn user if curve output goes negative
    8891            0 :         if (HeatCapFWaterFlow < 0.0) {
    8892            0 :             if (Coil.HCapFWaterFlowErrorIndex == 0) {
    8893            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8894            0 :                 ShowContinueError(state,
    8895            0 :                                   format(" HPWH Heating Capacity Modifier curve (function of water flow fraction) output is negative ({:.3T}).",
    8896              :                                          HeatCapFWaterFlow));
    8897            0 :                 ShowContinueError(state, format(" Negative value occurs using a water flow fraction of {:.3T}.", WaterFlowRateRatio));
    8898            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8899              :             }
    8900            0 :             ShowRecurringWarningErrorAtEnd(
    8901              :                 state,
    8902            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8903              :                     "\": HPWH Heating Capacity Modifier curve (function of water flow fraction) output is negative warning continues...",
    8904            0 :                 Coil.HCapFWaterFlowErrorIndex,
    8905              :                 HeatCapFWaterFlow,
    8906              :                 HeatCapFWaterFlow);
    8907            0 :             HeatCapFWaterFlow = 0.0;
    8908              :         }
    8909              :     } else {
    8910          170 :         HeatCapFWaterFlow = 1.0;
    8911              :     }
    8912              : 
    8913          170 :     if (Coil.HCOPFWaterFlow > 0) {
    8914            0 :         WaterFlowRateRatio = CondInletMassFlowRate / (Coil.RatedHPWHCondWaterFlow * RhoH2O(InletWaterTemp));
    8915            0 :         HeatCOPFWaterFlow = CurveValue(state, Coil.HCOPFWaterFlow, WaterFlowRateRatio);
    8916              :         //   Warn user if curve output goes negative
    8917            0 :         if (HeatCOPFWaterFlow < 0.0) {
    8918            0 :             if (Coil.HCOPFWaterFlowErrorIndex == 0) {
    8919            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8920            0 :                 ShowContinueError(
    8921              :                     state,
    8922            0 :                     format(" HPWH Heating COP Modifier curve (function of water flow fraction) output is negative ({:.3T}).", HeatCOPFWaterFlow));
    8923            0 :                 ShowContinueError(state, format(" Negative value occurs using a water flow fraction of {:.3T}.", WaterFlowRateRatio));
    8924            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8925              :             }
    8926            0 :             ShowRecurringWarningErrorAtEnd(
    8927              :                 state,
    8928            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8929              :                     "\": HPWH Heating COP Modifier curve (function of water flow fraction) output is negative warning continues...",
    8930            0 :                 Coil.HCOPFWaterFlowErrorIndex,
    8931              :                 HeatCOPFWaterFlow,
    8932              :                 HeatCOPFWaterFlow);
    8933            0 :             HeatCOPFWaterFlow = 0.0;
    8934              :         }
    8935              :     } else {
    8936          170 :         HeatCOPFWaterFlow = 1.0;
    8937              :     }
    8938              : 
    8939              :     // adjust Heating Capacity and COP for off-design conditions
    8940          170 :     OperatingHeatingCapacity = RatedHeatingCapacity * HeatCapFTemp * HeatCapFAirFlow * HeatCapFWaterFlow;
    8941          170 :     OperatingHeatingCOP = RatedHeatingCOP * HeatCOPFTemp * HeatCOPFAirFlow * HeatCOPFWaterFlow;
    8942              : 
    8943          170 :     if (OperatingHeatingCOP > 0.0) OperatingHeatingPower = OperatingHeatingCapacity / OperatingHeatingCOP;
    8944              : 
    8945          170 :     PumpHeatToWater = Coil.HPWHCondPumpElecNomPower * Coil.HPWHCondPumpFracToWater;
    8946          170 :     TankHeatingCOP = OperatingHeatingCOP;
    8947              : 
    8948              :     // account for pump heat if not included in total water heating capacity
    8949          170 :     if (Coil.CondPumpHeatInCapacity) {
    8950            0 :         TotalTankHeatingCapacity = OperatingHeatingCapacity;
    8951              :     } else {
    8952          170 :         TotalTankHeatingCapacity = OperatingHeatingCapacity + PumpHeatToWater;
    8953              :     }
    8954              : 
    8955              :     // find part load fraction to calculate RTF
    8956          170 :     if (Coil.PLFFPLR(1) > 0) {
    8957          162 :         PartLoadFraction = max(0.7, CurveValue(state, Coil.PLFFPLR(1), PartLoadRatio));
    8958              :     } else {
    8959            8 :         PartLoadFraction = 1.0;
    8960              :     }
    8961              : 
    8962          170 :     HPRTF = min(1.0, (PartLoadRatio / PartLoadFraction));
    8963              : 
    8964          170 :     Real64 locFanElecPower = state.dataFans->fans(Coil.SupplyFanIndex)->totalPower;
    8965              : 
    8966              :     // calculate evaporator total cooling capacity
    8967          170 :     if (HPRTF > 0.0) {
    8968          170 :         if (Coil.FanPowerIncludedInCOP) {
    8969            8 :             if (Coil.CondPumpPowerInCOP) {
    8970              :                 //       make sure fan power is full load fan power
    8971            0 :                 CompressorPower = OperatingHeatingPower - locFanElecPower / HPRTF - Coil.HPWHCondPumpElecNomPower;
    8972            0 :                 if (OperatingHeatingPower > 0.0) TankHeatingCOP = TotalTankHeatingCapacity / OperatingHeatingPower;
    8973              :             } else {
    8974            8 :                 CompressorPower = OperatingHeatingPower - locFanElecPower / HPRTF;
    8975            8 :                 if ((OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower) > 0.0)
    8976            8 :                     TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower);
    8977              :             }
    8978              :         } else {
    8979          162 :             if (Coil.CondPumpPowerInCOP) {
    8980              :                 //       make sure fan power is full load fan power
    8981            0 :                 CompressorPower = OperatingHeatingPower - Coil.HPWHCondPumpElecNomPower;
    8982            0 :                 if ((OperatingHeatingPower + locFanElecPower / HPRTF) > 0.0)
    8983            0 :                     TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + locFanElecPower / HPRTF);
    8984              :             } else {
    8985          162 :                 CompressorPower = OperatingHeatingPower;
    8986          162 :                 if ((OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower) > 0.0)
    8987          162 :                     TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower);
    8988              :             }
    8989              :         }
    8990              :     }
    8991              : 
    8992          170 :     if (Coil.CondPumpHeatInCapacity) {
    8993            0 :         EvapCoolingCapacity = TotalTankHeatingCapacity - PumpHeatToWater - CompressorPower;
    8994              :     } else {
    8995          170 :         EvapCoolingCapacity = TotalTankHeatingCapacity - CompressorPower;
    8996              :     }
    8997              : 
    8998              :     // set evaporator total cooling capacity prior to CalcDOE2DXCoil subroutine
    8999          170 :     Coil.RatedTotCap(1) = EvapCoolingCapacity;
    9000              : 
    9001              :     // determine condenser water inlet/outlet condition at full capacity
    9002          170 :     if (CondInletMassFlowRate == 0.0) {
    9003            8 :         OutletWaterTemp = InletWaterTemp;
    9004              :     } else {
    9005          162 :         OutletWaterTemp = InletWaterTemp + TotalTankHeatingCapacity / (CpWater * CondInletMassFlowRate);
    9006              :     }
    9007              : 
    9008          170 :     WaterOutletNode.Temp = OutletWaterTemp;
    9009              : 
    9010          170 :     WaterOutletNode.MassFlowRate = WaterInletNode.MassFlowRate;
    9011              : 
    9012              :     // send heating capacity and COP to water heater module for standards rating calculation
    9013              :     // total heating capacity including condenser pump
    9014          170 :     state.dataDXCoils->HPWHHeatingCapacity = TotalTankHeatingCapacity;
    9015              :     // total heating COP including compressor, fan, and condenser pump
    9016          170 :     state.dataDXCoils->HPWHHeatingCOP = TankHeatingCOP;
    9017              : 
    9018              :     // send DX coil total cooling capacity to HPWH for reporting
    9019          170 :     state.dataHVACGlobal->DXCoilTotalCapacity = EvapCoolingCapacity;
    9020              : 
    9021          170 :     Coil.TotalHeatingEnergyRate = TotalTankHeatingCapacity * PartLoadRatio;
    9022              : 
    9023              :     // calculate total compressor plus condenser pump power, fan power reported in fan module
    9024          170 :     Coil.ElecWaterHeatingPower = (CompressorPower + Coil.HPWHCondPumpElecNomPower) * HPRTF;
    9025              : }
    9026              : 
    9027       331312 : void CalcDoe2DXCoil(EnergyPlusData &state,
    9028              :                     int const DXCoilNum,                                 // the number of the DX coil to be simulated
    9029              :                     HVAC::CompressorOp const compressorOp,               // compressor operation; 1=on, 0=off
    9030              :                     bool const FirstHVACIteration,                       // true if this is the first iteration of HVAC
    9031              :                     Real64 const PartLoadRatio,                          // sensible cooling load / full load sensible cooling capacity
    9032              :                     HVAC::FanOp const fanOp,                             // Allows parent object to control fan operation
    9033              :                     ObjexxFCL::Optional_int_const PerfMode,              // Performance mode for MultiMode DX coil; Always 1 for other coil types
    9034              :                     ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
    9035              :                     ObjexxFCL::Optional<Real64 const> CoolingHeatingPLR  // used for cycling fan RH control
    9036              : )
    9037              : {
    9038              : 
    9039              :     // SUBROUTINE INFORMATION:
    9040              :     //       AUTHOR         Fred Buhl
    9041              :     //       DATE WRITTEN   May 2000
    9042              :     //       MODIFIED       Shirey, Feb/October 2001, Feb/Mar 2004
    9043              :     //                      Feb 2005 M. J. Witte, GARD Analytics, Inc.
    9044              :     //                        Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
    9045              :     //                      April 2010 Chandan Sharma, FSEC, Added basin heater
    9046              :     //       RE-ENGINEERED  Don Shirey, Aug/Sept 2000
    9047              : 
    9048              :     // PURPOSE OF THIS SUBROUTINE:
    9049              :     // Calculates the air-side performance and electrical energy use of a direct-
    9050              :     // expansion, air-cooled cooling unit.
    9051              : 
    9052              :     // METHODOLOGY EMPLOYED:
    9053              :     // This routine simulates the performance of air-cooled DX cooling equipment.
    9054              :     // The routine requires the user to enter the total cooling capacity, sensible heat ratio,
    9055              :     // and COP for the unit at ARI 210/240 rating conditions (26.67C [80F] dry-bulb, 19.44C [67F]
    9056              :     // wet-bulb air entering the cooling coil, 35C [95F] dry-bulb air entering the outdoor
    9057              :     // condenser. Since different manufacturer's rate their equipment at different air flow rates,
    9058              :     // the supply air flow rate corresponding to the rated capacities and rated COP must also be
    9059              :     // entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information entered by
    9060              :     // the user should NOT include the thermal or electrical impacts of the supply air fan, as
    9061              :     // this is addressed by another module.
    9062              : 
    9063              :     // With the rated performance data entered by the user, the model employs some of the
    9064              :     // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
    9065              :     // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
    9066              :     // does NOT employ the exact same methodology to calculate performance as DOE-2, although
    9067              :     // some of the DOE-2 curve fits are employed by this model.
    9068              : 
    9069              :     // The model checks for coil dryout conditions, and adjusts the calculated performance
    9070              :     // appropriately.
    9071              : 
    9072              :     // REFERENCES:
    9073              :     // ASHRAE HVAC 2 Toolkit page 4-81.
    9074              :     // Henderson, H.I. Jr., K. Rengarajan and D.B. Shirey, III. 1992.The impact of comfort
    9075              :     // control on air conditioner energy use in humid climates. ASHRAE Transactions 98(2):
    9076              :     // 104-113.
    9077              :     // Henderson, H.I. Jr., Danny Parker and Y.J. Huang. 2000.Improving DOE-2's RESYS routine:
    9078              :     // User Defined Functions to Provide More Accurate Part Load Energy Use and Humidity
    9079              :     // Predictions. Proceedings of ACEEE Conference.
    9080              : 
    9081              :     // Using/Aliasing
    9082              :     using Curve::CurveValue;
    9083       331312 :     Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
    9084       331312 :     Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
    9085              :     using General::CreateSysTimeIntervalString;
    9086              : 
    9087              :     // SUBROUTINE PARAMETER DEFINITIONS:
    9088              :     static constexpr std::string_view RoutineName("CalcDoe2DXCoil: ");
    9089              :     static constexpr std::string_view calcDoe2DXCoil("CalcDoe2DXCoil");
    9090              : 
    9091              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    9092              :     Real64 AirMassFlow;       // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
    9093              :     Real64 AirMassFlowRatio;  // Ratio of actual air mass flow to rated air mass flow (adjusted for bypass if any)
    9094              :     Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
    9095              :     // (average flow if cycling fan, full flow if constant fan)
    9096              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
    9097              :     Real64 BypassFlowFraction;    // Fraction of total flow which is bypassed around the cooling coil
    9098              :     Real64 TotCap;                // gross total cooling capacity at off-rated conditions [W]
    9099              :     Real64 TotCapTempModFac;      // Total capacity modifier (function of entering wetbulb, outside drybulb)
    9100              :     Real64 TotCapFlowModFac;      // Total capacity modifier (function of actual supply air flow vs rated flow)
    9101              :     Real64 InletAirWetBulbC;      // wetbulb temperature of inlet air [C]
    9102              :     Real64 InletAirDryBulbTemp;   // inlet air dry bulb temperature [C]
    9103              :     Real64 InletAirEnthalpy;      // inlet air enthalpy [J/kg]
    9104              :     Real64 InletAirHumRat;        // inlet air humidity ratio [kg/kg]
    9105              :     Real64 InletAirHumRatTemp;    // inlet air humidity ratio used in ADP/BF loop [kg/kg]
    9106              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9107              :     // REAL(r64) :: InletAirPressure      ! inlet air pressure [Pa]
    9108              :     Real64 RatedCBF;             // coil bypass factor at rated conditions
    9109              :     Real64 SHR;                  // Sensible Heat Ratio (sensible/total) of the cooling coil
    9110              :     Real64 CBF;                  // coil bypass factor at off rated conditions
    9111              :     Real64 A0;                   // NTU * air mass flow rate, used in CBF calculation
    9112              :     Real64 hDelta;               // Change in air enthalpy across the cooling coil [J/kg]
    9113              :     Real64 hADP;                 // Apparatus dew point enthalpy [J/kg]
    9114              :     Real64 hTinwADP;             // Enthalpy at inlet dry-bulb and wADP [J/kg]
    9115              :     Real64 hTinwout;             // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
    9116              :     Real64 tADP;                 // Apparatus dew point temperature [C]
    9117              :     Real64 wADP;                 // Apparatus dew point humidity ratio [kg/kg]
    9118              :     Real64 FullLoadOutAirEnth;   // outlet full load enthalpy [J/kg]
    9119              :     Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
    9120              :     Real64 FullLoadOutAirTemp;   // outlet air temperature at full load [C]
    9121              :     Real64 EIRTempModFac;        // EIR modifier (function of entering wetbulb, outside drybulb)
    9122              :     Real64 EIRFlowModFac;        // EIR modifier (function of actual supply air flow vs rated flow)
    9123              :     Real64 EIR;                  // EIR at part load and off rated conditions
    9124              :     Real64 PLF;                  // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
    9125              :     Real64 QLatActual;           // operating latent capacity of DX coil
    9126              :     Real64 QLatRated;            // Rated latent capacity of DX coil
    9127              :     Real64 SHRUnadjusted;        // SHR prior to latent degradation effective SHR calculation
    9128              :     int Counter;                 // Counter for dry evaporator iterations
    9129              :     int MaxIter;                 // Maximum number of iterations for dry evaporator calculations
    9130              :     Real64 RF;                   // Relaxation factor for dry evaporator iterations
    9131              :     Real64 Tolerance;            // Error tolerance for dry evaporator iterations
    9132              :     Real64 werror;               // Deviation of humidity ratio in dry evaporator iteration loop
    9133              :     Real64 CondInletTemp;        // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
    9134              :     // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
    9135              :     Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
    9136              :     // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
    9137              :     Real64 CondAirMassFlow;       // Condenser air mass flow rate [kg/s]
    9138              :     Real64 RhoAir;                // Density of air [kg/m3]
    9139              :     Real64 RhoWater;              // Density of water [kg/m3]
    9140              :     Real64 CrankcaseHeatingPower; // power due to crankcase heater
    9141       331312 :     Real64 CompAmbTemp(0.0);      // Ambient temperature at compressor
    9142              :     Real64 AirFlowRatio;          // ratio of compressor on airflow to average timestep airflow
    9143              :     // used when constant fan mode yields different air flow rates when compressor is ON and OFF
    9144              :     // (e.g. Packaged Terminal Heat Pump)
    9145              :     Real64 OutdoorDryBulb;  // Outdoor dry-bulb temperature at condenser (C)
    9146              :     Real64 OutdoorWetBulb;  // Outdoor wet-bulb temperature at condenser (C)
    9147              :     Real64 OutdoorHumRat;   // Outdoor humidity ratio at condenser (kg/kg)
    9148              :     Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
    9149              : 
    9150              :     int Mode;                    // Performance mode for Multimode DX coil; Always 1 for other coil types
    9151              :     Real64 OutletAirTemp;        // Supply air temperature (average value if constant fan, full output if cycling fan)
    9152              :     Real64 OutletAirHumRat;      // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
    9153              :     Real64 OutletAirEnthalpy;    // Supply air enthalpy (average value if constant fan, full output if cycling fan)
    9154              :     Real64 ADiff;                // Used for exponential
    9155              :     Real64 DXcoolToHeatPLRRatio; // ratio of cooling PLR to heating PLR, used for cycling fan RH control
    9156              :     Real64 HeatRTF;              // heating coil part-load ratio, used for cycling fan RH control
    9157              :     Real64 HeatingCoilPLF;       // heating coil PLF (function of PLR), used for cycling fan RH control
    9158              : 
    9159              :     // If Performance mode not present, then set to 1.  Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
    9160       331312 :     if (present(PerfMode)) {
    9161            0 :         Mode = PerfMode;
    9162              :     } else {
    9163       331312 :         Mode = 1;
    9164              :     }
    9165              : 
    9166              :     // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
    9167              :     // during cooling and when no cooling is required (constant fan, fan speed changes)
    9168       331312 :     if (present(OnOffAirFlowRatio)) {
    9169       247143 :         AirFlowRatio = OnOffAirFlowRatio;
    9170              :     } else {
    9171        84169 :         AirFlowRatio = 1.0;
    9172              :     }
    9173              : 
    9174              :     // If CoolingHeatingPLR not present, then set to 1. Used for cycling fan systems where
    9175              :     // heating PLR is greater than cooling PLR, otherwise CoolingHeatingPLR = 1.
    9176       331312 :     if (present(CoolingHeatingPLR)) {
    9177        59945 :         DXcoolToHeatPLRRatio = CoolingHeatingPLR;
    9178              :     } else {
    9179       271367 :         DXcoolToHeatPLRRatio = 1.0;
    9180              :     }
    9181              : 
    9182       331312 :     MaxIter = 30;
    9183       331312 :     RF = 0.4;
    9184       331312 :     Counter = 0;
    9185       331312 :     Tolerance = 0.01;
    9186       331312 :     CondInletTemp = 0.0;
    9187       331312 :     CondInletHumRat = 0.0;
    9188              : 
    9189       331312 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    9190              : 
    9191       331312 :     BypassFlowFraction = thisDXCoil.BypassedFlowFrac(Mode);
    9192       331312 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate * (1.0 - BypassFlowFraction);
    9193       331312 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
    9194       331312 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
    9195       331312 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
    9196              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9197              :     // InletAirPressure    = DXCoil(DXCoilNum)%InletAirPressure
    9198       331312 :     state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
    9199       331312 :     thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
    9200       331312 :     thisDXCoil.PartLoadRatio = 0.0;
    9201       331312 :     thisDXCoil.BasinHeaterPower = 0.0;
    9202              : 
    9203       331312 :     if (thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::WaterHeater) {
    9204       331149 :         if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
    9205       117452 :             OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
    9206              :             // If node is not connected to anything, pressure = default, use weather data
    9207       117452 :             if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
    9208            0 :                 OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
    9209            0 :                 OutdoorHumRat = state.dataEnvrn->OutHumRat;
    9210            0 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress;
    9211            0 :                 OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
    9212              :             } else {
    9213       117452 :                 OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
    9214       117452 :                 OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
    9215              :                 // this should use Node%WetBulbTemp or a PSYC function, not OAWB
    9216       117452 :                 OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
    9217              :             }
    9218              :         } else {
    9219       213697 :             OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
    9220       213697 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
    9221       213697 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
    9222       213697 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
    9223              :         }
    9224       331149 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
    9225            0 :             auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
    9226            0 :             OutdoorDryBulb = secZoneHB.ZT;
    9227            0 :             OutdoorHumRat = secZoneHB.airHumRat;
    9228            0 :             OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
    9229            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
    9230              :         }
    9231              :     } else {
    9232          163 :         if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
    9233          163 :             OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
    9234              :             // If node is not connected to anything, pressure = default, use weather data
    9235          163 :             if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press)
    9236          163 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress; // node not connected
    9237              :         } else {
    9238            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
    9239              :         }
    9240              :     }
    9241              : 
    9242       331312 :     if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
    9243       263297 :         CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
    9244       263297 :         CompAmbTemp = OutdoorDryBulb;
    9245       263297 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
    9246            0 :             auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
    9247            0 :             CondInletTemp = secZoneHB.ZT;
    9248            0 :             CompAmbTemp = CondInletTemp; // assumes compressor is in same location as secondary coil
    9249            0 :             OutdoorDryBulb = CondInletTemp;
    9250            0 :             OutdoorHumRat = secZoneHB.airHumRat;
    9251            0 :             OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
    9252            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
    9253              :         }
    9254        68015 :     } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
    9255        67852 :         RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
    9256        67852 :         CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
    9257              :         // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
    9258        67852 :         CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
    9259        67852 :         CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
    9260        67852 :         CompAmbTemp = OutdoorDryBulb;
    9261          163 :     } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::WaterHeater) {
    9262          163 :         CompAmbTemp = state.dataHVACGlobal->HPWHCrankcaseDBTemp;   // Temperature at HP water heater compressor
    9263          163 :         CondInletTemp = state.dataHVACGlobal->HPWHCrankcaseDBTemp; // Temperature at HP water heater compressor
    9264              :     }
    9265              : 
    9266              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
    9267              :     // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
    9268       331312 :     if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
    9269        82507 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
    9270        82507 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
    9271            3 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
    9272              :         }
    9273              :     } else {
    9274       248805 :         CrankcaseHeatingPower = 0.0;
    9275              :     }
    9276              : 
    9277              :     // calculate end time of current time step to determine if error messages should be printed
    9278       331312 :     state.dataDXCoils->CurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
    9279              : 
    9280              :     //   Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
    9281              :     //   Wait for next time step to print warnings. If simulation iterates, print out
    9282              :     //   the warning for the last iteration only. Must wait for next time step to accomplish this.
    9283              :     //   If a warning occurs and the simulation down shifts, the warning is not valid.
    9284              : 
    9285       331312 :     if (thisDXCoil.PrintLowAmbMessage) { // .AND. &
    9286          240 :         if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
    9287            0 :             if (thisDXCoil.LowAmbErrIndex == 0) {
    9288            0 :                 ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowAmbBuffer1));
    9289            0 :                 ShowContinueError(state, thisDXCoil.LowAmbBuffer2);
    9290            0 :                 ShowContinueError(state, "... Operation at low ambient temperatures may require special performance curves.");
    9291              :             }
    9292            0 :             if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
    9293            0 :                 ShowRecurringWarningErrorAtEnd(state,
    9294            0 :                                                std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9295              :                                                    "\" - Low condenser dry-bulb temperature error continues...",
    9296            0 :                                                thisDXCoil.LowAmbErrIndex,
    9297            0 :                                                thisDXCoil.LowTempLast,
    9298            0 :                                                thisDXCoil.LowTempLast,
    9299              :                                                _,
    9300              :                                                "[C]",
    9301              :                                                "[C]");
    9302              :             } else {
    9303            0 :                 ShowRecurringWarningErrorAtEnd(state,
    9304            0 :                                                std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9305              :                                                    "\" - Low condenser wet-bulb temperature error continues...",
    9306            0 :                                                thisDXCoil.LowAmbErrIndex,
    9307            0 :                                                thisDXCoil.LowTempLast,
    9308            0 :                                                thisDXCoil.LowTempLast,
    9309              :                                                _,
    9310              :                                                "[C]",
    9311              :                                                "[C]");
    9312              :             }
    9313              :         }
    9314              :     }
    9315              : 
    9316       331312 :     if (thisDXCoil.PrintLowOutTempMessage) {
    9317         1017 :         if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
    9318          376 :             if (thisDXCoil.LowOutletTempIndex == 0) {
    9319            4 :                 ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowOutTempBuffer1));
    9320            4 :                 ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
    9321            8 :                 ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
    9322            8 :                 ShowContinueError(state,
    9323            8 :                                   format("   1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
    9324            4 :                                          thisDXCoil.FullLoadInletAirTempLast));
    9325            8 :                 ShowContinueError(state, "   2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
    9326           12 :                 ShowContinueError(state,
    9327              :                                   "   3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
    9328              :             }
    9329         3008 :             ShowRecurringWarningErrorAtEnd(state,
    9330         1128 :                                            std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9331              :                                                "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
    9332              :                                                "Outlet air temperature statistics follow:",
    9333          376 :                                            thisDXCoil.LowOutletTempIndex,
    9334          376 :                                            thisDXCoil.FullLoadOutAirTempLast,
    9335          376 :                                            thisDXCoil.FullLoadOutAirTempLast);
    9336              :         }
    9337              :     }
    9338              : 
    9339              :     // save last system time step and last end time of current time step (used to determine if warning is valid)
    9340       331312 :     thisDXCoil.TimeStepSysLast = TimeStepSys;
    9341       331312 :     thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CurrentEndTime;
    9342       331312 :     thisDXCoil.PrintLowAmbMessage = false;
    9343       331312 :     thisDXCoil.PrintLowOutTempMessage = false;
    9344              : 
    9345       269753 :     if ((AirMassFlow > 0.0) &&
    9346       269908 :         (thisDXCoil.availSched->getCurrentVal() > 0.0 || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9347            3 :          thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
    9348       771102 :         (PartLoadRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On) &&
    9349       170037 :         CompAmbTemp > thisDXCoil.MinOATCompressor) { // criteria for coil operation
    9350       170031 :         if (fanOp == HVAC::FanOp::Cycling) {
    9351        57669 :             AirMassFlow /= (PartLoadRatio / DXcoolToHeatPLRRatio);
    9352       112362 :         } else if (fanOp == HVAC::FanOp::Continuous && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_CoolingTwoSpeed) {
    9353       112362 :             AirMassFlow *= AirFlowRatio;
    9354              :         } else {
    9355            0 :             AirMassFlow = thisDXCoil.RatedAirMassFlowRate(Mode);
    9356              :         }
    9357              : 
    9358              :         // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton)
    9359              : 
    9360              :         // for some reason there are diff's when using coil inlet air pressure
    9361              :         // these lines (more to follow) are commented out for the time being
    9362              : 
    9363       170031 :         InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
    9364       170031 :         AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
    9365              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9366              :         //  InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
    9367              :         //  AirVolumeFlowRate = AirMassFlow/ PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
    9368       170031 :         if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
    9369            0 :             ShowFatalError(
    9370            0 :                 state, format("{}{}=\"{}\" - Rated total cooling capacity is zero or less.", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9371              :         }
    9372       170031 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9373       169884 :             thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9374          147 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap2;
    9375              :         } else {
    9376       169884 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
    9377              :         }
    9378        81326 :         if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterPumped &&
    9379       263161 :             thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterWrapped &&
    9380        11804 :             ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
    9381        10710 :              (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
    9382         1095 :             if (thisDXCoil.ErrIndex1 == 0) {
    9383            8 :                 ShowWarningMessage(
    9384              :                     state,
    9385            8 :                     format("{}{}=\"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
    9386              :                            RoutineName,
    9387            4 :                            thisDXCoil.DXCoilType,
    9388            4 :                            thisDXCoil.Name,
    9389              :                            VolFlowperRatedTotCap));
    9390            8 :                 ShowContinueErrorTimeStamp(state, "");
    9391            8 :                 ShowContinueError(state,
    9392            8 :                                   format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
    9393            4 :                                          HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    9394            4 :                                          HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    9395            8 :                 ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components,");
    9396           12 :                 ShowContinueError(state, "or variable air volume [VAV] system using incorrect coil type.");
    9397              :             }
    9398         8760 :             ShowRecurringWarningErrorAtEnd(
    9399              :                 state,
    9400         3285 :                 std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9401              :                     "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
    9402         1095 :                 thisDXCoil.ErrIndex1,
    9403              :                 VolFlowperRatedTotCap,
    9404              :                 VolFlowperRatedTotCap);
    9405       168936 :         } else if (!state.dataGlobal->WarmupFlag &&
    9406        22954 :                    (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9407       191890 :                     thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
    9408           49 :                    ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
    9409           49 :                     (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
    9410            0 :             if (thisDXCoil.ErrIndex1 == 0) {
    9411            0 :                 ShowWarningMessage(
    9412              :                     state,
    9413            0 :                     format("{}{}=\"{}\" - Air volume flow rate per watt of rated total water heating capacity is out of range at {:.2R} m3/s/W.",
    9414              :                            RoutineName,
    9415            0 :                            thisDXCoil.DXCoilType,
    9416            0 :                            thisDXCoil.Name,
    9417              :                            VolFlowperRatedTotCap));
    9418            0 :                 ShowContinueErrorTimeStamp(state, "");
    9419            0 :                 ShowContinueError(state,
    9420            0 :                                   format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
    9421            0 :                                          HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    9422            0 :                                          HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    9423            0 :                 ShowContinueError(state,
    9424              :                                   "Possible causes may be that the parent object is calling for an actual supply air flow rate that is much "
    9425              :                                   "higher or lower than the DX coil rated supply air flow rate.");
    9426              :             }
    9427            0 :             ShowRecurringWarningErrorAtEnd(
    9428              :                 state,
    9429            0 :                 std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9430              :                     "\" - Air volume flow rate per watt of rated total water heating capacity is out of range error continues...",
    9431            0 :                 thisDXCoil.ErrIndex1,
    9432              :                 VolFlowperRatedTotCap,
    9433              :                 VolFlowperRatedTotCap);
    9434              :         }
    9435              :         //    Adjust coil bypass factor for actual air flow rate. Use relation CBF = exp(-NTU) where
    9436              :         //    NTU = A0/(m*cp). Relationship models the cooling coil as a heat exchanger with Cmin/Cmax = 0.
    9437              : 
    9438       170031 :         RatedCBF = thisDXCoil.RatedCBF(Mode);
    9439       170031 :         if (RatedCBF > 0.0) {
    9440       170031 :             A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
    9441              :         } else {
    9442            0 :             A0 = 0.0;
    9443              :         }
    9444       170031 :         ADiff = -A0 / AirMassFlow;
    9445       170031 :         if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
    9446       166270 :             CBF = std::exp(ADiff);
    9447              :         } else {
    9448         3761 :             CBF = 0.0;
    9449              :         }
    9450              : 
    9451              :         //   check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
    9452       170031 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
    9453       127084 :             if (OutdoorDryBulb < 0.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for air-cooled electric chiller
    9454            0 :                 thisDXCoil.PrintLowAmbMessage = true;
    9455            0 :                 thisDXCoil.LowTempLast = OutdoorDryBulb;
    9456            0 :                 if (thisDXCoil.LowAmbErrIndex == 0) {
    9457              :                     thisDXCoil.LowAmbBuffer1 =
    9458            0 :                         format("{} \"{}\" - Air-cooled condenser inlet dry-bulb temperature below 0 C. Outdoor dry-bulb temperature = {:.2R}",
    9459            0 :                                thisDXCoil.DXCoilType,
    9460            0 :                                thisDXCoil.Name,
    9461            0 :                                OutdoorDryBulb);
    9462            0 :                     thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
    9463            0 :                                                CreateSysTimeIntervalString(state);
    9464              :                 }
    9465              :             }
    9466        42947 :         } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
    9467        42800 :             if (OutdoorWetBulb < 10.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for evap-cooled electric chiller
    9468          240 :                 thisDXCoil.PrintLowAmbMessage = true;
    9469          240 :                 thisDXCoil.LowTempLast = OutdoorWetBulb;
    9470          240 :                 if (thisDXCoil.LowAmbErrIndex == 0) {
    9471              :                     thisDXCoil.LowAmbBuffer1 =
    9472          480 :                         format("{} \"{}\" - Evap-cooled condenser inlet wet-bulb temperature below 10 C. Outdoor wet-bulb temperature = {:.2R}",
    9473          240 :                                thisDXCoil.DXCoilType,
    9474          240 :                                thisDXCoil.Name,
    9475          240 :                                OutdoorWetBulb);
    9476          480 :                     thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
    9477          720 :                                                CreateSysTimeIntervalString(state);
    9478              :                 }
    9479              :             }
    9480              :         }
    9481              : 
    9482              :         //  Get total capacity modifying factor (function of temperature) for off-rated conditions
    9483              :         //  InletAirHumRat may be modified in this ADP/BF loop, use temporary variable for calculations
    9484       170031 :         InletAirHumRatTemp = InletAirHumRat;
    9485       170031 :         AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
    9486              :         while (true) {
    9487       199692 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9488       199545 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9489              :                 // Coil:DX:HeatPumpWaterHeater does not have total cooling capacity as a function of temp or flow curve
    9490          147 :                 TotCapTempModFac = 1.0;
    9491          147 :                 TotCapFlowModFac = 1.0;
    9492              :             } else {
    9493       199545 :                 if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
    9494       199504 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
    9495              :                 } else {
    9496           41 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), CondInletTemp);
    9497              :                 }
    9498              : 
    9499              :                 //    Warn user if curve output goes negative
    9500       199545 :                 if (TotCapTempModFac < 0.0) {
    9501            0 :                     if (thisDXCoil.CCapFTempErrorIndex == 0) {
    9502            0 :                         ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9503            0 :                         ShowContinueError(state,
    9504            0 :                                           format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).",
    9505              :                                                  TotCapTempModFac));
    9506            0 :                         if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
    9507            0 :                             ShowContinueError(state,
    9508            0 :                                               format(" Negative value occurs using a condenser inlet air temperature of {:.1T} and an inlet air "
    9509              :                                                      "wet-bulb temperature of {:.1T}.",
    9510              :                                                      CondInletTemp,
    9511              :                                                      InletAirWetBulbC));
    9512              :                         } else {
    9513            0 :                             ShowContinueError(state,
    9514            0 :                                               format(" Negative value occurs using a condenser inlet air temperature of {:.1T}.", CondInletTemp));
    9515              :                         }
    9516            0 :                         if (Mode > 1) {
    9517            0 :                             ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
    9518              :                         }
    9519            0 :                         ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    9520              :                     }
    9521            0 :                     ShowRecurringWarningErrorAtEnd(
    9522              :                         state,
    9523            0 :                         std::string{RoutineName} + thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
    9524              :                             "\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
    9525            0 :                         thisDXCoil.CCapFTempErrorIndex,
    9526              :                         TotCapTempModFac,
    9527              :                         TotCapTempModFac);
    9528            0 :                     TotCapTempModFac = 0.0;
    9529              :                 }
    9530              : 
    9531              :                 //    Get total capacity modifying factor (function of mass flow) for off-rated conditions
    9532       199545 :                 TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
    9533              :                 //    Warn user if curve output goes negative
    9534       199545 :                 if (TotCapFlowModFac < 0.0) {
    9535            0 :                     if (thisDXCoil.CCapFFlowErrorIndex == 0) {
    9536            0 :                         ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9537            0 :                         ShowContinueError(state,
    9538            0 :                                           format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).",
    9539              :                                                  TotCapFlowModFac));
    9540            0 :                         ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
    9541            0 :                         ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    9542            0 :                         if (Mode > 1) {
    9543            0 :                             ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
    9544              :                         }
    9545              :                     }
    9546            0 :                     ShowRecurringWarningErrorAtEnd(
    9547              :                         state,
    9548            0 :                         std::string{RoutineName} + thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
    9549              :                             "\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
    9550            0 :                         thisDXCoil.CCapFFlowErrorIndex,
    9551              :                         TotCapFlowModFac,
    9552              :                         TotCapFlowModFac);
    9553            0 :                     TotCapFlowModFac = 0.0;
    9554              :                 }
    9555              :             }
    9556       199692 :             TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
    9557              :             // if user specified SHR modifier curves are available calculate the SHR as follows:
    9558       199692 :             if (thisDXCoil.UserSHRCurveExists) {
    9559            0 :                 SHR = CalcSHRUserDefinedCurves(state,
    9560              :                                                InletAirDryBulbTemp,
    9561              :                                                InletAirWetBulbC,
    9562              :                                                AirMassFlowRatio,
    9563            0 :                                                thisDXCoil.SHRFTemp(Mode),
    9564            0 :                                                thisDXCoil.SHRFFlow(Mode),
    9565            0 :                                                thisDXCoil.RatedSHR(Mode));
    9566            0 :                 hDelta = TotCap / AirMassFlow;
    9567            0 :                 break;
    9568              :             } else {
    9569              :                 // Calculate apparatus dew point conditions using TotCap and CBF
    9570       199692 :                 hDelta = TotCap / AirMassFlow;
    9571       199692 :                 hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
    9572       199692 :                 tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, calcDoe2DXCoil);
    9573              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9574              :                 //  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
    9575       199692 :                 wADP = PsyWFnTdbH(state, tADP, hADP, calcDoe2DXCoil);
    9576       199692 :                 hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
    9577       199692 :                 if ((InletAirEnthalpy - hADP) > 1.e-10) {
    9578       199692 :                     SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
    9579              :                 } else {
    9580            0 :                     SHR = 1.0;
    9581              :                 }
    9582              :                 // Check for dry evaporator conditions (win < wadp)
    9583       199692 :                 if (wADP > InletAirHumRatTemp || (Counter >= 1 && Counter < MaxIter)) {
    9584        34640 :                     if (InletAirHumRatTemp == 0.0) InletAirHumRatTemp = 0.00001;
    9585        34640 :                     werror = (InletAirHumRatTemp - wADP) / InletAirHumRatTemp;
    9586              :                     // Increase InletAirHumRatTemp at constant InletAirTemp to find coil dry-out point. Then use the
    9587              :                     // capacity at the dry-out point to determine exiting conditions from coil. This is required
    9588              :                     // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
    9589        34640 :                     InletAirHumRatTemp = RF * wADP + (1.0 - RF) * InletAirHumRatTemp;
    9590        34640 :                     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRatTemp, OutdoorPressure);
    9591              :                     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment
    9592              :                     //  line InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRatTemp,InletAirPressure)
    9593        34640 :                     ++Counter;
    9594        34640 :                     if (std::abs(werror) > Tolerance) continue; // Recalculate with modified inlet conditions
    9595         4979 :                     break;
    9596              :                 } else {
    9597              :                     break;
    9598              :                 }
    9599              :             }
    9600              :         } // end of DO iteration loop
    9601              : 
    9602       170031 :         if (thisDXCoil.PLFFPLR(Mode) > 0) {
    9603       170031 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PartLoadRatio); // Calculate part-load factor
    9604              :         } else {
    9605            0 :             PLF = 1.0;
    9606              :         }
    9607              : 
    9608       170031 :         if (PLF < 0.7) {
    9609            0 :             if (thisDXCoil.ErrIndex2 == 0) {
    9610            0 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9611            0 :                     thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9612            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\", PLF curve value", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9613            0 :                     ShowContinueError(state, format("The PLF curve value = {:.3T} for part-load ratio = {:.3T}", PLF, PartLoadRatio));
    9614            0 :                     ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
    9615            0 :                     ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
    9616              :                 } else {
    9617            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\", PLF curve value", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9618            0 :                     ShowContinueError(state, format("The PLF curve value = {:.3T} for part-load ratio = {:.3T}", PLF, PartLoadRatio));
    9619            0 :                     ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
    9620            0 :                     ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
    9621              :                 }
    9622              :             }
    9623            0 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9624            0 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9625            0 :                 ShowRecurringWarningErrorAtEnd(
    9626            0 :                     state, thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
    9627              :             } else {
    9628            0 :                 ShowRecurringWarningErrorAtEnd(
    9629            0 :                     state, thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
    9630              :             }
    9631            0 :             PLF = 0.7;
    9632              :         }
    9633              : 
    9634       170031 :         thisDXCoil.PartLoadRatio = PartLoadRatio;
    9635       170031 :         thisDXCoil.CoolingCoilRuntimeFraction = PartLoadRatio / PLF;
    9636       170031 :         if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
    9637            0 :             if (thisDXCoil.ErrIndex3 == 0) {
    9638            0 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9639            0 :                     thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9640            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\", runtime fraction", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9641            0 :                     ShowWarningMessage(state, format("The runtime fraction exceeded 1.0. [{:.4R}].", thisDXCoil.CoolingCoilRuntimeFraction));
    9642            0 :                     ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
    9643            0 :                     ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
    9644            0 :                     ShowContinueErrorTimeStamp(state, "");
    9645              :                 } else {
    9646            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\", runtime fraction", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9647            0 :                     ShowWarningMessage(state, format("The runtime fraction exceeded 1.0. [{:.4R}].", thisDXCoil.CoolingCoilRuntimeFraction));
    9648            0 :                     ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
    9649            0 :                     ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
    9650            0 :                     ShowContinueErrorTimeStamp(state, "");
    9651              :                 }
    9652              :             }
    9653            0 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9654            0 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9655            0 :                 ShowRecurringWarningErrorAtEnd(state,
    9656            0 :                                                thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " runtime fraction > 1.0 warning continues...",
    9657            0 :                                                thisDXCoil.ErrIndex3,
    9658            0 :                                                thisDXCoil.CoolingCoilRuntimeFraction,
    9659            0 :                                                thisDXCoil.CoolingCoilRuntimeFraction);
    9660              :             } else {
    9661            0 :                 ShowRecurringWarningErrorAtEnd(state,
    9662            0 :                                                thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " runtime fraction > 1.0 warning continues...",
    9663            0 :                                                thisDXCoil.ErrIndex3,
    9664            0 :                                                thisDXCoil.CoolingCoilRuntimeFraction,
    9665            0 :                                                thisDXCoil.CoolingCoilRuntimeFraction);
    9666              :             }
    9667            0 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
    9668       170031 :         } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
    9669         5482 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
    9670              :         }
    9671              : 
    9672              :         // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
    9673       170031 :         if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
    9674              : 
    9675              :         //  Calculate full load output conditions
    9676       170031 :         if (thisDXCoil.UserSHRCurveExists) {
    9677            0 :             FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
    9678            0 :             if (SHR < 1.0) {
    9679            0 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9680            0 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9681            0 :                 if (FullLoadOutAirHumRat <= 0.0) {
    9682            0 :                     FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
    9683              :                 }
    9684              :             } else {
    9685            0 :                 SHR = 1.0;
    9686            0 :                 FullLoadOutAirHumRat = InletAirHumRat;
    9687              :             }
    9688              :         } else {
    9689       170031 :             if (SHR > 1.0 || Counter > 0) SHR = 1.0;
    9690       170031 :             FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
    9691       170031 :             hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9692       170031 :             if (SHR < 1.0) {
    9693       165052 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9694              :             } else {
    9695         4979 :                 FullLoadOutAirHumRat = InletAirHumRat;
    9696              :             }
    9697              :         }
    9698       170031 :         FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
    9699              : 
    9700              :         // Check for saturation error and modify temperature at constant enthalpy
    9701       170031 :         if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
    9702        17527 :             FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
    9703              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9704              :             //   IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
    9705              :             //    FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
    9706        17527 :             FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
    9707              :         }
    9708              : 
    9709              :         // Store actual outlet conditions when DX coil is ON for use in heat recovery module
    9710       170031 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
    9711       170031 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
    9712              : 
    9713              :         // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
    9714       170031 :         if (FullLoadOutAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
    9715         1018 :             thisDXCoil.PrintLowOutTempMessage = true;
    9716         1018 :             thisDXCoil.FullLoadOutAirTempLast = FullLoadOutAirTemp;
    9717         1018 :             if (thisDXCoil.LowOutletTempIndex == 0) {
    9718            8 :                 thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
    9719           16 :                 thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
    9720              :                                                       "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
    9721            8 :                                                       thisDXCoil.DXCoilType,
    9722            8 :                                                       thisDXCoil.Name,
    9723            8 :                                                       FullLoadOutAirTemp);
    9724           16 :                 thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
    9725           24 :                                                CreateSysTimeIntervalString(state);
    9726              :             }
    9727              :         }
    9728              : 
    9729              :         //  If constant fan with cycling compressor, call function to determine "effective SHR"
    9730              :         //  which includes the part-load degradation on latent capacity
    9731       170031 :         if (fanOp == HVAC::FanOp::Continuous) {
    9732       112362 :             QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode));
    9733       112362 :             QLatActual = TotCap * (1.0 - SHR);
    9734       112362 :             SHRUnadjusted = SHR;
    9735       112362 :             SHR = CalcEffectiveSHR(
    9736              :                 state, DXCoilNum, SHR, thisDXCoil.CoolingCoilRuntimeFraction, QLatRated, QLatActual, InletAirDryBulbTemp, InletAirWetBulbC, Mode);
    9737              :             // For multimode coil, if stage-2 operation (modes 2 or 4), adjust Stage1&2 SHR to account for
    9738              :             // Stage 1 operating at full load, so there is no degradation for that portion
    9739              :             // Use the stage 1 bypass fraction to allocate
    9740       112362 :             if (Mode == 2 || Mode == 4) {
    9741            0 :                 SHR = SHRUnadjusted * (1.0 - thisDXCoil.BypassedFlowFrac(Mode - 1)) + SHR * thisDXCoil.BypassedFlowFrac(Mode - 1);
    9742              :             }
    9743              : 
    9744              :             //  Calculate full load output conditions
    9745       112362 :             if (thisDXCoil.UserSHRCurveExists) {
    9746            0 :                 FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
    9747            0 :                 if (SHR < 1.0) {
    9748            0 :                     hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9749            0 :                     FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9750            0 :                     if (FullLoadOutAirHumRat <= 0.0) {
    9751            0 :                         FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
    9752              :                     }
    9753              :                 } else {
    9754            0 :                     SHR = 1.0;
    9755            0 :                     FullLoadOutAirHumRat = InletAirHumRat;
    9756              :                 }
    9757              :             } else {
    9758       112362 :                 if (SHR > 1.0 || Counter > 0) SHR = 1.0;
    9759       112362 :                 FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
    9760       112362 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9761       112362 :                 if (SHR < 1.0) {
    9762       102175 :                     FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9763              :                 } else {
    9764        10187 :                     FullLoadOutAirHumRat = InletAirHumRat;
    9765              :                 }
    9766              :             }
    9767       112362 :             FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
    9768              : 
    9769              :             // apply latent degradation model to cycling fan when RH control is desired and heating coil operates
    9770              :             // longer than the cooling coil. DXcoolToHeatPLRRatio = Cooling coil PLR / Heating coil PLR.
    9771        57669 :         } else if (fanOp == HVAC::FanOp::Cycling) {
    9772        57669 :             if (DXcoolToHeatPLRRatio < 1.0) {
    9773            0 :                 QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode));
    9774            0 :                 QLatActual = TotCap * (1.0 - SHR);
    9775            0 :                 HeatRTF = PartLoadRatio / DXcoolToHeatPLRRatio;
    9776            0 :                 if (thisDXCoil.HeatingCoilPLFCurvePTR > 0) {
    9777            0 :                     HeatingCoilPLF = CurveValue(state, thisDXCoil.HeatingCoilPLFCurvePTR, HeatRTF);
    9778            0 :                     if (HeatingCoilPLF > 0) HeatRTF /= HeatingCoilPLF;
    9779              :                 }
    9780            0 :                 SHRUnadjusted = SHR;
    9781            0 :                 SHR = CalcEffectiveSHR(state,
    9782              :                                        DXCoilNum,
    9783              :                                        SHR,
    9784              :                                        thisDXCoil.CoolingCoilRuntimeFraction,
    9785              :                                        QLatRated,
    9786              :                                        QLatActual,
    9787              :                                        InletAirDryBulbTemp,
    9788              :                                        InletAirWetBulbC,
    9789              :                                        Mode,
    9790              :                                        HeatRTF);
    9791              :                 //   Calculate full load output conditions
    9792            0 :                 if (thisDXCoil.UserSHRCurveExists) {
    9793            0 :                     FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
    9794            0 :                     if (SHR < 1.0) {
    9795            0 :                         hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9796            0 :                         FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9797            0 :                         if (FullLoadOutAirHumRat <= 0.0) {
    9798            0 :                             FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
    9799              :                         }
    9800              :                     } else {
    9801            0 :                         SHR = 1.0;
    9802            0 :                         FullLoadOutAirHumRat = InletAirHumRat;
    9803              :                     }
    9804              :                 } else {
    9805            0 :                     if (SHR > 1.0 || Counter > 0) SHR = 1.0;
    9806            0 :                     FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
    9807            0 :                     hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9808            0 :                     if (SHR < 1.0) {
    9809            0 :                         FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9810              :                     } else {
    9811            0 :                         FullLoadOutAirHumRat = InletAirHumRat;
    9812              :                     }
    9813              :                 }
    9814            0 :                 FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
    9815              :             }
    9816              :         }
    9817              : 
    9818              :         //  Calculate actual outlet conditions for the input part load ratio
    9819              :         //  Actual outlet conditions are "average" for time step
    9820              : 
    9821              :         // For multimode coil, if stage-2 operation (modes 2 or 4), return "full load" outlet conditions
    9822       170031 :         if (((fanOp == HVAC::FanOp::Continuous) && (Mode == 1)) || (Mode == 3)) {
    9823              :             // Continuous fan, cycling compressor
    9824       112362 :             OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
    9825       112362 :             OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
    9826       112362 :             OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
    9827              :         } else {
    9828              :             // Default to cycling fan, cycling compressor
    9829              :             // Also return this result for stage 2 operation of multimode coil
    9830              :             // Cycling fan typically provides full outlet conditions. When RH control is used, account for additional
    9831              :             // heating run time by using cooling/heating ratio the same as constant fan (otherwise PLRRatio = 1).
    9832        57669 :             OutletAirEnthalpy = FullLoadOutAirEnth * DXcoolToHeatPLRRatio + InletAirEnthalpy * (1.0 - DXcoolToHeatPLRRatio);
    9833        57669 :             OutletAirHumRat = FullLoadOutAirHumRat * DXcoolToHeatPLRRatio + InletAirHumRat * (1.0 - DXcoolToHeatPLRRatio);
    9834        57669 :             OutletAirTemp = FullLoadOutAirTemp * DXcoolToHeatPLRRatio + InletAirDryBulbTemp * (1.0 - DXcoolToHeatPLRRatio);
    9835              :         }
    9836              : 
    9837              :         // Check for saturation error and modify temperature at constant enthalpy
    9838       170031 :         if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, calcDoe2DXCoil)) {
    9839        10242 :             OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
    9840              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9841              :             //   IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
    9842              :             //    OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
    9843        10242 :             OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
    9844              :         }
    9845              : 
    9846              :         // Mix with air that was bypassed around coil, if any
    9847       170031 :         if (BypassFlowFraction > 0.0) {
    9848            0 :             OutletAirEnthalpy = (1.0 - BypassFlowFraction) * OutletAirEnthalpy + BypassFlowFraction * InletAirEnthalpy;
    9849            0 :             OutletAirHumRat = (1.0 - BypassFlowFraction) * OutletAirHumRat + BypassFlowFraction * InletAirHumRat;
    9850            0 :             OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
    9851              :             // Check for saturation error and modify temperature at constant enthalpy
    9852            0 :             if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) {
    9853            0 :                 OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
    9854              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9855              :                 //     IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
    9856              :                 //       OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
    9857            0 :                 OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
    9858              :             }
    9859              :         }
    9860              : 
    9861              :         // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
    9862       170031 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9863       169884 :             thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9864              :             //   Coil:DX:HeatPumpWaterHeater does not have EIR temp or flow curves
    9865          147 :             EIRTempModFac = 1.0;
    9866          147 :             EIRFlowModFac = 1.0;
    9867              :         } else {
    9868       169884 :             EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
    9869              : 
    9870              :             //   Warn user if curve output goes negative
    9871       169884 :             if (EIRTempModFac < 0.0) {
    9872            0 :                 if (thisDXCoil.EIRFTempErrorIndex == 0) {
    9873            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9874            0 :                     ShowContinueError(
    9875            0 :                         state, format(" Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).", EIRTempModFac));
    9876            0 :                     if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 2) {
    9877            0 :                         ShowContinueError(state,
    9878            0 :                                           format(" Negative value occurs using a condenser inlet air temperature of {:.1T} and an inlet air "
    9879              :                                                  "wet-bulb temperature of {:.1T}.",
    9880              :                                                  CondInletTemp,
    9881              :                                                  InletAirWetBulbC));
    9882              :                     } else {
    9883            0 :                         ShowContinueError(state, format(" Negative value occurs using a condenser inlet air temperature of {:.1T}.", CondInletTemp));
    9884              :                     }
    9885            0 :                     if (Mode > 1) {
    9886            0 :                         ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
    9887              :                     }
    9888            0 :                     ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    9889              :                 }
    9890            0 :                 ShowRecurringWarningErrorAtEnd(
    9891              :                     state,
    9892            0 :                     std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9893              :                         "\": Energy Input Ratio Modifier curve (function of temperature) output is negative warning continues...",
    9894            0 :                     thisDXCoil.EIRFTempErrorIndex,
    9895              :                     EIRTempModFac,
    9896              :                     EIRTempModFac);
    9897            0 :                 EIRTempModFac = 0.0;
    9898              :             }
    9899              : 
    9900       169884 :             EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
    9901              : 
    9902              :             //   Warn user if curve output goes negative
    9903       169884 :             if (EIRFlowModFac < 0.0) {
    9904            0 :                 if (thisDXCoil.EIRFFlowErrorIndex == 0) {
    9905            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9906            0 :                     ShowContinueError(
    9907            0 :                         state, format(" Energy Input Ratio Modifier curve (function of flow fraction) output is negative ({:.3T}).", EIRFlowModFac));
    9908            0 :                     ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
    9909            0 :                     ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    9910            0 :                     if (Mode > 1) {
    9911            0 :                         ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
    9912              :                     }
    9913              :                 }
    9914            0 :                 ShowRecurringWarningErrorAtEnd(
    9915              :                     state,
    9916            0 :                     std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9917              :                         "\": Energy Input Ratio Modifier curve (function of flow fraction) output is negative warning continues...",
    9918            0 :                     thisDXCoil.EIRFFlowErrorIndex,
    9919              :                     EIRFlowModFac,
    9920              :                     EIRFlowModFac);
    9921            0 :                 EIRFlowModFac = 0.0;
    9922              :             }
    9923              :         }
    9924              : 
    9925       170031 :         EIR = thisDXCoil.RatedEIR(Mode) * EIRFlowModFac * EIRTempModFac;
    9926              : 
    9927              :         // For multimode coil, if stage-2 operation (Modes 2 or 4), return "full load" power adjusted for PLF
    9928       170031 :         if (Mode == 1 || Mode == 3) {
    9929       170031 :             thisDXCoil.ElecCoolingPower = TotCap * EIR * thisDXCoil.CoolingCoilRuntimeFraction;
    9930              :         } else {
    9931            0 :             thisDXCoil.ElecCoolingPower = TotCap * EIR * thisDXCoil.CoolingCoilRuntimeFraction / PartLoadRatio;
    9932              :         }
    9933              : 
    9934              :         // Reset AirMassFlow to inlet node air mass flow for final total, sensible and latent calculations
    9935              :         // since AirMassFlow might have been modified above (in this subroutine):
    9936              :         //     IF (FanOpMode .EQ. FanOp::Cycling) AirMassFlow = AirMassFlow / PartLoadRatio
    9937              :         // For multimode coil, this should be full flow including bypassed fraction
    9938       170031 :         AirMassFlow = thisDXCoil.InletAirMassFlowRate;
    9939       170031 :         CalcComponentSensibleLatentOutput(AirMassFlow,
    9940              :                                           InletAirDryBulbTemp,
    9941              :                                           InletAirHumRat,
    9942              :                                           OutletAirTemp,
    9943              :                                           OutletAirHumRat,
    9944       170031 :                                           thisDXCoil.SensCoolingEnergyRate,
    9945       170031 :                                           thisDXCoil.LatCoolingEnergyRate,
    9946       170031 :                                           thisDXCoil.TotalCoolingEnergyRate);
    9947              : 
    9948              :         // Set DataHeatGlobal heat reclaim variable for use by heat reclaim coil (part load ratio is accounted for)
    9949              :         // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
    9950       170031 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
    9951              : 
    9952              :         // Calculate crankcase heater power using the runtime fraction for this DX cooling coil only if there is no companion DX coil.
    9953              :         // Else use the largest runtime fraction of this DX cooling coil and the companion DX heating coil.
    9954       170031 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
    9955       170031 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
    9956              :         } else {
    9957            0 :             thisDXCoil.CrankcaseHeaterPower =
    9958            0 :                 CrankcaseHeatingPower * (1.0 - max(thisDXCoil.CoolingCoilRuntimeFraction,
    9959            0 :                                                    state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction));
    9960              :         }
    9961              : 
    9962       170031 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
    9963              :             //******************
    9964              :             //             WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
    9965              :             //             H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
    9966              :             //                                /RhoWater [kgWater/m3]
    9967              :             //******************
    9968        42800 :             RhoWater = RhoH2O(OutdoorDryBulb);
    9969        42800 :             thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater * thisDXCoil.CoolingCoilRuntimeFraction;
    9970        42800 :             thisDXCoil.EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode) * thisDXCoil.CoolingCoilRuntimeFraction;
    9971              :             // Calculate basin heater power
    9972        42800 :             CalcBasinHeaterPower(state,
    9973              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
    9974              :                                  thisDXCoil.basinHeaterSched,
    9975              :                                  thisDXCoil.BasinHeaterSetPointTemp,
    9976        42800 :                                  thisDXCoil.BasinHeaterPower);
    9977        42800 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
    9978        42800 :                 thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
    9979              :             }
    9980              :         }
    9981              : 
    9982       170031 :         thisDXCoil.OutletAirTemp = OutletAirTemp;
    9983       170031 :         thisDXCoil.OutletAirHumRat = OutletAirHumRat;
    9984       170031 :         thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
    9985              : 
    9986              :     } else {
    9987              : 
    9988              :         // DX coil is off; just pass through conditions
    9989       161281 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
    9990       161281 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
    9991       161281 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
    9992              : 
    9993       161281 :         thisDXCoil.ElecCoolingPower = 0.0;
    9994       161281 :         thisDXCoil.TotalCoolingEnergyRate = 0.0;
    9995       161281 :         thisDXCoil.SensCoolingEnergyRate = 0.0;
    9996       161281 :         thisDXCoil.LatCoolingEnergyRate = 0.0;
    9997       161281 :         thisDXCoil.EvapCondPumpElecPower = 0.0;
    9998       161281 :         thisDXCoil.EvapWaterConsumpRate = 0.0;
    9999              : 
   10000              :         // Reset globals when DX coil is OFF for use in heat recovery module
   10001       161281 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
   10002       161281 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
   10003              : 
   10004              :         // Calculate crankcase heater power using the runtime fraction for this DX cooling coil (here DXCoolingCoilRTF=0) if
   10005              :         // there is no companion DX coil, or the runtime fraction of the companion DX heating coil (here DXHeatingCoilRTF>=0).
   10006       161281 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   10007       161281 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
   10008              :         } else {
   10009            0 :             thisDXCoil.CrankcaseHeaterPower =
   10010            0 :                 CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction);
   10011              :         }
   10012              : 
   10013              :         // Calculate basin heater power
   10014       161281 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
   10015            1 :             if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
   10016            0 :                 CalcBasinHeaterPower(state,
   10017              :                                      thisDXCoil.BasinHeaterPowerFTempDiff,
   10018              :                                      thisDXCoil.basinHeaterSched,
   10019              :                                      thisDXCoil.BasinHeaterSetPointTemp,
   10020            0 :                                      thisDXCoil.BasinHeaterPower);
   10021              :             }
   10022              :         } else {
   10023       161280 :             if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   10024        25052 :                 CalcBasinHeaterPower(state,
   10025              :                                      thisDXCoil.BasinHeaterPowerFTempDiff,
   10026              :                                      thisDXCoil.basinHeaterSched,
   10027              :                                      thisDXCoil.BasinHeaterSetPointTemp,
   10028        25052 :                                      thisDXCoil.BasinHeaterPower);
   10029              :             }
   10030              :         }
   10031              : 
   10032              :     } // end of on/off if - else
   10033              : 
   10034              :     // set water system demand request (if needed)
   10035       331312 :     if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
   10036            0 :         state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
   10037            0 :             thisDXCoil.EvapWaterConsumpRate;
   10038              :     }
   10039              : 
   10040       331312 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   10041       331312 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   10042       331312 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
   10043       331312 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   10044       331312 :     thisDXCoil.CondInletTemp = CondInletTemp;
   10045              : 
   10046              :     // set outlet node conditions
   10047       331312 :     int airOutletNode = thisDXCoil.AirOutNode;
   10048       331312 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   10049       331312 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   10050              : 
   10051              :     // calc secondary coil if specified
   10052       331312 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   10053            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   10054              :     }
   10055       331312 : }
   10056              : 
   10057        49499 : void CalcVRFCoolingCoil(EnergyPlusData &state,
   10058              :                         int const DXCoilNum,                                 // the number of the DX coil to be simulated
   10059              :                         HVAC::CompressorOp const compressorOp,               // compressor operation; 1=on, 0=off
   10060              :                         bool const FirstHVACIteration,                       // true if this is the first iteration of HVAC
   10061              :                         Real64 const PartLoadRatio,                          // sensible cooling load / full load sensible cooling capacity
   10062              :                         HVAC::FanOp const fanOp,                             // Allows parent object to control fan operation
   10063              :                         Real64 const CompCycRatio,                           // cycling ratio of VRF condenser
   10064              :                         ObjexxFCL::Optional_int_const PerfMode,              // Performance mode for MultiMode DX coil; Always 1 for other coil types
   10065              :                         ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
   10066              :                         ObjexxFCL::Optional<Real64 const> MaxCoolCap         // maximum capacity of DX coil
   10067              : )
   10068              : {
   10069              : 
   10070              :     // SUBROUTINE INFORMATION:
   10071              :     //       AUTHOR         Richard Raustad
   10072              :     //       DATE WRITTEN   August 2010
   10073              : 
   10074              :     // PURPOSE OF THIS SUBROUTINE:
   10075              :     // Calculates the air-side performance of a direct-expansion, air-cooled
   10076              :     // VRF terminal unit cooling coil.
   10077              :     // A new subroutine was created in case this DX coil model is significantly
   10078              :     // different from the existing CalcDoe2DXCoil subroutine. The VRF heating coil
   10079              :     // uses the existing DX heating coil subroutine (CalcDXHeatingCoil).
   10080              : 
   10081              :     // METHODOLOGY EMPLOYED:
   10082              :     // This routine simulates the performance of a variable refrigerant flow cooling coil.
   10083              :     // The routine requires the user to enter the total cooling capacity and sensible heat ratio.
   10084              :     // Since different manufacturer's rate their equipment at different air flow rates,
   10085              :     // the supply air flow rate corresponding to the rated capacities must also be
   10086              :     // entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information entered by
   10087              :     // the user should NOT include the thermal or electrical impacts of the supply air fan, as
   10088              :     // this is addressed by another module.
   10089              : 
   10090              :     // With the rated performance data entered by the user, the model employs some of the
   10091              :     // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
   10092              :     // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
   10093              :     // does NOT employ the exact same methodology to calculate performance as DOE-2.
   10094              :     // This VRF cooling coil model adjusts the rated total cooling capacity by the CAPFT
   10095              :     // and CAP function of flow curve/model currently used by the existing DX coil model.
   10096              :     // The part-load ratio is then applied to the total operating capacity to find the capacity
   10097              :     // required to meet the load. This VRF model then uses the ADP/bypass method to find the
   10098              :     // SHR and resulting outlet conditions given that total capacity (or delta H).
   10099              : 
   10100              :     // The model checks for coil dryout conditions, and adjusts the calculated performance
   10101              :     // appropriately.
   10102              : 
   10103              :     // Using/Aliasing
   10104              :     using Curve::CurveValue;
   10105        49499 :     Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
   10106        49499 :     Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
   10107              :     using General::CreateSysTimeIntervalString;
   10108              : 
   10109              :     // SUBROUTINE ARGUMENT DEFINITIONS:
   10110              :     //  REAL(r64), INTENT(IN), OPTIONAL :: CoolingHeatingPLR   ! used for cycling fan RH control
   10111              : 
   10112              :     // SUBROUTINE PARAMETER DEFINITIONS:
   10113              :     static constexpr std::string_view RoutineName("CalcVRFCoolingCoil");
   10114              : 
   10115              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   10116              :     Real64 AirMassFlow;       // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
   10117              :     Real64 AirMassFlowRatio;  // Ratio of actual air mass flow to rated air mass flow (adjusted for bypass if any)
   10118              :     Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
   10119              :     // (average flow if cycling fan, full flow if constant fan)
   10120              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
   10121              :     Real64 TotCap;                // gross total cooling capacity at off-rated conditions [W]
   10122              :     Real64 TotCapTempModFac;      // Total capacity modifier (function of entering wetbulb, outside drybulb)
   10123              :     Real64 TotCapFlowModFac;      // Total capacity modifier (function of actual supply air flow vs rated flow)
   10124              :     Real64 InletAirWetBulbC;      // wetbulb temperature of inlet air [C]
   10125              :     Real64 InletAirDryBulbTemp;   // inlet air dry bulb temperature [C]
   10126              :     Real64 InletAirEnthalpy;      // inlet air enthalpy [J/kg]
   10127              :     Real64 InletAirHumRat;        // inlet air humidity ratio [kg/kg]
   10128              :     Real64 InletAirHumRatTemp;    // inlet air humidity ratio used in ADP/BF loop [kg/kg]
   10129              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10130              :     // REAL(r64) :: InletAirPressure      ! inlet air pressure [Pa]
   10131              :     Real64 RatedCBF;             // coil bypass factor at rated conditions
   10132              :     Real64 SHR;                  // Sensible Heat Ratio (sensible/total) of the cooling coil
   10133              :     Real64 CBF;                  // coil bypass factor at off rated conditions
   10134              :     Real64 A0;                   // NTU * air mass flow rate, used in CBF calculation
   10135              :     Real64 hDelta;               // Change in air enthalpy across the cooling coil [J/kg]
   10136              :     Real64 hADP;                 // Apparatus dew point enthalpy [J/kg]
   10137              :     Real64 hTinwADP;             // Enthalpy at inlet dry-bulb and wADP [J/kg]
   10138              :     Real64 hTinwout;             // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
   10139              :     Real64 tADP;                 // Apparatus dew point temperature [C]
   10140              :     Real64 wADP;                 // Apparatus dew point humidity ratio [kg/kg]
   10141              :     Real64 FullLoadOutAirEnth;   // outlet full load enthalpy [J/kg]
   10142              :     Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
   10143              :     Real64 FullLoadOutAirTemp;   // outlet air temperature at full load [C]
   10144              :     Real64 PLF;                  // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
   10145              :     Real64 QLatActual;           // operating latent capacity of DX coil
   10146              :     Real64 QLatRated;            // Rated latent capacity of DX coil
   10147              :     Real64 SHRUnadjusted;        // SHR prior to latent degradation effective SHR calculation
   10148              :     int Counter;                 // Counter for dry evaporator iterations
   10149              :     int MaxIter;                 // Maximum number of iterations for dry evaporator calculations
   10150              :     Real64 RF;                   // Relaxation factor for dry evaporator iterations
   10151              :     Real64 Tolerance;            // Error tolerance for dry evaporator iterations
   10152              :     Real64 werror;               // Deviation of humidity ratio in dry evaporator iteration loop
   10153              :     Real64 CondInletTemp;        // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
   10154              :     // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
   10155              :     Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
   10156              :     // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
   10157              :     Real64 CondAirMassFlow;       // Condenser air mass flow rate [kg/s]
   10158              :     Real64 RhoAir;                // Density of air [kg/m3]
   10159              :     Real64 CrankcaseHeatingPower; // power due to crankcase heater
   10160        49499 :     Real64 CompAmbTemp(0.0);      // Ambient temperature at compressor
   10161              :     Real64 AirFlowRatio;          // ratio of compressor on airflow to average timestep airflow
   10162              :     // used when constant fan mode yields different air flow rates when compressor is ON and OFF
   10163              :     // (e.g. Packaged Terminal Heat Pump)
   10164              :     Real64 OutdoorDryBulb;  // Outdoor dry-bulb temperature at condenser (C)
   10165              :     Real64 OutdoorWetBulb;  // Outdoor wet-bulb temperature at condenser (C)
   10166              :     Real64 OutdoorHumRat;   // Outdoor humidity ratio at condenser (kg/kg)
   10167              :     Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
   10168              : 
   10169              :     int Mode;                 // Performance mode for Multimode DX coil; Always 1 for other coil types
   10170              :     Real64 OutletAirTemp;     // Supply air temperature (average value if constant fan, full output if cycling fan)
   10171              :     Real64 OutletAirHumRat;   // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
   10172              :     Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
   10173              :     Real64 ADiff;             // Used for exponential
   10174              : 
   10175              :     // If Performance mode not present, then set to 1.  Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
   10176        49499 :     if (present(PerfMode)) {
   10177            0 :         Mode = PerfMode;
   10178              :     } else {
   10179        49499 :         Mode = 1;
   10180              :     }
   10181              : 
   10182              :     // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
   10183              :     // during cooling and when no cooling is required (constant fan, fan speed changes)
   10184        49499 :     if (present(OnOffAirFlowRatio)) {
   10185        49492 :         AirFlowRatio = OnOffAirFlowRatio;
   10186              :     } else {
   10187            7 :         AirFlowRatio = 1.0;
   10188              :     }
   10189              : 
   10190        49499 :     MaxIter = 30;
   10191        49499 :     RF = 0.4;
   10192        49499 :     Counter = 0;
   10193        49499 :     Tolerance = 0.01;
   10194        49499 :     CondInletTemp = 0.0;
   10195        49499 :     CondInletHumRat = 0.0;
   10196              : 
   10197        49499 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   10198              : 
   10199        49499 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   10200        49499 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   10201        49499 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   10202        49499 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   10203              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10204              :     // InletAirPressure    = DXCoil(DXCoilNum)%InletAirPressure
   10205        49499 :     state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
   10206        49499 :     thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
   10207        49499 :     thisDXCoil.PartLoadRatio = 0.0;
   10208        49499 :     thisDXCoil.BasinHeaterPower = 0.0;
   10209              : 
   10210        49499 :     if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
   10211        49438 :         OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
   10212        49438 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
   10213           32 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10214           32 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10215           32 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10216              :         } else {
   10217        49406 :             OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
   10218              :             // If node is not connected to anything, pressure = default, use weather data
   10219        49406 :             if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   10220           94 :                 OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   10221           94 :                 OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10222           94 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10223           94 :                 OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10224              :             } else {
   10225        49312 :                 OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
   10226              :                 // this should use Node%WetBulbTemp or a PSYC function, not OAWB
   10227        49312 :                 OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
   10228              :             }
   10229              :         }
   10230              :     } else {
   10231           61 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   10232           61 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10233           61 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10234           61 :         OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10235              :     }
   10236              : 
   10237        49499 :     if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   10238            0 :         RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
   10239            0 :         CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
   10240              :         // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   10241            0 :         CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
   10242            0 :         CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
   10243            0 :         CompAmbTemp = OutdoorDryBulb;
   10244              :     } else {                            // for air or water-cooled, inlet temp is stored in OutdoorDryBulb temp
   10245        49499 :         CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
   10246        49499 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
   10247           32 :             CompAmbTemp = state.dataEnvrn->OutDryBulbTemp; // for crankcase heater use actual outdoor temp for water-cooled
   10248              :         } else {
   10249        49467 :             CompAmbTemp = OutdoorDryBulb;
   10250              :         }
   10251              :     }
   10252              : 
   10253              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
   10254              :     // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
   10255        49499 :     if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
   10256           71 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   10257           71 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   10258            0 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
   10259              :         }
   10260              :     } else {
   10261        49428 :         CrankcaseHeatingPower = 0.0;
   10262              :     }
   10263              : 
   10264              :     // calculate end time of current time step to determine if error messages should be printed
   10265        49499 :     state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
   10266              : 
   10267              :     //   Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
   10268              :     //   Wait for next time step to print warnings. If simulation iterates, print out
   10269              :     //   the warning for the last iteration only. Must wait for next time step to accomplish this.
   10270              :     //   If a warning occurs and the simulation down shifts, the warning is not valid.
   10271        49499 :     if (thisDXCoil.PrintLowAmbMessage) { // .AND. &
   10272            0 :         if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
   10273            0 :             if (thisDXCoil.LowAmbErrIndex == 0) {
   10274            0 :                 ShowWarningMessage(state, thisDXCoil.LowAmbBuffer1);
   10275            0 :                 ShowContinueError(state, thisDXCoil.LowAmbBuffer2);
   10276            0 :                 ShowContinueError(state, "... Operation at low inlet temperatures may require special performance curves.");
   10277              :             }
   10278            0 :             ShowRecurringWarningErrorAtEnd(state,
   10279            0 :                                            thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10280              :                                                "\" - Low condenser inlet temperature error continues...",
   10281            0 :                                            thisDXCoil.LowAmbErrIndex,
   10282            0 :                                            thisDXCoil.LowTempLast,
   10283            0 :                                            thisDXCoil.LowTempLast,
   10284              :                                            _,
   10285              :                                            "[C]",
   10286              :                                            "[C]");
   10287              :         }
   10288              :     }
   10289              : 
   10290        49499 :     if (thisDXCoil.PrintHighAmbMessage) { // .AND. &
   10291           60 :         if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
   10292            0 :             if (thisDXCoil.HighAmbErrIndex == 0) {
   10293            0 :                 ShowWarningMessage(state, thisDXCoil.HighAmbBuffer1);
   10294            0 :                 ShowContinueError(state, thisDXCoil.HighAmbBuffer2);
   10295            0 :                 ShowContinueError(state, "... Operation at high inlet temperatures may require special performance curves.");
   10296              :             }
   10297            0 :             ShowRecurringWarningErrorAtEnd(state,
   10298            0 :                                            thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10299              :                                                "\" - High condenser inlet temperature error continues...",
   10300            0 :                                            thisDXCoil.HighAmbErrIndex,
   10301            0 :                                            thisDXCoil.HighTempLast,
   10302            0 :                                            thisDXCoil.HighTempLast,
   10303              :                                            _,
   10304              :                                            "[C]",
   10305              :                                            "[C]");
   10306              :         }
   10307              :     }
   10308              : 
   10309        49499 :     if (thisDXCoil.PrintLowOutTempMessage) {
   10310            0 :         if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
   10311            0 :             if (thisDXCoil.LowOutletTempIndex == 0) {
   10312            0 :                 ShowWarningMessage(state, thisDXCoil.LowOutTempBuffer1);
   10313            0 :                 ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
   10314            0 :                 ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
   10315            0 :                 ShowContinueError(state,
   10316            0 :                                   format("   1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
   10317            0 :                                          thisDXCoil.FullLoadInletAirTempLast));
   10318            0 :                 ShowContinueError(state, "   2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
   10319            0 :                 ShowContinueError(state,
   10320              :                                   "   3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
   10321              :             }
   10322            0 :             ShowRecurringWarningErrorAtEnd(state,
   10323            0 :                                            thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10324              :                                                "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
   10325              :                                                "Outlet air temperature statistics follow:",
   10326            0 :                                            thisDXCoil.LowOutletTempIndex,
   10327            0 :                                            thisDXCoil.FullLoadOutAirTempLast,
   10328            0 :                                            thisDXCoil.FullLoadOutAirTempLast);
   10329              :         }
   10330              :     }
   10331              : 
   10332              :     // save last system time step and last end time of current time step (used to determine if warning is valid)
   10333        49499 :     thisDXCoil.TimeStepSysLast = TimeStepSys;
   10334        49499 :     thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime;
   10335        49499 :     thisDXCoil.PrintLowAmbMessage = false;
   10336        49499 :     thisDXCoil.PrintLowOutTempMessage = false;
   10337              : 
   10338        49499 :     if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
   10339              :         (compressorOp == HVAC::CompressorOp::On)) { // for cycling fan, reset mass flow to full on rate
   10340        21285 :         if (fanOp == HVAC::FanOp::Cycling) {
   10341           43 :             AirMassFlow /= PartLoadRatio;
   10342        21242 :         } else if (fanOp == HVAC::FanOp::Continuous) {
   10343        21242 :             AirMassFlow *= AirFlowRatio;
   10344              :         } else {
   10345            0 :             AirMassFlow = thisDXCoil.RatedAirMassFlowRate(Mode);
   10346              :         }
   10347              : 
   10348              :         // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton)
   10349              : 
   10350              :         // for some reason there are diff's when using coil inlet air pressure
   10351              :         // these lines (more to follow) are commented out for the time being
   10352              : 
   10353        21285 :         InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   10354        21285 :         AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
   10355        21285 :         VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
   10356              : 
   10357        21285 :         if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
   10358            0 :             ShowFatalError(state, format("{} \"{}\" - Rated total cooling capacity is zero or less.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   10359              :         }
   10360              : 
   10361        23678 :         if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag &&
   10362         2393 :             ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   10363         2393 :              (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
   10364            0 :             if (thisDXCoil.ErrIndex1 == 0) {
   10365            0 :                 ShowWarningMessage(
   10366              :                     state,
   10367            0 :                     format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
   10368            0 :                            thisDXCoil.DXCoilType,
   10369            0 :                            thisDXCoil.Name,
   10370              :                            VolFlowperRatedTotCap));
   10371            0 :                 ShowContinueErrorTimeStamp(state, "");
   10372            0 :                 ShowContinueError(state,
   10373            0 :                                   format("...Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
   10374            0 :                                          HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   10375            0 :                                          HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
   10376            0 :                 ShowContinueError(state, "...Possible causes include inconsistent air flow rates in system components,");
   10377            0 :                 ShowContinueError(state, "...or mixing manual inputs with autosize inputs. Also check the following values and calculations.");
   10378            0 :                 ShowContinueError(state, "...Volume Flow Rate per Rated Total Capacity = Volume Flow Rate / Rated Total Capacity");
   10379            0 :                 ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
   10380            0 :                 ShowContinueError(state, "...Data used for calculations:");
   10381            0 :                 ShowContinueError(state, format("...Rated Total Capacity = {:.2R} W.", thisDXCoil.RatedTotCap(Mode)));
   10382            0 :                 ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
   10383            0 :                 ShowContinueError(state, format("...Volume Flow Rate   = {:.8R} m3/s.", AirVolumeFlowRate));
   10384            0 :                 ShowContinueError(state, format("...Air Mass Flow Rate = {:.8R} kg/s.", AirMassFlow));
   10385            0 :                 ShowContinueError(
   10386              :                     state,
   10387            0 :                     format("...Air Density        = {:.8R} kg/m3.", PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat)));
   10388            0 :                 ShowContinueError(state, "...Data used for air density calculation:");
   10389            0 :                 ShowContinueError(state, format("...Outdoor Air Pressure     = {:.3R} Pa.", OutdoorPressure));
   10390            0 :                 ShowContinueError(state, format("...Inlet Air Dry-Bulb Temp  = {:.3R} C.", InletAirDryBulbTemp));
   10391            0 :                 ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.8R} kgWater/kgDryAir.", InletAirHumRat));
   10392              :             }
   10393            0 :             ShowRecurringWarningErrorAtEnd(
   10394              :                 state,
   10395            0 :                 thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10396              :                     "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
   10397            0 :                 thisDXCoil.ErrIndex1,
   10398              :                 VolFlowperRatedTotCap,
   10399              :                 VolFlowperRatedTotCap);
   10400              :         }
   10401              :         //    Adjust coil bypass factor for actual air flow rate. Use relation CBF = exp(-NTU) where
   10402              :         //    NTU = A0/(m*cp). Relationship models the cooling coil as a heat exchanger with Cmin/Cmax = 0.
   10403              : 
   10404        21285 :         RatedCBF = thisDXCoil.RatedCBF(Mode);
   10405        21285 :         if (RatedCBF > 0.0) {
   10406        21285 :             A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
   10407              :         } else {
   10408            0 :             A0 = 0.0;
   10409              :         }
   10410        21285 :         ADiff = -A0 / AirMassFlow;
   10411        21285 :         if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
   10412        21285 :             CBF = std::exp(ADiff);
   10413              :         } else {
   10414            0 :             CBF = 0.0;
   10415              :         }
   10416              : 
   10417              :         // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
   10418        21285 :         if (OutdoorDryBulb < thisDXCoil.MinOATCompressor && !state.dataGlobal->WarmupFlag) {
   10419            0 :             thisDXCoil.PrintLowAmbMessage = true;
   10420            0 :             thisDXCoil.LowTempLast = OutdoorDryBulb;
   10421            0 :             if (thisDXCoil.LowAmbErrIndex == 0) {
   10422            0 :                 thisDXCoil.LowAmbBuffer1 = format("{} \"{}\" - Condenser inlet temperature below {:.2R} C. Condenser inlet temperature = {:.2R}",
   10423            0 :                                                   thisDXCoil.DXCoilType,
   10424            0 :                                                   thisDXCoil.Name,
   10425            0 :                                                   thisDXCoil.MinOATCompressor,
   10426            0 :                                                   OutdoorDryBulb);
   10427            0 :                 thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
   10428            0 :                                            CreateSysTimeIntervalString(state);
   10429              :             }
   10430              :         }
   10431              : 
   10432              :         // check boundary for high ambient temperature and post warnings to individual DX coil buffers to print at end of time step
   10433        21285 :         if (OutdoorDryBulb > thisDXCoil.MaxOATCompressor && !state.dataGlobal->WarmupFlag) {
   10434           27 :             thisDXCoil.PrintHighAmbMessage = true;
   10435           27 :             thisDXCoil.HighTempLast = OutdoorDryBulb;
   10436           27 :             if (thisDXCoil.HighAmbErrIndex == 0) {
   10437           54 :                 thisDXCoil.HighAmbBuffer1 = format("{} \"{}\" - Condenser inlet temperature above {:.2R} C. Condenser temperature = {:.2R}",
   10438           27 :                                                    thisDXCoil.DXCoilType,
   10439           27 :                                                    thisDXCoil.Name,
   10440           27 :                                                    thisDXCoil.MaxOATCompressor,
   10441           27 :                                                    OutdoorDryBulb);
   10442           54 :                 thisDXCoil.HighAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
   10443           81 :                                             CreateSysTimeIntervalString(state);
   10444              :             }
   10445              :         }
   10446              : 
   10447              :         //  Get total capacity modifying factor (function of temperature) for off-rated conditions
   10448              :         //  InletAirHumRat may be modified in this ADP/BF loop, use temporary variable for calculations
   10449        21285 :         InletAirHumRatTemp = InletAirHumRat;
   10450              : 
   10451        21285 :     Label50:;
   10452        21285 :         switch (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims) {
   10453        21285 :         case 1:
   10454        21285 :             TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC);
   10455        21285 :             break;
   10456            0 :         case 2:
   10457              :         default: // this default allows the simulation to continue, but will issue a warning, should be removed eventually
   10458            0 :             TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
   10459            0 :             break;
   10460              :         }
   10461              : 
   10462              :         //  Warn user if curve output goes negative
   10463        21285 :         if (TotCapTempModFac < 0.0) {
   10464            0 :             if (thisDXCoil.CCapFTempErrorIndex == 0) {
   10465            0 :                 ShowWarningMessage(state, format("{} \"{}\":", thisDXCoil.DXCoilType, thisDXCoil.Name));
   10466            0 :                 ShowContinueError(
   10467            0 :                     state, format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
   10468            0 :                 ShowContinueError(
   10469              :                     state,
   10470            0 :                     format(" Negative value occurs using a condenser inlet temperature of {:.1T} and an inlet air wet-bulb temperature of {:.1T}.",
   10471              :                            CondInletTemp,
   10472              :                            InletAirWetBulbC));
   10473            0 :                 if (Mode > 1) {
   10474            0 :                     ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
   10475              :                 }
   10476            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
   10477              :             }
   10478            0 :             ShowRecurringWarningErrorAtEnd(
   10479              :                 state,
   10480            0 :                 thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10481              :                     "\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
   10482            0 :                 thisDXCoil.CCapFTempErrorIndex,
   10483              :                 TotCapTempModFac,
   10484              :                 TotCapTempModFac);
   10485            0 :             TotCapTempModFac = 0.0;
   10486              :         }
   10487              : 
   10488              :         //  Get total capacity modifying factor (function of mass flow) for off-rated conditions
   10489        21285 :         AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
   10490        21285 :         TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
   10491              : 
   10492              :         //  Warn user if curve output goes negative
   10493        21285 :         if (TotCapFlowModFac < 0.0) {
   10494            0 :             if (thisDXCoil.CCapFFlowErrorIndex == 0) {
   10495            0 :                 ShowWarningMessage(state, format("{} \"{}\":", thisDXCoil.DXCoilType, thisDXCoil.Name));
   10496            0 :                 ShowContinueError(
   10497              :                     state,
   10498            0 :                     format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).", TotCapFlowModFac));
   10499            0 :                 ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
   10500            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
   10501            0 :                 if (Mode > 1) {
   10502            0 :                     ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
   10503              :                 }
   10504              :             }
   10505            0 :             ShowRecurringWarningErrorAtEnd(
   10506              :                 state,
   10507            0 :                 thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10508              :                     "\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
   10509            0 :                 thisDXCoil.CCapFFlowErrorIndex,
   10510              :                 TotCapFlowModFac,
   10511              :                 TotCapFlowModFac);
   10512            0 :             TotCapFlowModFac = 0.0;
   10513              :         }
   10514              : 
   10515        21285 :         if (present(MaxCoolCap)) {
   10516        21278 :             TotCap = min(MaxCoolCap, thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac);
   10517              :         } else {
   10518            7 :             TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
   10519              :         }
   10520              : 
   10521        21285 :         TotCap *= PartLoadRatio;
   10522              : 
   10523              :         // Calculate apparatus dew point conditions using TotCap and CBF
   10524        21285 :         hDelta = TotCap / AirMassFlow;
   10525              :         // there is an issue here with using CBF to calculate the ADP enthalpy.
   10526              :         // at low loads the bypass factor increases significantly.
   10527        21285 :         hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
   10528        21285 :         tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
   10529              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10530              :         //  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   10531        21285 :         wADP = min(InletAirHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
   10532        21285 :         hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   10533        21285 :         if ((InletAirEnthalpy - hADP) > 1.e-10) {
   10534        18971 :             SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   10535              :         } else {
   10536         2314 :             SHR = 1.0;
   10537              :         }
   10538              :         // Check for dry evaporator conditions (win < wadp)
   10539        21285 :         if (wADP > InletAirHumRatTemp || (Counter >= 1 && Counter < MaxIter)) {
   10540            0 :             if (InletAirHumRatTemp == 0.0) InletAirHumRatTemp = 0.00001;
   10541            0 :             werror = (InletAirHumRatTemp - wADP) / InletAirHumRatTemp;
   10542              :             // Increase InletAirHumRatTemp at constant InletAirTemp to find coil dry-out point. Then use the
   10543              :             // capacity at the dry-out point to determine exiting conditions from coil. This is required
   10544              :             // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
   10545            0 :             InletAirHumRatTemp = RF * wADP + (1.0 - RF) * InletAirHumRatTemp;
   10546            0 :             InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRatTemp, OutdoorPressure);
   10547              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10548              :             //     InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRatTemp,InletAirPressure)
   10549            0 :             ++Counter;
   10550            0 :             if (std::abs(werror) > Tolerance) goto Label50; // Recalculate with modified inlet conditions
   10551              :         }
   10552              : 
   10553        21285 :         if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
   10554           26 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
   10555              :         } else {
   10556        21259 :             PLF = 1.0;
   10557              :         }
   10558              : 
   10559        21285 :         if (PLF < 0.7) {
   10560            0 :             if (thisDXCoil.ErrIndex2 == 0) {
   10561            0 :                 ShowWarningMessage(
   10562              :                     state,
   10563            0 :                     format(
   10564            0 :                         "The PLF curve value for the DX cooling coil {} ={:.3R} for part-load ratio ={:.3R}", thisDXCoil.Name, PLF, PartLoadRatio));
   10565            0 :                 ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   10566            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
   10567              :             }
   10568            0 :             ShowRecurringWarningErrorAtEnd(
   10569            0 :                 state, thisDXCoil.Name + ", DX cooling coil PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
   10570            0 :             PLF = 0.7;
   10571              :         }
   10572              : 
   10573        21285 :         thisDXCoil.PartLoadRatio = PartLoadRatio;
   10574        21285 :         thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
   10575        21285 :         if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
   10576            0 :             if (thisDXCoil.ErrIndex3 == 0) {
   10577            0 :                 ShowWarningMessage(state,
   10578            0 :                                    format("The runtime fraction for DX cooling coil {} exceeded 1.0. [{:.4R}].",
   10579            0 :                                           thisDXCoil.Name,
   10580            0 :                                           thisDXCoil.CoolingCoilRuntimeFraction));
   10581            0 :                 ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
   10582            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
   10583            0 :                 ShowContinueErrorTimeStamp(state, "");
   10584              :             }
   10585            0 :             ShowRecurringWarningErrorAtEnd(state,
   10586            0 :                                            thisDXCoil.Name + ", DX cooling coil runtime fraction > 1.0 warning continues...",
   10587            0 :                                            thisDXCoil.ErrIndex3,
   10588            0 :                                            thisDXCoil.CoolingCoilRuntimeFraction,
   10589            0 :                                            thisDXCoil.CoolingCoilRuntimeFraction);
   10590            0 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   10591        21285 :         } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
   10592            0 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   10593              :         }
   10594              : 
   10595              :         // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
   10596        21285 :         if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
   10597              : 
   10598              :         //  Calculate full load output conditions
   10599              :         //            if ( SHR > 1.0 || Counter > 0 ) SHR = 1.0;
   10600        21285 :         if (SHR > 1.0) SHR = 1.0;
   10601        21285 :         FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
   10602        21285 :         hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   10603        21285 :         if (SHR < 1.0) {
   10604        12378 :             FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   10605              :         } else {
   10606         8907 :             FullLoadOutAirHumRat = InletAirHumRat;
   10607              :         }
   10608        21285 :         FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   10609              : 
   10610              :         // Check for saturation error and modify temperature at constant enthalpy
   10611        21285 :         if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
   10612            0 :             FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
   10613              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10614              :             //   IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
   10615              :             //    FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
   10616            0 :             FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
   10617              :         }
   10618              : 
   10619              :         // Store actual outlet conditions when DX coil is ON for use in heat recovery module
   10620        21285 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
   10621        21285 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
   10622              : 
   10623              :         // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
   10624        21285 :         if (FullLoadOutAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
   10625            0 :             thisDXCoil.PrintLowOutTempMessage = true;
   10626            0 :             thisDXCoil.FullLoadOutAirTempLast = FullLoadOutAirTemp;
   10627            0 :             if (thisDXCoil.LowOutletTempIndex == 0) {
   10628            0 :                 thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
   10629            0 :                 thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
   10630              :                                                       "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
   10631            0 :                                                       thisDXCoil.DXCoilType,
   10632            0 :                                                       thisDXCoil.Name,
   10633            0 :                                                       FullLoadOutAirTemp);
   10634            0 :                 thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
   10635            0 :                                                CreateSysTimeIntervalString(state);
   10636              :             }
   10637              :         }
   10638              : 
   10639              :         //  If constant fan with cycling compressor, call function to determine "effective SHR"
   10640              :         //  which includes the part-load degradation on latent capacity
   10641        21285 :         if (fanOp == HVAC::FanOp::Continuous && CompCycRatio < 1.0) {
   10642         3662 :             QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode)); // always the same number
   10643         3662 :             QLatActual = TotCap * (1.0 - SHR);
   10644         3662 :             SHRUnadjusted = SHR;
   10645         3662 :             SHR = CalcEffectiveSHR(
   10646              :                 state, DXCoilNum, SHR, thisDXCoil.CoolingCoilRuntimeFraction, QLatRated, QLatActual, InletAirDryBulbTemp, InletAirWetBulbC, Mode);
   10647              : 
   10648              :             //  Calculate full load output conditions
   10649              :             //                if ( SHR > 1.0 || Counter > 0 ) SHR = 1.0;
   10650         3662 :             if (SHR > 1.0) SHR = 1.0;
   10651         3662 :             FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
   10652         3662 :             hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   10653         3662 :             if (SHR < 1.0) {
   10654         3180 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   10655              :             } else {
   10656          482 :                 FullLoadOutAirHumRat = InletAirHumRat;
   10657              :             }
   10658         3662 :             FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   10659              :         }
   10660              : 
   10661              :         //  Calculate actual outlet conditions for the input part load ratio
   10662              :         //  Actual outlet conditions are "average" for time step when compressor cycles
   10663              : 
   10664        21285 :         if (fanOp == HVAC::FanOp::Continuous && CompCycRatio < 1.0) {
   10665              :             // Continuous fan, cycling compressor
   10666              :             // hmmm ... this seems wrong. PLR * AirFlowRatio = 1. So we get FullLoadOutAirEnth all this time. This is OK since above TotCap *=
   10667              :             // PLR.
   10668         3662 :             OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
   10669         3662 :             OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
   10670         3662 :             OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   10671              :         } else {
   10672              :             // Default to cycling fan, cycling compressor
   10673        17623 :             OutletAirEnthalpy = FullLoadOutAirEnth;
   10674        17623 :             OutletAirHumRat = FullLoadOutAirHumRat;
   10675        17623 :             OutletAirTemp = FullLoadOutAirTemp;
   10676              :         }
   10677              : 
   10678              :         // Check for saturation error and modify temperature at constant enthalpy
   10679        21285 :         if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, RoutineName)) {
   10680          436 :             OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
   10681              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10682              :             //   IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
   10683              :             //    OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
   10684          436 :             OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
   10685              :         }
   10686              : 
   10687              :         // Reset AirMassFlow to inlet node air mass flow for final total, sensible and latent calculations
   10688              :         // since AirMassFlow might have been modified above (in this subroutine):
   10689              :         //     IF (FanOpMode .EQ. FanOp::Cycling) AirMassFlow = AirMassFlow / PartLoadRatio
   10690              :         // For multimode coil, this should be full flow including bypassed fraction
   10691        21285 :         AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   10692              : 
   10693              :         // Coil total/sensible/latent cooling rates
   10694        21285 :         CalcComponentSensibleLatentOutput(AirMassFlow,
   10695              :                                           InletAirDryBulbTemp,
   10696              :                                           InletAirHumRat,
   10697              :                                           OutletAirTemp,
   10698              :                                           OutletAirHumRat,
   10699        21285 :                                           thisDXCoil.SensCoolingEnergyRate,
   10700        21285 :                                           thisDXCoil.LatCoolingEnergyRate,
   10701        21285 :                                           thisDXCoil.TotalCoolingEnergyRate);
   10702              : 
   10703        21285 :         thisDXCoil.OutletAirTemp = OutletAirTemp;
   10704        21285 :         thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   10705        21285 :         thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   10706              : 
   10707              :     } else {
   10708              : 
   10709              :         // DX coil is off; just pass through conditions
   10710        28214 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   10711        28214 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   10712        28214 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   10713              : 
   10714        28214 :         thisDXCoil.ElecCoolingPower = 0.0;
   10715        28214 :         thisDXCoil.TotalCoolingEnergyRate = 0.0;
   10716        28214 :         thisDXCoil.SensCoolingEnergyRate = 0.0;
   10717        28214 :         thisDXCoil.LatCoolingEnergyRate = 0.0;
   10718        28214 :         thisDXCoil.EvapCondPumpElecPower = 0.0;
   10719        28214 :         thisDXCoil.EvapWaterConsumpRate = 0.0;
   10720              : 
   10721              :         // Reset globals when DX coil is OFF for use in heat recovery module
   10722        28214 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
   10723        28214 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
   10724              : 
   10725              :     } // end of on/off if - else
   10726              : 
   10727              :     // set water system demand request (if needed)
   10728        49499 :     if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
   10729            0 :         state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
   10730            0 :             thisDXCoil.EvapWaterConsumpRate;
   10731              :     }
   10732              : 
   10733        49499 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   10734        49499 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   10735        49499 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
   10736        49499 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   10737        49499 :     thisDXCoil.CondInletTemp = CondInletTemp;
   10738        49499 :     state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
   10739        49499 :     state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   10740              : 
   10741              :     // set outlet node conditions
   10742        49499 :     int airOutletNode = thisDXCoil.AirOutNode;
   10743        49499 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   10744        49499 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   10745        49499 : }
   10746              : 
   10747       177475 : void CalcDXHeatingCoil(EnergyPlusData &state,
   10748              :                        int const DXCoilNum,                                 // the number of the DX heating coil to be simulated
   10749              :                        Real64 const PartLoadRatio,                          // sensible cooling load / full load sensible cooling capacity
   10750              :                        HVAC::FanOp const fanOp,                             // Allows parent object to control fan mode
   10751              :                        ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
   10752              :                        ObjexxFCL::Optional<Real64 const> MaxHeatCap         // maximum allowed heating capacity
   10753              : )
   10754              : {
   10755              : 
   10756              :     // SUBROUTINE INFORMATION:
   10757              :     //       AUTHOR         Richard Raustad
   10758              :     //       DATE WRITTEN   October 2001
   10759              :     //       MODIFIED       Raustad/Shirey Mar 2004
   10760              :     //                      Kenneth Tang 2004 (Sensitivity of TotCapTempModFac & EIRTempModFac  to indoor dry bulb temp)
   10761              :     //                      Feb 2005 M. J. Witte, GARD Analytics, Inc.
   10762              :     //                        Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
   10763              : 
   10764              :     // PURPOSE OF THIS SUBROUTINE:
   10765              :     // Calculates the air-side heating performance and electrical heating energy
   10766              :     // use of a direct-expansion, air-cooled heat pump unit.
   10767              : 
   10768              :     // METHODOLOGY EMPLOYED:
   10769              :     // This routine simulates the performance of air-cooled DX heating equipment.
   10770              :     // The routine requires the user to enter the total heating capacity
   10771              :     // and COP for the unit at ARI 210/240 rating conditions (21.11C [70F] dry-bulb,
   10772              :     // 15.55C [60F] wet-bulb air entering the heating coil, 8.33C [47F] dry-bulb,
   10773              :     // 6.11C [43F] wet-bulb air entering the outdoor condenser. Since different
   10774              :     // manufacturer's rate their equipment at different air flow rates, the supply
   10775              :     // air flow rate corresponding to the rated capacities and rated COP must also
   10776              :     // be entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information
   10777              :     // entered by the user should NOT include the thermal or electrical impacts of the
   10778              :     // supply air fan, as this is addressed by another module.
   10779              : 
   10780              :     // With the rated performance data entered by the user, the model employs some of the
   10781              :     // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
   10782              :     // of outdoor air temperatures and supply air flow rate (actual vs rated flow). The
   10783              :     // model does NOT employ the exact same methodology to calculate performance as DOE-2,
   10784              :     // although some of the DOE-2 curve fits are employed by this model.
   10785              : 
   10786              :     // REFERENCES:
   10787              :     // Winkelmann, F.C., Birdsall, B.E., Buhl W.F., Ellington, K.L., Erdem, A.E. 1993.
   10788              :     // DOE-2 Supplement Version 2.1E.  Energy and Environment Division, Lawrence Berkeley
   10789              :     // Laboratory.
   10790              :     // Henderson, H.I. Jr., Y.J. Huang and Danny Parker. 1999. Residential Equipment Part
   10791              :     // Load Curves for Use in DOE-2.  Environmental Energy Technologies Division, Ernest
   10792              :     // Orlando Lawrence Berkeley National Laboratory.
   10793              : 
   10794              :     // Using/Aliasing
   10795              :     using Curve::CurveValue;
   10796              : 
   10797              :     // SUBROUTINE PARAMETER DEFINITIONS:
   10798              :     static constexpr std::string_view RoutineNameFullLoad("CalcDXHeatingCoil:fullload");
   10799              : 
   10800              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   10801              :     Real64 AirMassFlow;           // dry air mass flow rate through coil [kg/s]
   10802              :     Real64 AirMassFlowRatio;      // Ratio of actual air mass flow to rated air mass flow
   10803              :     Real64 AirVolumeFlowRate;     // Air volume flow rate across the cooling coil [m3/s]
   10804              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W]
   10805              :     Real64 TotCap;                // gross total cooling capacity at off-rated conditions [W]
   10806              :     Real64 TotCapAdj;             // adjusted total cooling capacity at off-rated conditions [W]
   10807              :     Real64 TotCapTempModFac;      // Total capacity modifier (function of entering drybulb, outside drybulb) depending
   10808              :     // on the type of curve
   10809              :     Real64 TotCapFlowModFac;    // Total capacity modifier (function of actual supply air flow vs rated flow)
   10810              :     Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
   10811              :     Real64 InletAirWetBulbC;    // wetbulb temperature of inlet air [C]
   10812              :     Real64 InletAirEnthalpy;    // inlet air enthalpy [J/kg]
   10813              :     Real64 InletAirHumRat;      // inlet air humidity ratio [kg/kg]
   10814              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10815              :     // REAL(r64)     :: InletAirPressure            ! inlet air pressure [Pa]
   10816              :     Real64 FullLoadOutAirEnth;   // outlet full load enthalpy [J/kg]
   10817              :     Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
   10818              :     Real64 FullLoadOutAirTemp;   // outlet air temperature at full load [C]
   10819              :     Real64 FullLoadOutAirRH;     // outlet air relative humidity at full load
   10820       177475 :     Real64 EIRTempModFac(0.0);   // EIR modifier (function of entering drybulb, outside drybulb) depending on the
   10821              :     // type of curve
   10822              :     Real64 DefrostEIRTempModFac;      // EIR modifier for defrost (function of entering wetbulb, outside drybulb)
   10823              :     Real64 EIRFlowModFac;             // EIR modifier (function of actual supply air flow vs rated flow)
   10824              :     Real64 EIR;                       // EIR at part load and off rated conditions
   10825              :     Real64 PLF;                       // Part load factor, accounts for thermal lag at compressor startup
   10826              :     Real64 PLRHeating;                // PartLoadRatio in heating
   10827              :     Real64 OutdoorCoilT;              // Outdoor coil temperature (C)
   10828              :     Real64 OutdoorCoildw;             // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
   10829              :     Real64 FractionalDefrostTime;     // Fraction of time step system is in defrost
   10830              :     Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
   10831              :     Real64 InputPowerMultiplier;      // Multiplier for power when system is in defrost
   10832              :     Real64 LoadDueToDefrost;          // Additional load due to defrost
   10833              :     Real64 CrankcaseHeatingPower;     // power due to crankcase heater
   10834              :     Real64 OutdoorDryBulb;            // Outdoor dry-bulb temperature at condenser (C)
   10835              :     Real64 OutdoorWetBulb;            // Outdoor wet-bulb temperature at condenser (C)
   10836              :     Real64 OutdoorHumRat;             // Outdoor humidity ratio at condenser (kg/kg)
   10837              :     Real64 OutdoorPressure;           // Outdoor barometric pressure at condenser (Pa)
   10838       177475 :     constexpr int Mode(1);            // Performance mode for MultiMode DX coil; Always 1 for other coil types
   10839              :     Real64 AirFlowRatio;              // Ratio of compressor on airflow to average timestep airflow
   10840              :     Real64 OutletAirTemp;             // Supply air temperature (average value if constant fan, full output if cycling fan)
   10841              :     Real64 OutletAirHumRat;           // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
   10842              :     Real64 OutletAirEnthalpy;         // Supply air enthalpy (average value if constant fan, full output if cycling fan)
   10843       177475 :     Real64 CompAmbTemp(0.0);          // Ambient temperature at compressor
   10844              : 
   10845       177475 :     if (present(OnOffAirFlowRatio)) {
   10846       177462 :         AirFlowRatio = OnOffAirFlowRatio;
   10847              :     } else {
   10848           13 :         AirFlowRatio = 1.0;
   10849              :     }
   10850              : 
   10851       177475 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   10852              :     // Get condenser outdoor node info from DX Heating Coil
   10853       177475 :     if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
   10854        49438 :         OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
   10855        49438 :         CompAmbTemp = OutdoorDryBulb;
   10856        49438 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
   10857           32 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10858           32 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10859           32 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10860           32 :             CompAmbTemp = state.dataEnvrn->OutDryBulbTemp;
   10861              :         } else {
   10862        49406 :             OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
   10863              :             // If node is not connected to anything, pressure = default, use weather data
   10864        49406 :             if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   10865           94 :                 OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   10866           94 :                 OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10867           94 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10868           94 :                 OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10869              :             } else {
   10870        49312 :                 OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
   10871              :                 // this should use Node%WetBulbTemp or a PSYC function, not OAWB
   10872        49312 :                 OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb;
   10873              :             }
   10874        49406 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
   10875            0 :                 auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   10876            0 :                 OutdoorDryBulb = secZoneHB.ZT;
   10877            0 :                 OutdoorHumRat = secZoneHB.airHumRat;
   10878            0 :                 OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   10879            0 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10880            0 :                 CompAmbTemp = OutdoorDryBulb;
   10881              :             }
   10882              :         }
   10883       128037 :     } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
   10884            0 :         auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   10885            0 :         OutdoorDryBulb = secZoneHB.ZT;
   10886            0 :         OutdoorHumRat = secZoneHB.airHumRat;
   10887            0 :         OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   10888            0 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10889            0 :         CompAmbTemp = OutdoorDryBulb;
   10890              :     } else {
   10891       128037 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   10892       128037 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10893       128037 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10894       128037 :         OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10895       128037 :         CompAmbTemp = OutdoorDryBulb;
   10896              :     }
   10897              : 
   10898       177475 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   10899       177475 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   10900       177475 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   10901       177475 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   10902              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10903              :     // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
   10904              :     // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
   10905       177475 :     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   10906       177475 :     PLRHeating = 0.0;
   10907       177475 :     thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
   10908              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
   10909       177475 :     if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
   10910        40005 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   10911        40005 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   10912            2 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
   10913              :         }
   10914              :     } else {
   10915       137470 :         CrankcaseHeatingPower = 0.0;
   10916              :     }
   10917              : 
   10918       220922 :     if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
   10919        43447 :         OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
   10920              :         // for cycling fan, reset mass flow to full on rate
   10921        14022 :         if (fanOp == HVAC::FanOp::Cycling) AirMassFlow /= PartLoadRatio;
   10922        14022 :         if (fanOp == HVAC::FanOp::Continuous) AirMassFlow *= AirFlowRatio;
   10923              :         // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
   10924        14022 :         AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
   10925              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10926              :         //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   10927        14022 :         VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
   10928              : 
   10929        28044 :         if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   10930        14022 :             (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
   10931            1 :             if (thisDXCoil.ErrIndex1 == 0) {
   10932            2 :                 ShowWarningMessage(
   10933              :                     state,
   10934            2 :                     format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at {:.3R} m3/s/W.",
   10935            1 :                            thisDXCoil.DXCoilType,
   10936            1 :                            thisDXCoil.Name,
   10937              :                            VolFlowperRatedTotCap));
   10938            2 :                 ShowContinueErrorTimeStamp(state, "");
   10939            2 :                 ShowContinueError(state,
   10940            2 :                                   format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
   10941            1 :                                          HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   10942            1 :                                          HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
   10943            2 :                 ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   10944            3 :                 ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   10945              :             }
   10946            8 :             ShowRecurringWarningErrorAtEnd(
   10947              :                 state,
   10948            2 :                 thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10949              :                     "\" - Air volume flow rate per watt of rated total heating capacity is out of range error continues...",
   10950            1 :                 thisDXCoil.ErrIndex1,
   10951              :                 VolFlowperRatedTotCap,
   10952              :                 VolFlowperRatedTotCap);
   10953              :         }
   10954              : 
   10955              :         // Get total capacity modifying factor (function of temperature) for off-rated conditions
   10956              :         // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
   10957              :         // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   10958              :         // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   10959        14022 :         if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
   10960           15 :             switch (thisDXCoil.HeatingPerformanceOATType) {
   10961           15 :             case HVAC::OATType::DryBulb: {
   10962           15 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
   10963           15 :             } break;
   10964            0 :             case HVAC::OATType::WetBulb: {
   10965            0 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorWetBulb);
   10966            0 :             } break;
   10967            0 :             default: {
   10968            0 :                 TotCapTempModFac = 1.0;
   10969            0 :             } break;
   10970              :             }
   10971              :         } else {
   10972        14007 :             switch (thisDXCoil.HeatingPerformanceOATType) {
   10973           14 :             case HVAC::OATType::DryBulb: {
   10974           14 :                 if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
   10975            3 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), OutdoorDryBulb);
   10976              :                 } else {
   10977           11 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
   10978              :                 }
   10979           14 :             } break;
   10980        13993 :             case HVAC::OATType::WetBulb: {
   10981        13993 :                 if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
   10982            0 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), OutdoorWetBulb);
   10983              :                 } else {
   10984        13993 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
   10985              :                 }
   10986        13993 :             } break;
   10987            0 :             default: {
   10988            0 :                 TotCapTempModFac = 1.0;
   10989            0 :             } break;
   10990              :             }
   10991              :         }
   10992              : 
   10993        14022 :         if (TotCapTempModFac < 0.0) {
   10994            0 :             if (thisDXCoil.CAPFTErrIndex == 0) {
   10995            0 :                 ShowWarningMessage(state,
   10996            0 :                                    format("The TotCapTempModFac curve value for DX heating coil {} ={:.2R}", thisDXCoil.Name, TotCapTempModFac));
   10997            0 :                 ShowContinueError(state,
   10998              :                                   "TotCapTempModFac curve value must be > 0. TotCapTempModFac curve value has been reset to 0.0 and "
   10999              :                                   "simulation is continuing.");
   11000            0 :                 ShowContinueError(state, format("Check the IO reference manual for TotCapTempModFac curve guidance [ {} ].", thisDXCoil.DXCoilType));
   11001            0 :                 ShowContinueErrorTimeStamp(state, "");
   11002              :             }
   11003            0 :             ShowRecurringWarningErrorAtEnd(state,
   11004              :                                            "DX heating coil TotCapTempModFac curve value < 0 warning continues... ",
   11005            0 :                                            thisDXCoil.CAPFTErrIndex,
   11006              :                                            TotCapTempModFac,
   11007              :                                            TotCapTempModFac);
   11008            0 :             TotCapTempModFac = 0.0;
   11009              :         }
   11010              : 
   11011              :         //  Get total capacity modifying factor (function of mass flow) for off-rated conditions
   11012        14022 :         AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
   11013        14022 :         TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
   11014              : 
   11015              :         // Calculate total heating capacity for off-rated conditions
   11016        14022 :         TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
   11017              : 
   11018              :         // Calculating adjustment factors for defrost
   11019              :         // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
   11020        14022 :         OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
   11021        14022 :         OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
   11022              : 
   11023              :         // Initializing defrost adjustment factors
   11024        14022 :         LoadDueToDefrost = 0.0;
   11025        14022 :         HeatingCapacityMultiplier = 1.0;
   11026        14022 :         FractionalDefrostTime = 0.0;
   11027        14022 :         InputPowerMultiplier = 1.0;
   11028              : 
   11029              :         // Check outdoor temperature to determine of defrost is active
   11030        14022 :         if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost && thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::Water) {
   11031              :             // Calculate defrost adjustment factors depending on defrost control type
   11032           37 :             if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
   11033           37 :                 FractionalDefrostTime = thisDXCoil.DefrostTime;
   11034           37 :                 if (FractionalDefrostTime > 0.0) {
   11035           37 :                     if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   11036            1 :                         HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   11037            1 :                         InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   11038              :                     } else {
   11039           36 :                         HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
   11040           36 :                         InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
   11041           36 :                         if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   11042            0 :                             ShowWarningMessage(state,
   11043            0 :                                                format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   11044              :                                                       "actuator must be both provided for DX heating coil {}",
   11045            0 :                                                       thisDXCoil.Name));
   11046            0 :                             ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   11047              :                         }
   11048              :                     }
   11049              :                 }
   11050              :             } else { // else defrost control is on-demand
   11051            0 :                 FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
   11052            0 :                 if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   11053            0 :                     HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   11054            0 :                     InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   11055              :                 } else {
   11056            0 :                     HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
   11057            0 :                     InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
   11058            0 :                     if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   11059            0 :                         ShowWarningMessage(state,
   11060            0 :                                            format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   11061              :                                                   "actuator must be both provided for DX heating coil {}",
   11062            0 :                                                   thisDXCoil.Name));
   11063            0 :                         ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   11064              :                     }
   11065              :                 }
   11066              :             }
   11067              : 
   11068           37 :             if (FractionalDefrostTime > 0.0) {
   11069              :                 // Calculate defrost adjustment factors depending on defrost control strategy
   11070           37 :                 if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
   11071           32 :                     LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.RatedTotCap(Mode) / 1.01667);
   11072           32 :                     DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
   11073           32 :                     thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.RatedTotCap(Mode) / 1.01667) * FractionalDefrostTime;
   11074              :                 } else { // Defrost strategy is resistive
   11075            5 :                     thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
   11076              :                 }
   11077              :             } else { // Defrost is not active because (FractionalDefrostTime .EQ. 0.0)
   11078            0 :                 thisDXCoil.DefrostPower = 0.0;
   11079              :             }
   11080              :         }
   11081              : 
   11082              :         // Modify total heating capacity based on defrost heating capacity multiplier
   11083              :         // MaxHeatCap passed from parent object VRF Condenser and is used to limit capacity of TU's to that available from condenser
   11084        14022 :         if (present(MaxHeatCap)) {
   11085        13997 :             TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
   11086        13997 :             TotCap = min(MaxHeatCap, TotCap);
   11087              :         } else {
   11088           25 :             TotCapAdj = TotCap * HeatingCapacityMultiplier;
   11089              :         }
   11090              : 
   11091              :         // Calculate full load outlet conditions
   11092        14022 :         FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
   11093        14022 :         FullLoadOutAirHumRat = InletAirHumRat;
   11094        14022 :         FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   11095        14022 :         FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
   11096              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11097              :         //  FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
   11098        14022 :         if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
   11099            0 :             FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
   11100              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11101              :             //    FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
   11102            0 :             FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
   11103              :         }
   11104              : 
   11105              :         // Calculate actual outlet conditions for the input part load ratio
   11106              :         // Actual outlet conditions are "average" for time step
   11107        14022 :         if (fanOp == HVAC::FanOp::Continuous) {
   11108              :             // continuous fan, cycling compressor
   11109        13990 :             OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
   11110        13990 :             OutletAirHumRat = (PartLoadRatio * FullLoadOutAirHumRat + (1.0 - PartLoadRatio) * InletAirHumRat);
   11111        13990 :             OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   11112              :         } else {
   11113              :             // default to cycling fan, cycling compressor
   11114           32 :             OutletAirEnthalpy = FullLoadOutAirEnth;
   11115           32 :             OutletAirHumRat = FullLoadOutAirHumRat;
   11116           32 :             OutletAirTemp = FullLoadOutAirTemp;
   11117              :         }
   11118              :         // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
   11119              :         // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
   11120              :         // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   11121              :         // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   11122        14022 :         if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
   11123           18 :             if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 1) {
   11124            2 :                 EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), OutdoorDryBulb);
   11125              :             } else {
   11126           16 :                 EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
   11127              :             }
   11128           18 :             EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
   11129              :         } else {
   11130        14004 :             EIRTempModFac = 1.0;
   11131        14004 :             EIRFlowModFac = 1.0;
   11132              :         }
   11133              : 
   11134        14022 :         if (EIRTempModFac < 0.0) {
   11135            0 :             if (thisDXCoil.EIRFTErrIndex == 0) {
   11136            0 :                 ShowWarningMessage(state, format("The EIRTempModFac curve value for DX heating coil {} ={:.2R}", thisDXCoil.Name, EIRTempModFac));
   11137            0 :                 ShowContinueError(
   11138              :                     state, "EIRTempModFac curve value must be > 0.  EIRTempModFac curve value has been reset to 0.0 and simulation is continuing.");
   11139            0 :                 ShowContinueError(state, format("Check the IO reference manual for EIRTempModFac curve guidance [ {} ].", thisDXCoil.DXCoilType));
   11140            0 :                 ShowContinueErrorTimeStamp(state, "");
   11141              :             }
   11142            0 :             ShowRecurringWarningErrorAtEnd(state,
   11143              :                                            "DX heating coil EIRTempModFac curve value < 0.0 warning continues... ",
   11144            0 :                                            thisDXCoil.EIRFTErrIndex,
   11145              :                                            EIRTempModFac,
   11146              :                                            EIRTempModFac);
   11147            0 :             EIRTempModFac = 0.0;
   11148              :         }
   11149              : 
   11150        14022 :         EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
   11151              :         // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
   11152        14022 :         if (TotCapAdj > 0.0) {
   11153        14021 :             PLRHeating = min(1.0, (PartLoadRatio + (LoadDueToDefrost * PartLoadRatio) / TotCapAdj));
   11154              :         } else {
   11155            1 :             PLRHeating = 0.0;
   11156              :         }
   11157        14022 :         if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating) {
   11158           18 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PLRHeating); // Calculate part-load factor
   11159              :         } else {
   11160        14004 :             PLF = 1.0;
   11161              :         }
   11162              : 
   11163        14022 :         if (PLF < 0.7) {
   11164            1 :             if (thisDXCoil.PLRErrIndex == 0) {
   11165            2 :                 ShowWarningMessage(
   11166              :                     state,
   11167            2 :                     format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
   11168            2 :                 ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   11169            2 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   11170            3 :                 ShowContinueErrorTimeStamp(state, "");
   11171              :             }
   11172            7 :             ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
   11173            1 :             PLF = 0.7;
   11174              :         }
   11175              : 
   11176        14022 :         thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
   11177        14022 :         if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
   11178            0 :             if (thisDXCoil.ErrIndex4 == 0) {
   11179            0 :                 ShowWarningMessage(state,
   11180            0 :                                    format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
   11181            0 :                                           thisDXCoil.Name,
   11182            0 :                                           thisDXCoil.HeatingCoilRuntimeFraction));
   11183            0 :                 ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
   11184            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   11185            0 :                 ShowContinueErrorTimeStamp(state, "");
   11186              :             }
   11187            0 :             ShowRecurringWarningErrorAtEnd(state,
   11188            0 :                                            thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
   11189            0 :                                            thisDXCoil.ErrIndex4,
   11190            0 :                                            thisDXCoil.HeatingCoilRuntimeFraction,
   11191            0 :                                            thisDXCoil.HeatingCoilRuntimeFraction);
   11192            0 :             thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   11193        14022 :         } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
   11194            0 :             thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   11195              :         }
   11196              :         // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
   11197        14022 :         if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
   11198        14022 :         thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
   11199              : 
   11200              :         // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
   11201              :         // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
   11202              : 
   11203        14022 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   11204        14017 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
   11205              :         } else {
   11206            5 :             thisDXCoil.CrankcaseHeaterPower =
   11207            5 :                 CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
   11208            5 :                                                    state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
   11209              :         }
   11210              : 
   11211        14022 :         AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   11212        14022 :         thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy);
   11213              :         // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
   11214              :         // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
   11215        14022 :         thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
   11216              : 
   11217        14022 :         thisDXCoil.OutletAirTemp = OutletAirTemp;
   11218        14022 :         thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   11219        14022 :         thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   11220        14022 :         thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
   11221              : 
   11222              :     } else {
   11223              : 
   11224              :         // DX coil is off; just pass through conditions
   11225       163453 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   11226       163453 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   11227       163453 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   11228              : 
   11229       163453 :         thisDXCoil.ElecHeatingPower = 0.0;
   11230       163453 :         thisDXCoil.TotalHeatingEnergyRate = 0.0;
   11231       163453 :         thisDXCoil.DefrostPower = 0.0;
   11232              : 
   11233              :         // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
   11234              :         // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
   11235       163453 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   11236        35512 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
   11237              :         } else {
   11238       127941 :             thisDXCoil.CrankcaseHeaterPower =
   11239       127941 :                 CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
   11240              :         }
   11241       163453 :         thisDXCoil.CompressorPartLoadRatio = 0.0;
   11242              : 
   11243              :     } // end of on/off if - else
   11244              : 
   11245       177475 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   11246       177475 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   11247       177475 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   11248       177475 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
   11249       177475 :     state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
   11250       177475 :     state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
   11251       177475 :     state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
   11252              : 
   11253              :     // set outlet node conditions
   11254       177475 :     int airOutletNode = thisDXCoil.AirOutNode;
   11255       177475 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   11256       177475 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   11257              : 
   11258              :     // calc secondary coil if specified
   11259       177475 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   11260            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   11261              :     }
   11262       177475 : }
   11263              : 
   11264        36791 : void CalcMultiSpeedDXCoil(EnergyPlusData &state,
   11265              :                           int const DXCoilNum,     // the number of the DX heating coil to be simulated
   11266              :                           Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
   11267              :                           Real64 const CycRatio,   // cycling part load ratio
   11268              :                           ObjexxFCL::Optional_bool_const ForceOn)
   11269              : {
   11270              : 
   11271              :     // SUBROUTINE INFORMATION:
   11272              :     //       AUTHOR         Fred Buhl
   11273              :     //       DATE WRITTEN   September 2002
   11274              :     //       MODIFIED       Raustad/Shirey, Feb 2004
   11275              :     //                      Feb 2005 M. J. Witte, GARD Analytics, Inc.
   11276              :     //                        Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
   11277              :     //                      April 2010, Chandan sharma, FSEC, added basin heater
   11278              : 
   11279              :     // PURPOSE OF THIS SUBROUTINE:
   11280              :     // Calculates the air-side performance and electrical energy use of a direct-
   11281              :     // expansion, air-cooled cooling unit with a 2 speed or variable speed compressor.
   11282              : 
   11283              :     // METHODOLOGY EMPLOYED:
   11284              :     // Uses the same methodology as the single speed DX unit model (SUBROUTINE CalcDoe2DXCoil).
   11285              :     // In addition it assumes that the unit performance is obtained by interpolating between
   11286              :     // the performance at high speed and that at low speed. If the output needed is below
   11287              :     // that produced at low speed, the compressor cycles between off and low speed.
   11288              : 
   11289              :     // Using/Aliasing
   11290              :     using Curve::CurveValue;
   11291              : 
   11292              :     // SUBROUTINE ARGUMENT DEFINITIONS:
   11293              :     // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
   11294              : 
   11295              :     // SUBROUTINE PARAMETER DEFINITIONS:
   11296              :     static constexpr std::string_view RoutineNameHighSpeedOutlet("CalcMultiSpeedDXCoil:highspeedoutlet");
   11297              :     static constexpr std::string_view RoutineNameLowSpeedOutlet("CalcMultiSpeedDXCoil:lowspeedoutlet");
   11298              :     static constexpr std::string_view RoutineNameNewDewPointConditions("CalcMultiSpeedDXCoil:newdewpointconditions");
   11299              : 
   11300              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   11301              :     Real64 AirMassFlow;         // dry air mass flow rate through coil [kg/s]
   11302              :     Real64 AirMassFlowRatio;    // Ratio of max air mass flow to rated air mass flow
   11303              :     Real64 InletAirWetBulbC;    // wetbulb temperature of inlet air [C]
   11304              :     Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
   11305              :     Real64 InletAirEnthalpy;    // inlet air enthalpy [J/kg]
   11306              :     Real64 InletAirHumRat;      // inlet air humidity ratio [kg/kg]
   11307              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11308              :     // REAL(r64) :: InletAirPressure    ! inlet air pressure [Pa]
   11309              :     Real64 OutletAirDryBulbTemp;    // outlet air dry bulb temperature [C]
   11310              :     Real64 OutletAirEnthalpy;       // outlet air enthalpy [J/kg]
   11311              :     Real64 OutletAirHumRat;         // outlet air humidity ratio [kg/kg]
   11312              :     Real64 OutletAirDryBulbTempSat; // outlet air dry bulb temp at saturation at the outlet enthalpy [C]
   11313              :     Real64 LSOutletAirDryBulbTemp;  // low speed outlet air dry bulb temperature [C]
   11314              :     Real64 LSOutletAirEnthalpy;     // low speed outlet air enthalpy [J/kg]
   11315              :     Real64 LSOutletAirHumRat;       // low speed outlet air humidity ratio [kg/kg]
   11316              :     Real64 hDelta;                  // Change in air enthalpy across the cooling coil [J/kg]
   11317              :     Real64 hTinwout;                // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
   11318              :     Real64 hADP;                    // Apparatus dew point enthalpy [J/kg]
   11319              :     Real64 tADP;                    // Apparatus dew point temperature [C]
   11320              :     Real64 wADP;                    // Apparatus dew point humidity ratio [kg/kg]
   11321              :     Real64 hTinwADP;                // Enthalpy at inlet dry-bulb and wADP [J/kg]
   11322              :     Real64 RatedCBFHS;              // coil bypass factor at rated conditions (high speed)
   11323              :     Real64 CBFHS;                   // coil bypass factor at max flow (high speed)
   11324              :     Real64 TotCapHS;                // total capacity at high speed [W]
   11325              :     Real64 SHRHS;                   // sensible heat ratio at high speed
   11326              :     Real64 TotCapLS;                // total capacity at low speed [W]
   11327              :     Real64 SHRLS;                   // sensible heat ratio at low speed
   11328              :     Real64 EIRTempModFacHS;         // EIR modifier (function of entering wetbulb, outside drybulb) (high speed)
   11329              :     Real64 EIRFlowModFacHS;         // EIR modifier (function of actual supply air flow vs rated flow) (high speed)
   11330              :     Real64 EIRHS;                   // EIR at off rated conditions (high speed)
   11331              :     Real64 EIRTempModFacLS;         // EIR modifier (function of entering wetbulb, outside drybulb) (low speed)
   11332              :     Real64 EIRLS;                   // EIR at off rated conditions (low speed)
   11333              :     Real64 TotCap;                  // total capacity at current speed [W]
   11334              :     Real64 SHR;                     // sensible heat ratio at current speed
   11335              :     Real64 EIR;                     // EIR at current speed
   11336              :     Real64 AirMassFlowNom;          // speed ratio weighted average of high and low speed air mass flow rates [kg/s]
   11337              :     Real64 CBFNom;                  // coil bypass factor corresponding to AirMassFlowNom and SpeedRatio
   11338              :     Real64 CBF;                     // CBFNom adjusted for actual air mass flow rate
   11339              :     Real64 PLF;                     // Part load factor, accounts for thermal lag at compressor startup, used in
   11340              :     // power calculation
   11341              :     Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
   11342              :     // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
   11343              :     Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
   11344              :     // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
   11345              :     Real64 RhoAir;                // Density of air [kg/m3]
   11346              :     Real64 RhoWater;              // Density of water [kg/m3]
   11347              :     Real64 CondAirMassFlow;       // Condenser air mass flow rate [kg/s]
   11348              :     Real64 EvapCondPumpElecPower; // Evaporative condenser electric pump power [W]
   11349        36791 :     constexpr int Mode(1);        // Performance mode for MultiMode DX coil; Always 1 for other coil types
   11350              :     Real64 OutdoorDryBulb;        // Outdoor dry-bulb temperature at condenser (C)
   11351              :     Real64 OutdoorWetBulb;        // Outdoor wet-bulb temperature at condenser (C)
   11352              :     Real64 OutdoorHumRat;         // Outdoor humidity ratio at condenser (kg/kg)
   11353              :     Real64 OutdoorPressure;       // Outdoor barometric pressure at condenser (Pa)
   11354              :     bool LocalForceOn;
   11355              :     Real64 AirMassFlowRatio2; // Ratio of low speed air mass flow to rated air mass flow
   11356        36791 :     Real64 CompAmbTemp(0.0);  // Ambient temperature at compressor
   11357              : 
   11358        36791 :     if (present(ForceOn)) {
   11359         3306 :         LocalForceOn = true;
   11360              :     } else {
   11361        33485 :         LocalForceOn = false;
   11362              :     }
   11363              : 
   11364        36791 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   11365              : 
   11366        36791 :     if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
   11367            0 :         OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
   11368              :         // If node is not connected to anything, pressure = default, use weather data
   11369            0 :         if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   11370            0 :             OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   11371            0 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   11372            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   11373            0 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   11374              :         } else {
   11375            0 :             OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
   11376            0 :             OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
   11377            0 :             OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure);
   11378              :         }
   11379            0 :         CompAmbTemp = OutdoorDryBulb;
   11380            0 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
   11381            0 :             auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   11382            0 :             OutdoorDryBulb = secZoneHB.ZT;
   11383            0 :             OutdoorHumRat = secZoneHB.airHumRat;
   11384            0 :             OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   11385            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   11386            0 :             CompAmbTemp = OutdoorDryBulb;
   11387              :         }
   11388        36791 :     } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
   11389            0 :         auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   11390            0 :         OutdoorDryBulb = secZoneHB.ZT;
   11391            0 :         OutdoorHumRat = secZoneHB.airHumRat;
   11392            0 :         OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   11393            0 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   11394            0 :         CompAmbTemp = OutdoorDryBulb;
   11395              :     } else {
   11396        36791 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   11397        36791 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   11398        36791 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   11399        36791 :         OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   11400        36791 :         CompAmbTemp = OutdoorDryBulb;
   11401              :     }
   11402              : 
   11403        36791 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   11404        36791 :     AirMassFlowRatio = thisDXCoil.InletAirMassFlowRateMax / thisDXCoil.RatedAirMassFlowRate(Mode);
   11405        36791 :     thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
   11406        36791 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   11407        36791 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   11408        36791 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   11409        36791 :     AirMassFlowRatio2 = 1.0; // DXCoil(DXCoilNum)%RatedAirMassFlowRate2 / DXCoil(DXCoilNum)%RatedAirMassFlowRate(Mode)
   11410              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11411              :     // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
   11412              :     // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
   11413        36791 :     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   11414        36791 :     if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
   11415        36780 :         CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
   11416           11 :     } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   11417              :         // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   11418           11 :         CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
   11419           11 :         CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
   11420              :     }
   11421              : 
   11422        58329 :     if ((AirMassFlow > 0.0 && CompAmbTemp >= thisDXCoil.MinOATCompressor) && ((thisDXCoil.availSched->getCurrentVal() > 0.0) || (LocalForceOn)) &&
   11423        21538 :         (SpeedRatio > 0.0 || CycRatio > 0.0)) {
   11424              : 
   11425        29226 :         RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
   11426        29226 :         if (SpeedRatio > 0.0) {
   11427              :             // Adjust high speed coil bypass factor for actual maximum air flow rate.
   11428        15248 :             RatedCBFHS = thisDXCoil.RatedCBF(Mode);
   11429        15248 :             CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.RatedAirMassFlowRate(Mode), thisDXCoil.InletAirMassFlowRateMax);
   11430              :             // get high speed total capacity and SHR at current conditions
   11431        45744 :             CalcTotCapSHR(state,
   11432              :                           InletAirDryBulbTemp,
   11433              :                           InletAirHumRat,
   11434              :                           InletAirEnthalpy,
   11435              :                           InletAirWetBulbC,
   11436              :                           AirMassFlowRatio,
   11437              :                           thisDXCoil.InletAirMassFlowRateMax,
   11438        15248 :                           thisDXCoil.RatedTotCap(Mode),
   11439              :                           CBFHS,
   11440        15248 :                           thisDXCoil.CCapFTemp(Mode),
   11441        15248 :                           thisDXCoil.CCapFFlow(Mode),
   11442              :                           TotCapHS,
   11443              :                           SHRHS,
   11444              :                           CondInletTemp,
   11445              :                           OutdoorPressure,
   11446        15248 :                           thisDXCoil.capModFacTotal);
   11447              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11448              :             //                       CondInletTemp, Node(DXCoil(DXCoilNum)%AirInNode)%Press)
   11449              :             // get the high speed SHR from user specified SHR modifier curves
   11450        15248 :             if (thisDXCoil.UserSHRCurveExists) {
   11451            0 :                 SHRHS = CalcSHRUserDefinedCurves(state,
   11452              :                                                  InletAirDryBulbTemp,
   11453              :                                                  InletAirWetBulbC,
   11454              :                                                  AirMassFlowRatio,
   11455            0 :                                                  thisDXCoil.SHRFTemp(Mode),
   11456            0 :                                                  thisDXCoil.SHRFFlow(Mode),
   11457            0 :                                                  thisDXCoil.RatedSHR(Mode));
   11458              :             }
   11459              :             // get low speed total capacity and SHR at current conditions
   11460        15248 :             CalcTotCapSHR(state,
   11461              :                           InletAirDryBulbTemp,
   11462              :                           InletAirHumRat,
   11463              :                           InletAirEnthalpy,
   11464              :                           InletAirWetBulbC,
   11465              :                           1.0,
   11466              :                           thisDXCoil.RatedAirMassFlowRate2,
   11467              :                           thisDXCoil.RatedTotCap2,
   11468              :                           thisDXCoil.RatedCBF2,
   11469              :                           thisDXCoil.CCapFTemp2,
   11470        15248 :                           thisDXCoil.CCapFFlow(Mode),
   11471              :                           TotCapLS,
   11472              :                           SHRLS,
   11473              :                           CondInletTemp,
   11474              :                           OutdoorPressure,
   11475        15248 :                           thisDXCoil.capModFacTotal);
   11476              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11477              :             //                       Node(DXCoil(DXCoilNum)%AirInNode)%Press)
   11478              :             // get the low speed SHR from user specified SHR modifier curves
   11479        15248 :             if (thisDXCoil.UserSHRCurveExists) {
   11480            0 :                 SHRLS = CalcSHRUserDefinedCurves(state,
   11481              :                                                  InletAirDryBulbTemp,
   11482              :                                                  InletAirWetBulbC,
   11483              :                                                  AirMassFlowRatio2,
   11484              :                                                  thisDXCoil.SHRFTemp2,
   11485              :                                                  thisDXCoil.SHRFFlow2,
   11486              :                                                  thisDXCoil.RatedSHR2);
   11487              :             }
   11488              :             // get high speed EIR at current conditions
   11489        15248 :             EIRTempModFacHS = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
   11490        15248 :             EIRFlowModFacHS = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
   11491        15248 :             EIRHS = thisDXCoil.RatedEIR(Mode) * EIRFlowModFacHS * EIRTempModFacHS;
   11492              :             // get low speed EIR at current conditions
   11493              :             //    EIRTempModFacLS = CurveValue(state, DXCoil(DXCoilNum)%EIRFTemp(Mode),InletAirWetBulbC,CondInletTemp)
   11494              :             //    CR7307 changed EIRTempModFacLS calculation to that shown below.
   11495        15248 :             EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
   11496        15248 :             EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
   11497              : 
   11498              :             // get current total capacity, SHR, EIR
   11499        15248 :             if (SpeedRatio >= 1.0) {
   11500         5106 :                 TotCap = TotCapHS;
   11501         5106 :                 SHR = SHRHS;
   11502         5106 :                 EIR = EIRHS;
   11503         5106 :                 CBFNom = CBFHS;
   11504         5106 :                 AirMassFlowNom = thisDXCoil.InletAirMassFlowRateMax;
   11505         5106 :                 CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
   11506         5106 :                 EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode);
   11507              :             } else {
   11508        10142 :                 TotCap = SpeedRatio * TotCapHS + (1.0 - SpeedRatio) * TotCapLS;
   11509        10142 :                 EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
   11510        10142 :                 CBFNom = SpeedRatio * CBFHS + (1.0 - SpeedRatio) * thisDXCoil.RatedCBF2;
   11511        10142 :                 AirMassFlowNom = SpeedRatio * thisDXCoil.InletAirMassFlowRateMax + (1.0 - SpeedRatio) * thisDXCoil.RatedAirMassFlowRate2;
   11512        10142 :                 CondAirMassFlow = RhoAir * (SpeedRatio * thisDXCoil.EvapCondAirFlow(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondAirFlow2);
   11513        10142 :                 EvapCondPumpElecPower =
   11514        10142 :                     SpeedRatio * thisDXCoil.EvapCondPumpElecNomPower(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondPumpElecNomPower2;
   11515              :             }
   11516        15248 :             hDelta = TotCap / AirMassFlow;
   11517        15248 :             if (thisDXCoil.UserSHRCurveExists) {
   11518            0 :                 if (SpeedRatio >= 1.0) {
   11519            0 :                     SHR = SHRHS;
   11520              :                 } else {
   11521            0 :                     SHR = min(SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS, 1.0);
   11522              :                 }
   11523            0 :                 OutletAirEnthalpy = InletAirEnthalpy - hDelta;
   11524            0 :                 if (SHR < 1.0) {
   11525            0 :                     hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   11526            0 :                     OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   11527            0 :                     if (OutletAirHumRat <= 0.0) {
   11528            0 :                         OutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
   11529              :                     }
   11530              :                 } else {
   11531            0 :                     SHR = 1.0;
   11532            0 :                     OutletAirHumRat = InletAirHumRat;
   11533              :                 }
   11534            0 :                 OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   11535            0 :                 OutletAirDryBulbTempSat = PsyTdpFnWPb(state, OutletAirHumRat, OutdoorPressure, RoutineNameHighSpeedOutlet);
   11536            0 :                 if (OutletAirDryBulbTempSat > OutletAirDryBulbTemp) {
   11537            0 :                     OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   11538            0 :                     OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineNameHighSpeedOutlet);
   11539              :                 }
   11540              : 
   11541              :             } else {
   11542              :                 // Adjust CBF for off-nominal flow
   11543        15248 :                 CBF = AdjustCBF(CBFNom, AirMassFlowNom, AirMassFlow);
   11544              :                 // Calculate new apparatus dew point conditions
   11545        15248 :                 hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
   11546        15248 :                 tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure);
   11547              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11548              :                 //    tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   11549        15248 :                 wADP = PsyWFnTdbH(state, tADP, hADP);
   11550        15248 :                 hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   11551              :                 // get corresponding SHR
   11552        15248 :                 if ((InletAirEnthalpy - hADP) > 1.e-10) {
   11553        15248 :                     SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   11554              :                 } else {
   11555            0 :                     SHR = 1.0;
   11556              :                 }
   11557              : 
   11558              :                 // cr8918    SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
   11559        15248 :                 OutletAirEnthalpy = InletAirEnthalpy - hDelta;
   11560              :                 // get outlet conditions
   11561        15248 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   11562        15248 :                 OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   11563              : 
   11564        15248 :                 OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   11565        15248 :                 OutletAirDryBulbTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
   11566        15248 :                 if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   11567           12 :                     OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   11568           12 :                     OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy);
   11569              :                 }
   11570              :             }
   11571              :             // Coil total/sensible/latent cooling rates and electrical power
   11572        15248 :             CalcComponentSensibleLatentOutput(AirMassFlow,
   11573              :                                               InletAirDryBulbTemp,
   11574              :                                               InletAirHumRat,
   11575              :                                               OutletAirDryBulbTemp,
   11576              :                                               OutletAirHumRat,
   11577        15248 :                                               thisDXCoil.SensCoolingEnergyRate,
   11578        15248 :                                               thisDXCoil.LatCoolingEnergyRate,
   11579        15248 :                                               thisDXCoil.TotalCoolingEnergyRate);
   11580        15248 :             thisDXCoil.ElecCoolingPower = TotCap * EIR;
   11581              :             //   Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
   11582        15248 :             state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
   11583        15248 :             thisDXCoil.PartLoadRatio = 1.0;
   11584        15248 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
   11585              : 
   11586        15248 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   11587        15248 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   11588        15248 :             thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
   11589              : 
   11590        13978 :         } else if (CycRatio > 0.0) {
   11591              : 
   11592        13978 :             if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   11593              :                 // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   11594            2 :                 CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect2);
   11595            2 :                 CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
   11596              :             }
   11597              : 
   11598              :             // Adjust low speed coil bypass factor for actual flow rate.
   11599              :             // CBF = AdjustCBF(DXCoil(DXCoilNum)%RatedCBF2,DXCoil(DXCoilNum)%RatedAirMassFlowRate2,AirMassFlow)
   11600              :             // get low speed total capacity and SHR at current conditions
   11601        13978 :             CalcTotCapSHR(state,
   11602              :                           InletAirDryBulbTemp,
   11603              :                           InletAirHumRat,
   11604              :                           InletAirEnthalpy,
   11605              :                           InletAirWetBulbC,
   11606              :                           1.0,
   11607              :                           thisDXCoil.RatedAirMassFlowRate2,
   11608              :                           thisDXCoil.RatedTotCap2,
   11609              :                           thisDXCoil.RatedCBF2,
   11610              :                           thisDXCoil.CCapFTemp2,
   11611        13978 :                           thisDXCoil.CCapFFlow(Mode),
   11612              :                           TotCapLS,
   11613              :                           SHRLS,
   11614              :                           CondInletTemp,
   11615              :                           OutdoorPressure,
   11616        13978 :                           thisDXCoil.capModFacTotal);
   11617              :             // get the low speed SHR from user specified SHR modifier curves
   11618        13978 :             if (thisDXCoil.UserSHRCurveExists) {
   11619            0 :                 SHRLS = CalcSHRUserDefinedCurves(
   11620              :                     state, InletAirDryBulbTemp, InletAirWetBulbC, 1.0, thisDXCoil.SHRFTemp2, thisDXCoil.SHRFFlow2, thisDXCoil.RatedSHR2);
   11621              :             }
   11622              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11623              :             //                       Node(DXCoil(DXCoilNum)%AirInNode)%Press)
   11624        13978 :             hDelta = TotCapLS / AirMassFlow;
   11625        13978 :             if (thisDXCoil.UserSHRCurveExists) {
   11626            0 :                 SHR = SHRLS;
   11627            0 :                 LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
   11628            0 :                 if (SHR < 1.0) {
   11629            0 :                     hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   11630            0 :                     LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   11631            0 :                     if (LSOutletAirHumRat <= 0.0) {
   11632            0 :                         LSOutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
   11633              :                     }
   11634              :                 } else {
   11635            0 :                     SHR = 1.0;
   11636            0 :                     LSOutletAirHumRat = InletAirHumRat;
   11637              :                 }
   11638            0 :                 LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
   11639            0 :                 OutletAirDryBulbTempSat = PsyTdpFnWPb(state, LSOutletAirHumRat, OutdoorPressure, RoutineNameLowSpeedOutlet);
   11640            0 :                 if (OutletAirDryBulbTempSat > LSOutletAirDryBulbTemp) {
   11641            0 :                     LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   11642            0 :                     LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
   11643              :                 }
   11644              : 
   11645              :             } else {
   11646              :                 // Adjust CBF for off-nominal flow
   11647        13978 :                 CBF = AdjustCBF(thisDXCoil.RatedCBF2, thisDXCoil.RatedAirMassFlowRate2, AirMassFlow);
   11648              :                 // Calculate new apparatus dew point conditions
   11649        13978 :                 hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
   11650        13978 :                 tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineNameNewDewPointConditions);
   11651              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11652              :                 //    tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   11653        13978 :                 wADP = PsyWFnTdbH(state, tADP, hADP, RoutineNameNewDewPointConditions);
   11654        13978 :                 hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   11655              :                 // get corresponding SHR
   11656        13978 :                 if ((InletAirEnthalpy - hADP) > 1.e-10) {
   11657        13978 :                     SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   11658              :                 } else {
   11659            0 :                     SHR = 1.0;
   11660              :                 }
   11661              :                 // cr8918    SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
   11662              :                 // get low speed outlet conditions
   11663        13978 :                 LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
   11664        13978 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   11665        13978 :                 LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   11666        13978 :                 LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
   11667        13978 :                 OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineNameLowSpeedOutlet);
   11668        13978 :                 if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   11669            6 :                     LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   11670            6 :                     LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
   11671              :                 }
   11672              :             }
   11673              :             // outlet conditions are average of inlet and low speed weighted by CycRatio
   11674        13978 :             OutletAirEnthalpy = CycRatio * LSOutletAirEnthalpy + (1.0 - CycRatio) * InletAirEnthalpy;
   11675        13978 :             OutletAirHumRat = CycRatio * LSOutletAirHumRat + (1.0 - CycRatio) * InletAirHumRat;
   11676        13978 :             OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   11677              :             // get low speed EIR at current conditions
   11678              :             //    EIRTempModFacLS = CurveValue(state, DXCoil(DXCoilNum)%EIRFTemp(Mode),InletAirWetBulbC,CondInletTemp)
   11679              :             //    CR7307 changed EIRTempModFacLS calculation to that shown below.
   11680        13978 :             EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
   11681        13978 :             EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
   11682              :             // get the part load factor that will account for cycling losses
   11683        13978 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CycRatio);
   11684        13978 :             if (PLF < 0.7) {
   11685            0 :                 PLF = 0.7;
   11686              :             }
   11687              :             // calculate the run time fraction
   11688        13978 :             thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
   11689        13978 :             thisDXCoil.PartLoadRatio = CycRatio;
   11690        13978 :             if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
   11691            0 :                 thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   11692              :             }
   11693              :             // get the electrical power consumption
   11694        13978 :             thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
   11695              : 
   11696              :             // Coil total/sensible/latent cooling rates and electrical power
   11697        13978 :             CalcComponentSensibleLatentOutput(AirMassFlow,
   11698              :                                               InletAirDryBulbTemp,
   11699              :                                               InletAirHumRat,
   11700              :                                               OutletAirDryBulbTemp,
   11701              :                                               OutletAirHumRat,
   11702        13978 :                                               thisDXCoil.SensCoolingEnergyRate,
   11703        13978 :                                               thisDXCoil.LatCoolingEnergyRate,
   11704        13978 :                                               thisDXCoil.TotalCoolingEnergyRate);
   11705        13978 :             state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
   11706        13978 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   11707        13978 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   11708        13978 :             thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
   11709        13978 :             CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow2 * thisDXCoil.CoolingCoilRuntimeFraction;
   11710        13978 :             EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower2 * thisDXCoil.CoolingCoilRuntimeFraction;
   11711              :         }
   11712              : 
   11713        29226 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   11714              :             //******************
   11715              :             //             WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
   11716              :             //             H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
   11717              :             //                                /RhoWater [kgWater/m3]
   11718              :             //******************
   11719            9 :             RhoWater = RhoH2O(OutdoorDryBulb);
   11720            9 :             thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater;
   11721            9 :             thisDXCoil.EvapCondPumpElecPower = EvapCondPumpElecPower;
   11722              :             // set water system demand request (if needed)
   11723            9 :             if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
   11724              : 
   11725            0 :                 state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
   11726            0 :                     thisDXCoil.EvapWaterConsumpRate;
   11727              :             }
   11728              : 
   11729              :             // Calculate basin heater power
   11730            9 :             CalcBasinHeaterPower(state,
   11731              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
   11732              :                                  thisDXCoil.basinHeaterSched,
   11733              :                                  thisDXCoil.BasinHeaterSetPointTemp,
   11734            9 :                                  thisDXCoil.BasinHeaterPower);
   11735            9 :             thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   11736              :         }
   11737              : 
   11738              :     } else {
   11739              : 
   11740              :         // DX coil is off; just pass through conditions
   11741         7565 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   11742         7565 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   11743         7565 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   11744              : 
   11745         7565 :         thisDXCoil.ElecCoolingPower = 0.0;
   11746         7565 :         thisDXCoil.TotalCoolingEnergyRate = 0.0;
   11747         7565 :         thisDXCoil.SensCoolingEnergyRate = 0.0;
   11748         7565 :         thisDXCoil.LatCoolingEnergyRate = 0.0;
   11749         7565 :         thisDXCoil.EvapCondPumpElecPower = 0.0;
   11750         7565 :         thisDXCoil.EvapWaterConsumpRate = 0.0;
   11751              : 
   11752              :         // Calculate basin heater power
   11753         7565 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   11754            2 :             CalcBasinHeaterPower(state,
   11755              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
   11756              :                                  thisDXCoil.basinHeaterSched,
   11757              :                                  thisDXCoil.BasinHeaterSetPointTemp,
   11758            2 :                                  thisDXCoil.BasinHeaterPower);
   11759              :         }
   11760              :     }
   11761              : 
   11762        36791 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   11763        36791 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   11764        36791 :     thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
   11765              : 
   11766              :     // set outlet node conditions
   11767        36791 :     int airOutletNode = thisDXCoil.AirOutNode;
   11768        36791 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   11769        36791 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   11770              : 
   11771              :     // calc secondary coil if specified
   11772        36791 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   11773            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   11774              :     }
   11775        36791 : }
   11776              : 
   11777            0 : void CalcBasinHeaterPowerForMultiModeDXCoil(EnergyPlusData &state,
   11778              :                                             int const DXCoilNum,             // Index of coil being simulated
   11779              :                                             HVAC::CoilMode const DehumidMode // Dehumidification mode (0=normal, 1=enhanced)
   11780              : )
   11781              : {
   11782              : 
   11783              :     // SUBROUTINE INFORMATION:
   11784              :     //       AUTHOR         Chandan Sharma, FSEC
   11785              :     //       DATE WRITTEN   May 2010
   11786              : 
   11787              :     // PURPOSE OF THIS SUBROUTINE:
   11788              :     // To calculate the basin heater power for multi mode DX cooling coil
   11789              : 
   11790              :     // METHODOLOGY EMPLOYED:
   11791              :     // The methodology employed is as follows:
   11792              :     // 1) If the number of capacity stages is equal to 1 and the CondenserType for stage 1
   11793              :     //    is EvapCooled, then the basin heater power is calculated for (1-runtimefractionstage1) of DX coil
   11794              :     // 2) If the number of capacity stages is greater than 1, then
   11795              :     //    a) If the CondenserType for stage 1 is EvapCooled, then the basin heater power is calculated for
   11796              :     //       (1-runtimefractionofstage1) of DX coil
   11797              :     //    b) Elseif the CondenserType for stage 2 is EvapCooled, then the basin heater power is calculated for
   11798              :     //       (1-runtimefractionofstage2) of DX coil
   11799              : 
   11800              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   11801              :     int PerfMode; // Performance mode for MultiMode DX coil; Always 1 for other coil types
   11802              :     // 1-2=normal mode: 1=stage 1 only, 2=stage 1&2
   11803              :     // 3-4=enhanced dehumidification mode: 3=stage 1 only, 4=stage 1&2
   11804              : 
   11805            0 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   11806              : 
   11807            0 :     if (thisDXCoil.NumCapacityStages == 1) {
   11808            0 :         thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   11809              :     } else {
   11810            0 :         PerfMode = (int)DehumidMode * 2 + 1;
   11811            0 :         if (thisDXCoil.CondenserType(PerfMode) == DataHeatBalance::RefrigCondenserType::Evap) {
   11812            0 :             thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   11813            0 :         } else if (thisDXCoil.CondenserType(PerfMode + 1) == DataHeatBalance::RefrigCondenserType::Evap) {
   11814            0 :             CalcBasinHeaterPower(state,
   11815              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
   11816              :                                  thisDXCoil.basinHeaterSched,
   11817              :                                  thisDXCoil.BasinHeaterSetPointTemp,
   11818            0 :                                  thisDXCoil.BasinHeaterPower);
   11819            0 :             thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilStg2RuntimeFrac);
   11820              :         }
   11821              :     }
   11822            0 : }
   11823              : 
   11824        59001 : Real64 AdjustCBF(Real64 const CBFNom,             // nominal coil bypass factor
   11825              :                  Real64 const AirMassFlowRateNom, // nominal air mass flow rate [kg/s]
   11826              :                  Real64 const AirMassFlowRate     // actual air mass flow rate [kg/s]
   11827              : )
   11828              : {
   11829              : 
   11830              :     // FUNCTION INFORMATION:
   11831              :     //       AUTHOR         Fred Buhl using Don Shirey's code
   11832              :     //       DATE WRITTEN   September 2002
   11833              : 
   11834              :     // PURPOSE OF THIS FUNCTION:
   11835              :     //    Adjust coil bypass factor for actual air flow rate.
   11836              : 
   11837              :     // METHODOLOGY EMPLOYED:
   11838              :     // Uses relation CBF = exp(-NTU) whereNTU = A0/(m*cp). Relationship models the cooling coil
   11839              :     // as a heat exchanger with Cmin/Cmax = 0.
   11840              : 
   11841              :     // Return value
   11842              :     Real64 CBFAdj; // the result - the adjusted coil bypass factor
   11843              : 
   11844              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   11845              :     Real64 A0;    // intermediate variable
   11846              :     Real64 ADiff; // intermediate variable
   11847              : 
   11848        59001 :     if (CBFNom > 0.0) {
   11849        58998 :         A0 = -std::log(CBFNom) * AirMassFlowRateNom;
   11850              :     } else {
   11851            3 :         A0 = 0.0;
   11852              :     }
   11853        59001 :     ADiff = -A0 / AirMassFlowRate;
   11854        59001 :     if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
   11855        58541 :         CBFAdj = std::exp(ADiff);
   11856              :     } else {
   11857          460 :         CBFAdj = 1.0e-6;
   11858              :     }
   11859              : 
   11860        59001 :     return CBFAdj;
   11861              : }
   11862              : 
   11863         3120 : Real64 CalcCBF(EnergyPlusData &state,
   11864              :                std::string const &UnitType,
   11865              :                std::string const &UnitName,
   11866              :                Real64 const InletAirTemp,   // inlet air temperature [C]
   11867              :                Real64 const InletAirHumRat, // inlet air humidity ratio [kg water / kg dry air]
   11868              :                Real64 const TotCap,         // total cooling  capacity [Watts]
   11869              :                Real64 const AirVolFlowRate, // the air volume flow rate at the given capacity [m3/s]
   11870              :                Real64 const SHR,            // sensible heat ratio at the given capacity and flow rate
   11871              :                bool const PrintFlag         // flag used to print warnings if desired
   11872              : )
   11873              : {
   11874              : 
   11875              :     // FUNCTION INFORMATION:
   11876              :     //       AUTHOR         Fred Buhl using Don Shirey's code
   11877              :     //       DATE WRITTEN   September 2002
   11878              : 
   11879              :     // PURPOSE OF THIS FUNCTION:
   11880              :     // Calculate the coil bypass factor for a coil given the total capacity at the entering conditions,
   11881              :     // air mass flow rate at the entering conditions, and the sensible heat ratio (SHR) at the
   11882              :     // entering conditions. Standard barometric pressure is used for this model parameter.
   11883              : 
   11884              :     // METHODOLOGY EMPLOYED:
   11885              :     // calculate SlopeRated (deltahumrat/deltaT) using rated unit information provided by
   11886              :     // user. Then hunt along saturation curve of psychrometric chart until the slope of the line
   11887              :     // between the saturation point and rated inlet air humidity ratio and T is the same as SlopeRated.
   11888              :     // When the slopes are equal, then we have located the apparatus dewpoint of the coil at rated
   11889              :     // conditions. From this information, coil bypass factor is calculated.
   11890              : 
   11891              :     // Using/Aliasing
   11892              : 
   11893              :     // Return value
   11894         3120 :     Real64 CBF(0.0); // the result - the coil bypass factor
   11895              : 
   11896              :     // FUNCTION PARAMETER DEFINITIONS:
   11897              :     static constexpr std::string_view RoutineName("CalcCBF");
   11898         3120 :     constexpr Real64 SmallDifferenceTest(0.00000001);
   11899              : 
   11900              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   11901              :     Real64 InletAirEnthalpy;                // Enthalpy of inlet air to evaporator at given conditions [J/kg]
   11902         3120 :     Real64 DeltaH(0.0);                     // Enthalpy drop across evaporator at given conditions [J/kg]
   11903         3120 :     Real64 DeltaT(0.0);                     // Temperature drop across evaporator at given conditions [C]
   11904         3120 :     Real64 DeltaHumRat(0.0);                // Humidity ratio drop across evaporator at given conditions [kg/kg]
   11905         3120 :     Real64 OutletAirTemp(InletAirTemp);     // Outlet dry-bulb temperature from evaporator at given conditions [C]
   11906         3120 :     Real64 OutletAirTempSat(InletAirTemp);  // Saturation dry-bulb temperature from evaporator at outlet air enthalpy [C]
   11907              :     Real64 OutletAirEnthalpy;               // Enthalpy of outlet air at given conditions [J/kg]
   11908         3120 :     Real64 OutletAirHumRat(InletAirHumRat); // Outlet humidity ratio from evaporator at given conditions [kg/kg]
   11909              :     Real64 OutletAirRH;                     // relative humidity of the outlet air
   11910              :     Real64 Error;                           // Error term used in given coil bypass factor (CBF) calculations
   11911              :     Real64 ErrorLast;                       // Error term, from previous iteration
   11912              :     int Iter;                               // Iteration loop counter in CBF calculations
   11913         3120 :     int IterMax(50);                        // Maximum number of iterations in CBF calculations
   11914              :     Real64 ADPTemp;                         // Apparatus dewpoint temperature used in CBF calculations [C]
   11915              :     Real64 ADPHumRat;                       // Apparatus dewpoint humidity used in CBF calculations [kg/kg]
   11916              :     Real64 ADPEnthalpy;                     // Air enthalpy at apparatus dew point [J/kg]
   11917              :     Real64 DeltaADPTemp;                    // Change in Apparatus Dew Point used in CBF calculations [C]
   11918         3120 :     Real64 SlopeAtConds(0.0);               // Slope (DeltaHumRat/DeltaT) at given conditions
   11919         3120 :     Real64 Slope(0.0);                      // Calculated Slope used while hunting for Tadp
   11920              :     Real64 Tolerance;                       // Convergence tolerance for CBF calculations
   11921              :     Real64 HTinHumRatOut;                   // Air enthalpy at inlet air temp and outlet air humidity ratio [J/kg]
   11922              :     Real64 AirMassFlowRate;                 // the standard air mass flow rate at the given capacity [kg/s]
   11923              :     Real64 adjustedSHR;                     // SHR calculated using adjusted outlet air properties []
   11924         3120 :     bool CBFErrors(false);                  // Set to true if errors in CBF calculation, fatal at end of routine
   11925              : 
   11926         3120 :     if (AirVolFlowRate <= 0.0 || TotCap <= 0.0) { // Coil not running or has no capacity, don't calculate CBF
   11927            5 :         return CBF;
   11928              :     }
   11929              : 
   11930         3115 :     AirMassFlowRate = AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, InletAirTemp, InletAirHumRat, RoutineName);
   11931         3115 :     DeltaH = TotCap / AirMassFlowRate;
   11932         3115 :     InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
   11933         3115 :     HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
   11934         3115 :     OutletAirHumRat = PsyWFnTdbH(state, InletAirTemp, HTinHumRatOut);
   11935         3115 :     DeltaHumRat = InletAirHumRat - OutletAirHumRat;
   11936         3115 :     OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
   11937         3115 :     OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   11938              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11939              :     //  Pressure will have to be pass into this subroutine to fix this one
   11940         3115 :     OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
   11941         3115 :     if (OutletAirRH >= 1.0 && PrintFlag) {
   11942           16 :         ShowWarningError(state, format("For object = {}, name = \"{}\"", UnitType, UnitName));
   11943           32 :         ShowContinueError(state, "Calculated outlet air relative humidity greater than 1. The combination of");
   11944           32 :         ShowContinueError(state, "rated air volume flow rate, total cooling capacity and sensible heat ratio yields coil exiting");
   11945           32 :         ShowContinueError(state, "air conditions above the saturation curve. Possible fixes are to reduce the rated total cooling");
   11946           32 :         ShowContinueError(state, "capacity, increase the rated air volume flow rate, or reduce the rated sensible heat ratio for this coil.");
   11947           32 :         ShowContinueError(state, "If autosizing, it is recommended that all three of these values be autosized.");
   11948           32 :         ShowContinueError(state, "...Inputs used for calculating cooling coil bypass factor.");
   11949           16 :         ShowContinueError(state, format("...Inlet Air Temperature     = {:.2R} C", InletAirTemp));
   11950           16 :         ShowContinueError(state, format("...Outlet Air Temperature    = {:.2R} C", OutletAirTemp));
   11951           16 :         ShowContinueError(state, format("...Inlet Air Humidity Ratio  = {:.6R} kgWater/kgDryAir", InletAirHumRat));
   11952           16 :         ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
   11953           16 :         ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
   11954           16 :         ShowContinueError(state, format("...Air Mass Flow Rate used in calculation     = {:.6R} kg/s", AirMassFlowRate));
   11955           16 :         ShowContinueError(state, format("...Air Volume Flow Rate used in calculation   = {:.6R} m3/s", AirVolFlowRate));
   11956           16 :         if (TotCap > 0.0) {
   11957           28 :             if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
   11958           12 :                 ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
   11959           12 :                 ShowContinueError(state,
   11960           12 :                                   format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
   11961           12 :                                          AirVolFlowRate / TotCap));
   11962              :             }
   11963              :         }
   11964           32 :         ShowContinueErrorTimeStamp(state, "");
   11965           16 :         OutletAirTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, DataEnvironment::StdPressureSeaLevel, RoutineName);
   11966           16 :         if (OutletAirTemp < OutletAirTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   11967           16 :             OutletAirTemp = OutletAirTempSat + 0.005;
   11968           16 :             OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy, RoutineName);
   11969           16 :             DeltaHumRat = InletAirHumRat - OutletAirHumRat;
   11970           16 :             HTinHumRatOut = PsyHFnTdbW(InletAirTemp, OutletAirHumRat);
   11971           16 :             adjustedSHR = (HTinHumRatOut - OutletAirEnthalpy) / DeltaH;
   11972           32 :             ShowContinueError(state, "CalcCBF: SHR adjusted to achieve valid outlet air properties and the simulation continues.");
   11973           16 :             ShowContinueError(state, format("CalcCBF: initial SHR = {:.5R}", SHR));
   11974           16 :             ShowContinueError(state, format("CalcCBF: adjusted SHR = {:.5R}", adjustedSHR));
   11975              :         }
   11976              :     }
   11977         3115 :     DeltaT = InletAirTemp - OutletAirTemp;
   11978         3115 :     if (DeltaT <= 0.0) {
   11979            0 :         ShowSevereError(state, format("For object = {}, name = \"{}\"", UnitType, UnitName));
   11980            0 :         ShowContinueError(state, "Calculated coil delta T is less than or equal to 0. The combination of");
   11981            0 :         ShowContinueError(state, "rated air volume flow rate, total cooling capacity and sensible heat ratio yields coil exiting");
   11982            0 :         ShowContinueError(state, "air conditions that are not reasonable. Possible fixes are to adjust the rated total cooling");
   11983            0 :         ShowContinueError(state, "capacity, rated air volume flow rate, or rated sensible heat ratio for this coil.");
   11984            0 :         ShowContinueError(state, "If autosizing, it is recommended that all three of these values be autosized.");
   11985            0 :         ShowContinueError(state, "...Inputs used for calculating cooling coil bypass factor.");
   11986            0 :         ShowContinueError(state, format("...Inlet Air Temperature     = {:.2R} C", InletAirTemp));
   11987            0 :         ShowContinueError(state, format("...Outlet Air Temperature    = {:.2R} C", OutletAirTemp));
   11988            0 :         ShowContinueError(state, format("...Inlet Air Humidity Ratio  = {:.6R} kgWater/kgDryAir", InletAirHumRat));
   11989            0 :         ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
   11990            0 :         ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
   11991            0 :         ShowContinueError(state, format("...Air Mass Flow Rate used in calculation     = {:.6R} kg/s", AirMassFlowRate));
   11992            0 :         ShowContinueError(state, format("...Air Volume Flow Rate used in calculation   = {:.6R} m3/s", AirVolFlowRate));
   11993            0 :         if (TotCap > 0.0) {
   11994            0 :             if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
   11995            0 :                 ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
   11996            0 :                 ShowContinueError(state,
   11997            0 :                                   format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
   11998            0 :                                          AirVolFlowRate / TotCap));
   11999              :             }
   12000              :         }
   12001            0 :         ShowContinueErrorTimeStamp(state, "");
   12002            0 :         ShowFatalError(state, "Check and revise the input data for this coil before rerunning the simulation.");
   12003              :     }
   12004              :     // Calculate slope at given conditions
   12005         3115 :     if (DeltaT > 0.0) SlopeAtConds = DeltaHumRat / DeltaT;
   12006              : 
   12007              :     //  IF (SlopeAtConds .le. .0000001d0 .or. OutletAirHumRat .le. 0.0d0) THEN
   12008         3115 :     if (SlopeAtConds < 0.0 || OutletAirHumRat <= 0.0) {
   12009              :         //   Invalid conditions, slope can't be less than zero (SHR > 1) or
   12010              :         //   outlet air humidity ratio can't be less than zero.
   12011            0 :         ShowSevereError(state, format("{} \"{}\"", UnitType, UnitName));
   12012            0 :         ShowContinueError(state, "...Invalid slope or outlet air condition when calculating cooling coil bypass factor.");
   12013            0 :         ShowContinueError(state, format("...Slope = {:.8R}", SlopeAtConds));
   12014            0 :         ShowContinueError(state, format("...Inlet Air Temperature     = {:.2R} C", InletAirTemp));
   12015            0 :         ShowContinueError(state, format("...Outlet Air Temperature    = {:.2R} C", OutletAirTemp));
   12016            0 :         ShowContinueError(state, format("...Inlet Air Humidity Ratio  = {:.6R} kgWater/kgDryAir", InletAirHumRat));
   12017            0 :         ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
   12018            0 :         ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
   12019            0 :         ShowContinueError(state, format("...Air Mass Flow Rate used in calculation     = {:.6R} kg/s", AirMassFlowRate));
   12020            0 :         ShowContinueError(state, format("...Air Volume Flow Rate used in calculation   = {:.6R} m3/s", AirVolFlowRate));
   12021            0 :         if (TotCap > 0.0) {
   12022            0 :             if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
   12023            0 :                 ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
   12024            0 :                 ShowContinueError(state,
   12025            0 :                                   format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
   12026            0 :                                          AirVolFlowRate / TotCap));
   12027              :             }
   12028              :         }
   12029            0 :         ShowContinueErrorTimeStamp(state, "");
   12030            0 :         CBFErrors = true;
   12031            0 :         CBF = 0.0; //? Added: Is this what should be returned
   12032              :     } else {
   12033              : 
   12034              :         //   First guess for Tadp is outlet air dew point
   12035              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12036              :         //  Pressure will have to be pass into this subroutine to fix this one
   12037         3115 :         ADPTemp = PsyTdpFnWPb(state, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel);
   12038              : 
   12039         3115 :         Tolerance = 1.0; // initial conditions for iteration
   12040         3115 :         ErrorLast = 100.0;
   12041         3115 :         Iter = 0;
   12042         3115 :         DeltaADPTemp = 5.0;
   12043        51003 :         while ((Iter <= IterMax) && (Tolerance > 0.001)) {
   12044              :             //     Do for IterMax iterations or until the error gets below .1%
   12045        47888 :             if (Iter > 0) ADPTemp += DeltaADPTemp;
   12046        47888 :             ++Iter;
   12047              : 
   12048              :             //     Find new slope using guessed Tadp
   12049              : 
   12050              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12051              :             //  Pressure will have to be pass into this subroutine to fix this one
   12052        47888 :             ADPHumRat = min(OutletAirHumRat, PsyWFnTdpPb(state, ADPTemp, DataEnvironment::StdPressureSeaLevel));
   12053        47888 :             Slope = (InletAirHumRat - ADPHumRat) / max(0.001, (InletAirTemp - ADPTemp));
   12054              : 
   12055              :             //     check for convergence (slopes are equal to within error tolerance)
   12056              : 
   12057        47888 :             Error = (Slope - SlopeAtConds) / SlopeAtConds;
   12058        47888 :             if ((Error > 0.0) && (ErrorLast < 0.0)) {
   12059        11633 :                 DeltaADPTemp = -DeltaADPTemp / 2.0;
   12060        36255 :             } else if ((Error < 0.0) && (ErrorLast > 0.0)) {
   12061        13158 :                 DeltaADPTemp = -DeltaADPTemp / 2.0;
   12062        23097 :             } else if (std::abs(Error) > std::abs(ErrorLast)) {
   12063         2957 :                 DeltaADPTemp = -DeltaADPTemp / 2.0;
   12064              :             }
   12065        47888 :             ErrorLast = Error;
   12066              : 
   12067        47888 :             Tolerance = std::abs(Error);
   12068              :         }
   12069              : 
   12070              :         //   Calculate Bypass Factor from Enthalpies
   12071              : 
   12072         3115 :         InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
   12073         3115 :         OutletAirEnthalpy = PsyHFnTdbW(OutletAirTemp, OutletAirHumRat);
   12074         3115 :         ADPEnthalpy = PsyHFnTdbW(ADPTemp, ADPHumRat);
   12075         3115 :         CBF = min(1.0, (OutletAirEnthalpy - ADPEnthalpy) / (InletAirEnthalpy - ADPEnthalpy));
   12076         3115 :         if (Iter > IterMax && PrintFlag) {
   12077            0 :             ShowSevereError(state, format("{} \"{}\" -- coil bypass factor calculation did not converge after max iterations.", UnitType, UnitName));
   12078            0 :             ShowContinueError(state, format("The RatedSHR of [{:.3R}], entered by the user or autosized (see *.eio file),", SHR));
   12079            0 :             ShowContinueError(state, "may be causing this. The line defined by the coil rated inlet air conditions");
   12080            0 :             ShowContinueError(state, "(26.7C drybulb and 19.4C wetbulb) and the RatedSHR (i.e., slope of the line) must intersect");
   12081            0 :             ShowContinueError(state, "the saturation curve of the psychrometric chart. If the RatedSHR is too low, then this");
   12082            0 :             ShowContinueError(state, "intersection may not occur and the coil bypass factor calculation will not converge.");
   12083            0 :             ShowContinueError(state, "If autosizing the SHR, recheck the design supply air humidity ratio and design supply air");
   12084            0 :             ShowContinueError(state, "temperature values in the Sizing:System and Sizing:Zone objects. In general, the temperatures");
   12085            0 :             ShowContinueError(state, "and humidity ratios specified in these two objects should be the same for each system");
   12086            0 :             ShowContinueError(state, "and the zones that it serves.");
   12087            0 :             ShowContinueErrorTimeStamp(state, "");
   12088            0 :             CBFErrors = true; // Didn't converge within MaxIter iterations
   12089              :         }
   12090         3115 :         if (CBF < 0.0 && PrintFlag) {
   12091            0 :             ShowSevereError(state, format("{} \"{}\" -- negative coil bypass factor calculated.", UnitType, UnitName));
   12092            0 :             ShowContinueErrorTimeStamp(state, "");
   12093            0 :             CBFErrors = true; // Negative CBF not valid
   12094              :         }
   12095              :     }
   12096              : 
   12097              :     // Show fatal error for specific coil that caused a CBF error
   12098         3115 :     if (CBFErrors) {
   12099            0 :         ShowFatalError(state, format("{} \"{}\" Errors found in calculating coil bypass factors", UnitType, UnitName));
   12100              :     }
   12101              : 
   12102         3115 :     return CBF;
   12103              : }
   12104              : 
   12105           90 : Real64 ValidateADP(EnergyPlusData &state,
   12106              :                    std::string const &UnitType,      // component name
   12107              :                    std::string const &UnitName,      // component type
   12108              :                    Real64 const RatedInletAirTemp,   // coil inlet air temperature [C]
   12109              :                    Real64 const RatedInletAirHumRat, // coil inlet air humidity ratio [kg/kg]
   12110              :                    Real64 const TotCap,              // coil total capacity [W]
   12111              :                    Real64 const AirVolFlowRate,      // coil air volume flow rate [m3/s]
   12112              :                    Real64 const InitialSHR,          // coil sensible heat ratio []
   12113              :                    std::string const &CallingRoutine // function name calling this routine
   12114              : )
   12115              : {
   12116              : 
   12117              :     // FUNCTION INFORMATION:
   12118              :     //    AUTHOR         Richard Raustad, FSEC
   12119              :     //    DATE WRITTEN   December 2015
   12120              : 
   12121              :     // PURPOSE OF THIS FUNCTION:
   12122              :     //    Validates that the calculated bypass factor represents valid SHR based on total capacity and air mass flow rate.
   12123              : 
   12124              :     // METHODOLOGY EMPLOYED:
   12125              :     //    With model parameters autosized by the user, the SHR is selected based on an empirical model.
   12126              :     //    This can sometimes lead to an SHR that does not cross the saturation curve, or one that crosses excessively where
   12127              :     //    the coil outlet air conditions exceed the saturation curve (i.e., RH > 1).
   12128              :     //    This function checks to see if the ADP based on coil delta T and calculated bypass factor and the ADP based
   12129              :     //    on coil delta W and calculated bypass factor land on the saturation curve at the same place within a tolerance.
   12130              :     //    The result is passed back to the sizing routine as the new value for SHR.
   12131              :     //    If the SHR is not autosized, this routine will still adjust the design SHR appropriately, however, the hard-sized SHR will not
   12132              :     //    change.
   12133              : 
   12134              :     // Return value
   12135           90 :     Real64 SHR(0.0); // the result - the adjusted design SHR
   12136              : 
   12137              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   12138           90 :     Real64 CBF_calculated(0.0);    // coil bypass factor based on TotCap, AirFlow, SHR, and BaroPress
   12139           90 :     Real64 InletAirEnthalpy(0.0);  // Enthalpy of inlet air to evaporator at given conditions [J/kg]
   12140           90 :     Real64 DeltaH(0.0);            // Enthalpy drop across evaporator at given conditions [J/kg]
   12141           90 :     Real64 HTinHumRatOut(0.0);     // Air enthalpy at inlet air temp and outlet air humidity ratio [J/kg]
   12142           90 :     Real64 DeltaHumRat(0.0);       // Humidity ratio drop across evaporator at given conditions [kg/kg]
   12143           90 :     Real64 OutletAirTemp(0.0);     // Outlet dry-bulb temperature from evaporator at given conditions [C]
   12144           90 :     Real64 OutletAirEnthalpy(0.0); // Enthalpy of outlet air at given conditions [J/kg]
   12145           90 :     Real64 OutletAirHumRat(0.0);   // Outlet humidity ratio from evaporator at given conditions [kg/kg]
   12146           90 :     Real64 OutletAirRH(0.0);       // relative humidity of the outlet air
   12147           90 :     Real64 CalcADPTemp(0.0);       // actual ADP temperature based on bypass factor [C]
   12148           90 :     Real64 CalcADPHumRat(0.0);     // actual ADP humidity ratio based on bypass factor [kg/kg]
   12149           90 :     Real64 CalcADPTempFnHR(0.0);   // actual ADP temperature as a function of humidity ratio based on bypass factor [C]
   12150           90 :     Real64 ADPerror(0.0);          // difference between ADP function of temperature and humidity ratio [deltaC]
   12151           90 :     Real64 AirMassFlow(0.0);       // air mass flow rate based on standard barometric pressure [kg/s]
   12152           90 :     bool bStillValidating(true);   // while loop flag
   12153           90 :     bool bNoReporting(false);      // don't report specific warnings in calcCBF while iterating on result
   12154           90 :     bool bReversePerturb(false);   // identifies when SHR is being lowered based on outlet air RH
   12155              : 
   12156           90 :     SHR = InitialSHR;
   12157           90 :     AirMassFlow =
   12158           90 :         AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, RatedInletAirTemp, RatedInletAirHumRat, CallingRoutine);
   12159         3059 :     while (bStillValidating) {
   12160         2969 :         CBF_calculated = max(0.0, CalcCBF(state, UnitType, UnitName, RatedInletAirTemp, RatedInletAirHumRat, TotCap, AirMassFlow, SHR, bNoReporting));
   12161         2969 :         DeltaH = TotCap / AirMassFlow;
   12162         2969 :         InletAirEnthalpy = PsyHFnTdbW(RatedInletAirTemp, RatedInletAirHumRat);
   12163         2969 :         HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
   12164         2969 :         OutletAirHumRat = PsyWFnTdbH(state, RatedInletAirTemp, HTinHumRatOut, CallingRoutine);
   12165         2969 :         DeltaHumRat = RatedInletAirHumRat - OutletAirHumRat;
   12166         2969 :         OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
   12167         2969 :         OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   12168         2969 :         OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
   12169         2969 :         if (CBF_calculated < 1) {
   12170         2969 :             CalcADPTemp = RatedInletAirTemp - ((RatedInletAirTemp - OutletAirTemp) / (1 - CBF_calculated));
   12171         2969 :             CalcADPHumRat = RatedInletAirHumRat - ((DeltaHumRat) / (1 - CBF_calculated));
   12172         2969 :             CalcADPTempFnHR = PsyTdpFnWPb(state, CalcADPHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
   12173         2969 :             ADPerror = CalcADPTemp - CalcADPTempFnHR;
   12174              :         } else {
   12175            0 :             ADPerror = 0; // might be able to check for RH >= 1 and reduce SHR, need defect file for that since can't create one
   12176              :         }
   12177              : 
   12178         2969 :         if (std::abs(ADPerror) > 0.012) {
   12179         2969 :             if (OutletAirRH >= 1.0) { // if RH > 1, reduce SHR until it crosses the saturation curve
   12180          344 :                 SHR -= 0.001;
   12181          344 :                 bReversePerturb = true;
   12182          344 :                 if (SHR < 0.5)
   12183            0 :                     bStillValidating = false; // have to stop somewhere, this is lower than the lower limit of SHR empirical model (see
   12184              :                                               // Autosizing/CoolingSHRSizing)
   12185              :             } else {
   12186         2625 :                 if (bReversePerturb) {
   12187           60 :                     bStillValidating = false; // stop iterating once SHR causes ADP to cross back under saturation curve, take what you get
   12188              :                 } else {
   12189         2565 :                     SHR += 0.001; // increase SHR slowly until ADP temps are resolved
   12190              :                 }
   12191              :             }
   12192         2969 :             if (SHR > 0.8)
   12193           30 :                 bStillValidating = false; // have to stop somewhere, this is the upper limit of SHR empirical model (see Autosizing/CoolingSHRSizing)
   12194              :         } else {
   12195            0 :             bStillValidating = false; // ADP temps are close enough. Normal input files hit this on first pass
   12196              :         }
   12197              :     }
   12198              : 
   12199           90 :     return SHR;
   12200              : }
   12201              : 
   12202       116065 : Real64 CalcEffectiveSHR(EnergyPlusData &state,
   12203              :                         int const DXCoilNum,                         // Index number for cooling coil
   12204              :                         Real64 const SHRss,                          // Steady-state sensible heat ratio
   12205              :                         Real64 const RTF,                            // Compressor run-time fraction
   12206              :                         Real64 const QLatRated,                      // Rated latent capacity
   12207              :                         Real64 const QLatActual,                     // Actual latent capacity
   12208              :                         Real64 const EnteringDB,                     // Entering air dry-bulb temperature
   12209              :                         Real64 const EnteringWB,                     // Entering air wet-bulb temperature
   12210              :                         ObjexxFCL::Optional_int_const Mode,          // Performance mode for MultiMode DX coil; Always 1 for other coil types
   12211              :                         ObjexxFCL::Optional<Real64 const> HeatingRTF // Used to recalculate Toff for cycling fan systems
   12212              : )
   12213              : {
   12214              : 
   12215              :     // FUNCTION INFORMATION:
   12216              :     //    AUTHOR         Richard Raustad, FSEC
   12217              :     //    DATE WRITTEN   September 2003
   12218              :     //                   Feb 2005 M. J. Witte, GARD Analytics, Inc.
   12219              :     //                    Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
   12220              :     //                   Nov 2008 R. Raustad, FSEC
   12221              :     //                    Modified to allow latent degradation with cycling fan
   12222              : 
   12223              :     // PURPOSE OF THIS FUNCTION:
   12224              :     //    Adjust sensible heat ratio to account for degradation of DX coil latent
   12225              :     //    capacity at part-load (cycling) conditions.
   12226              : 
   12227              :     // METHODOLOGY EMPLOYED:
   12228              :     //    With model parameters entered by the user, the part-load latent performance
   12229              :     //    of a DX cooling coil is determined for a constant air flow system with
   12230              :     //    a cooling coil that cycles on/off. The model calculates the time
   12231              :     //    required for condensate to begin falling from the cooling coil.
   12232              :     //    Runtimes greater than this are integrated to a "part-load" latent
   12233              :     //    capacity which is used to determine the "part-load" sensible heat ratio.
   12234              :     //    See reference below for additional details (linear decay model, Eq. 8b).
   12235              :     // REFERENCES:
   12236              :     //   "A Model to Predict the Latent Capacity of Air Conditioners and
   12237              :     //    Heat Pumps at Part-Load Conditions with Constant Fan Operation"
   12238              :     //    1996 ASHRAE Transactions, Volume 102, Part 1, Pp. 266 - 274,
   12239              :     //    Hugh I. Henderson, Jr., P.E., Kannan Rengarajan, P.E.
   12240              : 
   12241              :     // Return value
   12242              :     Real64 SHReff; // Effective sensible heat ratio, includes degradation due to cycling effects
   12243              : 
   12244              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   12245              :     Real64 Twet; // Nominal time for condensate to begin leaving the coil's condensate drain line
   12246              :     //   at the current operating conditions (sec)
   12247              :     Real64 Gamma; // Initial moisture evaporation rate divided by steady-state AC latent capacity
   12248              :     //   at the current operating conditions
   12249              :     Real64 Twet_Rated;  // Twet at rated conditions (coil air flow rate and air temperatures), sec
   12250              :     Real64 Gamma_Rated; // Gamma at rated conditions (coil air flow rate and air temperatures)
   12251              :     Real64 Twet_max;    // Maximum allowed value for Twet
   12252              :     Real64 Nmax;        // Maximum ON/OFF cycles per hour for the compressor (cycles/hr)
   12253              :     Real64 Tcl;         // Time constant for latent capacity to reach steady state after startup (sec)
   12254              :     Real64 Ton;         // Coil on time (sec)
   12255              :     Real64 Toff;        // Coil off time (sec)
   12256              :     Real64 Toffa;       // Actual coil off time (sec). Equations valid for Toff <= (2.0 * Twet/Gamma)
   12257              :     Real64 aa;          // Intermediate variable
   12258              :     Real64 To1;         // Intermediate variable (first guess at To). To = time to the start of moisture removal
   12259              :     Real64 To2;         // Intermediate variable (second guess at To). To = time to the start of moisture removal
   12260              :     Real64 Error;       // Error for iteration (DO) loop
   12261              :     Real64 LHRmult;     // Latent Heat Ratio (LHR) multiplier. The effective latent heat ratio LHR = (1-SHRss)*LHRmult
   12262              :     Real64 Ton_heating;
   12263              :     Real64 Toff_heating;
   12264              : 
   12265       116065 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   12266              : 
   12267       116065 :     if (thisDXCoil.DXCoilType_Num != HVAC::CoilDX_MultiSpeedCooling) {
   12268       116024 :         Twet_Rated = thisDXCoil.Twet_Rated(Mode);
   12269       116024 :         Gamma_Rated = thisDXCoil.Gamma_Rated(Mode);
   12270       116024 :         Nmax = thisDXCoil.MaxONOFFCyclesperHour(Mode);
   12271       116024 :         Tcl = thisDXCoil.LatentCapacityTimeConstant(Mode);
   12272              :     } else {
   12273           41 :         Twet_Rated = thisDXCoil.MSTwet_Rated(Mode);
   12274           41 :         Gamma_Rated = thisDXCoil.MSGamma_Rated(Mode);
   12275           41 :         Nmax = thisDXCoil.MSMaxONOFFCyclesperHour(Mode);
   12276           41 :         Tcl = thisDXCoil.MSLatentCapacityTimeConstant(Mode);
   12277              :     }
   12278              : 
   12279              :     //  No moisture evaporation (latent degradation) occurs for runtime fraction of 1.0
   12280              :     //  All latent degradation model parameters cause divide by 0.0 if not greater than 0.0
   12281              :     //  Latent degradation model parameters initialize to 0.0 meaning no evaporation model used.
   12282       116065 :     if (RTF >= 1.0 || Twet_Rated <= 0.0 || Gamma_Rated <= 0.0 || Nmax <= 0.0 || Tcl <= 0.0) {
   12283       107135 :         SHReff = SHRss;
   12284       107135 :         return SHReff;
   12285              :     }
   12286              : 
   12287         8930 :     Twet_max = 9999.0; // high limit for Twet
   12288              : 
   12289              :     //  Calculate the model parameters at the actual operating conditions
   12290         8930 :     Twet = min(Twet_Rated * QLatRated / (QLatActual + 1.e-10), Twet_max);
   12291         8930 :     Gamma = Gamma_Rated * QLatRated * (EnteringDB - EnteringWB) / ((26.7 - 19.4) * QLatActual + 1.e-10);
   12292              : 
   12293              :     //  Calculate the compressor on and off times using a conventional thermostat curve
   12294         8930 :     Ton = 3600.0 / (4.0 * Nmax * (1.0 - RTF)); // duration of cooling coil on-cycle (sec)
   12295         8930 :     Toff = 3600.0 / (4.0 * Nmax * RTF);        // duration of cooling coil off-cycle (sec)
   12296              : 
   12297              :     //  Cap Toff to meet the equation restriction
   12298         8930 :     if (Gamma > 0.0) {
   12299         8930 :         Toffa = min(Toff, 2.0 * Twet / Gamma);
   12300              :     } else {
   12301            0 :         Toffa = Toff;
   12302              :     }
   12303              : 
   12304              :     //  Need to include the reheat coil operation to account for actual fan run time. E+ uses a
   12305              :     //  separate heating coil for heating and reheat (to separate the heating and reheat loads)
   12306              :     //  and real world applications would use a single heating coil for both purposes, the actual
   12307              :     //  fan operation is based on HeatingPLR + ReheatPLR. For cycling fan RH control, latent
   12308              :     //  degradation only occurs when a heating load exists, in this case the reheat load is
   12309              :     //  equal to and opposite in magnitude to the cooling coil sensible output but the reheat
   12310              :     //  coil is not always active. This additional fan run time has not been accounted for at this time.
   12311              :     //  Recalculate Toff for cycling fan systems when heating is active
   12312         8930 :     if (present(HeatingRTF)) {
   12313            0 :         if (HeatingRTF < 1.0 && HeatingRTF > RTF) {
   12314            0 :             Ton_heating = 3600.0 / (4.0 * Nmax * (1.0 - HeatingRTF));
   12315            0 :             Toff_heating = 3600.0 / (4.0 * Nmax * HeatingRTF);
   12316              :             //    add additional heating coil operation during cooling coil off cycle (due to cycling rate difference of coils)
   12317            0 :             Ton_heating += max(0.0, min(Ton_heating, (Ton + Toffa) - (Ton_heating + Toff_heating)));
   12318            0 :             Toffa = min(Toffa, Ton_heating - Ton);
   12319              :         }
   12320              :     }
   12321              : 
   12322              :     //  Use successive substitution to solve for To
   12323         8930 :     aa = (Gamma * Toffa) - (0.25 / Twet) * pow_2(Gamma) * pow_2(Toffa);
   12324         8930 :     To1 = aa + Tcl;
   12325         8930 :     Error = 1.0;
   12326        19126 :     while (Error > 0.001) {
   12327        10196 :         To2 = aa - Tcl * (std::exp(-To1 / Tcl) - 1.0);
   12328        10196 :         Error = std::abs((To2 - To1) / To1);
   12329        10196 :         To1 = To2;
   12330              :     }
   12331              : 
   12332              :     //  Adjust Sensible Heat Ratio (SHR) using Latent Heat Ratio (LHR) multiplier
   12333              :     //  Floating underflow errors occur when -Ton/Tcl is a large negative number.
   12334              :     //  Cap lower limit at -700 to avoid the underflow errors.
   12335         8930 :     aa = std::exp(max(-700.0, -Ton / Tcl));
   12336              :     //  Calculate latent heat ratio multiplier
   12337         8930 :     LHRmult = max(((Ton - To2) / (Ton + Tcl * (aa - 1.0))), 0.0);
   12338              : 
   12339              :     //  Calculate part-load or "effective" sensible heat ratio
   12340         8930 :     SHReff = 1.0 - (1.0 - SHRss) * LHRmult;
   12341              : 
   12342         8930 :     if (SHReff < SHRss) SHReff = SHRss; // Effective SHR can be less than the steady-state SHR
   12343         8930 :     if (SHReff > 1.0) SHReff = 1.0;     // Effective sensible heat ratio can't be greater than 1.0
   12344              : 
   12345         8930 :     return SHReff;
   12346              : }
   12347              : 
   12348        44594 : void CalcTotCapSHR(EnergyPlusData &state,
   12349              :                    Real64 const InletDryBulb,     // inlet air dry bulb temperature [C]
   12350              :                    Real64 const InletHumRat,      // inlet air humidity ratio [kg water / kg dry air]
   12351              :                    Real64 const InletEnthalpy,    // inlet air specific enthalpy [J/kg]
   12352              :                    Real64 const InletWetBulb,     // inlet air wet bulb temperature [C]
   12353              :                    Real64 const AirMassFlowRatio, // Ratio of actual air mass flow to nominal air mass flow
   12354              :                    Real64 const AirMassFlow,      // actual mass flow for capacity and SHR calculation
   12355              :                    Real64 const TotCapNom,        // nominal total capacity [W]
   12356              :                    Real64 const CBF,              // coil bypass factor
   12357              :                    int const CCapFTemp,           // capacity modifier curve index, function of entering wetbulb
   12358              :                    int const CCapFFlow,           // capacity modifier curve, function of actual flow vs rated flow
   12359              :                    Real64 &TotCap,                // total capacity at the given conditions [W]
   12360              :                    Real64 &SHR,                   // sensible heat ratio at the given conditions
   12361              :                    Real64 const CondInletTemp,    // Condenser inlet temperature [C]
   12362              :                    Real64 const Pressure,         // air pressure [Pa]
   12363              :                    Real64 &TotCapModFac           // capacity modification factor, func of temp and func of flow
   12364              : )
   12365              : {
   12366              : 
   12367              :     // SUBROUTINE INFORMATION:
   12368              :     //       AUTHOR         Fred Buhl using Don Shirey's code
   12369              :     //       DATE WRITTEN   September 2002
   12370              : 
   12371              :     // PURPOSE OF THIS SUBROUTINE:
   12372              :     // Calculates total capacity and sensible heat ratio of a DX coil at the specified conditions
   12373              : 
   12374              :     // METHODOLOGY EMPLOYED:
   12375              :     // With the rated performance data entered by the user, the model employs some of the
   12376              :     // DOE-2.1E curve fits to adjust the capacity and SHR of the unit as a function
   12377              :     // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
   12378              :     // does NOT employ the exact same methodology to calculate performance as DOE-2, although
   12379              :     // some of the DOE-2 curve fits are employed by this model.
   12380              : 
   12381              :     // The model checks for coil dryout conditions, and adjusts the calculated performance
   12382              :     // appropriately.
   12383              : 
   12384              :     // REFERENCES:
   12385              :     // ASHRAE HVAC 2 Toolkit page 4-81.
   12386              :     // Henderson, H.I. Jr., K. Rengarajan and D.B. Shirey, III. 1992.The impact of comfort
   12387              :     // control on air conditioner energy use in humid climates. ASHRAE Transactions 98(2):
   12388              :     // 104-113.
   12389              :     // Henderson, H.I. Jr., Danny Parker and Y.J. Huang. 2000.Improving DOE-2's RESYS routine:
   12390              :     // User Defined Functions to Provide More Accurate Part Load Energy Use and Humidity
   12391              :     // Predictions. Proceedings of ACEEE Conference.
   12392              : 
   12393              :     // Using/Aliasing
   12394              :     using Curve::CurveValue;
   12395              : 
   12396              :     // Locals
   12397              :     // SUBROUTINE ARGUMENT DEFINITIONS:
   12398              :     // and outside drybulb
   12399              : 
   12400              :     // SUBROUTINE PARAMETER DEFINITIONS:
   12401        44594 :     constexpr int MaxIter(30);               // Maximum number of iterations for dry evaporator calculations
   12402        44594 :     constexpr Real64 RF(0.4);                // Relaxation factor for dry evaporator iterations
   12403        44594 :     constexpr Real64 Tolerance(0.01);        // Error tolerance for dry evaporator iterations
   12404        44594 :     constexpr Real64 MinHumRatCalc(0.00001); // Error tolerance for dry evaporator iterations
   12405              : 
   12406              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   12407              :     Real64 InletWetBulbCalc; // calculated inlet wetbulb temperature used for finding dry coil point [C]
   12408              :     Real64 InletHumRatCalc;  // calculated inlet humidity ratio used for finding dry coil point [kg water / kg dry air]
   12409              :     Real64 TotCapTempModFac; // Total capacity modifier (function of entering wetbulb, outside drybulb)
   12410              :     Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs nominal flow)
   12411              :     Real64 hDelta;           // Change in air enthalpy across the cooling coil [J/kg]
   12412              :     Real64 hADP;             // Apparatus dew point enthalpy [J/kg]
   12413              :     Real64 tADP;             // Apparatus dew point temperature [C]
   12414              :     Real64 wADP;             // Apparatus dew point humidity ratio [kg/kg]
   12415              :     Real64 hTinwADP;         // Enthalpy at inlet dry-bulb and wADP [J/kg]
   12416              :     Real64 SHRCalc;          // temporary calculated value of SHR
   12417              :     Real64 TotCapCalc;       // temporary calculated value of total capacity [W]
   12418              :     int Counter;             // Counter for dry evaporator iterations
   12419              :     Real64 werror;           // Deviation of humidity ratio in dry evaporator iteration loop
   12420              : 
   12421              :     //  MaxIter = 30
   12422              :     //  RF = 0.4d0
   12423        44594 :     Counter = 0;
   12424              :     //  Tolerance = 0.01d0
   12425        44594 :     werror = 0.0;
   12426              : 
   12427        44594 :     InletWetBulbCalc = InletWetBulb;
   12428        44594 :     InletHumRatCalc = InletHumRat;
   12429              : 
   12430        44594 :     if (AirMassFlow <= 0.00001) {
   12431            3 :         TotCap = 0.0;
   12432            3 :         SHR = 0.0;
   12433            3 :         return;
   12434              :     }
   12435              : 
   12436              :     //  DO WHILE (ABS(werror) .gt. Tolerance .OR. Counter == 0)
   12437              :     //   Get capacity modifying factor (function of inlet wetbulb & outside drybulb) for off-rated conditions
   12438              :     while (true) {
   12439       158090 :         TotCapTempModFac = CurveValue(state, CCapFTemp, InletWetBulbCalc, CondInletTemp);
   12440              :         //   Get capacity modifying factor (function of mass flow) for off-rated conditions
   12441       158090 :         TotCapFlowModFac = CurveValue(state, CCapFFlow, AirMassFlowRatio);
   12442              :         //   Get total capacity
   12443       158090 :         TotCapCalc = TotCapNom * TotCapFlowModFac * TotCapTempModFac;
   12444              : 
   12445              :         //   Calculate apparatus dew point conditions using TotCap and CBF
   12446       158090 :         hDelta = TotCapCalc / AirMassFlow;
   12447       158090 :         hADP = InletEnthalpy - hDelta / (1.0 - CBF);
   12448       158090 :         tADP = PsyTsatFnHPb(state, hADP, Pressure);
   12449       158090 :         wADP = PsyWFnTdbH(state, tADP, hADP);
   12450       158090 :         hTinwADP = PsyHFnTdbW(InletDryBulb, wADP);
   12451       158090 :         if ((InletEnthalpy - hADP) > 1.e-10) {
   12452       158090 :             SHRCalc = min((hTinwADP - hADP) / (InletEnthalpy - hADP), 1.0);
   12453              :         } else {
   12454            0 :             SHRCalc = 1.0;
   12455              :         }
   12456              :         //   Check for dry evaporator conditions (win < wadp)
   12457       158090 :         if (wADP > InletHumRatCalc || (Counter >= 1 && Counter < MaxIter)) {
   12458       128338 :             if (InletHumRatCalc == 0.0) InletHumRatCalc = MinHumRatCalc;
   12459              :             //      InletHumRatCalc=MAX(InletHumRatCalc,MinHumRatCalc)  ! proposed.
   12460              : 
   12461       128338 :             werror = (InletHumRatCalc - wADP) / InletHumRatCalc;
   12462              :             //     Increase InletHumRatCalc at constant inlet air temp to find coil dry-out point. Then use the
   12463              :             //     capacity at the dry-out point to determine exiting conditions from coil. This is required
   12464              :             //     since the TotCapTempModFac doesn't work properly with dry-coil conditions.
   12465       128338 :             InletHumRatCalc = RF * wADP + (1.0 - RF) * InletHumRatCalc;
   12466       128338 :             InletWetBulbCalc = PsyTwbFnTdbWPb(state, InletDryBulb, InletHumRatCalc, Pressure);
   12467       128338 :             ++Counter;
   12468       128338 :             if (std::abs(werror) > Tolerance) continue; // Recalculate with modified inlet conditions
   12469        14839 :             break;                                      // conditions are satisfied
   12470              :         } else {
   12471              :             break; // conditions are satisfied
   12472              :         }
   12473              :     }
   12474              : 
   12475              :     // END DO
   12476              : 
   12477              :     //  Calculate full load output conditions
   12478        44591 :     if (SHRCalc > 1.0 || Counter > 0) SHRCalc = 1.0;
   12479              : 
   12480        44591 :     SHR = SHRCalc;
   12481        44591 :     TotCap = TotCapCalc;
   12482        44591 :     TotCapModFac = TotCapTempModFac * TotCapFlowModFac;
   12483              : }
   12484              : 
   12485          265 : void CalcMultiSpeedDXCoilCooling(EnergyPlusData &state,
   12486              :                                  int const DXCoilNum,     // the number of the DX heating coil to be simulated
   12487              :                                  Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
   12488              :                                  Real64 const CycRatio,   // cycling part load ratio
   12489              :                                  int const SpeedNum,      // Speed number
   12490              :                                  HVAC::FanOp const fanOp, // Sets fan control to FanOp::Cycling or FanOp::Continuous
   12491              :                                  HVAC::CompressorOp const compressorOp, // Compressor on/off; 1=on, 0=off
   12492              :                                  int const SingleMode                   // Single mode operation Yes/No; 1=Yes, 0=No
   12493              : )
   12494              : {
   12495              : 
   12496              :     // SUBROUTINE INFORMATION:
   12497              :     //       AUTHOR         Lixing Gu, FSEC
   12498              :     //       DATE WRITTEN   June 2007
   12499              :     //       MODIFIED       April 2010, Chandan sharma, FSEC, added basin heater
   12500              :     //       RE-ENGINEERED  Revised based on CalcMultiSpeedDXCoil
   12501              : 
   12502              :     // PURPOSE OF THIS SUBROUTINE:
   12503              :     // Calculates the air-side performance and electrical energy use of a direct-
   12504              :     // expansion, air-cooled cooling unit with a multispeed compressor.
   12505              : 
   12506              :     // METHODOLOGY EMPLOYED:
   12507              :     // Uses the same methodology as the single speed DX unit model (SUBROUTINE CalcDoe2DXCoil).
   12508              :     // In addition it assumes that the unit performance is obtained by interpolating between
   12509              :     // the performance at high speed and that at low speed. If the output needed is below
   12510              :     // that produced at low speed, the compressor cycles between off and low speed.
   12511              : 
   12512              :     // Using/Aliasing
   12513              :     using Curve::CurveValue;
   12514          265 :     Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
   12515          265 :     Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
   12516          265 :     auto &MSHPWasteHeat = state.dataHVACGlobal->MSHPWasteHeat;
   12517              : 
   12518              :     // Locals
   12519              :     // SUBROUTINE ARGUMENT DEFINITIONS:
   12520              :     // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
   12521              : 
   12522              :     // SUBROUTINE PARAMETER DEFINITIONS:
   12523              :     static constexpr std::string_view RoutineName("CalcMultiSpeedDXCoilCooling");
   12524              :     static constexpr std::string_view RoutineNameHighSpeedAlt("CalcMultiSpeedDXCoilCooling highspeed");
   12525              : 
   12526              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   12527              :     Real64 AirMassFlow;         // dry air mass flow rate through coil [kg/s]
   12528              :     Real64 InletAirWetBulbC;    // wetbulb temperature of inlet air [C]
   12529              :     Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
   12530              :     Real64 InletAirEnthalpy;    // inlet air enthalpy [J/kg]
   12531              :     Real64 InletAirHumRat;      // inlet air humidity ratio [kg/kg]
   12532              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12533              :     // REAL(r64)   :: InletAirPressure    ! inlet air pressure [Pa]
   12534              :     Real64 OutletAirDryBulbTemp;    // outlet air dry bulb temperature [C]
   12535              :     Real64 OutletAirEnthalpy;       // outlet air enthalpy [J/kg]
   12536              :     Real64 OutletAirHumRat;         // outlet air humidity ratio [kg/kg]
   12537              :     Real64 OutletAirDryBulbTempSat; // outlet air dry bulb temp at saturation at the outlet enthalpy [C]
   12538              :     Real64 LSOutletAirDryBulbTemp;  // low speed outlet air dry bulb temperature [C]
   12539              :     Real64 LSOutletAirEnthalpy;     // low speed outlet air enthalpy [J/kg]
   12540              :     Real64 LSOutletAirHumRat;       // low speed outlet air humidity ratio [kg/kg]
   12541              :     Real64 HSOutletAirDryBulbTemp;  // high speed outlet air dry bulb temperature [C]
   12542              :     Real64 HSOutletAirEnthalpy;     // high speed outlet air enthalpy [J/kg]
   12543              :     Real64 HSOutletAirHumRat;       // high speed outlet air humidity ratio [kg/kg]
   12544              :     Real64 hDelta;                  // Change in air enthalpy across the cooling coil [J/kg]
   12545              :     Real64 hTinwout;                // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
   12546              :     Real64 hADP;                    // Apparatus dew point enthalpy [J/kg]
   12547              :     Real64 tADP;                    // Apparatus dew point temperature [C]
   12548              :     Real64 wADP;                    // Apparatus dew point humidity ratio [kg/kg]
   12549              :     Real64 hTinwADP;                // Enthalpy at inlet dry-bulb and wADP [J/kg]
   12550              :     Real64 RatedCBFHS;              // coil bypass factor at rated conditions (high speed)
   12551              :     Real64 CBFHS;                   // coil bypass factor at max flow (high speed)
   12552              :     Real64 RatedCBFLS;              // coil bypass factor at rated conditions (low speed)
   12553              :     Real64 CBFLS;                   // coil bypass factor at max flow (low speed)
   12554              :     Real64 TotCapHS;                // total capacity at high speed [W]
   12555              :     Real64 SHRHS;                   // sensible heat ratio at high speed
   12556              :     Real64 TotCapLS;                // total capacity at low speed [W]
   12557              :     Real64 SHRLS;                   // sensible heat ratio at low speed
   12558              :     Real64 EIRTempModFacHS;         // EIR modifier (function of entering wetbulb, outside drybulb) (high speed)
   12559              :     Real64 EIRFlowModFacHS;         // EIR modifier (function of actual supply air flow vs rated flow) (high speed)
   12560              :     Real64 EIRHS;                   // EIR at off rated conditions (high speed)
   12561              :     Real64 EIRTempModFacLS;         // EIR modifier (function of entering wetbulb, outside drybulb) (low speed)
   12562              :     Real64 EIRFlowModFacLS;         // EIR modifier (function of actual supply air flow vs rated flow) (low speed)
   12563              :     Real64 EIRLS;                   // EIR at off rated conditions (low speed)
   12564              :     Real64 SHR;                     // sensible heat ratio at current speed
   12565              :     Real64 EIR;                     // EIR at current speed
   12566              :     Real64 CBF;                     // CBFNom adjusted for actual air mass flow rate
   12567              :     Real64 PLF;                     // Part load factor, accounts for thermal lag at compressor startup, used in
   12568              :     // power calculation
   12569              :     Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
   12570              :     // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
   12571              :     Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
   12572              :     // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
   12573              :     Real64 RhoAir;                // Density of air [kg/m3]
   12574              :     Real64 RhoWater;              // Density of water [kg/m3]
   12575              :     Real64 CondAirMassFlow;       // Condenser air mass flow rate [kg/s]
   12576              :     Real64 EvapCondPumpElecPower; // Evaporative condenser electric pump power [W]
   12577          265 :     constexpr int DXMode(1);      // Performance mode for MultiMode DX coil; Always 1 for other coil types
   12578              :     Real64 OutdoorDryBulb;        // Outdoor dry-bulb temperature at condenser (C)
   12579              :     Real64 OutdoorWetBulb;        // Outdoor wet-bulb temperature at condenser (C)
   12580              :     Real64 OutdoorHumRat;         // Outdoor humidity ratio at condenser (kg/kg)
   12581              :     Real64 OutdoorPressure;       // Outdoor barometric pressure at condenser (Pa)
   12582              :     int SpeedNumHS;               // High speed number
   12583              :     int SpeedNumLS;               // Low speed number
   12584              :     Real64 SHRUnadjusted;         // Temp SHR
   12585              :     Real64 QLatRated;             // Qlatent at rated conditions of indoor(TDB,TWB)=(26.7C,19.4C)
   12586              :     Real64 QLatActual;            // Qlatent at actual operating conditions
   12587              :     Real64 AirMassFlowRatioLS;    // airflow ratio at low speed
   12588              :     Real64 AirMassFlowRatioHS;    // airflow ratio at high speed
   12589              :     Real64 WasteHeatLS;           // Waste heat at low speed
   12590              :     Real64 WasteHeatHS;           // Waste heat at high speed
   12591              :     Real64 LSElecCoolingPower;    // low speed power [W]
   12592              :     Real64 HSElecCoolingPower;    // high speed power [W]
   12593              :     Real64 CrankcaseHeatingPower; // Power due to crank case heater
   12594              :     Real64 AirVolumeFlowRate;     // Air volume flow rate across the heating coil
   12595              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total heating capacity
   12596              : 
   12597          265 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   12598              : 
   12599          265 :     if (thisDXCoil.CondenserInletNodeNum(DXMode) != 0) {
   12600           74 :         OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Press;
   12601              :         // If node is not connected to anything, pressure = default, use weather data
   12602           74 :         if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   12603           74 :             OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   12604           74 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   12605           74 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   12606           74 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   12607              :         } else {
   12608            0 :             OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Temp;
   12609            0 :             OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).HumRat;
   12610            0 :             OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, RoutineName);
   12611              :         }
   12612           74 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
   12613            0 :             auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   12614            0 :             OutdoorDryBulb = secZoneHB.ZT;
   12615            0 :             OutdoorHumRat = secZoneHB.airHumRat;
   12616            0 :             OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   12617            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   12618              :         }
   12619          191 :     } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
   12620            0 :         auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   12621            0 :         OutdoorDryBulb = secZoneHB.ZT;
   12622            0 :         OutdoorHumRat = secZoneHB.airHumRat;
   12623            0 :         OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   12624            0 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   12625              :     } else {
   12626          191 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   12627          191 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   12628          191 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   12629          191 :         OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   12630              :     }
   12631              : 
   12632          265 :     if (SpeedNum > 1) {
   12633           59 :         SpeedNumLS = SpeedNum - 1;
   12634           59 :         SpeedNumHS = SpeedNum;
   12635           59 :         if (SpeedNum > thisDXCoil.NumOfSpeeds) {
   12636            0 :             SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
   12637            0 :             SpeedNumHS = thisDXCoil.NumOfSpeeds;
   12638              :         }
   12639              :     } else {
   12640          206 :         SpeedNumLS = 1;
   12641          206 :         SpeedNumHS = 1;
   12642              :     }
   12643              : 
   12644          265 :     MSHPWasteHeat = 0.0;
   12645          265 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   12646          265 :     AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
   12647          265 :     AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
   12648          265 :     if ((AirMassFlow > 0.0) && (CycRatio > 0.0) && (MSHPMassFlowRateHigh == 0.0)) {
   12649            0 :         ShowSevereError(
   12650              :             state,
   12651            0 :             format("CalcMultiSpeedDXCoilCooling: {} \"{} Developer error - inconsistent airflow rates.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   12652            0 :         if (MSHPMassFlowRateLow == 0.0 && SpeedNum > 1) {
   12653            0 :             ShowContinueError(state,
   12654              :                               "When AirMassFlow > 0.0 and CycRatio > 0.0 and SpeedNum > 1, then MSHPMassFlowRateLow and MSHPMassFlowRateHigh "
   12655              :                               "must also be > 0.0");
   12656            0 :             ShowContinueErrorTimeStamp(state, "");
   12657            0 :             ShowContinueError(state,
   12658            0 :                               format("AirMassFlow={:.3R},CycRatio={:.3R},SpeedNum={:.0R}, MSHPMassFlowRateLow={:.3R}, MSHPMassFlowRateHigh={:.3R}",
   12659              :                                      AirMassFlow,
   12660            0 :                                      double(SpeedNum),
   12661              :                                      CycRatio,
   12662              :                                      MSHPMassFlowRateLow,
   12663              :                                      MSHPMassFlowRateHigh));
   12664            0 :             ShowFatalError(state, "Preceding condition(s) causes termination.");
   12665              :         } else {
   12666            0 :             ShowContinueError(state, "When AirMassFlow > 0.0 and CycRatio > 0.0, then MSHPMassFlowRateHigh must also be > 0.0");
   12667            0 :             ShowContinueErrorTimeStamp(state, "");
   12668            0 :             ShowContinueError(state,
   12669            0 :                               format("AirMassFlow={:.3R},CycRatio={:.3R}, MSHPMassFlowRateHigh={:.3R}", AirMassFlow, CycRatio, MSHPMassFlowRateHigh));
   12670            0 :             ShowFatalError(state, "Preceding condition(s) causes termination.");
   12671              :         }
   12672          265 :     } else if (CycRatio > 1.0 || SpeedRatio > 1.0) {
   12673            0 :         ShowSevereError(
   12674              :             state,
   12675            0 :             format("CalcMultiSpeedDXCoilCooling: {} \"{} Developer error - inconsistent speed ratios.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   12676            0 :         ShowContinueError(state, "CycRatio and SpeedRatio must be between 0.0 and 1.0");
   12677            0 :         ShowContinueErrorTimeStamp(state, "");
   12678            0 :         ShowContinueError(state, format("CycRatio={:.1R}, SpeedRatio = {:.1R}", CycRatio, SpeedRatio));
   12679            0 :         ShowFatalError(state, "Preceding condition(s) causes termination.");
   12680              :     }
   12681              : 
   12682          265 :     thisDXCoil.PartLoadRatio = 0.0;
   12683          265 :     state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
   12684          265 :     thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
   12685          265 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   12686          265 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   12687          265 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   12688              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12689              :     // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
   12690              :     // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
   12691          265 :     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
   12692          265 :     if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Air) {
   12693          265 :         CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
   12694            0 :     } else if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
   12695              :         // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   12696            0 :         CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.MSEvapCondEffect(SpeedNumHS));
   12697            0 :         CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure, RoutineName);
   12698              :     }
   12699          265 :     if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
   12700          168 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   12701          168 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   12702            2 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
   12703              :         }
   12704              :     } else {
   12705           97 :         CrankcaseHeatingPower = 0.0;
   12706              :     }
   12707              : 
   12708          230 :     if ((AirMassFlow > 0.0 && CondInletTemp >= thisDXCoil.MinOATCompressor) && (thisDXCoil.availSched->getCurrentVal() > 0.0) &&
   12709          495 :         ((SpeedRatio > 0.0 && SingleMode == 0) || CycRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On)) {
   12710              : 
   12711           99 :         RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat, RoutineName);
   12712           99 :         if (SpeedNum > 1 && SingleMode == 0) {
   12713              : 
   12714              :             // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at low speed
   12715           21 :             AirVolumeFlowRate = MSHPMassFlowRateLow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   12716              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12717              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   12718           21 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
   12719           21 :             if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   12720           26 :                  (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
   12721            5 :                 state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
   12722            5 :                 if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
   12723            2 :                     ShowWarningMessage(
   12724              :                         state,
   12725            2 :                         format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
   12726            1 :                                thisDXCoil.DXCoilType,
   12727            1 :                                thisDXCoil.Name,
   12728              :                                SpeedNumLS));
   12729            2 :                     ShowContinueErrorTimeStamp(state, "");
   12730            2 :                     ShowContinueError(state,
   12731            2 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   12732            1 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   12733            1 :                                              HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   12734              :                                              VolFlowperRatedTotCap));
   12735            2 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   12736            3 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   12737              :                 }
   12738           40 :                 ShowRecurringWarningErrorAtEnd(state,
   12739           10 :                                                format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
   12740              :                                                       "at speed {} error continues...",
   12741            5 :                                                       thisDXCoil.DXCoilType,
   12742            5 :                                                       thisDXCoil.Name,
   12743              :                                                       SpeedNumLS),
   12744              :                                                thisDXCoil.MSErrIndex(SpeedNumLS),
   12745              :                                                VolFlowperRatedTotCap,
   12746              :                                                VolFlowperRatedTotCap);
   12747              :             }
   12748              : 
   12749              :             // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at high speed
   12750           21 :             AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   12751              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12752              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   12753           21 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
   12754           21 :             if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   12755           21 :                  (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
   12756            0 :                 state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
   12757            0 :                 if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
   12758            0 :                     ShowWarningMessage(
   12759              :                         state,
   12760            0 :                         format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
   12761            0 :                                thisDXCoil.DXCoilType,
   12762            0 :                                thisDXCoil.Name,
   12763              :                                SpeedNumHS));
   12764            0 :                     ShowContinueErrorTimeStamp(state, "");
   12765            0 :                     ShowContinueError(state,
   12766            0 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   12767            0 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   12768            0 :                                              HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   12769              :                                              VolFlowperRatedTotCap));
   12770            0 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   12771            0 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   12772              :                 }
   12773            0 :                 ShowRecurringWarningErrorAtEnd(state,
   12774            0 :                                                format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
   12775              :                                                       "at speed {} error continues...",
   12776            0 :                                                       thisDXCoil.DXCoilType,
   12777            0 :                                                       thisDXCoil.Name,
   12778              :                                                       SpeedNumHS),
   12779              :                                                thisDXCoil.MSErrIndex(SpeedNumHS),
   12780              :                                                VolFlowperRatedTotCap,
   12781              :                                                VolFlowperRatedTotCap);
   12782              :             }
   12783              : 
   12784              :             // Adjust high speed coil bypass factor for actual maximum air flow rate.
   12785           21 :             RatedCBFHS = thisDXCoil.MSRatedCBF(SpeedNumHS);
   12786           21 :             CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS), MSHPMassFlowRateHigh);
   12787           21 :             RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNumLS);
   12788           21 :             CBFLS = AdjustCBF(RatedCBFLS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS), MSHPMassFlowRateLow);
   12789              :             // get low speed total capacity and SHR at current conditions
   12790           63 :             CalcTotCapSHR(state,
   12791              :                           InletAirDryBulbTemp,
   12792              :                           InletAirHumRat,
   12793              :                           InletAirEnthalpy,
   12794              :                           InletAirWetBulbC,
   12795              :                           AirMassFlowRatioLS,
   12796              :                           MSHPMassFlowRateLow,
   12797           21 :                           thisDXCoil.MSRatedTotCap(SpeedNumLS),
   12798              :                           CBFLS,
   12799           21 :                           thisDXCoil.MSCCapFTemp(SpeedNumLS),
   12800           21 :                           thisDXCoil.MSCCapFFlow(SpeedNumLS),
   12801              :                           TotCapLS,
   12802              :                           SHRLS,
   12803              :                           CondInletTemp,
   12804              :                           OutdoorPressure,
   12805           21 :                           thisDXCoil.capModFacTotal);
   12806              :             // get low speed outlet conditions
   12807           21 :             hDelta = TotCapLS / MSHPMassFlowRateLow;
   12808              :             // Calculate new apparatus dew point conditions
   12809           21 :             hADP = InletAirEnthalpy - hDelta / (1.0 - CBFLS);
   12810           21 :             tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineNameHighSpeedAlt);
   12811              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12812              :             //  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   12813           21 :             wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
   12814           21 :             hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   12815              :             // get corresponding SHR
   12816           21 :             if ((InletAirEnthalpy - hADP) > 1.e-10) {
   12817           21 :                 SHRLS = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   12818              :             } else {
   12819            0 :                 SHRLS = 1.0;
   12820              :             }
   12821              :             // cr8918    SHRLS = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
   12822              :             // get low speed outlet conditions
   12823           21 :             LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
   12824           21 :             hTinwout = InletAirEnthalpy - (1.0 - SHRLS) * hDelta;
   12825           21 :             LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
   12826           21 :             LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
   12827           21 :             OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
   12828           21 :             if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   12829            1 :                 LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   12830            1 :                 LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineName);
   12831              :             }
   12832              : 
   12833              :             // get high speed total capacity and SHR at current conditions
   12834              : 
   12835           63 :             CalcTotCapSHR(state,
   12836              :                           InletAirDryBulbTemp,
   12837              :                           InletAirHumRat,
   12838              :                           InletAirEnthalpy,
   12839              :                           InletAirWetBulbC,
   12840              :                           AirMassFlowRatioHS,
   12841              :                           MSHPMassFlowRateHigh,
   12842           21 :                           thisDXCoil.MSRatedTotCap(SpeedNumHS),
   12843              :                           CBFHS,
   12844           21 :                           thisDXCoil.MSCCapFTemp(SpeedNumHS),
   12845           21 :                           thisDXCoil.MSCCapFFlow(SpeedNumHS),
   12846              :                           TotCapHS,
   12847              :                           SHRHS,
   12848              :                           CondInletTemp,
   12849              :                           OutdoorPressure,
   12850           21 :                           thisDXCoil.capModFacTotal);
   12851           21 :             hDelta = TotCapHS / MSHPMassFlowRateHigh;
   12852              :             // Calculate new apparatus dew point conditions
   12853           21 :             hADP = InletAirEnthalpy - hDelta / (1.0 - CBFHS);
   12854           21 :             tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
   12855              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12856              :             //  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   12857           21 :             wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
   12858           21 :             hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   12859              :             // get corresponding SHR
   12860           21 :             if ((InletAirEnthalpy - hADP) > 1.e-10) {
   12861           21 :                 SHRHS = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   12862              :             } else {
   12863            0 :                 SHRHS = 1.0;
   12864              :             }
   12865              :             // cr8918    SHRHS = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
   12866              :             // get the part load factor that will account for cycling losses
   12867           21 :             PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), SpeedRatio);
   12868           21 :             if (PLF < 0.7) {
   12869            0 :                 PLF = 0.7;
   12870              :             }
   12871              :             // calculate the run time fraction
   12872           21 :             thisDXCoil.CoolingCoilRuntimeFraction = SpeedRatio / PLF;
   12873           21 :             thisDXCoil.PartLoadRatio = SpeedRatio;
   12874              : 
   12875           21 :             if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
   12876            0 :                 thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   12877              :             }
   12878              : 
   12879              :             // get high speed outlet conditions
   12880           21 :             HSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
   12881           21 :             hTinwout = InletAirEnthalpy - (1.0 - SHRHS) * hDelta;
   12882           21 :             HSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
   12883           21 :             HSOutletAirDryBulbTemp = PsyTdbFnHW(HSOutletAirEnthalpy, HSOutletAirHumRat);
   12884           21 :             OutletAirDryBulbTempSat = PsyTsatFnHPb(state, HSOutletAirEnthalpy, OutdoorPressure, RoutineName);
   12885           21 :             if (HSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   12886            1 :                 HSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   12887            1 :                 HSOutletAirHumRat = PsyWFnTdbH(state, HSOutletAirDryBulbTemp, HSOutletAirEnthalpy, RoutineName);
   12888              :             }
   12889              : 
   12890              :             //  If constant fan with cycling compressor, call function to determine "effective SHR"
   12891              :             //  which includes the part-load degradation on latent capacity
   12892           21 :             if (thisDXCoil.LatentImpact && fanOp == HVAC::FanOp::Continuous && SpeedRatio > 0.0) {
   12893            0 :                 QLatRated = thisDXCoil.MSRatedTotCap(SpeedNumHS) * (1.0 - thisDXCoil.MSRatedSHR(SpeedNumHS));
   12894            0 :                 QLatActual = TotCapHS * (1.0 - SHRHS);
   12895            0 :                 SHRUnadjusted = SHRHS;
   12896            0 :                 SHR = CalcEffectiveSHR(state,
   12897              :                                        DXCoilNum,
   12898              :                                        SHRHS,
   12899              :                                        thisDXCoil.CoolingCoilRuntimeFraction,
   12900              :                                        QLatRated,
   12901              :                                        QLatActual,
   12902              :                                        InletAirDryBulbTemp,
   12903              :                                        InletAirWetBulbC,
   12904              :                                        SpeedNumHS);
   12905              :                 // Calculate full load output conditions
   12906            0 :                 if (SHR > 1.0) SHR = 1.0;
   12907            0 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   12908            0 :                 if (SHR < 1.0) {
   12909            0 :                     HSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
   12910              :                 } else {
   12911            0 :                     HSOutletAirHumRat = InletAirHumRat;
   12912              :                 }
   12913            0 :                 HSOutletAirDryBulbTemp = PsyTdbFnHW(HSOutletAirEnthalpy, HSOutletAirHumRat);
   12914              :             }
   12915              : 
   12916              :             // get high speed EIR at current conditions
   12917           21 :             EIRTempModFacHS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirWetBulbC, CondInletTemp);
   12918           21 :             EIRFlowModFacHS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
   12919           21 :             EIRHS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumHS) * EIRFlowModFacHS * EIRTempModFacHS;
   12920              :             // get low speed EIR at current conditions
   12921           21 :             EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirWetBulbC, CondInletTemp);
   12922           21 :             EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
   12923           21 :             EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFacLS * EIRFlowModFacLS;
   12924              : 
   12925              :             // get current total capacity, SHR, EIR
   12926           21 :             if (SpeedRatio >= 1.0) {
   12927           15 :                 SHR = SHRHS;
   12928           15 :                 EIR = EIRHS;
   12929           15 :                 CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS);
   12930           15 :                 EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS);
   12931              :             } else {
   12932            6 :                 EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
   12933            6 :                 SHR = SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS;
   12934            6 :                 CondAirMassFlow =
   12935            6 :                     RhoAir * (SpeedRatio * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS) + (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondAirFlow(SpeedNumLS));
   12936            6 :                 EvapCondPumpElecPower = SpeedRatio * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS) +
   12937            6 :                                         (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumLS);
   12938              :             }
   12939              : 
   12940              :             // Outlet calculation
   12941           21 :             Real64 SensibleOutputLS(0.0); // low speed sensible output rate
   12942           21 :             Real64 LatentOutputLS(0.0);   // low speed latent output rate
   12943           21 :             Real64 TotalOutputLS(0.0);    // low speed total output rate
   12944           21 :             Real64 SensibleOutputHS(0.0); // high speed sensible output rate
   12945           21 :             Real64 LatentOutputHS(0.0);   // high speed latent output rate
   12946           21 :             Real64 TotalOutputHS(0.0);    // high speed total output rate
   12947           21 :             CalcComponentSensibleLatentOutput(MSHPMassFlowRateLow,
   12948              :                                               InletAirDryBulbTemp,
   12949              :                                               InletAirHumRat,
   12950              :                                               LSOutletAirDryBulbTemp,
   12951              :                                               LSOutletAirHumRat,
   12952              :                                               SensibleOutputLS,
   12953              :                                               LatentOutputLS,
   12954              :                                               TotalOutputLS);
   12955           21 :             CalcComponentSensibleLatentOutput(MSHPMassFlowRateHigh,
   12956              :                                               InletAirDryBulbTemp,
   12957              :                                               InletAirHumRat,
   12958              :                                               HSOutletAirDryBulbTemp,
   12959              :                                               HSOutletAirHumRat,
   12960              :                                               SensibleOutputHS,
   12961              :                                               LatentOutputHS,
   12962              :                                               TotalOutputHS);
   12963           21 :             thisDXCoil.TotalCoolingEnergyRate = TotalOutputHS * SpeedRatio + TotalOutputLS * (1.0 - SpeedRatio);
   12964           21 :             thisDXCoil.SensCoolingEnergyRate = SensibleOutputHS * SpeedRatio + SensibleOutputLS * (1.0 - SpeedRatio);
   12965           21 :             thisDXCoil.LatCoolingEnergyRate = LatentOutputHS * SpeedRatio + LatentOutputLS * (1.0 - SpeedRatio);
   12966              :             // Average outlet enthalpy
   12967           21 :             OutletAirEnthalpy = InletAirEnthalpy - thisDXCoil.TotalCoolingEnergyRate / thisDXCoil.InletAirMassFlowRate;
   12968              : 
   12969           21 :             if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
   12970              :             // Update outlet conditions
   12971           21 :             if (SpeedRatio == 0.0 && fanOp == HVAC::FanOp::Cycling) {
   12972            3 :                 OutletAirEnthalpy = LSOutletAirEnthalpy;
   12973            3 :                 OutletAirHumRat = LSOutletAirHumRat;
   12974            3 :                 OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
   12975           18 :             } else if (SpeedRatio >= 1.0 && fanOp == HVAC::FanOp::Cycling) {
   12976            6 :                 OutletAirEnthalpy = HSOutletAirEnthalpy;
   12977            6 :                 OutletAirHumRat = HSOutletAirHumRat;
   12978            6 :                 OutletAirDryBulbTemp = HSOutletAirDryBulbTemp;
   12979              :             } else {
   12980           12 :                 OutletAirHumRat =
   12981           12 :                     ((HSOutletAirHumRat * SpeedRatio * MSHPMassFlowRateHigh) + (LSOutletAirHumRat * (1.0 - SpeedRatio) * MSHPMassFlowRateLow)) /
   12982           12 :                     thisDXCoil.InletAirMassFlowRate;
   12983           12 :                 OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   12984           12 :                 if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   12985            0 :                     OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   12986            0 :                     OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineName);
   12987            0 :                     CalcComponentSensibleLatentOutput(AirMassFlow,
   12988              :                                                       InletAirDryBulbTemp,
   12989              :                                                       InletAirHumRat,
   12990              :                                                       OutletAirDryBulbTemp,
   12991              :                                                       OutletAirHumRat,
   12992            0 :                                                       thisDXCoil.SensCoolingEnergyRate,
   12993            0 :                                                       thisDXCoil.LatCoolingEnergyRate,
   12994            0 :                                                       thisDXCoil.TotalCoolingEnergyRate);
   12995              :                 }
   12996              :             }
   12997              : 
   12998           21 :             LSElecCoolingPower = TotCapLS * EIRLS;
   12999           21 :             HSElecCoolingPower = TotCapHS * EIRHS;
   13000              : 
   13001              :             // Power calculation
   13002           21 :             if (!thisDXCoil.PLRImpact) {
   13003           21 :                 thisDXCoil.ElecCoolingPower = SpeedRatio * HSElecCoolingPower + (1.0 - SpeedRatio) * LSElecCoolingPower;
   13004              :             } else {
   13005            0 :                 thisDXCoil.ElecCoolingPower =
   13006            0 :                     thisDXCoil.CoolingCoilRuntimeFraction * HSElecCoolingPower + (1.0 - thisDXCoil.CoolingCoilRuntimeFraction) * LSElecCoolingPower;
   13007              :             }
   13008              :             // Now reset runtime fraction to 1.0 (because LS is running the full timestep)
   13009           21 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
   13010              : 
   13011              :             //   Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
   13012           21 :             state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
   13013              : 
   13014              :             // Waste heat calculation
   13015              :             // TODO: waste heat not considered even if defined in Cooling:DX:MultiSpeed, N16, \field Speed 1 Rated Waste Heat Fraction of
   13016              :             // Power Input
   13017           21 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   13018            8 :                 if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
   13019            7 :                     WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
   13020              :                 } else {
   13021            1 :                     WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
   13022            1 :                                   thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
   13023              :                 }
   13024            8 :                 if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
   13025            7 :                     WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
   13026              :                 } else {
   13027            1 :                     WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
   13028            1 :                                   thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
   13029              :                 }
   13030            8 :                 thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
   13031            8 :                 if (thisDXCoil.MSHPHeatRecActive) {
   13032            1 :                     MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
   13033              :                 }
   13034              :             }
   13035              : 
   13036              :             // Energy use for other fuel types
   13037           21 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   13038            8 :                 thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
   13039            8 :                 thisDXCoil.ElecCoolingPower = 0.0;
   13040              :             }
   13041              : 
   13042           21 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   13043           21 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   13044           21 :             thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
   13045           21 :             thisDXCoil.CrankcaseHeaterPower = 0.0;
   13046              : 
   13047           99 :         } else if (CycRatio > 0.0) {
   13048              : 
   13049           78 :             if (fanOp == HVAC::FanOp::Cycling) AirMassFlow /= CycRatio;
   13050           78 :             if (fanOp == HVAC::FanOp::Continuous) AirMassFlow = MSHPMassFlowRateHigh;
   13051              : 
   13052              :             // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at low speed
   13053           78 :             AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   13054              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13055              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   13056           78 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
   13057           78 :             if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   13058           99 :                  (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
   13059           21 :                 state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
   13060           21 :                 if (thisDXCoil.MSErrIndex(SpeedNum) == 0) {
   13061            4 :                     ShowWarningMessage(
   13062              :                         state,
   13063            4 :                         format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
   13064            2 :                                thisDXCoil.DXCoilType,
   13065            2 :                                thisDXCoil.Name,
   13066              :                                SpeedNum));
   13067            4 :                     ShowContinueErrorTimeStamp(state, "");
   13068            4 :                     ShowContinueError(state,
   13069            4 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   13070            2 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13071            2 :                                              HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13072              :                                              VolFlowperRatedTotCap));
   13073            4 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   13074            6 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   13075              :                 }
   13076          168 :                 ShowRecurringWarningErrorAtEnd(state,
   13077           42 :                                                format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
   13078              :                                                       "at speed {} error continues...",
   13079           21 :                                                       thisDXCoil.DXCoilType,
   13080           21 :                                                       thisDXCoil.Name,
   13081              :                                                       SpeedNumHS),
   13082              :                                                thisDXCoil.MSErrIndex(SpeedNumHS),
   13083              :                                                VolFlowperRatedTotCap,
   13084              :                                                VolFlowperRatedTotCap);
   13085              :             }
   13086              : 
   13087           78 :             if (thisDXCoil.CondenserType(SpeedNum) == DataHeatBalance::RefrigCondenserType::Evap) {
   13088              :                 // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   13089            0 :                 CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.MSEvapCondEffect(SpeedNum));
   13090            0 :                 CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure, RoutineName);
   13091              :             }
   13092              : 
   13093           78 :             RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNum);
   13094           78 :             CBFLS = AdjustCBF(RatedCBFLS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNum), MSHPMassFlowRateHigh);
   13095              : 
   13096              :             // Adjust low speed coil bypass factor for actual flow rate.
   13097              :             // CBF = AdjustCBF(DXCoil(DXCoilNum)%RatedCBF2,DXCoil(DXCoilNum)%RatedAirMassFlowRate2,AirMassFlow)
   13098              :             // get low speed total capacity and SHR at current conditions
   13099          234 :             CalcTotCapSHR(state,
   13100              :                           InletAirDryBulbTemp,
   13101              :                           InletAirHumRat,
   13102              :                           InletAirEnthalpy,
   13103              :                           InletAirWetBulbC,
   13104              :                           AirMassFlowRatioLS,
   13105              :                           MSHPMassFlowRateHigh,
   13106           78 :                           thisDXCoil.MSRatedTotCap(SpeedNum),
   13107              :                           CBFLS,
   13108           78 :                           thisDXCoil.MSCCapFTemp(SpeedNum),
   13109           78 :                           thisDXCoil.MSCCapFFlow(SpeedNum),
   13110              :                           TotCapLS,
   13111              :                           SHRLS,
   13112              :                           CondInletTemp,
   13113              :                           OutdoorPressure,
   13114           78 :                           thisDXCoil.capModFacTotal);
   13115              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13116              :             //  Node(DXCoil(DXCoilNum)%AirInNode)%Press)
   13117           78 :             hDelta = TotCapLS / AirMassFlow;
   13118              :             // Adjust CBF for off-nominal flow
   13119           78 :             CBF = AdjustCBF(thisDXCoil.MSRatedCBF(SpeedNum), thisDXCoil.MSRatedAirMassFlowRate(SpeedNum), AirMassFlow);
   13120              :             // Calculate new apparatus dew point conditions
   13121           78 :             hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
   13122           78 :             tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
   13123              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13124              :             //  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   13125           78 :             wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
   13126           78 :             hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   13127              :             // get corresponding SHR
   13128           78 :             if ((InletAirEnthalpy - hADP) > 1.e-10) {
   13129           78 :                 SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   13130              :             } else {
   13131            0 :                 SHR = 1.0;
   13132              :             }
   13133              :             // cr8918    SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
   13134              : 
   13135              :             // get the part load factor that will account for cycling losses
   13136           78 :             PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNum), CycRatio);
   13137           78 :             if (fanOp == HVAC::FanOp::Cycling && CycRatio == 1.0 && PLF != 1.0) {
   13138            0 :                 if (thisDXCoil.PLFErrIndex == 0) {
   13139            0 :                     ShowWarningMessage(state,
   13140            0 :                                        format("The PLF curve value for DX cooling coil {} ={:.2R} for part-load ratio = 1", thisDXCoil.Name, PLF));
   13141            0 :                     ShowContinueError(state, "PLF curve value must be = 1.0 and has been reset to 1.0. Simulation is continuing.");
   13142            0 :                     ShowContinueErrorTimeStamp(state, "");
   13143              :                 }
   13144            0 :                 ShowRecurringWarningErrorAtEnd(
   13145            0 :                     state, thisDXCoil.Name + "\": DX cooling coil PLF curve value <> 1.0 warning continues...", thisDXCoil.PLFErrIndex, PLF, PLF);
   13146            0 :                 PLF = 1.0;
   13147              :             }
   13148              : 
   13149           78 :             if (PLF < 0.7) {
   13150            0 :                 PLF = 0.7;
   13151              :             }
   13152              :             // calculate the run time fraction
   13153           78 :             thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
   13154           78 :             thisDXCoil.PartLoadRatio = CycRatio;
   13155              : 
   13156           78 :             if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
   13157            0 :                 thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   13158              :             }
   13159              : 
   13160              :             // get low speed outlet conditions
   13161           78 :             LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
   13162           78 :             hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   13163           78 :             LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
   13164           78 :             LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
   13165           78 :             OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
   13166           78 :             if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   13167            0 :                 LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   13168            0 :                 LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineName);
   13169              :             }
   13170              : 
   13171              :             //  If constant fan with cycling compressor, call function to determine "effective SHR"
   13172              :             //  which includes the part-load degradation on latent capacity
   13173           78 :             if (fanOp == HVAC::FanOp::Continuous) {
   13174           41 :                 QLatRated = thisDXCoil.MSRatedTotCap(SpeedNum) * (1.0 - thisDXCoil.MSRatedSHR(SpeedNum));
   13175           41 :                 QLatActual = TotCapLS * (1.0 - SHR);
   13176           41 :                 SHRUnadjusted = SHR;
   13177           41 :                 SHR = CalcEffectiveSHR(state,
   13178              :                                        DXCoilNum,
   13179              :                                        SHR,
   13180              :                                        thisDXCoil.CoolingCoilRuntimeFraction,
   13181              :                                        QLatRated,
   13182              :                                        QLatActual,
   13183              :                                        InletAirDryBulbTemp,
   13184              :                                        InletAirWetBulbC,
   13185              :                                        SpeedNum);
   13186              :                 // Calculate full load output conditions
   13187           41 :                 if (SHR > 1.0) SHR = 1.0;
   13188           41 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   13189           41 :                 if (SHR < 1.0) {
   13190           33 :                     LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
   13191              :                 } else {
   13192            8 :                     LSOutletAirHumRat = InletAirHumRat;
   13193              :                 }
   13194           41 :                 LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
   13195              :             }
   13196              : 
   13197           78 :             if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
   13198           78 :             if (fanOp == HVAC::FanOp::Continuous) {
   13199              :                 // outlet conditions are average of inlet and low speed weighted by CycRatio
   13200              :                 // Continuous fan, cycling compressor
   13201           41 :                 Real64 CycAirFlowRatio =
   13202           41 :                     CycRatio * AirMassFlow / thisDXCoil.InletAirMassFlowRate; // ratio of compressor on airflow to average timestep airflow
   13203           41 :                 OutletAirEnthalpy = CycAirFlowRatio * LSOutletAirEnthalpy + (1.0 - CycAirFlowRatio) * InletAirEnthalpy;
   13204           41 :                 OutletAirHumRat = CycAirFlowRatio * LSOutletAirHumRat + (1.0 - CycAirFlowRatio) * InletAirHumRat;
   13205           41 :                 OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   13206              :             } else {
   13207           37 :                 OutletAirHumRat = LSOutletAirHumRat;
   13208           37 :                 OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
   13209           37 :                 OutletAirEnthalpy = LSOutletAirEnthalpy;
   13210              :             }
   13211              : 
   13212              :             // get low speed EIR at current conditions
   13213           78 :             EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNum), InletAirWetBulbC, CondInletTemp);
   13214           78 :             EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNum), AirMassFlowRatioLS);
   13215           78 :             EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNum) * EIRTempModFacLS * EIRFlowModFacLS;
   13216              : 
   13217              :             // get the electrical power consumption
   13218           78 :             thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
   13219              :             // calculate cooling output power
   13220              :             //    AirMassFlow = DXCoil(DXCoilNum)%InletAirMassFlowRate
   13221           78 :             CalcComponentSensibleLatentOutput(AirMassFlow,
   13222              :                                               InletAirDryBulbTemp,
   13223              :                                               InletAirHumRat,
   13224              :                                               LSOutletAirDryBulbTemp,
   13225              :                                               LSOutletAirHumRat,
   13226           78 :                                               thisDXCoil.SensCoolingEnergyRate,
   13227           78 :                                               thisDXCoil.LatCoolingEnergyRate,
   13228           78 :                                               thisDXCoil.TotalCoolingEnergyRate);
   13229           78 :             thisDXCoil.TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate * CycRatio;
   13230           78 :             thisDXCoil.SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate * CycRatio;
   13231           78 :             thisDXCoil.LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate * CycRatio;
   13232              : 
   13233              :             //   Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
   13234           78 :             state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
   13235           78 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   13236           78 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   13237           78 :             thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
   13238           78 :             CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
   13239           78 :             EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
   13240              : 
   13241              :             // Waste heat
   13242           78 :             if (thisDXCoil.MSHPHeatRecActive) {
   13243            0 :                 if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
   13244            0 :                     thisDXCoil.MSFuelWasteHeat = thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecCoolingPower;
   13245              :                 } else {
   13246            0 :                     thisDXCoil.MSFuelWasteHeat = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNum), OutdoorDryBulb, InletAirDryBulbTemp) *
   13247            0 :                                                  thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecCoolingPower;
   13248              :                 }
   13249            0 :                 if (thisDXCoil.MSHPHeatRecActive) {
   13250            0 :                     MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
   13251              :                 }
   13252              :             }
   13253              :             // Energy use for other fuel types
   13254           78 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   13255           22 :                 thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
   13256           22 :                 thisDXCoil.ElecCoolingPower = 0.0;
   13257              :             }
   13258              : 
   13259           78 :             if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   13260           78 :                 thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   13261              :             } else {
   13262            0 :                 thisDXCoil.CrankcaseHeaterPower =
   13263            0 :                     CrankcaseHeatingPower * (1.0 - max(thisDXCoil.CoolingCoilRuntimeFraction,
   13264            0 :                                                        state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction));
   13265              :             }
   13266              :         }
   13267              : 
   13268           99 :         if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
   13269              :             //******************
   13270              :             //             WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
   13271              :             //             H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
   13272              :             //                                /RhoWater [kgWater/m3]
   13273              :             //******************
   13274            0 :             RhoWater = RhoH2O(OutdoorDryBulb);
   13275            0 :             thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater;
   13276            0 :             thisDXCoil.EvapCondPumpElecPower = EvapCondPumpElecPower;
   13277              :             // set water system demand request (if needed)
   13278            0 :             if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
   13279            0 :                 state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
   13280            0 :                     thisDXCoil.EvapWaterConsumpRate;
   13281              :             }
   13282              : 
   13283              :             // Calculate basin heater power
   13284            0 :             CalcBasinHeaterPower(state,
   13285              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
   13286              :                                  thisDXCoil.basinHeaterSched,
   13287              :                                  thisDXCoil.BasinHeaterSetPointTemp,
   13288            0 :                                  thisDXCoil.BasinHeaterPower);
   13289            0 :             thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   13290              :         }
   13291              : 
   13292              :     } else {
   13293              : 
   13294              :         // DX coil is off; just pass through conditions
   13295          166 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   13296          166 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   13297          166 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   13298              : 
   13299          166 :         thisDXCoil.FuelUsed = 0.0;
   13300          166 :         thisDXCoil.ElecCoolingPower = 0.0;
   13301          166 :         thisDXCoil.TotalCoolingEnergyRate = 0.0;
   13302          166 :         thisDXCoil.SensCoolingEnergyRate = 0.0;
   13303          166 :         thisDXCoil.LatCoolingEnergyRate = 0.0;
   13304          166 :         thisDXCoil.EvapCondPumpElecPower = 0.0;
   13305          166 :         thisDXCoil.EvapWaterConsumpRate = 0.0;
   13306              : 
   13307          166 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   13308          166 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
   13309              :         } else {
   13310            0 :             thisDXCoil.CrankcaseHeaterPower =
   13311            0 :                 CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction);
   13312              :         }
   13313              : 
   13314              :         // Calculate basin heater power
   13315          166 :         if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
   13316            0 :             CalcBasinHeaterPower(state,
   13317              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
   13318              :                                  thisDXCoil.basinHeaterSched,
   13319              :                                  thisDXCoil.BasinHeaterSetPointTemp,
   13320            0 :                                  thisDXCoil.BasinHeaterPower);
   13321              :         }
   13322              :     }
   13323              : 
   13324          265 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   13325          265 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   13326          265 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
   13327          265 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   13328          265 :     thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
   13329              : 
   13330              :     // set outlet node conditions
   13331          265 :     int airOutletNode = thisDXCoil.AirOutNode;
   13332          265 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   13333          265 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   13334              : 
   13335              :     // calc secondary coil if specified
   13336          265 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   13337            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   13338              :     }
   13339          265 : }
   13340              : 
   13341          211 : void CalcMultiSpeedDXCoilHeating(EnergyPlusData &state,
   13342              :                                  int const DXCoilNum,     // the number of the DX heating coil to be simulated
   13343              :                                  Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
   13344              :                                  Real64 const CycRatio,   // cycling part load ratio
   13345              :                                  int const SpeedNum,      // Speed number
   13346              :                                  HVAC::FanOp const fanOp, // Fan operation mode
   13347              :                                  int const SingleMode     // Single mode operation Yes/No; 1=Yes, 0=No
   13348              : )
   13349              : {
   13350              : 
   13351              :     // SUBROUTINE INFORMATION:
   13352              :     //       AUTHOR         Lixing Gu, FSEC
   13353              :     //       DATE WRITTEN   June 2007
   13354              :     //       RE-ENGINEERED  Revised based on CalcDXHeatingCoil
   13355              : 
   13356              :     // PURPOSE OF THIS SUBROUTINE:
   13357              :     // Calculates the air-side performance and electrical energy use of a direct-
   13358              :     // expansion, air-cooled cooling unit with a multispeed compressor.
   13359              : 
   13360              :     // METHODOLOGY EMPLOYED:
   13361              :     // Uses the same methodology as the single speed DX heating unit model (SUBROUTINE CalcDXHeatingCoil).
   13362              :     // In addition it assumes that the unit performance is obtained by interpolating between
   13363              :     // the performance at high speed and that at low speed. If the output needed is below
   13364              :     // that produced at low speed, the compressor cycles between off and low speed.
   13365              : 
   13366              :     // Using/Aliasing
   13367              :     using Curve::CurveValue;
   13368          211 :     Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
   13369          211 :     Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
   13370          211 :     auto &MSHPWasteHeat = state.dataHVACGlobal->MSHPWasteHeat;
   13371              : 
   13372              :     // SUBROUTINE ARGUMENT DEFINITIONS:
   13373              :     // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
   13374              : 
   13375              :     // SUBROUTINE PARAMETER DEFINITIONS:
   13376              :     static constexpr std::string_view RoutineName("CalcMultiSpeedDXCoilHeating");
   13377              :     static constexpr std::string_view RoutineNameAverageLoad("CalcMultiSpeedDXCoilHeating:Averageload");
   13378              :     static constexpr std::string_view RoutineNameFullLoad("CalcMultiSpeedDXCoilHeating:fullload");
   13379              : 
   13380              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   13381              :     Real64 AirMassFlow;         // dry air mass flow rate through coil [kg/s]
   13382              :     Real64 InletAirWetBulbC;    // wetbulb temperature of inlet air [C]
   13383              :     Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
   13384              :     Real64 InletAirEnthalpy;    // inlet air enthalpy [J/kg]
   13385              :     Real64 InletAirHumRat;      // inlet air humidity ratio [kg/kg]
   13386              :     Real64 OutletAirEnthalpy;   // outlet air enthalpy [J/kg]
   13387              :     Real64 OutletAirHumRat;     // outlet air humidity ratio [kg/kg]
   13388              :     Real64 TotCapHS;            // total capacity at high speed [W]
   13389              :     Real64 TotCapLS;            // total capacity at low speed [W]
   13390              :     Real64 TotCapHSAdj;         // total adjusted capacity at high speed [W]
   13391              :     Real64 TotCapLSAdj;         // total adjusted capacity at low speed [W]
   13392              :     Real64 EIRHS;               // EIR at off rated conditions (high speed)
   13393              :     Real64 EIRLS;               // EIR at off rated conditions (low speed)
   13394              :     Real64 TotCap;              // total capacity at current speed [W]
   13395              :     Real64 TotCapAdj;           // total adjusted capacity at current speed [W]
   13396              :     Real64 EIR;                 // EIR at current speed
   13397              :     Real64 PLF;                 // Part load factor, accounts for thermal lag at compressor startup, used in
   13398              :     // power calculation
   13399              :     Real64 OutdoorDryBulb;            // Outdoor dry-bulb temperature at condenser (C)
   13400              :     Real64 OutdoorHumRat;             // Outdoor humidity ratio at condenser (kg/kg)
   13401              :     Real64 OutdoorPressure;           // Outdoor barometric pressure at condenser (Pa)
   13402              :     int SpeedNumHS;                   // High speed number
   13403              :     int SpeedNumLS;                   // Low speed number
   13404              :     Real64 AirMassFlowRatioLS;        // airflow ratio at low speed
   13405              :     Real64 AirMassFlowRatioHS;        // airflow ratio at high speed
   13406              :     Real64 AirFlowRatio;              // Airflow ratio
   13407              :     Real64 PLRHeating;                // Part load ratio in heating
   13408              :     Real64 CrankcaseHeatingPower;     // Power due to crank case heater
   13409              :     Real64 AirVolumeFlowRate;         // Air volume flow rate across the heating coil
   13410              :     Real64 VolFlowperRatedTotCap;     // Air volume flow rate divided by rated total heating capacity
   13411          211 :     Real64 TotCapTempModFac(0.0);     // Total capacity modifier as a function of temperature
   13412              :     Real64 TotCapFlowModFac;          // Total capacity modifier as a function of flow ratio
   13413              :     Real64 OutdoorCoilT;              // Outdoor coil temperature
   13414              :     Real64 OutdoorCoildw;             // Outdoor coil delta w assuming coil temperature of OutdoorCoilT
   13415              :     Real64 LoadDueToDefrost;          // Additional load due to defrost
   13416              :     Real64 LoadDueToDefrostLS;        // Additional load due to defrost at low speed
   13417              :     Real64 LoadDueToDefrostHS;        // Additional load due to defrost at high speed
   13418              :     Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
   13419              :     Real64 FractionalDefrostTime;     // Fraction of time step when system is in defrost
   13420              :     Real64 InputPowerMultiplier;      // Multiplier for power when system is in defrost
   13421              :     Real64 DefrostEIRTempModFac;      // EIR modifier for defrost
   13422              :     Real64 FullLoadOutAirEnth;        // Outlet full load enthalpy
   13423              :     Real64 FullLoadOutAirHumRat;      // Outlet humidity ratio at full load
   13424              :     Real64 FullLoadOutAirTemp;        // Outlet temperature at full load
   13425              :     Real64 FullLoadOutAirRH;          // Outlet relative humidity at full load
   13426              :     Real64 OutletAirTemp;             // Supply air temperature
   13427          211 :     Real64 EIRTempModFac(0.0);        // EIR modifier as a function of temperature
   13428              :     Real64 EIRFlowModFac;             // EIR modifier as a function of airflow ratio
   13429              :     Real64 WasteHeatLS;               // Waste heat at low speed
   13430              :     Real64 WasteHeatHS;               // Waste heat at high speed
   13431              :     Real64 LSFullLoadOutAirEnth;      // Outlet full load enthalpy at low speed
   13432              :     Real64 HSFullLoadOutAirEnth;      // Outlet full load enthalpy at high speed
   13433              :     Real64 LSElecHeatingPower;        // Full load power at low speed
   13434              :     Real64 HSElecHeatingPower;        // Full load power at high speed
   13435              :     Real64 DefrostPowerLS;            // Defrost power at low speed [W]
   13436              :     Real64 DefrostPowerHS;            // Defrost power at high speed [W]
   13437              : 
   13438              :     // Autodesk:Uninit Initialize variables used uninitialized
   13439          211 :     FullLoadOutAirEnth = 0.0; // Autodesk:Uninit Force default initialization
   13440              : 
   13441          211 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   13442              : 
   13443          211 :     if (SpeedNum > 1) {
   13444           54 :         SpeedNumLS = SpeedNum - 1;
   13445           54 :         SpeedNumHS = SpeedNum;
   13446           54 :         if (SpeedNum > thisDXCoil.NumOfSpeeds) {
   13447            0 :             SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
   13448            0 :             SpeedNumHS = thisDXCoil.NumOfSpeeds;
   13449              :         }
   13450              :     } else {
   13451          157 :         SpeedNumLS = 1;
   13452          157 :         SpeedNumHS = 1;
   13453              :     }
   13454              : 
   13455          211 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   13456          211 :     AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
   13457          211 :     AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
   13458          211 :     if ((AirMassFlow > 0.0) && (CycRatio > 0.0) && (MSHPMassFlowRateHigh == 0.0)) {
   13459            0 :         ShowSevereError(
   13460              :             state,
   13461            0 :             format("CalcMultiSpeedDXCoilHeating: {} \"{} Developer error - inconsistent airflow rates.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   13462            0 :         if (MSHPMassFlowRateLow == 0.0 && SpeedNum > 1) {
   13463            0 :             ShowContinueError(state,
   13464              :                               "When AirMassFlow > 0.0 and CycRatio > 0.0 and SpeedNum > 1, then MSHPMassFlowRateLow and MSHPMassFlowRateHigh "
   13465              :                               "must also be > 0.0");
   13466            0 :             ShowContinueErrorTimeStamp(state, "");
   13467            0 :             ShowContinueError(state,
   13468            0 :                               format("AirMassFlow={:.3R},CycRatio={:.3R},SpeedNum={:.0R}, MSHPMassFlowRateLow={:.3R}, MSHPMassFlowRateHigh={:.3R}",
   13469              :                                      AirMassFlow,
   13470            0 :                                      double(SpeedNum),
   13471              :                                      CycRatio,
   13472              :                                      MSHPMassFlowRateLow,
   13473              :                                      MSHPMassFlowRateHigh));
   13474            0 :             ShowFatalError(state, "Preceding condition(s) causes termination.");
   13475              :         } else {
   13476            0 :             ShowContinueError(state, "When AirMassFlow > 0.0 and CycRatio > 0.0, then MSHPMassFlowRateHigh must also be > 0.0");
   13477            0 :             ShowContinueErrorTimeStamp(state, "");
   13478            0 :             ShowContinueError(state,
   13479            0 :                               format("AirMassFlow={:.3R},CycRatio={:.3R}, MSHPMassFlowRateHigh={:.3R}", AirMassFlow, CycRatio, MSHPMassFlowRateHigh));
   13480            0 :             ShowFatalError(state, "Preceding condition(s) causes termination.");
   13481              :         }
   13482          211 :     } else if (CycRatio > 1.0 || SpeedRatio > 1.0) {
   13483            0 :         ShowSevereError(
   13484              :             state,
   13485            0 :             format("CalcMultiSpeedDXCoilHeating: {} \"{} Developer error - inconsistent speed ratios.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   13486            0 :         ShowContinueError(state, "CycRatio and SpeedRatio must be between 0.0 and 1.0");
   13487            0 :         ShowContinueErrorTimeStamp(state, "");
   13488            0 :         ShowContinueError(state, format("CycRatio={:.1R}, SpeedRatio = {:.1R}", CycRatio, SpeedRatio));
   13489            0 :         ShowFatalError(state, "Preceding condition(s) causes termination.");
   13490              :     }
   13491              : 
   13492          211 :     AirFlowRatio = 1.0;
   13493          211 :     if (thisDXCoil.CompanionUpstreamDXCoil == 0) MSHPWasteHeat = 0.0;
   13494              : 
   13495              :     // Get condenser outdoor node info from DX Heating Coil
   13496          211 :     if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
   13497           71 :         OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
   13498              :         // If node is not connected to anything, pressure = default, use weather data
   13499           71 :         if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   13500           71 :             OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   13501           71 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   13502           71 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   13503              :         } else {
   13504            0 :             OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
   13505            0 :             OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
   13506              :         }
   13507           71 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
   13508            0 :             auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   13509            0 :             OutdoorDryBulb = secZoneHB.ZT;
   13510            0 :             OutdoorHumRat = secZoneHB.airHumRat;
   13511              :             // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb;
   13512            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   13513              :         }
   13514          140 :     } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
   13515            0 :         auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   13516            0 :         OutdoorDryBulb = secZoneHB.ZT;
   13517            0 :         OutdoorHumRat = secZoneHB.airHumRat;
   13518              :         // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb;
   13519            0 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   13520              :     } else {
   13521          140 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   13522          140 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   13523          140 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   13524              :     }
   13525              : 
   13526          211 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   13527          211 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   13528          211 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   13529              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13530              :     // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
   13531              :     // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
   13532          211 :     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
   13533          211 :     PLRHeating = 0.0;
   13534          211 :     thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
   13535              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
   13536          211 :     if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
   13537          123 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   13538          123 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   13539            0 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
   13540              :         }
   13541              :     } else {
   13542           88 :         CrankcaseHeatingPower = 0.0;
   13543              :     }
   13544          211 :     thisDXCoil.PartLoadRatio = 0.0;
   13545          211 :     state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
   13546              : 
   13547          302 :     if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && ((CycRatio > 0.0) || (SpeedRatio > 0.0 && SingleMode == 0)) &&
   13548           91 :         OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
   13549              : 
   13550           91 :         if (SpeedNum > 1 && SingleMode == 0) {
   13551              : 
   13552              :             // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton) at low speed
   13553           28 :             AirVolumeFlowRate = MSHPMassFlowRateLow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   13554              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13555              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   13556           28 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
   13557           56 :             if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   13558           28 :                 (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
   13559            0 :                 if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
   13560            0 :                     ShowWarningMessage(
   13561              :                         state,
   13562            0 :                         format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
   13563            0 :                                thisDXCoil.DXCoilType,
   13564            0 :                                thisDXCoil.Name,
   13565              :                                SpeedNumLS));
   13566            0 :                     ShowContinueErrorTimeStamp(state, "");
   13567            0 :                     ShowContinueError(state,
   13568            0 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   13569            0 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13570            0 :                                              HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13571              :                                              VolFlowperRatedTotCap));
   13572            0 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   13573            0 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   13574              :                 }
   13575            0 :                 ShowRecurringWarningErrorAtEnd(state,
   13576            0 :                                                format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
   13577              :                                                       "at speed {} error continues...",
   13578            0 :                                                       thisDXCoil.DXCoilType,
   13579            0 :                                                       thisDXCoil.Name,
   13580              :                                                       SpeedNumLS),
   13581              :                                                thisDXCoil.MSErrIndex(SpeedNumLS),
   13582              :                                                VolFlowperRatedTotCap,
   13583              :                                                VolFlowperRatedTotCap);
   13584              :             }
   13585              : 
   13586              :             // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton) at high speed
   13587           28 :             AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   13588              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13589              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   13590           28 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
   13591           56 :             if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   13592           28 :                 (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
   13593            0 :                 if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
   13594            0 :                     ShowWarningMessage(
   13595              :                         state,
   13596            0 :                         format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
   13597            0 :                                thisDXCoil.DXCoilType,
   13598            0 :                                thisDXCoil.Name,
   13599              :                                SpeedNumHS));
   13600            0 :                     ShowContinueErrorTimeStamp(state, "");
   13601            0 :                     ShowContinueError(state,
   13602            0 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   13603            0 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13604            0 :                                              HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13605              :                                              VolFlowperRatedTotCap));
   13606            0 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   13607            0 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   13608              :                 }
   13609            0 :                 ShowRecurringWarningErrorAtEnd(state,
   13610            0 :                                                format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
   13611              :                                                       "at speed {} error continues...",
   13612            0 :                                                       thisDXCoil.DXCoilType,
   13613            0 :                                                       thisDXCoil.Name,
   13614              :                                                       SpeedNumHS),
   13615              :                                                thisDXCoil.MSErrIndex(SpeedNumHS),
   13616              :                                                VolFlowperRatedTotCap,
   13617              :                                                VolFlowperRatedTotCap);
   13618              :             }
   13619              : 
   13620              :             // Get total capacity modifying factor (function of temperature) for off-rated conditions
   13621              :             // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
   13622              :             // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   13623              :             // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   13624              :             // Low speed
   13625           28 :             if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNumLS))->numDims == 1) {
   13626            1 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), OutdoorDryBulb);
   13627              :             } else {
   13628           27 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
   13629              :             }
   13630              :             //  Get total capacity modifying factor (function of mass flow) for off-rated conditions
   13631           28 :             TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumLS), AirMassFlowRatioLS);
   13632              :             // Calculate total heating capacity for off-rated conditions
   13633           28 :             TotCapLS = thisDXCoil.MSRatedTotCap(SpeedNumLS) * TotCapFlowModFac * TotCapTempModFac;
   13634              :             // High speed
   13635           28 :             if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNumHS))->numDims == 1) {
   13636            1 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), OutdoorDryBulb);
   13637              :             } else {
   13638           27 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
   13639              :             }
   13640              :             //  Get total capacity modifying factor (function of mass flow) for off-rated conditions
   13641           28 :             TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumHS), AirMassFlowRatioHS);
   13642              :             // Calculate total heating capacity for off-rated conditions
   13643           28 :             TotCapHS = thisDXCoil.MSRatedTotCap(SpeedNumHS) * TotCapFlowModFac * TotCapTempModFac;
   13644              :             // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
   13645              :             // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
   13646              :             // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   13647              :             // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   13648              :             // Low Speed
   13649           28 :             if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(SpeedNumLS))->numDims == 1) {
   13650            1 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), OutdoorDryBulb);
   13651              :             } else {
   13652           27 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
   13653              :             }
   13654           28 :             EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
   13655           28 :             EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFac * EIRFlowModFac;
   13656              :             // High Speed
   13657           28 :             if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(SpeedNumHS))->numDims == 1) {
   13658            1 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), OutdoorDryBulb);
   13659              :             } else {
   13660           27 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
   13661              :             }
   13662           28 :             EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
   13663           28 :             EIRHS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumHS) * EIRTempModFac * EIRFlowModFac;
   13664              : 
   13665              :             // Calculating adjustment factors for defrost
   13666              :             // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
   13667           28 :             OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
   13668           28 :             OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
   13669              : 
   13670              :             // Initializing defrost adjustment factors
   13671           28 :             LoadDueToDefrostLS = 0.0;
   13672           28 :             LoadDueToDefrostHS = 0.0;
   13673           28 :             HeatingCapacityMultiplier = 1.0;
   13674           28 :             FractionalDefrostTime = 0.0;
   13675           28 :             InputPowerMultiplier = 1.0;
   13676           28 :             DefrostPowerLS = 0.0;
   13677           28 :             DefrostPowerHS = 0.0;
   13678              : 
   13679              :             // Check outdoor temperature to determine if defrost is active
   13680           28 :             if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
   13681              :                 // Calculate defrost adjustment factors depending on defrost control type
   13682            6 :                 if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
   13683            6 :                     FractionalDefrostTime = thisDXCoil.DefrostTime;
   13684            6 :                     if (FractionalDefrostTime > 0.0) {
   13685            5 :                         if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13686            2 :                             HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   13687            2 :                             InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   13688              :                         } else {
   13689            3 :                             HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
   13690            3 :                             InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
   13691            3 :                             if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13692            2 :                                 ShowWarningMessage(
   13693              :                                     state,
   13694            2 :                                     format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   13695              :                                            "actuator must be both provided for DX heating coil {}",
   13696            1 :                                            thisDXCoil.Name));
   13697            3 :                                 ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   13698              :                             }
   13699              :                         }
   13700              :                     }
   13701              :                 } else { // else defrost control is on-demand
   13702            0 :                     FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
   13703            0 :                     if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13704            0 :                         HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   13705            0 :                         InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   13706              :                     } else {
   13707            0 :                         HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
   13708            0 :                         InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
   13709            0 :                         if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13710            0 :                             ShowWarningMessage(state,
   13711            0 :                                                format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   13712              :                                                       "actuator must be both provided for DX heating coil {}",
   13713            0 :                                                       thisDXCoil.Name));
   13714            0 :                             ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   13715              :                         }
   13716              :                     }
   13717              :                 }
   13718              : 
   13719            6 :                 if (FractionalDefrostTime > 0.0) {
   13720              :                     // Calculate defrost adjustment factors depending on defrost control strategy
   13721            5 :                     if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
   13722            1 :                         DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
   13723            1 :                         LoadDueToDefrostLS =
   13724            1 :                             (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667);
   13725            1 :                         DefrostPowerLS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667) * FractionalDefrostTime;
   13726            1 :                         LoadDueToDefrostHS =
   13727            1 :                             (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667);
   13728            1 :                         DefrostPowerHS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667) * FractionalDefrostTime;
   13729              :                     } else { // Defrost strategy is resistive
   13730            4 :                         thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
   13731              :                     }
   13732              :                 } else { // Defrost is not active because (OutDryBulbTemp .GT. DXCoil(DXCoilNum)%MaxOATDefrost)
   13733            1 :                     thisDXCoil.DefrostPower = 0.0;
   13734              :                 }
   13735              :             }
   13736              : 
   13737           28 :             TotCapLSAdj = TotCapLS * HeatingCapacityMultiplier;
   13738           28 :             TotCapHSAdj = TotCapHS * HeatingCapacityMultiplier;
   13739              : 
   13740              :             // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
   13741           28 :             PLRHeating = min(1.0, (SpeedRatio + LoadDueToDefrostHS / TotCapHSAdj));
   13742           28 :             PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), PLRHeating); // Calculate part-load factor
   13743              : 
   13744           28 :             if (PLF < 0.7) {
   13745            0 :                 if (thisDXCoil.PLRErrIndex == 0) {
   13746            0 :                     ShowWarningMessage(
   13747              :                         state,
   13748            0 :                         format("The PLF curve value at high speed for DX multispeed heating coil {} ={:.2R} for part-load ratio ={:.2R}",
   13749            0 :                                thisDXCoil.Name,
   13750              :                                PLF,
   13751              :                                PLRHeating));
   13752            0 :                     ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   13753            0 :                     ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:MultiSpeed].");
   13754            0 :                     ShowContinueErrorTimeStamp(state, "");
   13755              :                 }
   13756            0 :                 ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
   13757            0 :                 PLF = 0.7;
   13758              :             }
   13759              : 
   13760           28 :             thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
   13761           28 :             if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
   13762            0 :                 if (thisDXCoil.ErrIndex4 == 0) {
   13763            0 :                     ShowWarningMessage(state,
   13764            0 :                                        format("The runtime fraction at high speed for DX multispeed heating coil {} exceeded 1.0. [{:.4R}].",
   13765            0 :                                               thisDXCoil.Name,
   13766            0 :                                               thisDXCoil.HeatingCoilRuntimeFraction));
   13767            0 :                     ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
   13768            0 :                     ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   13769            0 :                     ShowContinueErrorTimeStamp(state, "");
   13770              :                 }
   13771            0 :                 ShowRecurringWarningErrorAtEnd(state,
   13772            0 :                                                thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
   13773            0 :                                                thisDXCoil.ErrIndex4,
   13774            0 :                                                thisDXCoil.HeatingCoilRuntimeFraction,
   13775            0 :                                                thisDXCoil.HeatingCoilRuntimeFraction);
   13776            0 :                 thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   13777           28 :             } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
   13778            0 :                 thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   13779              :             }
   13780              : 
   13781              :             // Get full load output and power
   13782           28 :             LSFullLoadOutAirEnth = InletAirEnthalpy + TotCapLSAdj / MSHPMassFlowRateLow;
   13783           28 :             HSFullLoadOutAirEnth = InletAirEnthalpy + TotCapHSAdj / MSHPMassFlowRateHigh;
   13784           28 :             LSElecHeatingPower = TotCapLS * EIRLS * InputPowerMultiplier;
   13785           28 :             HSElecHeatingPower = TotCapHS * EIRHS * InputPowerMultiplier;
   13786           28 :             OutletAirHumRat = InletAirHumRat;
   13787              : 
   13788              :             // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
   13789           28 :             if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
   13790              : 
   13791              :             // Power calculation
   13792           28 :             if (!thisDXCoil.PLRImpact) {
   13793           28 :                 thisDXCoil.ElecHeatingPower = SpeedRatio * HSElecHeatingPower + (1.0 - SpeedRatio) * LSElecHeatingPower;
   13794              :             } else {
   13795            0 :                 thisDXCoil.ElecHeatingPower =
   13796            0 :                     thisDXCoil.HeatingCoilRuntimeFraction * HSElecHeatingPower + (1.0 - thisDXCoil.HeatingCoilRuntimeFraction) * LSElecHeatingPower;
   13797              :             }
   13798              : 
   13799           28 :             thisDXCoil.TotalHeatingEnergyRate = MSHPMassFlowRateHigh * (HSFullLoadOutAirEnth - InletAirEnthalpy) * SpeedRatio +
   13800           28 :                                                 MSHPMassFlowRateLow * (LSFullLoadOutAirEnth - InletAirEnthalpy) * (1.0 - SpeedRatio);
   13801           28 :             OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
   13802           28 :             OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   13803           28 :             FullLoadOutAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, OutdoorPressure, RoutineNameAverageLoad);
   13804           28 :             if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
   13805            0 :                 OutletAirTemp = PsyTsatFnHPb(state,
   13806              :                                              FullLoadOutAirEnth,
   13807              :                                              OutdoorPressure,
   13808              :                                              RoutineName); // Autodesk:Uninit FullLoadOutAirEnth was possibly uninitialized
   13809            0 :                 OutletAirHumRat = PsyWFnTdbH(
   13810              :                     state, OutletAirTemp, FullLoadOutAirEnth, RoutineName); // Autodesk:Uninit FullLoadOutAirEnth was possibly uninitialized
   13811              :             }
   13812              : 
   13813              :             // Waste heat calculation
   13814           28 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   13815            1 :                 if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
   13816            0 :                     WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
   13817              :                 } else {
   13818            1 :                     WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
   13819            1 :                                   thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
   13820              :                 }
   13821            1 :                 if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
   13822            0 :                     WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
   13823              :                 } else {
   13824            1 :                     WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
   13825            1 :                                   thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
   13826              :                 }
   13827            1 :                 thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
   13828            1 :                 if (thisDXCoil.MSHPHeatRecActive) {
   13829            0 :                     MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
   13830              :                 }
   13831              :             }
   13832           28 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   13833              : 
   13834            1 :                 thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
   13835            1 :                 thisDXCoil.ElecHeatingPower = 0.0;
   13836              :             }
   13837              : 
   13838              :             // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
   13839              :             // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
   13840           28 :             if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
   13841           21 :                 if (!thisDXCoil.PLRImpact) {
   13842           21 :                     thisDXCoil.DefrostPower = DefrostPowerHS * SpeedRatio + DefrostPowerLS * (1.0 - SpeedRatio);
   13843              :                 } else {
   13844            0 :                     thisDXCoil.DefrostPower =
   13845            0 :                         DefrostPowerHS * thisDXCoil.HeatingCoilRuntimeFraction + DefrostPowerLS * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
   13846              :                 }
   13847              :             }
   13848           28 :             thisDXCoil.OutletAirTemp = OutletAirTemp;
   13849           28 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   13850           28 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   13851           28 :             thisDXCoil.CrankcaseHeaterPower = 0.0;
   13852              : 
   13853              :             // Stage 1
   13854           63 :         } else if (CycRatio > 0.0 || (CycRatio > 0.0 && SingleMode == 1)) {
   13855              : 
   13856              :             // for cycling fan, reset mass flow to full on rate
   13857           63 :             if (fanOp == HVAC::FanOp::Cycling) AirMassFlow /= CycRatio;
   13858           63 :             if (fanOp == HVAC::FanOp::Continuous) AirMassFlow = MSHPMassFlowRateHigh;
   13859              :             // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
   13860           63 :             AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   13861              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13862              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   13863           63 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
   13864              : 
   13865          126 :             if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   13866           63 :                 (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
   13867            5 :                 if (thisDXCoil.ErrIndex1 == 0) {
   13868            2 :                     ShowWarningMessage(state,
   13869            2 :                                        format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed 1.",
   13870            1 :                                               thisDXCoil.DXCoilType,
   13871            1 :                                               thisDXCoil.Name));
   13872            2 :                     ShowContinueErrorTimeStamp(state, "");
   13873            2 :                     ShowContinueError(state,
   13874            2 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   13875            1 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13876            1 :                                              HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13877              :                                              VolFlowperRatedTotCap));
   13878            2 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   13879            3 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   13880              :                 }
   13881           40 :                 ShowRecurringWarningErrorAtEnd(
   13882              :                     state,
   13883           10 :                     thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   13884              :                         "\" - Air volume flow rate per watt of rated total heating capacity is out of range error continues at speed 1...",
   13885            5 :                     thisDXCoil.ErrIndex1,
   13886              :                     VolFlowperRatedTotCap,
   13887              :                     VolFlowperRatedTotCap);
   13888              :             }
   13889              : 
   13890              :             // Get total capacity modifying factor (function of temperature) for off-rated conditions
   13891              :             // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
   13892              :             // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   13893              :             // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   13894           63 :             if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNum))->numDims == 1) {
   13895           32 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNum), OutdoorDryBulb);
   13896              :             } else {
   13897           31 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNum), InletAirDryBulbTemp, OutdoorDryBulb);
   13898              :             }
   13899              : 
   13900              :             //  Get total capacity modifying factor (function of mass flow) for off-rated conditions
   13901              :             //    AirMassFlowRatio = AirMassFlow/DXCoil(DXCoilNum)%MSRatedAirMassFlowRate(SpeedNumLS)
   13902              :             //    TotCapFlowModFac = CurveValue(state, DXCoil(DXCoilNum)%MSCCapFFlow(SpeedNumLS),AirMassFlowRatio)
   13903           63 :             TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNum), AirMassFlowRatioLS);
   13904              :             // Calculate total heating capacity for off-rated conditions
   13905           63 :             TotCap = thisDXCoil.MSRatedTotCap(SpeedNum) * TotCapFlowModFac * TotCapTempModFac;
   13906              : 
   13907              :             // Calculating adjustment factors for defrost
   13908              :             // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
   13909           63 :             OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
   13910           63 :             OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
   13911              : 
   13912              :             // Initializing defrost adjustment factors
   13913           63 :             LoadDueToDefrost = 0.0;
   13914           63 :             HeatingCapacityMultiplier = 1.0;
   13915           63 :             FractionalDefrostTime = 0.0;
   13916           63 :             InputPowerMultiplier = 1.0;
   13917              : 
   13918              :             // Check outdoor temperature to determine of defrost is active
   13919           63 :             if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
   13920              :                 // Calculate defrost adjustment factors depending on defrost control type
   13921           36 :                 if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
   13922           36 :                     FractionalDefrostTime = thisDXCoil.DefrostTime;
   13923           36 :                     if (FractionalDefrostTime > 0.0) {
   13924           36 :                         if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13925            2 :                             HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   13926            2 :                             InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   13927              :                         } else {
   13928           34 :                             HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
   13929           34 :                             InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
   13930           34 :                             if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13931            4 :                                 ShowWarningMessage(
   13932              :                                     state,
   13933            4 :                                     format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   13934              :                                            "actuator must be both provided for DX heating coil {}",
   13935            2 :                                            thisDXCoil.Name));
   13936            6 :                                 ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   13937              :                             }
   13938              :                         }
   13939              :                     }
   13940              :                 } else { // else defrost control is on-demand
   13941            0 :                     FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
   13942            0 :                     if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13943            0 :                         HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   13944            0 :                         InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   13945              :                     } else {
   13946            0 :                         HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
   13947            0 :                         InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
   13948            0 :                         if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13949            0 :                             ShowWarningMessage(state,
   13950            0 :                                                format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   13951              :                                                       "actuator must be both provided for DX heating coil {}",
   13952            0 :                                                       thisDXCoil.Name));
   13953            0 :                             ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   13954              :                         }
   13955              :                     }
   13956              :                 }
   13957              : 
   13958           36 :                 if (FractionalDefrostTime > 0.0) {
   13959              :                     // Calculate defrost adjustment factors depending on defrost control strategy
   13960           36 :                     if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
   13961           32 :                         LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(1) / 1.01667);
   13962           32 :                         DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
   13963           32 :                         thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(1) / 1.01667) * FractionalDefrostTime;
   13964              :                     } else { // Defrost strategy is resistive
   13965            4 :                         thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
   13966              :                     }
   13967              :                 } else { // Defrost is not active because (OutDryBulbTemp .GT. DXCoil(DXCoilNum)%MaxOATDefrost)
   13968            0 :                     thisDXCoil.DefrostPower = 0.0;
   13969              :                 }
   13970              :             }
   13971              : 
   13972              :             // Modify total heating capacity based on defrost heating capacity multiplier
   13973           63 :             TotCapAdj = TotCap * HeatingCapacityMultiplier;
   13974              : 
   13975              :             // Calculate full load outlet conditions
   13976           63 :             FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
   13977           63 :             FullLoadOutAirHumRat = InletAirHumRat;
   13978           63 :             FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   13979           63 :             FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
   13980              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13981              :             //  FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
   13982           63 :             if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
   13983            0 :                 FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure, RoutineName);
   13984              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13985              :                 //  FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
   13986            0 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
   13987              :             }
   13988              : 
   13989              :             // Set outlet conditions from the full load calculation
   13990           63 :             OutletAirEnthalpy = FullLoadOutAirEnth;
   13991           63 :             OutletAirHumRat = FullLoadOutAirHumRat;
   13992           63 :             OutletAirTemp = FullLoadOutAirTemp;
   13993              :             // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
   13994              :             // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
   13995              :             // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   13996              :             // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   13997           63 :             if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(1))->numDims == 1) {
   13998           32 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), OutdoorDryBulb);
   13999              :             } else {
   14000           31 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), InletAirDryBulbTemp, OutdoorDryBulb);
   14001              :             }
   14002           63 :             EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(1), AirMassFlowRatioLS);
   14003           63 :             EIR = 1.0 / thisDXCoil.MSRatedCOP(1) * EIRTempModFac * EIRFlowModFac;
   14004              :             // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
   14005           63 :             PLRHeating = min(1.0, (CycRatio + LoadDueToDefrost / TotCapAdj));
   14006           63 :             PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(1), PLRHeating); // Calculate part-load factor
   14007           63 :             if (fanOp == HVAC::FanOp::Cycling && CycRatio == 1.0 && PLF != 1.0) {
   14008            0 :                 if (thisDXCoil.PLFErrIndex == 0) {
   14009            0 :                     ShowWarningMessage(state,
   14010            0 :                                        format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio = 1", thisDXCoil.Name, PLF));
   14011            0 :                     ShowContinueError(state, "PLF curve value must be = 1.0 and has been reset to 1.0. Simulation is continuing.");
   14012            0 :                     ShowContinueErrorTimeStamp(state, "");
   14013              :                 }
   14014            0 :                 ShowRecurringWarningErrorAtEnd(
   14015            0 :                     state, thisDXCoil.Name + "\": DX heating coil PLF curve value <> 1.0 warning continues...", thisDXCoil.PLFErrIndex, PLF, PLF);
   14016            0 :                 PLF = 1.0;
   14017              :             }
   14018              : 
   14019           63 :             if (PLF < 0.7) {
   14020            0 :                 if (thisDXCoil.PLRErrIndex == 0) {
   14021            0 :                     ShowWarningMessage(
   14022              :                         state,
   14023            0 :                         format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
   14024            0 :                     ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   14025            0 :                     ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   14026            0 :                     ShowContinueErrorTimeStamp(state, "");
   14027              :                 }
   14028            0 :                 ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
   14029            0 :                 PLF = 0.7;
   14030              :             }
   14031              : 
   14032           63 :             thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
   14033           63 :             if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
   14034            0 :                 if (thisDXCoil.ErrIndex4 == 0) {
   14035            0 :                     ShowWarningMessage(state,
   14036            0 :                                        format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
   14037            0 :                                               thisDXCoil.Name,
   14038            0 :                                               thisDXCoil.HeatingCoilRuntimeFraction));
   14039            0 :                     ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
   14040            0 :                     ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   14041            0 :                     ShowContinueErrorTimeStamp(state, "");
   14042              :                 }
   14043            0 :                 ShowRecurringWarningErrorAtEnd(state,
   14044            0 :                                                thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
   14045            0 :                                                thisDXCoil.ErrIndex4,
   14046            0 :                                                thisDXCoil.HeatingCoilRuntimeFraction,
   14047            0 :                                                thisDXCoil.HeatingCoilRuntimeFraction);
   14048            0 :                 thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   14049           63 :             } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
   14050            0 :                 thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   14051              :             }
   14052              :             // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
   14053           63 :             if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
   14054           63 :             thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
   14055              : 
   14056              :             // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
   14057              :             // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
   14058              : 
   14059           63 :             if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   14060            5 :                 thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
   14061              :             } else {
   14062           58 :                 thisDXCoil.CrankcaseHeaterPower =
   14063           58 :                     CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
   14064           58 :                                                        state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
   14065              :             }
   14066              : 
   14067           63 :             thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (FullLoadOutAirEnth - InletAirEnthalpy) * CycRatio;
   14068           63 :             if (fanOp == HVAC::FanOp::Continuous) {
   14069           31 :                 OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
   14070           31 :                 OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   14071              :             }
   14072           63 :             if (thisDXCoil.MSHPHeatRecActive || thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   14073           32 :                 if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
   14074            0 :                     thisDXCoil.MSFuelWasteHeat = thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
   14075              :                 } else {
   14076           32 :                     thisDXCoil.MSFuelWasteHeat = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNum), OutdoorDryBulb, InletAirDryBulbTemp) *
   14077           32 :                                                  thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
   14078              :                 }
   14079           32 :                 if (thisDXCoil.MSHPHeatRecActive) {
   14080            0 :                     MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
   14081              :                 }
   14082              :             }
   14083           63 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   14084              : 
   14085           32 :                 thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
   14086           32 :                 thisDXCoil.ElecHeatingPower = 0.0;
   14087              :             }
   14088              :             // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
   14089              :             // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
   14090           63 :             thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
   14091              : 
   14092           63 :             thisDXCoil.OutletAirTemp = OutletAirTemp;
   14093           63 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   14094           63 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   14095              :         }
   14096              : 
   14097              :     } else {
   14098              : 
   14099              :         // DX coil is off; just pass through conditions
   14100          120 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   14101          120 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   14102          120 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   14103              : 
   14104          120 :         thisDXCoil.ElecHeatingPower = 0.0;
   14105          120 :         thisDXCoil.FuelUsed = 0.0;
   14106          120 :         thisDXCoil.TotalHeatingEnergyRate = 0.0;
   14107          120 :         thisDXCoil.DefrostPower = 0.0;
   14108              : 
   14109              :         // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
   14110              :         // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
   14111          120 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   14112           10 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
   14113              :         } else {
   14114          110 :             thisDXCoil.CrankcaseHeaterPower =
   14115          110 :                 CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
   14116              :         }
   14117              : 
   14118              :     } // end of on/off if - else
   14119              : 
   14120          211 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   14121          211 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   14122          211 :     thisDXCoil.PartLoadRatio = PLRHeating;
   14123          211 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   14124          211 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
   14125          211 :     thisDXCoil.MSSpeedNumLS = SpeedNumLS;
   14126          211 :     thisDXCoil.MSSpeedNumHS = SpeedNumHS;
   14127          211 :     thisDXCoil.MSSpeedRatio = SpeedRatio;
   14128          211 :     thisDXCoil.MSCycRatio = CycRatio;
   14129              : 
   14130              :     // set outlet node conditions
   14131          211 :     int airOutletNode = thisDXCoil.AirOutNode;
   14132          211 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   14133          211 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   14134              : 
   14135              :     // calc secondary coil if specified
   14136          211 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   14137            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   14138              :     }
   14139          211 : }
   14140              : 
   14141       539062 : void UpdateDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current fan coil unit being simulated
   14142              : {
   14143              : 
   14144              :     // SUBROUTINE INFORMATION:
   14145              :     //       AUTHOR         Fred Buhl
   14146              :     //       DATE WRITTEN   May 2000
   14147              : 
   14148              :     // PURPOSE OF THIS SUBROUTINE:
   14149              :     // This subroutine is for passing results to the outlet air node.
   14150              : 
   14151              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   14152              :     int AirOutletNode; // air outlet node number
   14153              :     int AirInletNode;  // air inlet node number
   14154              : 
   14155       539062 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   14156              : 
   14157       539062 :     AirOutletNode = thisDXCoil.AirOutNode;
   14158       539062 :     AirInletNode = thisDXCoil.AirInNode;
   14159              :     // changed outputs
   14160       539062 :     state.dataLoopNodes->Node(AirOutletNode).Enthalpy = thisDXCoil.OutletAirEnthalpy;
   14161       539062 :     state.dataLoopNodes->Node(AirOutletNode).Temp = thisDXCoil.OutletAirTemp;
   14162       539062 :     state.dataLoopNodes->Node(AirOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   14163       539062 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = thisDXCoil.InletAirMassFlowRate;
   14164              :     // pass through outputs
   14165       539062 :     state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
   14166       539062 :     state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
   14167       539062 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
   14168       539062 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
   14169       539062 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
   14170       539062 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMaxAvail;
   14171              : 
   14172       539062 :     if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
   14173            0 :         state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
   14174              :     }
   14175       539062 :     if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
   14176            0 :         state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
   14177              :     }
   14178       539062 : }
   14179              : 
   14180       539064 : void ReportDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current fan coil unit being simulated
   14181              : {
   14182              : 
   14183              :     // SUBROUTINE INFORMATION:
   14184              :     //       AUTHOR         Fred Buhl
   14185              :     //       DATE WRITTEN   May 2000
   14186              :     //       MODIFIED       Richard Raustad/Don Shirey Oct 2001, Feb 2004
   14187              :     //                      Feb 2005 M. J. Witte, GARD Analytics, Inc.
   14188              :     //                        Always update evap value to support new coil type COIL:DX:MultiMode:CoolingEmpirical:
   14189              :     //                      Lixing Gu. Jan. 5, 2007, pass information to the AirflowNetwork model
   14190              : 
   14191              :     // PURPOSE OF THIS SUBROUTINE:
   14192              :     // Fills some of the report variables for the DX coils
   14193              : 
   14194              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   14195              : 
   14196       539064 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   14197              : 
   14198       539064 :     if (thisDXCoil.reportCoilFinalSizes) {
   14199       192897 :         if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
   14200          104 :             Real64 ratedSensCap(0.0);
   14201          104 :             ratedSensCap = thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1);
   14202          104 :             state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
   14203          104 :                 state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.RatedTotCap(1), ratedSensCap, thisDXCoil.RatedAirVolFlowRate(1), -999.0);
   14204          104 :             thisDXCoil.reportCoilFinalSizes = false;
   14205              :         }
   14206              :     }
   14207              : 
   14208       539064 :     Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
   14209              : 
   14210       539064 :     switch (thisDXCoil.DXCoilType_Num) {
   14211       201111 :     case HVAC::CoilDX_HeatingEmpirical:
   14212              :     case HVAC::CoilVRF_Heating:
   14213              :     case HVAC::CoilVRF_FluidTCtrl_Heating: {
   14214       201111 :         thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
   14215       201111 :         thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
   14216       201111 :         thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
   14217       201111 :         thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
   14218       201111 :         state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
   14219       201111 :         state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
   14220       201111 :     } break;
   14221          199 :     case HVAC::CoilDX_MultiSpeedHeating: {
   14222          199 :         thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
   14223          199 :         if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
   14224          116 :             thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
   14225              :         } else {
   14226           83 :             thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
   14227              :         }
   14228          199 :         thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
   14229          199 :         thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
   14230          199 :         state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
   14231          199 :         state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
   14232          199 :     } break;
   14233          251 :     case HVAC::CoilDX_MultiSpeedCooling: {
   14234          251 :         thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
   14235          251 :         thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
   14236          251 :         thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
   14237          251 :         thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
   14238          251 :         state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
   14239          251 :         thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
   14240          251 :         thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
   14241          251 :         if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
   14242          179 :             thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
   14243              :         } else {
   14244           72 :             thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
   14245              :         }
   14246          251 :         if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
   14247            0 :             thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
   14248              :         }
   14249          251 :     } break;
   14250          161 :     case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
   14251              :     case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
   14252              :         // water heating energy for HP water heater DX Coil condenser
   14253          161 :         thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
   14254              :         // water heating power for HP water heater
   14255          161 :         thisDXCoil.ElecWaterHeatingConsumption = thisDXCoil.ElecWaterHeatingPower * ReportingConstant;
   14256              :         // other usual DX cooling coil outputs
   14257          161 :         thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
   14258          161 :         thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
   14259          161 :         thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
   14260          161 :         thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
   14261          161 :         thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
   14262              :         // DXElecCoolingPower global is only used for air-to-air cooling and heating coils
   14263          161 :         state.dataHVACGlobal->DXElecCoolingPower = 0.0;
   14264          161 :     } break;
   14265       337342 :     default: {
   14266       337342 :         thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
   14267       337342 :         thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
   14268       337342 :         thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
   14269       337342 :         thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
   14270       337342 :         thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
   14271       337342 :         state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
   14272       337342 :         thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
   14273       337342 :         thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
   14274       337342 :         if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
   14275        33575 :             thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
   14276              :         }
   14277       337342 :     } break;
   14278              :     }
   14279              : 
   14280       539064 :     if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
   14281              :         // calculate and report condensation rates  (how much water extracted from the air stream)
   14282              :         // water flow of water in m3/s for water system interactions
   14283              :         //  put here to catch all types of DX coils
   14284            2 :         Real64 Tavg = (thisDXCoil.InletAirTemp + thisDXCoil.OutletAirTemp) / 2.0;
   14285              :         // CR9155 Remove specific humidity calculations
   14286              :         //  mdot * del HumRat / rho water
   14287            2 :         thisDXCoil.CondensateVdot =
   14288            2 :             max(0.0, (thisDXCoil.InletAirMassFlowRate * (thisDXCoil.InletAirHumRat - thisDXCoil.OutletAirHumRat) / Psychrometrics::RhoH2O(Tavg)));
   14289            2 :         thisDXCoil.CondensateVol = thisDXCoil.CondensateVdot * ReportingConstant;
   14290              : 
   14291            2 :         state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).VdotAvailSupply(thisDXCoil.CondensateTankSupplyARRID) =
   14292            2 :             thisDXCoil.CondensateVdot;
   14293            2 :         state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).TwaterSupply(thisDXCoil.CondensateTankSupplyARRID) = thisDXCoil.OutletAirTemp;
   14294              :     }
   14295              : 
   14296       539064 :     state.dataAirLoop->LoopDXCoilRTF = max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
   14297       539064 :     if (thisDXCoil.AirLoopNum > 0) {
   14298       223282 :         state.dataAirLoop->AirLoopAFNInfo(thisDXCoil.AirLoopNum).AFNLoopDXCoilRTF =
   14299       223282 :             max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
   14300              :     }
   14301       539064 : }
   14302              : 
   14303            6 : void CalcTwoSpeedDXCoilStandardRating(EnergyPlusData &state, int const DXCoilNum)
   14304              : {
   14305              :     // SUBROUTINE INFORMATION:
   14306              :     //       AUTHOR         B. Griffith, (Derived from CalcDXCoilStandardRating by Bereket Nigusse & Chandan Sharma)
   14307              :     //       DATE WRITTEN   July 2012
   14308              : 
   14309              :     // PURPOSE OF THIS SUBROUTINE:
   14310              :     // Calculate the following
   14311              :     //                 (1) Standard Rated (net) Cooling Capacity
   14312              :     //                 (2) Energy Efficiency Ratio (EER),
   14313              :     //                 (3) Integrated Energy Efficiency Ratio (IEER)
   14314              : 
   14315              :     // REFERENCES:
   14316              :     // ANSI/AHRI Standard 340/360-2007, Performance Rating of Commercial and Industrial Unitary Air-Conditioning and
   14317              :     //  Heat Pump Equipment, Air-Conditioning, Heating, and Refrigeration Institute, Arlington VA.
   14318              : 
   14319              :     // Using/Aliasing
   14320              :     using Curve::CurveValue;
   14321              :     using namespace OutputReportPredefined;
   14322              : 
   14323              :     // SUBROUTINE PARAMETER DEFINITIONS:
   14324              :     // AHRI Standard 340/360-2007 Performance Rating of Commercial and Industrial Unitary Air-Conditioning and Heat Pump Equipment
   14325            6 :     Real64 constexpr CoolingCoilInletAirWetBulbTempRated(19.4); // 19.44C (67F)
   14326            6 :     Real64 constexpr CoolingCoilInletAirDryBulbTempRated(26.7);
   14327            6 :     Real64 constexpr OutdoorUnitInletAirDryBulbTempRated(35.0); // 35.00C (95F)
   14328            6 :     static Array1D<Real64> const OutdoorUnitInletAirDryBulbTempPLTestPoint(3, {27.5, 20.0, 18.3});
   14329            6 :     static Array1D<Real64> const NetCapacityFactorPLTestPoint(3, {0.75, 0.50, 0.25});
   14330            6 :     Real64 constexpr ConvFromSIToIP(3.412141633); // Conversion from SI to IP [3.412 Btu/hr-W]
   14331              : 
   14332            6 :     Real64 constexpr AirMassFlowRatioRated(1.0); // AHRI test is at the design flow rate
   14333              :     // and hence AirMassFlowRatio is 1.0
   14334              : 
   14335            6 :     Real64 constexpr DefaultFanPowerPerEvapAirFlowRate(773.3);      // 365 W/1000 scfm or 773.3 W/(m3/s). The AHRI standard
   14336            6 :     Real64 constexpr DefaultFanPowerPerEvapAirFlowRateSEER2(934.4); // 441 W/1000 scfm or 934.4 W/(m3/s). The AHRI standard
   14337              :     // specifies a nominal/default fan electric power consumption per rated air
   14338              :     // volume flow rate to account for indoor fan electric power consumption
   14339              :     // when the standard tests are conducted on units that do not have an
   14340              :     // indoor air circulating fan. Used if user doesn't enter a specific value.
   14341              : 
   14342              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   14343              :     static constexpr std::string_view RoutineName("CalcTwoSpeedDXCoilStandardRating");
   14344              : 
   14345            6 :     auto &NetCoolingCapRated = state.dataDXCoils->NetCoolingCapRated;
   14346            6 :     auto &EER = state.dataDXCoils->EER;
   14347            6 :     auto &IEER = state.dataDXCoils->IEER;
   14348            6 :     auto &TotCapTempModFac = state.dataDXCoils->TotCapTempModFac;
   14349            6 :     auto &TotCapFlowModFac = state.dataDXCoils->TotCapFlowModFac;
   14350            6 :     auto &EIRTempModFac = state.dataDXCoils->EIRTempModFac;
   14351            6 :     auto &EIRFlowModFac = state.dataDXCoils->EIRFlowModFac;
   14352            6 :     auto &TempDryBulb_Leaving_Apoint = state.dataDXCoils->TempDryBulb_Leaving_Apoint;
   14353              : 
   14354            6 :     constexpr Real64 AccuracyTolerance(0.2); // tolerance in AHRI 340/360 Table 6 note 1
   14355            6 :     constexpr int MaximumIterations(1000);
   14356              :     Real64 EIR;
   14357              :     Real64 TotalElecPowerRated;
   14358            6 :     Array1D<Real64> EER_TestPoint_SI(4);      // 1 = A, 2 = B, 3= C, 4= D
   14359            6 :     Array1D<Real64> EER_TestPoint_IP(4);      // 1 = A, 2 = B, 3= C, 4= D
   14360            6 :     Array1D<Real64> NetCapacity_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
   14361            6 :     Array1D<Real64> NetPower_TestPoint(4);    // 1 = A, 2 = B, 3= C, 4= D
   14362            6 :     Array1D<Real64> SupAirMdot_TestPoint(4);  // 1 = A, 2 = B, 3= C, 4= D
   14363              : 
   14364              :     Real64 HighSpeedNetCoolingCap;
   14365              :     Real64 LowSpeedNetCoolingCap;
   14366              : 
   14367              :     Real64 PartLoadAirMassFlowRate;
   14368              :     Real64 AirMassFlowRatio;
   14369              :     int SolverFlag;
   14370              :     Real64 EIR_HighSpeed;
   14371              :     Real64 EIR_LowSpeed;
   14372              :     int FanInletNode;
   14373              :     int FanOutletNode;
   14374              :     int Iter;
   14375              :     Real64 ExternalStatic;
   14376              :     Real64 FanStaticPressureRise;
   14377              :     Real64 FanHeatCorrection;
   14378              :     Real64 FanPowerCorrection;
   14379            6 :     Real64 FanPowerPerEvapAirFlowRate = 0.0;
   14380              :     Real64 FanPowerPerEvapAirFlowRateSEER2;
   14381              :     Real64 SpeedRatio;
   14382              :     Real64 CycRatio;
   14383              :     Real64 TargetNetCapacity;
   14384              :     Real64 SupplyAirHumRat;
   14385              :     Real64 SupplyAirRho;
   14386              :     Real64 SupplyAirVolFlowRate;
   14387              :     Real64 HighSpeedTotCoolingCap;
   14388              :     Real64 LowSpeedTotCoolingCap;
   14389              :     Real64 TotCoolingCap;
   14390              :     Real64 NetCoolingCap;
   14391              :     Real64 PLF;
   14392              :     Real64 RunTimeFraction;
   14393              :     Real64 LowerBoundMassFlowRate;
   14394              :     int PartLoadTestPoint;
   14395              :     int countStaticInputs;
   14396              :     int index;
   14397              : 
   14398              :     // Formats
   14399              :     static constexpr std::string_view Header(
   14400              :         "! <VAV DX Cooling Coil Standard Rating Information>, DX Coil Type, DX Coil Name, Fan Type, Fan Name, Standard Net Cooling Capacity "
   14401              :         "{{W}}, Standard Net Cooling Capacity {{Btu/h}}, IEER {{Btu/W-h}}, COP 100% Capacity {{W/W}}, COP 75% Capacity {{W/W}}, COP 50% Capacity "
   14402              :         "{{W/W}}, COP 25% Capacity {{W/W}}, EER 100% Capacity {{Btu/W-h}}, EER 75% Capacity {{Btu/W-h}}, EER 50% Capacity {{Btu/W-h}}, EER 25% "
   14403              :         "Capacity {{Btu/W-h}}, Supply Air Flow 100% {{kg/s}}, Supply Air Flow 75% {{kg/s}},Supply Air Flow 50% {{kg/s}},Supply Air Flow 25% "
   14404              :         "{{kg/s}}\n");
   14405              : 
   14406              :     static constexpr std::string_view Format_891{
   14407              :         " VAV DX Cooling Coil Standard Rating Information, "
   14408              :         "{},{},{},{},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.4R},{:.4R},{:.4R},{:.4R},\n"};
   14409              : 
   14410            6 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   14411              : 
   14412              :     // Get fan index and name if not already available
   14413            6 :     if (thisDXCoil.SupplyFanIndex == 0)
   14414            2 :         GetFanIndexForTwoSpeedCoil(state, DXCoilNum, thisDXCoil.SupplyFanIndex, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType);
   14415            6 :     if (thisDXCoil.SupplyFanIndex == 0) { // didn't find VAV fan, do not rate this coil
   14416            0 :         thisDXCoil.RateWithInternalStaticAndFanObject = false;
   14417            0 :         ShowWarningError(state,
   14418            0 :                          format("CalcTwoSpeedDXCoilStandardRating: Did not find an appropriate fan associated with DX coil named = \"{}\". Standard "
   14419              :                                 "Ratings will not be calculated.",
   14420            0 :                                 thisDXCoil.Name));
   14421            0 :         return;
   14422              :     }
   14423            6 :     bool saveTurnFansOn = state.dataHVACGlobal->TurnFansOn;
   14424            6 :     bool saveTurnFansOff = state.dataHVACGlobal->TurnFansOff;
   14425            6 :     state.dataHVACGlobal->TurnFansOn = true; // enable fans, will override fan availability schedule if needed
   14426            6 :     state.dataHVACGlobal->TurnFansOff = false;
   14427              : 
   14428              :     // Calculate the Indoor fan electric power consumption.  The electric power consumption is estimated
   14429              :     // using either user supplied or AHRI default value for fan power per air volume flow rate
   14430            6 :     if (thisDXCoil.RateWithInternalStaticAndFanObject) {
   14431              : 
   14432            3 :         TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
   14433            3 :         TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
   14434           15 :         for (Iter = 1; Iter <= 4; ++Iter) { // iterative solution in the event that net capacity is near a threshold for external static
   14435              :             // Obtain external static pressure from Table 5 in ANSI/AHRI Std. 340/360-2007
   14436           12 :             if (NetCoolingCapRated <= 21000.0) {
   14437           12 :                 ExternalStatic = 50.0;
   14438            0 :             } else if (21000.0 < NetCoolingCapRated && NetCoolingCapRated <= 30800.0) {
   14439            0 :                 ExternalStatic = 60.0;
   14440            0 :             } else if (30800.0 < NetCoolingCapRated && NetCoolingCapRated <= 39300.0) {
   14441            0 :                 ExternalStatic = 70.0;
   14442            0 :             } else if (39300.0 < NetCoolingCapRated && NetCoolingCapRated <= 61500.0) {
   14443            0 :                 ExternalStatic = 90.0;
   14444            0 :             } else if (61500.0 < NetCoolingCapRated && NetCoolingCapRated <= 82100.0) {
   14445            0 :                 ExternalStatic = 100.0;
   14446            0 :             } else if (82100.0 < NetCoolingCapRated && NetCoolingCapRated <= 103000.0) {
   14447            0 :                 ExternalStatic = 110.0;
   14448            0 :             } else if (103000.0 < NetCoolingCapRated && NetCoolingCapRated <= 117000.0) {
   14449            0 :                 ExternalStatic = 140.0;
   14450            0 :             } else if (117000.0 < NetCoolingCapRated && NetCoolingCapRated <= 147000.0) {
   14451            0 :                 ExternalStatic = 160.0;
   14452            0 :             } else if (147000.0 < NetCoolingCapRated) {
   14453            0 :                 ExternalStatic = 190.0;
   14454              :             }
   14455           12 :             FanStaticPressureRise = ExternalStatic + thisDXCoil.InternalStaticPressureDrop;
   14456           12 :             FanInletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->inletNodeNum;
   14457           12 :             FanOutletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->outletNodeNum;
   14458              : 
   14459              :             // set node state variables in preparation for fan model.
   14460           12 :             state.dataLoopNodes->Node(FanInletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
   14461           12 :             state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
   14462           12 :             state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
   14463           12 :             state.dataLoopNodes->Node(FanInletNode).HumRat = PsyWFnTdbTwbPb(
   14464           12 :                 state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
   14465           12 :             state.dataLoopNodes->Node(FanInletNode).Enthalpy =
   14466           12 :                 PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, state.dataLoopNodes->Node(FanInletNode).HumRat);
   14467           12 :             state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
   14468           12 :             FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
   14469              : 
   14470           12 :             FanHeatCorrection = state.dataLoopNodes->Node(FanInletNode).MassFlowRate *
   14471           12 :                                 (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
   14472              : 
   14473           12 :             NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
   14474              :         }
   14475              : 
   14476              :     } else {
   14477            3 :         FanPowerPerEvapAirFlowRate = DefaultFanPowerPerEvapAirFlowRate;
   14478            3 :         FanPowerPerEvapAirFlowRateSEER2 = DefaultFanPowerPerEvapAirFlowRateSEER2;
   14479            3 :         FanPowerCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
   14480            3 :         FanHeatCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
   14481            3 :         TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
   14482            3 :         TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
   14483            3 :         NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
   14484              :     }
   14485              : 
   14486            6 :     SupAirMdot_TestPoint(1) = thisDXCoil.RatedAirMassFlowRate(1);
   14487              : 
   14488              :     // Calculate Energy Efficiency Ratio (EER) at (19.44C WB and 35.0C DB ), ANSI/AHRI Std. 340/360
   14489            6 :     EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
   14490            6 :     EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatioRated);
   14491            6 :     if (thisDXCoil.RatedCOP(1) > 0.0) {
   14492              :         // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
   14493            6 :         EIR = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP(1);
   14494              :     } else {
   14495            0 :         EIR = 0.0;
   14496              :     }
   14497            6 :     TotalElecPowerRated = EIR * (thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac) + FanPowerCorrection;
   14498              : 
   14499            6 :     if (TotalElecPowerRated > 0.0) {
   14500            6 :         EER = NetCoolingCapRated / TotalElecPowerRated;
   14501              :     } else {
   14502            0 :         EER = 0.0;
   14503              :     }
   14504              : 
   14505              :     // IEER - A point 100 % net capacity
   14506            6 :     EER_TestPoint_SI(1) = EER;
   14507            6 :     EER_TestPoint_IP(1) = EER * ConvFromSIToIP;
   14508              : 
   14509              :     // find coil leaving drybulb at point A, with full rated air flow rate.
   14510              :     // init coil
   14511            6 :     thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
   14512            6 :     thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(1);
   14513            6 :     thisDXCoil.InletAirTemp = 26.7;
   14514            6 :     thisDXCoil.InletAirHumRat = PsyWFnTdbTwbPb(state, 26.7, 19.4, state.dataEnvrn->OutBaroPress, RoutineName);
   14515            6 :     thisDXCoil.InletAirEnthalpy = PsyHFnTdbW(26.7, thisDXCoil.InletAirHumRat);
   14516              : 
   14517            6 :     Real64 const heldOutDryBulb = state.dataEnvrn->OutDryBulbTemp;
   14518            6 :     if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
   14519            0 :         state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempRated;
   14520              :     } else {
   14521            6 :         state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempRated;
   14522              :     }
   14523            6 :     SpeedRatio = 1.0;
   14524            6 :     CycRatio = 1.0;
   14525            6 :     CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
   14526            6 :     TempDryBulb_Leaving_Apoint = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum); // store result
   14527              : 
   14528              :     // IEER - part load test points ***************************************************
   14529           24 :     for (PartLoadTestPoint = 1; PartLoadTestPoint <= 3; ++PartLoadTestPoint) {
   14530              :         // determine minimum unloading capacity fraction at point B conditions.
   14531           18 :         if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
   14532            0 :             state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
   14533              :         } else {
   14534           18 :             state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
   14535              :         }
   14536              : 
   14537           18 :         TargetNetCapacity = NetCapacityFactorPLTestPoint(PartLoadTestPoint) * NetCoolingCapRated;
   14538              : 
   14539              :         // set up parameters for the solver here
   14540           18 :         Real64 const par3 = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
   14541           18 :         Real64 par7 = FanPowerPerEvapAirFlowRate;
   14542           18 :         int fanInNode = 0;
   14543           18 :         int fanOutNode = 0;
   14544           18 :         Real64 externalStatic = 0.0;
   14545           18 :         int fanIndex = 0;
   14546           18 :         if (thisDXCoil.RateWithInternalStaticAndFanObject) {
   14547            9 :             par7 = 0.0;
   14548            9 :             fanInNode = FanInletNode;
   14549            9 :             fanOutNode = FanOutletNode;
   14550            9 :             externalStatic = ExternalStatic;
   14551            9 :             fanIndex = thisDXCoil.SupplyFanIndex;
   14552              :         }
   14553              : 
   14554           18 :         LowerBoundMassFlowRate = 0.01 * thisDXCoil.RatedAirMassFlowRate(1);
   14555              : 
   14556              :         // OK, so there are two variables here which are const at compile time.  The question is whether compile time data needs to be
   14557              :         // explicitly captured in the lambda capture block.
   14558              :         // For GCC it currently doesn't mind whether they are captured or not, no warnings.
   14559              :         // On Clang, if you list them, there is a compiler warning.
   14560              :         // On our version of MSVC, if you take them out, the compiler will fail.  On newer versions, I think it's OK.  Should be soon anyway.
   14561              :         // To avoid this, you could pragma away the Clang warning in this section, or tell Clang to hush via compiler flags.  However, to keep things
   14562              :         // really simple, I'm just going to use two local variables and capture them instead of the original data.
   14563              :         // I'm not sure if there are any more of these instances in the codebase.  If so I am going to tag all of them with CONST_LAMBDA_CAPTURE.
   14564           18 :         Real64 dbRated = CoolingCoilInletAirDryBulbTempRated;
   14565           18 :         Real64 wbRated = CoolingCoilInletAirWetBulbTempRated;
   14566              :         auto f = // (AUTO_OK_LAMBDA)
   14567         3318 :             [&state, DXCoilNum, TempDryBulb_Leaving_Apoint, TargetNetCapacity, par3, par7, fanInNode, fanOutNode, externalStatic, dbRated, wbRated](
   14568              :                 Real64 SupplyAirMassFlowRate) {
   14569              :                 static constexpr std::string_view RoutineName("CalcTwoSpeedDXCoilIEERResidual");
   14570         3300 :                 auto &coil = state.dataDXCoils->DXCoil(DXCoilNum);
   14571         3300 :                 Real64 AirMassFlowRatio = 0.0;
   14572         3300 :                 if (coil.RatedAirMassFlowRate(1) > 0.0) {
   14573         3300 :                     AirMassFlowRatio = SupplyAirMassFlowRate / coil.RatedAirMassFlowRate(1);
   14574              :                 }
   14575         3300 :                 Real64 SupplyAirHumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
   14576         3300 :                 Real64 SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, dbRated, SupplyAirHumRat, RoutineName);
   14577         3300 :                 Real64 SupplyAirVolFlowRate = SupplyAirMassFlowRate / SupplyAirRho;
   14578              : 
   14579              :                 Real64 FanHeatCorrection;
   14580         3300 :                 if (coil.RateWithInternalStaticAndFanObject) {
   14581              :                     // modify external static per AHRI 340/360, Table 6, note 1.
   14582         1539 :                     Real64 FanStaticPressureRise = coil.InternalStaticPressureDrop + (externalStatic * pow_2(AirMassFlowRatio));
   14583         1539 :                     auto &inletNode = state.dataLoopNodes->Node(fanInNode);
   14584         1539 :                     auto &outletNode = state.dataLoopNodes->Node(fanOutNode);
   14585         1539 :                     inletNode.MassFlowRate = SupplyAirMassFlowRate;
   14586         1539 :                     outletNode.MassFlowRate = SupplyAirMassFlowRate;
   14587         1539 :                     inletNode.Temp = dbRated;
   14588         1539 :                     inletNode.HumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
   14589         1539 :                     inletNode.Enthalpy = PsyHFnTdbW(dbRated, inletNode.HumRat);
   14590         1539 :                     state.dataFans->fans(coil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
   14591         1539 :                     FanHeatCorrection = SupplyAirMassFlowRate * (outletNode.Enthalpy - inletNode.Enthalpy);
   14592              :                 } else {
   14593         1761 :                     FanHeatCorrection = par7 * SupplyAirVolFlowRate;
   14594              :                 }
   14595              : 
   14596         3300 :                 Real64 TotCapFlowModFac = Curve::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
   14597         3300 :                 Real64 TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp(1), wbRated, par3);
   14598         3300 :                 Real64 HighSpeedNetCoolingCap = coil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
   14599              : 
   14600              :                 // TotCapFlowModFac = CurveManager::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
   14601         3300 :                 TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp2, wbRated, par3);
   14602         3300 :                 Real64 LowSpeedNetCoolingCap = coil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
   14603              : 
   14604              :                 Real64 SpeedRatio;
   14605              :                 Real64 CycRatio;
   14606         3300 :                 if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
   14607         1899 :                     CycRatio = 1.0;
   14608         1899 :                     SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
   14609              :                 } else { // minimum unloading limit exceeded for no cycling
   14610         1401 :                     SpeedRatio = 0.0;
   14611         1401 :                     CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
   14612              :                 }
   14613              : 
   14614         3300 :                 coil.InletAirMassFlowRate = SupplyAirMassFlowRate;
   14615         3300 :                 CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
   14616         3300 :                 Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum);
   14617         3300 :                 return TempDryBulb_Leaving_Apoint - OutletAirTemp;
   14618           18 :             };
   14619           18 :         General::SolveRoot(state,
   14620              :                            AccuracyTolerance,
   14621              :                            MaximumIterations,
   14622              :                            SolverFlag,
   14623              :                            PartLoadAirMassFlowRate,
   14624              :                            f,
   14625              :                            LowerBoundMassFlowRate,
   14626           18 :                            thisDXCoil.RatedAirMassFlowRate(1));
   14627              : 
   14628           18 :         if (SolverFlag == -1) {
   14629              : 
   14630            0 :             ShowWarningError(state, "CalcTwoSpeedDXCoilStandardRating: air flow rate solver failed. Iteration limit exceeded ");
   14631              : 
   14632            0 :             SupAirMdot_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14633            0 :             EER_TestPoint_SI(1 + PartLoadTestPoint) = -999.0;
   14634            0 :             EER_TestPoint_IP(1 + PartLoadTestPoint) = -999.0;
   14635            0 :             NetCapacity_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14636            0 :             NetPower_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14637              : 
   14638           18 :         } else if (SolverFlag == -2) {
   14639            0 :             ShowWarningError(state, "CalcTwoSpeedDXCoilStandardRating: air flow rate solver failed. root not bounded ");
   14640              : 
   14641            0 :             SupAirMdot_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14642            0 :             EER_TestPoint_SI(1 + PartLoadTestPoint) = -999.0;
   14643            0 :             EER_TestPoint_IP(1 + PartLoadTestPoint) = -999.0;
   14644            0 :             NetCapacity_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14645            0 :             NetPower_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14646              :         } else {
   14647              :             // now we have the supply air flow rate
   14648           18 :             SupAirMdot_TestPoint(1 + PartLoadTestPoint) = PartLoadAirMassFlowRate;
   14649           18 :             AirMassFlowRatio = PartLoadAirMassFlowRate / thisDXCoil.RatedAirMassFlowRate(1);
   14650           18 :             SupplyAirHumRat = PsyWFnTdbTwbPb(
   14651           18 :                 state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
   14652           18 :             SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat, RoutineName);
   14653           18 :             SupplyAirVolFlowRate = PartLoadAirMassFlowRate / SupplyAirRho;
   14654              : 
   14655           18 :             if (thisDXCoil.RateWithInternalStaticAndFanObject) {
   14656            9 :                 FanStaticPressureRise = thisDXCoil.InternalStaticPressureDrop + (ExternalStatic * pow_2(AirMassFlowRatio));
   14657            9 :                 state.dataLoopNodes->Node(FanInletNode).MassFlowRate = PartLoadAirMassFlowRate;
   14658            9 :                 state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
   14659            9 :                 state.dataLoopNodes->Node(FanInletNode).HumRat = SupplyAirHumRat;
   14660            9 :                 state.dataLoopNodes->Node(FanInletNode).Enthalpy = PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat);
   14661              : 
   14662            9 :                 state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
   14663            9 :                 FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
   14664              : 
   14665            9 :                 FanHeatCorrection =
   14666            9 :                     PartLoadAirMassFlowRate * (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
   14667              : 
   14668              :             } else {
   14669            9 :                 FanPowerCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
   14670            9 :                 FanHeatCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
   14671              :             }
   14672              : 
   14673           18 :             TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatio);
   14674              :             //    Warn user if curve output goes negative
   14675           18 :             if (TotCapFlowModFac < 0.0) {
   14676            0 :                 if (thisDXCoil.CCapFFlowErrorIndex == 0) {
   14677            0 :                     ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
   14678            0 :                     ShowContinueError(
   14679              :                         state,
   14680            0 :                         format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).", TotCapFlowModFac));
   14681            0 :                     ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
   14682            0 :                     ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
   14683              :                 }
   14684            0 :                 ShowRecurringWarningErrorAtEnd(
   14685              :                     state,
   14686            0 :                     format("{}{}\"{}\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
   14687              :                            RoutineName,
   14688            0 :                            thisDXCoil.DXCoilType,
   14689            0 :                            thisDXCoil.Name),
   14690            0 :                     thisDXCoil.CCapFFlowErrorIndex,
   14691              :                     TotCapFlowModFac,
   14692              :                     TotCapFlowModFac);
   14693            0 :                 TotCapFlowModFac = 0.0;
   14694              :             }
   14695              : 
   14696           54 :             TotCapTempModFac = CurveValue(
   14697           18 :                 state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
   14698              :             //    Warn user if curve output goes negative
   14699           18 :             if (TotCapTempModFac < 0.0) {
   14700            0 :                 if (thisDXCoil.CCapFTempErrorIndex == 0) {
   14701            0 :                     ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
   14702            0 :                     ShowContinueError(
   14703              :                         state,
   14704            0 :                         format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
   14705            0 :                     ShowContinueError(state,
   14706            0 :                                       format(" Negative value occurs using a coil inlet wet-bulb temperature of {:.1T} and an outdoor unit inlet air "
   14707              :                                              "dry-bulb temperature of {:.1T}.",
   14708              :                                              CoolingCoilInletAirWetBulbTempRated,
   14709              :                                              OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint)));
   14710            0 :                     ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
   14711              :                 }
   14712            0 :                 ShowRecurringWarningErrorAtEnd(
   14713              :                     state,
   14714            0 :                     format("{}{} \"{}\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
   14715              :                            RoutineName,
   14716            0 :                            thisDXCoil.DXCoilType,
   14717            0 :                            thisDXCoil.Name),
   14718            0 :                     thisDXCoil.CCapFTempErrorIndex,
   14719              :                     TotCapTempModFac,
   14720              :                     TotCapTempModFac);
   14721            0 :                 TotCapTempModFac = 0.0;
   14722              :             }
   14723              : 
   14724           18 :             HighSpeedTotCoolingCap = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac;
   14725           18 :             HighSpeedNetCoolingCap = HighSpeedTotCoolingCap - FanHeatCorrection;
   14726              : 
   14727           54 :             EIRTempModFac = CurveValue(
   14728           18 :                 state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
   14729           18 :             EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
   14730           18 :             if (thisDXCoil.RatedCOP(1) > 0.0) {
   14731              :                 // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
   14732           18 :                 EIR_HighSpeed = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP(1);
   14733              :             } else {
   14734            0 :                 EIR = 0.0;
   14735              :             }
   14736              : 
   14737              :             // TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatio);
   14738           36 :             TotCapTempModFac = CurveValue(
   14739           18 :                 state, thisDXCoil.CCapFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
   14740              :             //    Warn user if curve output goes negative
   14741           18 :             if (TotCapTempModFac < 0.0) {
   14742            0 :                 if (thisDXCoil.CCapFTempErrorIndex == 0) {
   14743            0 :                     ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
   14744            0 :                     ShowContinueError(
   14745              :                         state,
   14746            0 :                         format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
   14747            0 :                     ShowContinueError(state,
   14748            0 :                                       format(" Negative value occurs using a coil inlet wet-bulb temperature of {:.1T} and an outdoor unit inlet air "
   14749              :                                              "dry-bulb temperature of {:.1T}.",
   14750              :                                              CoolingCoilInletAirWetBulbTempRated,
   14751              :                                              OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint)));
   14752            0 :                     ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
   14753              :                 }
   14754            0 :                 ShowRecurringWarningErrorAtEnd(
   14755              :                     state,
   14756            0 :                     format("{}{} \"{}\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
   14757              :                            RoutineName,
   14758            0 :                            thisDXCoil.DXCoilType,
   14759            0 :                            thisDXCoil.Name),
   14760            0 :                     thisDXCoil.CCapFTempErrorIndex,
   14761              :                     TotCapTempModFac,
   14762              :                     TotCapTempModFac);
   14763            0 :                 TotCapTempModFac = 0.0;
   14764              :             }
   14765              : 
   14766           18 :             LowSpeedTotCoolingCap = thisDXCoil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac;
   14767           18 :             LowSpeedNetCoolingCap = LowSpeedTotCoolingCap - FanHeatCorrection;
   14768              : 
   14769           36 :             EIRTempModFac = CurveValue(
   14770           18 :                 state, thisDXCoil.EIRFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
   14771           18 :             EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
   14772           18 :             if (thisDXCoil.RatedCOP2 > 0.0) {
   14773              :                 // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
   14774           18 :                 EIR_LowSpeed = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP2;
   14775              :             } else {
   14776            0 :                 EIR_LowSpeed = 0.0;
   14777              :             }
   14778              : 
   14779           18 :             if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
   14780           12 :                 CycRatio = 1.0;
   14781           12 :                 SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
   14782           12 :                 TotCoolingCap = HighSpeedTotCoolingCap * SpeedRatio + LowSpeedTotCoolingCap * (1.0 - SpeedRatio);
   14783           12 :                 NetCoolingCap = TotCoolingCap - FanHeatCorrection;
   14784           12 :                 EIR = EIR_HighSpeed * SpeedRatio + EIR_LowSpeed * (1.0 - SpeedRatio);
   14785           12 :                 TotalElecPowerRated = TotCoolingCap * EIR + FanPowerCorrection;
   14786           12 :                 EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
   14787           12 :                 EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
   14788           12 :                 NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
   14789           12 :                 NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
   14790              :             } else { // minimum unloading limit exceeded without cycling, so cycle
   14791            6 :                 SpeedRatio = 0.0;
   14792            6 :                 CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
   14793            6 :                 PLF = CurveValue(state, thisDXCoil.PLFFPLR(1), CycRatio);
   14794            6 :                 if (PLF < 0.7) {
   14795            0 :                     PLF = 0.7;
   14796              :                 }
   14797            6 :                 RunTimeFraction = CycRatio / PLF;
   14798            6 :                 RunTimeFraction = min(RunTimeFraction, 1.0);
   14799            6 :                 TotCoolingCap = LowSpeedTotCoolingCap * RunTimeFraction;
   14800            6 :                 NetCoolingCap = TotCoolingCap - FanHeatCorrection;
   14801            6 :                 TotalElecPowerRated = LowSpeedTotCoolingCap * EIR_LowSpeed * RunTimeFraction + FanPowerCorrection;
   14802            6 :                 EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
   14803            6 :                 EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
   14804            6 :                 NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
   14805            6 :                 NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
   14806              :             }
   14807              :         }
   14808              :     } // loop over 3 part load test points
   14809            6 :     state.dataHVACGlobal->TurnFansOn = saveTurnFansOn;
   14810            6 :     state.dataHVACGlobal->TurnFansOff = saveTurnFansOff;
   14811              : 
   14812            6 :     IEER = (0.02 * EER_TestPoint_IP(1)) + (0.617 * EER_TestPoint_IP(2)) + (0.238 * EER_TestPoint_IP(3)) + (0.125 * EER_TestPoint_IP(4));
   14813              :     // CalcMultiSpeedDXCoilCooling() //??
   14814              :     // begin output
   14815            6 :     if (state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite) {
   14816            4 :         print(state.files.eio, Header);
   14817            4 :         state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite = false;
   14818            8 :         state.dataOutRptPredefined->pdstVAVDXCoolCoil =
   14819            4 :             newPreDefSubTable(state, state.dataOutRptPredefined->pdrEquip, "VAV DX Cooling Standard Rating Details");
   14820            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilType =
   14821            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "DX Cooling Coil Type");
   14822            4 :         state.dataOutRptPredefined->pdchVAVDXFanName = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Associated Fan");
   14823            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI =
   14824            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Net Cooling Capacity [W]");
   14825            4 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP [W/W]");
   14826            4 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER [Btu/W-h]");
   14827            4 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "IEER [Btu/W-h]");
   14828            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA =
   14829            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 100% [kg/s]");
   14830            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B =
   14831            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 75% Capacity [W/W]");
   14832            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP =
   14833            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 75% Capacity [Btu/W-h]");
   14834            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB =
   14835            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 75% [kg/s]");
   14836            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C =
   14837            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 50% Capacity [W/W]");
   14838            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP =
   14839            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 50% Capacity [Btu/W-h]");
   14840            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC =
   14841            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 50% [kg/s]");
   14842            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D =
   14843            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 25% Capacity [W/W]");
   14844            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP =
   14845            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 25% Capacity [Btu/W-h]");
   14846            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD =
   14847            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 25% [kg/s]");
   14848              : 
   14849              :         // determine footnote content
   14850            4 :         countStaticInputs = 0;
   14851            8 :         for (index = 1; index <= state.dataDXCoils->NumDXCoils; ++index) {
   14852              : 
   14853            7 :             if (state.dataDXCoils->DXCoil(index).RateWithInternalStaticAndFanObject &&
   14854            3 :                 state.dataDXCoils->DXCoil(index).DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
   14855            3 :                 ++countStaticInputs;
   14856              :             }
   14857              :         }
   14858              : 
   14859            4 :         if (countStaticInputs == state.dataDXCoils->NumDXMulSpeedCoils) {
   14860            6 :             addFootNoteSubTable(state,
   14861            3 :                                 state.dataOutRptPredefined->pdstVAVDXCoolCoil,
   14862              :                                 "Packaged VAV unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2");
   14863            1 :         } else if (countStaticInputs == 0) {
   14864            2 :             addFootNoteSubTable(state,
   14865            1 :                                 state.dataOutRptPredefined->pdstVAVDXCoolCoil,
   14866              :                                 "Indoor-coil-only unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2, with "
   14867              :                                 "supply fan specific power at 365 {{W/1000cfm}} (773.3 {{W/(m3/s)}})");
   14868              :         } else { // both
   14869            0 :             addFootNoteSubTable(state,
   14870            0 :                                 state.dataOutRptPredefined->pdstVAVDXCoolCoil,
   14871              :                                 "Packaged VAV unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2, "
   14872              :                                 "indoor-coil-only units with supply fan specific power at 365 {{W/1000cfm}} (773.3 {{W/(m3/s)}})");
   14873              :         }
   14874              :     }
   14875              : 
   14876            0 :     const auto &fan_type_name = [&]() -> std::pair<const char *, std::string> {
   14877            6 :         if (thisDXCoil.RateWithInternalStaticAndFanObject) {
   14878            3 :             return {"Fan:VariableVolume", thisDXCoil.SupplyFanName};
   14879              :         } else {
   14880            3 :             return {"N/A", "N/A"};
   14881              :         }
   14882            6 :     }();
   14883              : 
   14884            6 :     print(state.files.eio,
   14885              :           Format_891,
   14886              :           "Coil:Cooling:DX:TwoSpeed",
   14887            6 :           thisDXCoil.Name,
   14888            6 :           fan_type_name.first,
   14889            6 :           fan_type_name.second,
   14890              :           NetCoolingCapRated,
   14891            6 :           (NetCoolingCapRated * ConvFromSIToIP),
   14892              :           IEER,
   14893              :           EER_TestPoint_SI(1),
   14894              :           EER_TestPoint_SI(2),
   14895              :           EER_TestPoint_SI(3),
   14896              :           EER_TestPoint_SI(4),
   14897              :           EER_TestPoint_IP(1),
   14898              :           EER_TestPoint_IP(2),
   14899              :           EER_TestPoint_IP(3),
   14900              :           EER_TestPoint_IP(4),
   14901              :           SupAirMdot_TestPoint(1),
   14902              :           SupAirMdot_TestPoint(2),
   14903              :           SupAirMdot_TestPoint(3),
   14904              :           SupAirMdot_TestPoint(4));
   14905              : 
   14906            6 :     if (state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag) {
   14907              :         static constexpr std::string_view Format_994(
   14908              :             "! <DX Cooling Coil Standard Rating Information>, Component Type, Component Name, Standard Rating (Net) "
   14909              :             "Cooling Capacity {W}, Standard Rating Net COP {W/W}, EER {Btu/W-h}, SEER User {Btu/W-h}, SEER Standard {Btu/W-h}, "
   14910              :             "IEER "
   14911              :             "{Btu/W-h}");
   14912            4 :         print(state.files.eio, "{}\n", Format_994);
   14913            4 :         state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag = false;
   14914              :     }
   14915              :     static constexpr std::string_view Format_995(" DX Cooling Coil Standard Rating Information, {}, {}, {:.1R}, {}, {}, {}, {}, {}\n");
   14916            6 :     print(state.files.eio,
   14917              :           Format_995,
   14918              :           "Coil:Cooling:DX:TwoSpeed",
   14919            6 :           thisDXCoil.Name,
   14920              :           NetCoolingCapRated,
   14921              :           EER_TestPoint_SI(1),
   14922              :           EER_TestPoint_IP(1),
   14923              :           "N/A",
   14924              :           "N/A",
   14925              :           IEER);
   14926              : 
   14927            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
   14928              :     // W to tons
   14929            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilNetCapSI, thisDXCoil.Name, NetCoolingCapRated, 1);
   14930              : 
   14931              :     // TODO: Commercial and industrial unitary air-conditioning condensing units with a capacity greater than 135,000 Btu/h (39564.59445 Watts)
   14932              :     // as defined in ANSI/AHRI Standard 365(I-P). | Scope 2.2.6 (ANSI/AHRI 340-360 2022)
   14933              :     //
   14934              :     // These will convert with a factor of 1 which is ok
   14935              :     // SEER | Capacity less than 65K Btu/h (19050 W) - calculated as per AHRI Standard 210/240-2023.
   14936            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
   14937            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilEERIP, thisDXCoil.Name, EER_TestPoint_IP(1), 2);
   14938              :     // These will convert with a factor of 1 which is ok
   14939              :     // IEER | Capacity of 65K Btu/h (19050 W) to less than 135K Btu/h (39565 W) - calculated as per AHRI Standard 340/360-2022.
   14940            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 1);
   14941            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERUserIP, thisDXCoil.Name, "N/A");
   14942            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERStandardIP, thisDXCoil.Name, "N/A");
   14943              : 
   14944            6 :     addFootNoteSubTable(state, state.dataOutRptPredefined->pdstDXCoolCoil, StandardRatings::AHRI2017FOOTNOTE);
   14945              : 
   14946            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
   14947            6 :     if (thisDXCoil.RateWithInternalStaticAndFanObject) {
   14948            3 :         PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, thisDXCoil.SupplyFanName);
   14949              :     } else {
   14950            3 :         PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, "None");
   14951              :     }
   14952            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI, thisDXCoil.Name, NetCoolingCapRated, 2);
   14953            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
   14954            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 2);
   14955            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP, thisDXCoil.Name, EER_TestPoint_IP(1), 2);
   14956            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA, thisDXCoil.Name, SupAirMdot_TestPoint(1), 4);
   14957            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B, thisDXCoil.Name, EER_TestPoint_SI(2), 2);
   14958            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP, thisDXCoil.Name, EER_TestPoint_IP(2), 2);
   14959            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB, thisDXCoil.Name, SupAirMdot_TestPoint(2), 4);
   14960            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C, thisDXCoil.Name, EER_TestPoint_SI(3), 2);
   14961            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP, thisDXCoil.Name, EER_TestPoint_IP(3), 2);
   14962            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC, thisDXCoil.Name, SupAirMdot_TestPoint(3), 4);
   14963            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D, thisDXCoil.Name, EER_TestPoint_SI(4), 2);
   14964            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP, thisDXCoil.Name, EER_TestPoint_IP(4), 2);
   14965            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD, thisDXCoil.Name, SupAirMdot_TestPoint(4), 4);
   14966              : 
   14967            6 :     state.dataEnvrn->OutDryBulbTemp = heldOutDryBulb; // reset the outdoor dry bulb when done with it
   14968            6 : }
   14969              : 
   14970            2 : void GetFanIndexForTwoSpeedCoil(
   14971              :     EnergyPlusData &state, int const CoolingCoilIndex, int &SupplyFanIndex, std::string &SupplyFanName, HVAC::FanType &supplyFanType)
   14972              : {
   14973              : 
   14974              :     // SUBROUTINE INFORMATION:
   14975              :     //       AUTHOR         <author>
   14976              :     //       DATE WRITTEN   <date_written>
   14977              : 
   14978              :     // PURPOSE OF THIS SUBROUTINE:
   14979              :     // This routine looks up the given TwoSpeed DX coil and returns the companion supply fan index
   14980              : 
   14981              :     // Using/Aliasing
   14982            2 :     int NumPrimaryAirSys = state.dataHVACGlobal->NumPrimaryAirSys;
   14983              : 
   14984              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   14985              :     int FoundBranch;
   14986              :     int FoundAirSysNum;
   14987              :     int AirSysNum;
   14988              :     int BranchNum;
   14989              :     int CompNum;
   14990              : 
   14991            2 :     FoundBranch = 0;
   14992            2 :     FoundAirSysNum = 0;
   14993            2 :     SupplyFanIndex = 0;
   14994            2 :     SupplyFanName = "n/a";
   14995            4 :     for (AirSysNum = 1; AirSysNum <= NumPrimaryAirSys; ++AirSysNum) {
   14996              : 
   14997            4 :         for (BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).NumBranches; ++BranchNum) {
   14998              : 
   14999            4 :             for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).TotalComponents; ++CompNum) {
   15000              : 
   15001            4 :                 if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
   15002              :                     SimAirServingZones::CompType::DXSystem) {
   15003              : 
   15004            2 :                     if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
   15005            2 :                                          state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
   15006            2 :                         FoundBranch = BranchNum;
   15007            2 :                         FoundAirSysNum = AirSysNum;
   15008            2 :                         break;
   15009              :                     }
   15010              :                     // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
   15011            2 :                 } else if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
   15012              :                            SimAirServingZones::CompType::UnitarySystemModel) {
   15013              : 
   15014            0 :                     if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
   15015            0 :                                          state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
   15016            0 :                         FoundBranch = BranchNum;
   15017            0 :                         FoundAirSysNum = AirSysNum;
   15018            0 :                         break;
   15019              :                     }
   15020              :                 }
   15021              :             }
   15022              : 
   15023            2 :             if (FoundBranch > 0 && FoundAirSysNum > 0) {
   15024            9 :                 for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).TotalComponents;
   15025              :                      ++CompNum) {
   15026            8 :                     if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
   15027              :                         SimAirServingZones::CompType::Fan_Simple_VAV) {
   15028            1 :                         SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
   15029            1 :                         SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
   15030            1 :                         supplyFanType = HVAC::FanType::VAV;
   15031            1 :                         break;
   15032              :                         // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
   15033            7 :                     } else if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
   15034              :                                SimAirServingZones::CompType::Fan_System_Object) {
   15035            1 :                         SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
   15036            1 :                         SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
   15037            1 :                         supplyFanType = HVAC::FanType::SystemModel;
   15038              : 
   15039            6 :                     } else if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
   15040              :                                SimAirServingZones::CompType::UnitarySystemModel) {
   15041              :                         // fan may not be specified in a unitary system object, keep looking
   15042              :                         // Unitary System will "set" the fan index to the DX coil if contained within the HVAC system
   15043            0 :                         if (state.dataDXCoils->DXCoil(CoolingCoilIndex).SupplyFanIndex > 0) break;
   15044              :                     }
   15045              :                 }
   15046              :             }
   15047              :         }
   15048              :     }
   15049            2 : }
   15050              : 
   15051          165 : void GetDXCoilIndex(EnergyPlusData &state,
   15052              :                     std::string const &DXCoilName,
   15053              :                     int &DXCoilIndex,
   15054              :                     bool &ErrorsFound,
   15055              :                     std::string_view const ThisObjectType,
   15056              :                     bool const SuppressWarning)
   15057              : {
   15058              : 
   15059              :     // SUBROUTINE INFORMATION:
   15060              :     //       AUTHOR         Richard Raustad
   15061              :     //       DATE WRITTEN   March 2005
   15062              : 
   15063              :     // PURPOSE OF THIS SUBROUTINE:
   15064              :     // This subroutine sets an index for a given DX Coil -- issues error message if that
   15065              :     // DX Coil is not a legal DX Coil.
   15066              : 
   15067          165 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15068           58 :         GetDXCoils(state);
   15069           58 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15070              :     }
   15071              : 
   15072          165 :     DXCoilIndex = Util::FindItemInList(DXCoilName, state.dataDXCoils->DXCoil);
   15073          165 :     if (DXCoilIndex == 0) {
   15074            0 :         if (!SuppressWarning) {
   15075              :             //     No warning printed if only searching for the existence of a DX Coil
   15076            0 :             if (!ThisObjectType.empty()) {
   15077            0 :                 ShowSevereError(state, fmt::format("{}, GetDXCoilIndex: DX Coil not found={}", ThisObjectType, DXCoilName));
   15078              :             } else {
   15079            0 :                 ShowSevereError(state, format("GetDXCoilIndex: DX Coil not found={}", DXCoilName));
   15080              :             }
   15081              :         }
   15082            0 :         ErrorsFound = true;
   15083              :     }
   15084          165 : }
   15085              : 
   15086              : std::string
   15087            0 : GetDXCoilName(EnergyPlusData &state, int &DXCoilIndex, bool &ErrorsFound, std::string_view const ThisObjectType, bool const SuppressWarning)
   15088              : {
   15089              : 
   15090              :     // SUBROUTINE INFORMATION:
   15091              :     //       AUTHOR         Richard Raustad
   15092              :     //       DATE WRITTEN   May 2017
   15093              : 
   15094              :     // PURPOSE OF THIS SUBROUTINE:
   15095              :     // This subroutine gets a name for a given DX Coil -- issues error message if that
   15096              :     // DX Coil is not a legal DX Coil.
   15097              : 
   15098            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15099            0 :         GetDXCoils(state);
   15100            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15101              :     }
   15102              : 
   15103            0 :     if (DXCoilIndex == 0) {
   15104            0 :         if (!SuppressWarning) {
   15105              :             //     No warning printed if only searching for the existence of a DX Coil
   15106            0 :             if (!ThisObjectType.empty()) {
   15107            0 :                 ShowSevereError(state, fmt::format("{}, GetDXCoilIndex: DX Coil not found ", ThisObjectType));
   15108              :             } else {
   15109            0 :                 ShowSevereError(state, "GetDXCoilIndex: DX Coil not found ");
   15110              :             }
   15111              :         }
   15112            0 :         ErrorsFound = true;
   15113            0 :         return " "; // This does not seem great
   15114              : 
   15115              :     } else {
   15116            0 :         return state.dataDXCoils->DXCoil(DXCoilIndex).Name;
   15117              :     }
   15118              : }
   15119              : 
   15120            6 : Real64 GetCoilCapacity(EnergyPlusData &state,
   15121              :                        std::string const &CoilType, // must match coil types in this module
   15122              :                        std::string const &CoilName, // must match coil names for the coil type
   15123              :                        bool &ErrorsFound            // set to true if problem
   15124              : )
   15125              : {
   15126              : 
   15127              :     // FUNCTION INFORMATION:
   15128              :     //       AUTHOR         Linda Lawrie
   15129              :     //       DATE WRITTEN   February 2006
   15130              : 
   15131              :     // PURPOSE OF THIS FUNCTION:
   15132              :     // This function looks up the coil capacity for the given coil and returns it.  If
   15133              :     // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
   15134              :     // as negative.
   15135              : 
   15136              :     // Return value
   15137              :     Real64 CoilCapacity; // returned capacity of matched coil
   15138              : 
   15139              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15140              :     int WhichCoil;
   15141              : 
   15142              :     // Obtains and Allocates DXCoils
   15143            6 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15144            0 :         GetDXCoils(state);
   15145            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15146              :     }
   15147              : 
   15148            6 :     if (Util::SameString(CoilType, "Coil:Heating:DX:SingleSpeed") || Util::SameString(CoilType, "Coil:Cooling:DX:SingleSpeed")) {
   15149            6 :         WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
   15150            6 :         if (WhichCoil != 0) {
   15151            6 :             CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(1);
   15152              :         }
   15153            0 :     } else if (Util::SameString(CoilType, "Coil:Cooling:DX:TwoStageWithHumidityControlMode")) {
   15154            0 :         WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
   15155            0 :         if (WhichCoil != 0) {
   15156            0 :             CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(state.dataDXCoils->DXCoil(WhichCoil).NumCapacityStages);
   15157              :         }
   15158            0 :     } else if (Util::SameString(CoilType, "Coil:Cooling:DX:TwoSpeed")) {
   15159            0 :         WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
   15160            0 :         if (WhichCoil != 0) {
   15161            0 :             CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(1);
   15162              :         }
   15163            0 :     } else if (Util::SameString(CoilType, "Coil:Cooling:DX:MultiSpeed") || Util::SameString(CoilType, "Coil:Heating:DX:MultiSpeed")) {
   15164            0 :         WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
   15165            0 :         if (WhichCoil != 0) {
   15166            0 :             CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).MSRatedTotCap(state.dataDXCoils->DXCoil(WhichCoil).NumOfSpeeds);
   15167              :         }
   15168              :     } else {
   15169            0 :         WhichCoil = 0;
   15170              :     }
   15171              : 
   15172            6 :     if (WhichCoil == 0) {
   15173            0 :         ShowSevereError(state, format("GetCoilCapacity: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
   15174            0 :         ShowContinueError(state, "... returning capacity as -1000.");
   15175            0 :         ErrorsFound = true;
   15176            0 :         CoilCapacity = -1000.0;
   15177              :     }
   15178              : 
   15179            6 :     return CoilCapacity;
   15180              : }
   15181              : 
   15182           39 : Real64 GetCoilCapacityByIndexType(EnergyPlusData &state,
   15183              :                                   int const CoilIndex,    // must match coil index for the coil type
   15184              :                                   int const CoilType_Num, // must match coil types in this module
   15185              :                                   bool &ErrorsFound       // set to true if problem
   15186              : )
   15187              : {
   15188              : 
   15189              :     // FUNCTION INFORMATION:
   15190              :     //       AUTHOR         Richard Raustad
   15191              :     //       DATE WRITTEN   October 2010
   15192              : 
   15193              :     // PURPOSE OF THIS FUNCTION:
   15194              :     // This function looks up the coil capacity for the given coil and returns it.  If
   15195              :     // incorrect coil index or type is given, ErrorsFound is returned as true and capacity is returned
   15196              :     // as negative.
   15197              : 
   15198              :     // Return value
   15199              :     Real64 CoilCapacity; // returned capacity of matched coil
   15200              : 
   15201              :     // Obtains and Allocates DXCoils
   15202           39 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15203            0 :         GetDXCoils(state);
   15204            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15205              :     }
   15206              : 
   15207           39 :     if (CoilIndex == 0) {
   15208            0 :         ShowSevereError(state, "GetCoilCapacityByIndexType: Invalid index passed = 0");
   15209            0 :         ShowContinueError(state, "... returning capacity as -1000.");
   15210            0 :         ErrorsFound = true;
   15211            0 :         CoilCapacity = -1000.0;
   15212            0 :         return CoilCapacity;
   15213              :     }
   15214              : 
   15215           39 :     if (CoilType_Num != state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
   15216            0 :         ShowSevereError(state, "GetCoilCapacityByIndexType: Index passed does not match DX Coil type passed.");
   15217            0 :         ShowContinueError(state, "... returning capacity as -1000.");
   15218            0 :         ErrorsFound = true;
   15219            0 :         CoilCapacity = -1000.0;
   15220              :     } else {
   15221           39 :         switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
   15222            4 :         case HVAC::CoilDX_MultiSpeedCooling:
   15223              :         case HVAC::CoilDX_MultiSpeedHeating: {
   15224            4 :             CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).MSRatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
   15225            4 :         } break;
   15226           35 :         default: {
   15227           35 :             CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).RatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumCapacityStages);
   15228           35 :         } break;
   15229              :         }
   15230              :     }
   15231              : 
   15232           39 :     return CoilCapacity;
   15233              : }
   15234              : 
   15235           76 : int GetCoilTypeNum(EnergyPlusData &state,
   15236              :                    std::string const &CoilType,                // must match coil types in this module
   15237              :                    std::string const &CoilName,                // must match coil names for the coil type
   15238              :                    bool &ErrorsFound,                          // set to true if problem
   15239              :                    ObjexxFCL::Optional_bool_const PrintWarning // prints warning when true
   15240              : )
   15241              : {
   15242              : 
   15243              :     // FUNCTION INFORMATION:
   15244              :     //       AUTHOR         R. Raustad - FSEC
   15245              :     //       DATE WRITTEN   August 2008
   15246              : 
   15247              :     // PURPOSE OF THIS FUNCTION:
   15248              :     // This function looks up the integerized coil type for the given coil and returns it.  If
   15249              :     // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
   15250              :     // as negative.
   15251              : 
   15252              :     // Return value
   15253              :     int TypeNum; // returned integerized type of matched coil
   15254              : 
   15255              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15256              :     int WhichCoil;
   15257              :     bool PrintMessage;
   15258              : 
   15259              :     // Obtains and Allocates DXCoils
   15260           76 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15261           29 :         GetDXCoils(state);
   15262           29 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15263              :     }
   15264              : 
   15265           76 :     if (present(PrintWarning)) {
   15266           74 :         PrintMessage = PrintWarning;
   15267              :     } else {
   15268            2 :         PrintMessage = true;
   15269              :     }
   15270              : 
   15271           76 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15272           76 :     if (WhichCoil != 0) {
   15273           76 :         TypeNum = state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num;
   15274              :     } else {
   15275            0 :         if (PrintMessage) {
   15276            0 :             ShowSevereError(state, format("GetCoilTypeNum: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
   15277              :         }
   15278            0 :         ErrorsFound = true;
   15279            0 :         TypeNum = 0;
   15280              :     }
   15281              : 
   15282           76 :     return TypeNum;
   15283              : }
   15284              : 
   15285           76 : Real64 GetMinOATCompressor(EnergyPlusData &state,
   15286              :                            int const CoilIndex, // index to cooling coil
   15287              :                            bool &ErrorsFound    // set to true if problem
   15288              : )
   15289              : {
   15290              : 
   15291              :     // Obtains and Allocates DXCoils
   15292           76 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15293            0 :         GetDXCoils(state);
   15294            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15295              :     }
   15296              : 
   15297           76 :     if (CoilIndex == 0) {
   15298            0 :         ShowSevereError(state, "GetMinOATCompressor: Index passed = 0");
   15299            0 :         ShowContinueError(state, "... returning Min OAT for compressor operation as -1000.");
   15300            0 :         ErrorsFound = true;
   15301            0 :         return -1000.0;
   15302              :     } else {
   15303           76 :         return state.dataDXCoils->DXCoil(CoilIndex).MinOATCompressor;
   15304              :     }
   15305              : }
   15306              : 
   15307           78 : int GetCoilInletNode(EnergyPlusData &state,
   15308              :                      std::string const &CoilType, // must match coil types in this module
   15309              :                      std::string const &CoilName, // must match coil names for the coil type
   15310              :                      bool &ErrorsFound            // set to true if problem
   15311              : )
   15312              : {
   15313              : 
   15314              :     // FUNCTION INFORMATION:
   15315              :     //       AUTHOR         Linda Lawrie
   15316              :     //       DATE WRITTEN   February 2006
   15317              : 
   15318              :     // PURPOSE OF THIS FUNCTION:
   15319              :     // This function looks up the given coil and returns the inlet node number.  If
   15320              :     // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
   15321              :     // as zero.
   15322              : 
   15323              :     // Return value
   15324              :     int NodeNumber; // returned node number of matched coil
   15325              : 
   15326              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15327              :     int WhichCoil;
   15328              : 
   15329              :     // Obtains and Allocates DXCoils
   15330           78 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15331            1 :         GetDXCoils(state);
   15332            1 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15333              :     }
   15334              : 
   15335           78 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15336           78 :     if (WhichCoil != 0) {
   15337           78 :         NodeNumber = state.dataDXCoils->DXCoil(WhichCoil).AirInNode;
   15338              :     } else {
   15339            0 :         ShowSevereError(state, format("GetCoilInletNode: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
   15340            0 :         ErrorsFound = true;
   15341            0 :         NodeNumber = 0;
   15342              :     }
   15343              : 
   15344           78 :     return NodeNumber;
   15345              : }
   15346              : 
   15347            0 : int getCoilInNodeIndex(EnergyPlusData &state,
   15348              :                        int const CoilIndex, // coil index
   15349              :                        bool &ErrorsFound    // set to true if problem
   15350              : )
   15351              : {
   15352              : 
   15353              :     int NodeNumber; // returned node number of matched coil
   15354              : 
   15355              :     // Obtains and Allocates DXCoils
   15356            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15357            0 :         GetDXCoils(state);
   15358            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15359              :     }
   15360              : 
   15361            0 :     if (CoilIndex != 0) {
   15362            0 :         NodeNumber = state.dataDXCoils->DXCoil(CoilIndex).AirInNode;
   15363              :     } else {
   15364            0 :         ShowSevereError(state, "GetCoilInletNode: Could not find Coil Type");
   15365            0 :         ErrorsFound = true;
   15366            0 :         NodeNumber = 0;
   15367              :     }
   15368              : 
   15369            0 :     return NodeNumber;
   15370              : }
   15371              : 
   15372           83 : int GetCoilOutletNode(EnergyPlusData &state,
   15373              :                       std::string const &CoilType, // must match coil types in this module
   15374              :                       std::string const &CoilName, // must match coil names for the coil type
   15375              :                       bool &ErrorsFound            // set to true if problem
   15376              : )
   15377              : {
   15378              : 
   15379              :     // FUNCTION INFORMATION:
   15380              :     //       AUTHOR         Linda Lawrie
   15381              :     //       DATE WRITTEN   February 2006
   15382              : 
   15383              :     // PURPOSE OF THIS FUNCTION:
   15384              :     // This function looks up the given coil and returns the inlet node number.  If
   15385              :     // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
   15386              :     // as zero.
   15387              : 
   15388              :     // Return value
   15389              :     int NodeNumber; // returned node number of matched coil
   15390              : 
   15391              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15392              :     int WhichCoil;
   15393              : 
   15394              :     // Obtains and Allocates DXCoils
   15395           83 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15396            3 :         GetDXCoils(state);
   15397            3 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15398              :     }
   15399              : 
   15400           83 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15401           83 :     if (WhichCoil != 0) {
   15402           83 :         NodeNumber = state.dataDXCoils->DXCoil(WhichCoil).AirOutNode;
   15403              :     } else {
   15404            0 :         ShowSevereError(
   15405              :             state,
   15406            0 :             format("GetCoilOutletNode: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil outlet node number.", CoilType, CoilName));
   15407            0 :         ErrorsFound = true;
   15408            0 :         NodeNumber = 0;
   15409              :     }
   15410              : 
   15411           83 :     return NodeNumber;
   15412              : }
   15413              : 
   15414            0 : int getCoilOutNodeIndex(EnergyPlusData &state,
   15415              :                         int const CoilIndex, // must match coil types in this module
   15416              :                         bool &ErrorsFound    // set to true if problem
   15417              : )
   15418              : {
   15419              : 
   15420              :     int NodeNumber; // returned node number of matched coil
   15421              : 
   15422              :     // Obtains and Allocates DXCoils
   15423            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15424            0 :         GetDXCoils(state);
   15425            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15426              :     }
   15427              : 
   15428            0 :     if (CoilIndex != 0) {
   15429            0 :         NodeNumber = state.dataDXCoils->DXCoil(CoilIndex).AirOutNode;
   15430              :     } else {
   15431            0 :         ShowSevereError(state, "GetCoilOutletNode: Could not find Coil Type");
   15432            0 :         ErrorsFound = true;
   15433            0 :         NodeNumber = 0;
   15434              :     }
   15435              : 
   15436            0 :     return NodeNumber;
   15437              : }
   15438              : 
   15439           45 : int GetCoilCondenserInletNode(EnergyPlusData &state,
   15440              :                               std::string const &CoilType, // must match coil types in this module
   15441              :                               std::string const &CoilName, // must match coil names for the coil type
   15442              :                               bool &ErrorsFound            // set to true if problem
   15443              : )
   15444              : {
   15445              : 
   15446              :     // FUNCTION INFORMATION:
   15447              :     //       AUTHOR         R. Raustad
   15448              :     //       DATE WRITTEN   January 2007
   15449              : 
   15450              :     // PURPOSE OF THIS FUNCTION:
   15451              :     // This function looks up the given coil and returns the condenser inlet node.  If
   15452              :     // incorrect coil type or name is given, ErrorsFound is returned as true.
   15453              : 
   15454              :     // Return value
   15455              :     int CondNode; // returned condenser node number of matched coil
   15456              : 
   15457              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15458              :     int WhichCoil;
   15459              : 
   15460              :     // Obtains and Allocates DXCoils
   15461           45 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15462            0 :         GetDXCoils(state);
   15463            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15464              :     }
   15465              : 
   15466           45 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15467           45 :     if (WhichCoil != 0) {
   15468           45 :         CondNode = state.dataDXCoils->DXCoil(WhichCoil).CondenserInletNodeNum(1);
   15469              :     } else {
   15470            0 :         ShowSevereError(state, format("GetCoilCondenserInletNode: Invalid DX Coil, Type= \"{}\" Name=\"{}\"", CoilType, CoilName));
   15471            0 :         ErrorsFound = true;
   15472            0 :         CondNode = 0;
   15473              :     }
   15474              : 
   15475           45 :     return CondNode;
   15476              : }
   15477              : 
   15478            2 : Real64 GetDXCoilBypassedFlowFrac(EnergyPlusData &state,
   15479              :                                  std::string const &CoilType, // must match coil types in this module
   15480              :                                  std::string const &CoilName, // must match coil names for the coil type
   15481              :                                  bool &ErrorsFound            // set to true if problem
   15482              : )
   15483              : {
   15484              : 
   15485              :     // FUNCTION INFORMATION:
   15486              :     //       AUTHOR         R. Raustad
   15487              :     //       DATE WRITTEN   June 2007
   15488              : 
   15489              :     // PURPOSE OF THIS FUNCTION:
   15490              :     // This function looks up the given coil and returns the bypassed air flow fraction.
   15491              :     // Bypassed air flow fraction can only be greater than 0 for multimode DX cooling coils and is typical for 1st stage
   15492              :     // If incorrect coil type or name is given, ErrorsFound is returned as true.
   15493              : 
   15494              :     // Return value
   15495              :     Real64 BypassFraction; // returned bypass air fraction of matched coil
   15496              : 
   15497              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15498              :     int WhichCoil;
   15499              : 
   15500              :     // Obtains and Allocates DXCoils
   15501            2 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15502            0 :         GetDXCoils(state);
   15503            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15504              :     }
   15505              : 
   15506            2 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15507            2 :     if (WhichCoil != 0) {
   15508            2 :         BypassFraction = state.dataDXCoils->DXCoil(WhichCoil).BypassedFlowFrac(1);
   15509              :     } else {
   15510            0 :         ShowSevereError(state, format("GetDXCoilBypassedFlowFrac: Invalid DX Coil Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
   15511            0 :         ErrorsFound = true;
   15512            0 :         BypassFraction = 0.0;
   15513              :     }
   15514              : 
   15515            2 :     return BypassFraction;
   15516              : }
   15517              : 
   15518           40 : int GetHPCoolingCoilIndex(EnergyPlusData &state,
   15519              :                           std::string const &HeatingCoilType, // Type of DX heating coil used in HP
   15520              :                           std::string const &HeatingCoilName, // Name of DX heating coil used in HP
   15521              :                           int const HeatingCoilIndex          // Index of DX heating coil used in HP
   15522              : )
   15523              : {
   15524              : 
   15525              :     // FUNCTION INFORMATION:
   15526              :     //       AUTHOR         R. Raustad
   15527              :     //       DATE WRITTEN   February 2007
   15528              : 
   15529              :     // PURPOSE OF THIS FUNCTION:
   15530              :     // This function looks up the given DX heating coil and returns the companion DX cooling coil.
   15531              : 
   15532              :     // Return value
   15533              :     int DXCoolingCoilIndex; // Index of HP DX cooling coil returned from this function
   15534              : 
   15535              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15536              :     int WhichComp;           // DO loop counter to find correct comp set
   15537              :     int WhichCompanionComp;  // DO loop counter to find companion coil comp set
   15538              :     int WhichHXAssistedComp; // DO loop counter when DX coil is used in a HX assisted cooling coil
   15539              : 
   15540           40 :     DXCoolingCoilIndex = 0;
   15541              : 
   15542              :     DataLoopNode::ConnectionObjectType HeatingCoilTypeNum = static_cast<DataLoopNode::ConnectionObjectType>(
   15543           40 :         getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC, Util::makeUPPER(HeatingCoilType)));
   15544              : 
   15545              :     DataLoopNode::ConnectionObjectType CompSetsParentType; // Parent object type which uses DX heating coil pass into this function
   15546           40 :     std::string CompSetsParentName;
   15547          110 :     for (WhichComp = 1; WhichComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichComp) {
   15548              : 
   15549          151 :         if (HeatingCoilTypeNum != state.dataBranchNodeConnections->CompSets(WhichComp).ComponentObjectType ||
   15550           41 :             !Util::SameString(HeatingCoilName, state.dataBranchNodeConnections->CompSets(WhichComp).CName))
   15551           70 :             continue;
   15552           40 :         CompSetsParentType = state.dataBranchNodeConnections->CompSets(WhichComp).ParentObjectType;
   15553           40 :         CompSetsParentName = state.dataBranchNodeConnections->CompSets(WhichComp).ParentCName;
   15554           40 :         if ((CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAir) ||
   15555           14 :             (CompSetsParentType == DataLoopNode::ConnectionObjectType::ZoneHVACPackagedTerminalHeatPump) ||
   15556           12 :             (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed) ||
   15557           12 :             (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass) ||
   15558              :             (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitarySystem)) {
   15559              :             //       Search for DX cooling coils
   15560          104 :             for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
   15561          154 :                 if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
   15562           64 :                     (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
   15563              :                      DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed))
   15564           64 :                     continue;
   15565              :                 DXCoolingCoilIndex =
   15566           26 :                     Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
   15567           26 :                 break;
   15568              :             }
   15569          152 :             for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
   15570          207 :                 if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
   15571           91 :                     (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
   15572              :                      DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed))
   15573          112 :                     continue;
   15574              :                 DXCoolingCoilIndex =
   15575            4 :                     Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
   15576            4 :                 break;
   15577              :             }
   15578              :             //       Search for Heat Exchanger Assisted DX cooling coils
   15579           40 :             if (DXCoolingCoilIndex == 0) {
   15580           93 :                 for (WhichHXAssistedComp = 1; WhichHXAssistedComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichHXAssistedComp) {
   15581          124 :                     if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ParentCName, CompSetsParentName) ||
   15582           62 :                         (state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ComponentObjectType !=
   15583              :                          DataLoopNode::ConnectionObjectType::CoilSystemCoolingDXHeatExchangerAssisted))
   15584           62 :                         continue;
   15585              :                     DataLoopNode::ConnectionObjectType HXCompSetsParentType; // Used when DX cooling coil is a child of a HX assisted cooling coil
   15586            0 :                     HXCompSetsParentType = state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ComponentObjectType;
   15587            0 :                     std::string const &HXCompSetsParentName = state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).CName;
   15588            0 :                     for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
   15589            0 :                         if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, HXCompSetsParentName) ||
   15590            0 :                             (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
   15591              :                              DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed))
   15592            0 :                             continue;
   15593              :                         DXCoolingCoilIndex =
   15594            0 :                             Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
   15595            0 :                         break;
   15596              :                     }
   15597            0 :                     break;
   15598              :                 }
   15599              :             }
   15600           40 :         } else {
   15601              :             //     ErrorFound, Coil:Heating:DX:SingleSpeed is used in wrong type of parent object (should never get here)
   15602            0 :             ShowSevereError(state,
   15603            0 :                             format("Configuration error in {}\"{}\"",
   15604            0 :                                    BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(CompSetsParentType)],
   15605              :                                    CompSetsParentName));
   15606            0 :             ShowContinueError(state, "DX heating coil not allowed in this configuration.");
   15607            0 :             ShowFatalError(state, "Preceding condition(s) causes termination.");
   15608              :         }
   15609           40 :         break;
   15610              :     }
   15611              : 
   15612              :     // Check and warn user is crankcase heater power or max OAT for crankcase heater differs in DX cooling and heating coils
   15613           40 :     if (DXCoolingCoilIndex > 0) {
   15614            9 :         if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity != 0.0) {
   15615            1 :             if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity !=
   15616            2 :                     state.dataDXCoils->DXCoil(HeatingCoilIndex).CrankcaseHeaterCapacity ||
   15617            1 :                 state.dataDXCoils->DXCoil(DXCoolingCoilIndex).MaxOATCrankcaseHeater !=
   15618            1 :                     state.dataDXCoils->DXCoil(HeatingCoilIndex).MaxOATCrankcaseHeater) {
   15619            0 :                 ShowWarningError(state, "Crankcase heater capacity or max outdoor temp for crankcase heater operation specified in");
   15620            0 :                 ShowContinueError(state, format("Coil:Cooling:DX:SingleSpeed = {}", state.dataDXCoils->DXCoil(DXCoolingCoilIndex).Name));
   15621            0 :                 ShowContinueError(state, format("is different than that specified in Coil:Heating:DX:SingleSpeed = {}.", HeatingCoilName));
   15622            0 :                 ShowContinueError(state,
   15623            0 :                                   format("Both of these DX coils are part of {}={}.",
   15624            0 :                                          BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(CompSetsParentType)],
   15625              :                                          CompSetsParentName));
   15626            0 :                 ShowContinueError(state, "The value specified in the DX heating coil will be used and the simulation continues...");
   15627              :             }
   15628              :         }
   15629              :     }
   15630              : 
   15631           40 :     return DXCoolingCoilIndex;
   15632           40 : }
   15633              : 
   15634            6 : int GetDXCoilNumberOfSpeeds(EnergyPlusData &state,
   15635              :                             std::string const &CoilType, // must match coil types in this module
   15636              :                             std::string const &CoilName, // must match coil names for the coil type
   15637              :                             bool &ErrorsFound            // set to true if problem
   15638              : )
   15639              : {
   15640              : 
   15641              :     // FUNCTION INFORMATION:
   15642              :     //       AUTHOR         L. Gu
   15643              :     //       DATE WRITTEN   July 2007
   15644              : 
   15645              :     // PURPOSE OF THIS FUNCTION:
   15646              :     // This function looks up the given coil and returns the number of speeds for multispeed coils.
   15647              :     // If incorrect coil type or name is given, ErrorsFound is returned as true.
   15648              : 
   15649              :     // Return value
   15650              :     int NumberOfSpeeds; // returned the number of speed of matched coil
   15651              : 
   15652              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15653              :     int WhichCoil;
   15654              : 
   15655              :     // Obtains and Allocates DXCoils
   15656            6 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15657            0 :         GetDXCoils(state);
   15658            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15659              :     }
   15660              : 
   15661            6 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15662            6 :     if (WhichCoil != 0) {
   15663            6 :         NumberOfSpeeds = state.dataDXCoils->DXCoil(WhichCoil).NumOfSpeeds;
   15664              :     } else {
   15665            0 :         ShowSevereError(state, format("GetDXCoilNumberOfSpeeds: Invalid DX Coil Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
   15666            0 :         ErrorsFound = true;
   15667            0 :         NumberOfSpeeds = 0;
   15668              :     }
   15669              : 
   15670            6 :     return NumberOfSpeeds;
   15671              : }
   15672              : 
   15673           68 : Sched::Schedule *GetDXCoilAvailSched(EnergyPlusData &state,
   15674              :                                      std::string const &CoilType,            // must match coil types in this module
   15675              :                                      std::string const &CoilName,            // must match coil names for the coil type
   15676              :                                      bool &ErrorsFound,                      // set to true if problem
   15677              :                                      ObjexxFCL::Optional_int_const CoilIndex // Coil index number
   15678              : )
   15679              : {
   15680              : 
   15681              :     // FUNCTION INFORMATION:
   15682              :     //       AUTHOR         Richard Raustad
   15683              :     //       DATE WRITTEN   January 2013
   15684              : 
   15685              :     // PURPOSE OF THIS FUNCTION:
   15686              :     // This function looks up the given coil and returns the availability schedule index.  If
   15687              :     // incorrect coil type or name is given, ErrorsFound is returned as true and schedule index is returned
   15688              :     // as -1.
   15689              : 
   15690              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15691              :     int WhichCoil;
   15692              : 
   15693              :     // Obtains and Allocates DXCoils
   15694           68 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15695            0 :         GetDXCoils(state);
   15696            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15697              :     }
   15698              : 
   15699           68 :     if (present(CoilIndex)) {
   15700            2 :         if (CoilIndex == 0) {
   15701            0 :             ShowSevereError(state, "GetDXCoilAvailSchPtr: Invalid index passed = 0");
   15702            0 :             ShowContinueError(state, "... returning DXCoilAvailSchPtr as -1.");
   15703            0 :             ErrorsFound = true;
   15704            0 :             return nullptr;
   15705              :         } else {
   15706            2 :             WhichCoil = CoilIndex;
   15707              :         }
   15708              :     } else {
   15709           66 :         WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15710              :     }
   15711           68 :     if (WhichCoil != 0) {
   15712           68 :         return state.dataDXCoils->DXCoil(WhichCoil).availSched;
   15713              :     } else {
   15714            0 :         if (!present(CoilIndex)) {
   15715            0 :             ShowSevereError(state,
   15716            0 :                             format("GetDXCoilAvailSch: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil availability schedule index.",
   15717              :                                    CoilType,
   15718              :                                    CoilName));
   15719              :         }
   15720            0 :         ErrorsFound = true;
   15721            0 :         return nullptr;
   15722              :     }
   15723              : }
   15724              : 
   15725            0 : Real64 GetDXCoilAirFlow(EnergyPlusData &state,
   15726              :                         std::string const &CoilType, // must match coil types in this module
   15727              :                         std::string const &CoilName, // must match coil names for the coil type
   15728              :                         bool &ErrorsFound            // set to true if problem
   15729              : )
   15730              : {
   15731              : 
   15732              :     // FUNCTION INFORMATION:
   15733              :     //       AUTHOR         Richard Raustad
   15734              :     //       DATE WRITTEN   January 2013
   15735              : 
   15736              :     // PURPOSE OF THIS FUNCTION:
   15737              :     // This function looks up the given coil and returns the availability schedule index.  If
   15738              :     // incorrect coil type or name is given, ErrorsFound is returned as true and schedule index is returned
   15739              :     // as -1.
   15740              : 
   15741              :     // Return value
   15742              :     Real64 AirFlow; // returned coil air flow rate
   15743              : 
   15744              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15745              :     int WhichCoil;
   15746              : 
   15747              :     // Obtains and Allocates DXCoils
   15748            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15749            0 :         GetDXCoils(state);
   15750            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15751              :     }
   15752              : 
   15753            0 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15754            0 :     if (WhichCoil != 0) {
   15755            0 :         switch (state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num) {
   15756            0 :         case HVAC::CoilDX_CoolingSingleSpeed:
   15757              :         case HVAC::CoilDX_CoolingTwoSpeed:
   15758              :         case HVAC::CoilDX_HeatingEmpirical:
   15759              :         case HVAC::CoilDX_CoolingTwoStageWHumControl: {
   15760            0 :             AirFlow = state.dataDXCoils->DXCoil(WhichCoil).RatedAirVolFlowRate(1);
   15761            0 :         } break;
   15762            0 :         case HVAC::CoilDX_MultiSpeedCooling:
   15763              :         case HVAC::CoilDX_MultiSpeedHeating: {
   15764            0 :             AirFlow = state.dataDXCoils->DXCoil(WhichCoil).MSRatedAirVolFlowRate(1);
   15765            0 :         } break;
   15766            0 :         default: {
   15767            0 :             ShowSevereError(
   15768              :                 state,
   15769            0 :                 format("GetDXCoilAirFlow: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil air flow rate.", CoilType, CoilName));
   15770            0 :             ErrorsFound = true;
   15771            0 :             AirFlow = -1.0;
   15772            0 :         } break;
   15773              :         }
   15774              :     } else {
   15775            0 :         ShowSevereError(
   15776            0 :             state, format("GetDXCoilAirFlow: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil air flow rate.", CoilType, CoilName));
   15777            0 :         ErrorsFound = true;
   15778            0 :         AirFlow = -1.0;
   15779              :     }
   15780              : 
   15781            0 :     return AirFlow;
   15782              : }
   15783              : 
   15784           48 : int GetDXCoilCapFTCurveIndex(EnergyPlusData &state,
   15785              :                              int const CoilIndex, // coil index pointer
   15786              :                              bool &ErrorsFound    // set to true if problem
   15787              : )
   15788              : {
   15789              : 
   15790              :     // FUNCTION INFORMATION:
   15791              :     //       AUTHOR         Richard Raustad
   15792              :     //       DATE WRITTEN   August 2013
   15793              : 
   15794              :     // PURPOSE OF THIS FUNCTION:
   15795              :     // This function looks up the given coil and returns the CapFT schedule index.  If
   15796              :     // incorrect coil index is given, ErrorsFound is returned as true and schedule index is returned
   15797              :     // as -1.
   15798              : 
   15799              :     // Return value
   15800              :     int CapFTCurveIndex; // returned coil CapFT curve index
   15801              : 
   15802              :     // Obtains and Allocates DXCoils
   15803           48 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15804            0 :         GetDXCoils(state);
   15805            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15806              :     }
   15807              : 
   15808           48 :     if (CoilIndex != 0) {
   15809           48 :         switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
   15810           18 :         case HVAC::CoilDX_CoolingSingleSpeed:
   15811              :         case HVAC::CoilDX_CoolingTwoSpeed:
   15812              :         case HVAC::CoilDX_HeatingEmpirical:
   15813              :         case HVAC::CoilDX_CoolingTwoStageWHumControl: {
   15814           18 :             CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
   15815           18 :         } break;
   15816            8 :         case HVAC::CoilDX_MultiSpeedCooling:
   15817              :         case HVAC::CoilDX_MultiSpeedHeating: {
   15818            8 :             CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).MSCCapFTemp(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
   15819            8 :         } break;
   15820           22 :         case HVAC::CoilVRF_Heating: {
   15821           22 :             CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
   15822           22 :         } break;
   15823            0 :         default: {
   15824              :             //        CALL ShowSevereError(state, 'GetDXCoilCapFTCurveIndex: Could not find Coil, Type="'// &
   15825              :             //             TRIM(cAllCoilTypes(DXCoil(CoilIndex)%DXCoilType_Num))//'" Name="'//TRIM(DXCoil(CoilIndex)%Name)//  &
   15826              :             //              '" when accessing coil capacity as a function of temperature curve.')
   15827            0 :             ErrorsFound = true;
   15828            0 :             CapFTCurveIndex = 0;
   15829            0 :         } break;
   15830              :         }
   15831              :     } else {
   15832              :         //    CALL ShowSevereError(state, 'GetDXCoilCapFTCurveIndex: Could not find Coil, Index = 0'// &
   15833              :         //          ' when accessing coil air flow rate.')
   15834            0 :         ErrorsFound = true;
   15835            0 :         CapFTCurveIndex = 0;
   15836              :     }
   15837              : 
   15838           48 :     return CapFTCurveIndex;
   15839              : }
   15840              : 
   15841          643 : void SetDXCoolingCoilData(
   15842              :     EnergyPlusData &state,
   15843              :     int const DXCoilNum,                                                     // Number of DX Cooling Coil
   15844              :     bool &ErrorsFound,                                                       // Set to true if certain errors found
   15845              :     ObjexxFCL::Optional_int HeatingCoilPLFCurvePTR,                          // Parameter equivalent of heating coil PLR curve index
   15846              :     ObjexxFCL::Optional<DataHeatBalance::RefrigCondenserType> CondenserType, // Parameter equivalent of condenser type parameter
   15847              :     ObjexxFCL::Optional_int CondenserInletNodeNum,                           // Parameter equivalent of condenser inlet node number
   15848              :     ObjexxFCL::Optional<Real64> MaxOATCrankcaseHeater,                       // Parameter equivalent of condenser Max OAT for Crank Case Heater temp
   15849              :     ObjexxFCL::Optional<Real64> MinOATCooling,                    // Parameter equivalent of condenser Min OAT for compressor cooling operation
   15850              :     ObjexxFCL::Optional<Real64> MaxOATCooling,                    // Parameter equivalent of condenser Max OAT for compressor cooling operation
   15851              :     ObjexxFCL::Optional<Real64> MinOATHeating,                    // Parameter equivalent of condenser Min OAT for compressor heating operation
   15852              :     ObjexxFCL::Optional<Real64> MaxOATHeating,                    // Parameter equivalent of condenser Max OAT for compressor heating operation
   15853              :     ObjexxFCL::Optional<HVAC::OATType> HeatingPerformanceOATType, // Parameter equivalent to condenser entering air temp type (1-db, 2=wb)
   15854              :     ObjexxFCL::Optional<StandardRatings::DefrostStrat> DefrostStrategy,
   15855              :     ObjexxFCL::Optional<StandardRatings::HPdefrostControl> DefrostControl,
   15856              :     ObjexxFCL::Optional_int DefrostEIRPtr,
   15857              :     ObjexxFCL::Optional<Real64> DefrostFraction,
   15858              :     ObjexxFCL::Optional<Real64> DefrostCapacity,
   15859              :     ObjexxFCL::Optional<Real64> MaxOATDefrost,
   15860              :     ObjexxFCL::Optional_bool CoolingCoilPresent,
   15861              :     ObjexxFCL::Optional_bool HeatingCoilPresent,
   15862              :     ObjexxFCL::Optional<Real64> HeatSizeRatio,
   15863              :     ObjexxFCL::Optional<Real64> TotCap,
   15864              :     ObjexxFCL::Optional_int SupplyFanIndex,
   15865              :     ObjexxFCL::Optional_string SupplyFanName,
   15866              :     ObjexxFCL::Optional<HVAC::FanType> supplyFanType)
   15867              : {
   15868              : 
   15869              :     // SUBROUTINE INFORMATION:
   15870              :     //       AUTHOR         Richard Raustad, FSEC
   15871              :     //       DATE WRITTEN   December 2008
   15872              : 
   15873              :     // PURPOSE OF THIS SUBROUTINE:
   15874              :     // This routine was designed to allow the DX coil to access information from a gas or
   15875              :     // electric heating coil when these coils are each used in a parent object.
   15876              :     // Also, this is an illustration of setting Data from an outside source.
   15877              : 
   15878              :     // Using/Aliasing
   15879              : 
   15880              :     // Obtains and Allocates DXCoils
   15881          643 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15882            0 :         GetDXCoils(state);
   15883            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15884              :     }
   15885              : 
   15886          643 :     if (DXCoilNum <= 0 || DXCoilNum > state.dataDXCoils->NumDXCoils) {
   15887            4 :         ShowSevereError(state,
   15888            4 :                         format("SetDXCoolingCoilData: called with DX Cooling Coil Number out of range={} should be >0 and <{}",
   15889              :                                DXCoilNum,
   15890            2 :                                state.dataDXCoils->NumDXCoils));
   15891            2 :         ErrorsFound = true;
   15892            2 :         return;
   15893              :     }
   15894              : 
   15895          641 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   15896          641 :     if (present(HeatingCoilPLFCurvePTR)) {
   15897            0 :         thisDXCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurvePTR;
   15898              :     }
   15899              : 
   15900          641 :     if (present(CondenserType)) {
   15901           66 :         thisDXCoil.CondenserType = CondenserType;
   15902              :     }
   15903              : 
   15904          641 :     if (present(CondenserInletNodeNum)) {
   15905           66 :         thisDXCoil.CondenserInletNodeNum(1) = CondenserInletNodeNum;
   15906              :     }
   15907              : 
   15908          641 :     if (present(MaxOATCrankcaseHeater)) {
   15909           66 :         thisDXCoil.MaxOATCrankcaseHeater = MaxOATCrankcaseHeater;
   15910              :     }
   15911              : 
   15912          641 :     if (present(MaxOATCooling)) {
   15913           33 :         thisDXCoil.MaxOATCompressor = MaxOATCooling;
   15914              :     }
   15915              : 
   15916          641 :     if (present(MaxOATHeating)) {
   15917           11 :         thisDXCoil.MaxOATCompressor = MaxOATHeating;
   15918              :     }
   15919              : 
   15920          641 :     if (present(MinOATCooling)) {
   15921           33 :         thisDXCoil.MinOATCompressor = MinOATCooling;
   15922              :     }
   15923              : 
   15924          641 :     if (present(MinOATHeating)) {
   15925           33 :         thisDXCoil.MinOATCompressor = MinOATHeating;
   15926              :     }
   15927              : 
   15928          641 :     if (present(HeatingPerformanceOATType)) {
   15929           33 :         thisDXCoil.HeatingPerformanceOATType = HeatingPerformanceOATType;
   15930              :     }
   15931              : 
   15932          641 :     if (present(DefrostStrategy)) {
   15933           33 :         thisDXCoil.DefrostStrategy = DefrostStrategy;
   15934              :     }
   15935              : 
   15936          641 :     if (present(DefrostControl)) {
   15937           33 :         thisDXCoil.DefrostControl = DefrostControl;
   15938              :     }
   15939              : 
   15940          641 :     if (present(DefrostEIRPtr)) {
   15941           33 :         thisDXCoil.DefrostEIRFT = DefrostEIRPtr;
   15942              :     }
   15943              : 
   15944          641 :     if (present(DefrostFraction)) {
   15945           33 :         thisDXCoil.DefrostTime = DefrostFraction;
   15946              :     }
   15947              : 
   15948          641 :     if (present(DefrostCapacity)) {
   15949           33 :         thisDXCoil.DefrostCapacity = DefrostCapacity;
   15950              :     }
   15951              : 
   15952          641 :     if (present(MaxOATDefrost)) {
   15953           33 :         thisDXCoil.MaxOATDefrost = MaxOATDefrost;
   15954              :     }
   15955              : 
   15956          641 :     if (present(CoolingCoilPresent)) {
   15957           33 :         thisDXCoil.CoolingCoilPresent = CoolingCoilPresent;
   15958              :     }
   15959              : 
   15960          641 :     if (present(HeatingCoilPresent)) {
   15961           33 :         thisDXCoil.HeatingCoilPresent = HeatingCoilPresent;
   15962              :     }
   15963              : 
   15964          641 :     if (present(HeatSizeRatio)) {
   15965            0 :         thisDXCoil.HeatSizeRatio = HeatSizeRatio;
   15966              :     }
   15967              : 
   15968          641 :     if (present(TotCap)) {
   15969            0 :         thisDXCoil.RatedTotCap(1) = TotCap;
   15970              :     }
   15971              : 
   15972          641 :     if (present(SupplyFanIndex)) {
   15973           12 :         thisDXCoil.SupplyFanIndex = SupplyFanIndex;
   15974              :     }
   15975              : 
   15976          641 :     if (present(SupplyFanName)) {
   15977           12 :         thisDXCoil.SupplyFanName = SupplyFanName;
   15978              :     }
   15979              : 
   15980          641 :     if (present(supplyFanType)) {
   15981           12 :         thisDXCoil.supplyFanType = supplyFanType;
   15982           12 :         if (thisDXCoil.SupplyFanIndex > 0) {
   15983           12 :             state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
   15984           12 :                                                                                      thisDXCoil.Name,
   15985           12 :                                                                                      thisDXCoil.DXCoilType,
   15986           12 :                                                                                      state.dataFans->fans(thisDXCoil.SupplyFanIndex)->Name,
   15987           12 :                                                                                      state.dataFans->fans(thisDXCoil.SupplyFanIndex)->type,
   15988              :                                                                                      thisDXCoil.SupplyFanIndex);
   15989              :         }
   15990              :     }
   15991              : }
   15992              : 
   15993            1 : void SetCoilSystemHeatingDXFlag(EnergyPlusData &state,
   15994              :                                 std::string const &CoilType, // must match coil types in this module
   15995              :                                 std::string const &CoilName  // must match coil names for the coil type
   15996              : )
   15997              : {
   15998              : 
   15999              :     // SUBROUTINE INFORMATION:
   16000              :     //       AUTHOR         B. Griffith
   16001              :     //       DATE WRITTEN   Jan. 2012
   16002              : 
   16003              :     // PURPOSE OF THIS SUBROUTINE:
   16004              :     // inform DX heating coil that is is part of a CoilSystem:Heating:DX
   16005              :     // and therefore it need not find its companion cooling coil
   16006              : 
   16007              :     // METHODOLOGY EMPLOYED:
   16008              :     // set value of logical flag FindCompanionUpStreamCoil to true
   16009              : 
   16010              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16011              :     int WhichCoil;
   16012              : 
   16013              :     // Obtains and Allocates DXCoils
   16014            1 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   16015            0 :         GetDXCoils(state);
   16016            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   16017              :     }
   16018              : 
   16019            1 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   16020            1 :     if (WhichCoil != 0) {
   16021            1 :         state.dataDXCoils->DXCoil(WhichCoil).FindCompanionUpStreamCoil = false;
   16022              :     } else {
   16023            0 :         ShowSevereError(state, format("SetCoilSystemHeatingDXFlag: Could not find Coil, Type=\"{}\"Name=\"{}\"", CoilType, CoilName));
   16024              :     }
   16025            1 : }
   16026              : 
   16027            2 : void SetCoilSystemCoolingData(EnergyPlusData &state,
   16028              :                               std::string const &CoilName, // must match coil names for the coil type
   16029              :                               std::string const &CoilSystemName)
   16030              : {
   16031              : 
   16032              :     // SUBROUTINE INFORMATION:
   16033              :     //       AUTHOR         B. Griffith
   16034              :     //       DATE WRITTEN   July 2012
   16035              : 
   16036              :     // PURPOSE OF THIS SUBROUTINE:
   16037              :     // inform the child DX coil what the name of its parent is.
   16038              : 
   16039              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16040              :     int WhichCoil;
   16041              : 
   16042            2 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   16043            0 :         GetDXCoils(state);
   16044            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   16045              :     }
   16046              : 
   16047            2 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   16048            2 :     if (WhichCoil != 0) {
   16049            2 :         state.dataDXCoils->DXCoil(WhichCoil).CoilSystemName = CoilSystemName;
   16050              :     } else {
   16051            0 :         ShowSevereError(state, format("SetCoilSystemCoolingData: Could not find Coil \"Name=\"{}\"", CoilName));
   16052              :     }
   16053            2 : }
   16054              : 
   16055            3 : Real64 CalcSHRUserDefinedCurves(EnergyPlusData &state,
   16056              :                                 Real64 const InletDryBulb,     // inlet air dry bulb temperature [C]
   16057              :                                 Real64 const InletWetBulb,     // inlet air wet bulb temperature [C]
   16058              :                                 Real64 const AirMassFlowRatio, // ratio of actual air mass flow to rated air mass flow
   16059              :                                 int const SHRFTempCurveIndex,  // SHR modifier curve index
   16060              :                                 int const SHRFFlowCurveIndex,  // SHR modifier curve index
   16061              :                                 Real64 const SHRRated          // rated sensible heat ratio, user input
   16062              : )
   16063              : {
   16064              : 
   16065              :     // SUBROUTINE INFORMATION:
   16066              :     //       AUTHOR         Bereket Nigusse, FSEC
   16067              :     //       DATE WRITTEN   December 2012
   16068              : 
   16069              :     // PURPOSE OF THIS FUNCTION:
   16070              :     //    Returns the operating sensible heat ratio for a given Rated SHR and coil entering
   16071              :     //    air DBT and WBT, and supply air mass flow fraction.
   16072              : 
   16073              :     // METHODOLOGY EMPLOYED:
   16074              :     //    Model uses user specified rated SHR, and SHR modifying curves for temperature and flow
   16075              :     //    fraction.  The curves adjust the rated SHR based on biquadratic curve for temperatures
   16076              :     //    and quadratic function for supply air mass flow ratio (actual vs rated).
   16077              :     //    The biquadratic and quadratic curves are normalized curves generated from manufacturer's
   16078              :     //    performance data
   16079              : 
   16080              :     // Using/Aliasing
   16081              :     using Curve::CurveValue;
   16082              : 
   16083              :     // Return value
   16084              :     Real64 SHRopr; // operating SHR, corrected for Temp and Flow Fraction
   16085              : 
   16086              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   16087              :     Real64 SHRTempModFac; // Sensible Heat Ratio modifier (function of entering wetbulb, entering drybulb)
   16088              :     Real64 SHRFlowModFac; // Sensible Heat Ratio modifier (function of actual vs rated flow)
   16089              : 
   16090              :     //   Get SHR modifying factor (function of inlet wetbulb & drybulb) for off-rated conditions
   16091            3 :     if (SHRFTempCurveIndex == 0) {
   16092            3 :         SHRTempModFac = 1.0;
   16093              :     } else {
   16094            0 :         SHRTempModFac = CurveValue(state, SHRFTempCurveIndex, InletWetBulb, InletDryBulb);
   16095            0 :         if (SHRTempModFac < 0.0) {
   16096            0 :             SHRTempModFac = 0.0;
   16097              :         }
   16098              :     }
   16099              :     //   Get SHR modifying factor (function of mass flow ratio) for off-rated conditions
   16100            3 :     if (SHRFFlowCurveIndex == 0) {
   16101            3 :         SHRFlowModFac = 1.0;
   16102              :     } else {
   16103            0 :         SHRFlowModFac = CurveValue(state, SHRFFlowCurveIndex, AirMassFlowRatio);
   16104            0 :         if (SHRFlowModFac < 0.0) {
   16105            0 :             SHRFlowModFac = 0.0;
   16106              :         }
   16107              :     }
   16108              :     //  Calculate "operating" sensible heat ratio
   16109            3 :     SHRopr = SHRRated * SHRTempModFac * SHRFlowModFac;
   16110              : 
   16111            3 :     if (SHRopr < 0.0) SHRopr = 0.0; // SHR cannot be less than zero
   16112            3 :     if (SHRopr > 1.0) SHRopr = 1.0; // SHR cannot be greater than 1.0
   16113              : 
   16114            3 :     return SHRopr;
   16115              : }
   16116              : 
   16117            0 : void SetDXCoilTypeData(EnergyPlusData &state, std::string const &CoilName) // must match coil names for the coil type
   16118              : {
   16119              : 
   16120              :     // SUBROUTINE INFORMATION:
   16121              :     //       AUTHOR         B. Nigusse
   16122              :     //       DATE WRITTEN   January 2013
   16123              : 
   16124              :     // PURPOSE OF THIS SUBROUTINE:
   16125              :     // inform the child DX coil if the DX cooling coil is for 100% DOAS application.
   16126              : 
   16127              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16128              :     int WhichCoil;
   16129              : 
   16130            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   16131            0 :         GetDXCoils(state);
   16132            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   16133              :     }
   16134              : 
   16135            0 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   16136            0 :     if (WhichCoil != 0) {
   16137            0 :         state.dataDXCoils->DXCoil(WhichCoil).ISHundredPercentDOASDXCoil = true;
   16138              :     } else {
   16139              :         // DXCoil(WhichCoil)%ISHundredPercentDOASDXCoil = .FALSE. //Autodesk:BoundsViolation DXCoil(0): DXCoil is not allocated with a 0
   16140              :         // element: Commented out
   16141            0 :         ShowSevereError(state, format("SetDXCoilTypeData: Could not find Coil \"Name=\"{}\"", CoilName));
   16142              :     }
   16143            0 : }
   16144              : 
   16145            5 : void CalcSecondaryDXCoils(EnergyPlusData &state, int const DXCoilNum)
   16146              : {
   16147              : 
   16148              :     // SUBROUTINE INFORMATION:
   16149              :     //       AUTHOR         B. Nigusse
   16150              :     //       DATE WRITTEN   February 2015
   16151              : 
   16152              :     // PURPOSE OF THIS SUBROUTINE:
   16153              :     // Calculates secondary zone heat gain from secondary DX coils placed in a zone.
   16154              : 
   16155              :     // METHODOLOGY EMPLOYED:
   16156              :     // Energy balance:
   16157              :     //  (1) Condenser placed in a zone, the zone total (sensible) heat
   16158              :     //      gain rate is given Qcond = QEvap + WcompPluscondFanPower
   16159              :     //  (2) Evaporator placed in a zone, the zone total heat removal
   16160              :     //      rate is given Qevap = Qcond - WcompPluscondFanPower
   16161              :     //      Furthermore, the evaporator total heat removal is split into
   16162              :     //      latent and sensible components using user specified SHR
   16163              : 
   16164              :     // Using/Aliasing
   16165              :     using Curve::CurveValue;
   16166              : 
   16167              :     // SUBROUTINE PARAMETER DEFINITIONS:
   16168              :     static constexpr std::string_view RoutineName("CalcSecondaryDXCoils");
   16169              : 
   16170              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16171              :     Real64 CondInletDryBulb;       // condenser entering air dry-bulb temperature (C)
   16172              :     Real64 EvapAirMassFlow;        // Condenser air mass flow rate [kg/s]
   16173              :     Real64 EvapInletDryBulb;       // evaporator inlet air drybulb [C]
   16174              :     Real64 EvapInletHumRat;        // evaporator inlet air humidity ratio [kg/kg]
   16175              :     Real64 EvapInletWetBulb;       // evaporator inlet air wetbulb [C]
   16176              :     Real64 EvapInletEnthalpy;      // evaporator inlet air enthalpy [J/kg]
   16177              :     Real64 FullLoadOutAirEnth;     // evaporator outlet full load enthalpy [J/kg]
   16178              :     Real64 FullLoadOutAirHumRat;   // evaporator outlet humidity ratio at full load
   16179              :     Real64 FullLoadOutAirTemp;     // evaporator outlet air temperature at full load [C]
   16180              :     Real64 hTinwout;               // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
   16181            5 :     Real64 SHR(0);                 // sensible heat ratio
   16182              :     Real64 RhoAir;                 // secondary coil entering air density [kg/m3]
   16183            5 :     Real64 PartLoadRatio(0);       // primary coil part-load ratio [-]
   16184              :     Real64 SecCoilRatedSHR;        // secondary DX coil nominal or rated sensible heat ratio
   16185              :     Real64 SecCoilFlowFraction;    // secondary coil flow fraction, is 1.0 for single speed machine
   16186              :     Real64 TotalHeatRemovalRate;   // secondary coil total heat removal rate
   16187              :     Real64 TotalHeatRejectionRate; // secondary coil total heat rejection rate
   16188              :     int SecCoilSHRFT;              // index of the SHR modifier curve for temperature of a secondary DX coil
   16189              :     int SecCoilSHRFF;              // index of the sHR modifier curve for flow fraction of a secondary DX coil
   16190              :     int MSSpeedNumLS;              // current low speed number of multispeed HP
   16191              :     int MSSpeedNumHS;              // current high speed number of multispeed HP
   16192              :     Real64 MSSpeedRatio;           // current speed ratio of multispeed HP
   16193              :     Real64 MSCycRatio;             // current cycling ratio of multispeed HP
   16194              :     Real64 SHRHighSpeed;           // sensible heat ratio at high speed
   16195              :     Real64 SHRLowSpeed;            // sensible heat ratio at low speed
   16196              : 
   16197            5 :     EvapAirMassFlow = 0.0;
   16198              : 
   16199            5 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   16200              : 
   16201            5 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   16202            5 :         auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   16203              :         // Select the correct unit type
   16204            5 :         switch (thisDXCoil.DXCoilType_Num) {
   16205            3 :         case HVAC::CoilDX_CoolingSingleSpeed:
   16206              :         case HVAC::CoilDX_CoolingTwoSpeed:
   16207              :         case HVAC::CoilDX_MultiSpeedCooling: {
   16208              :             // total sensible heat gain of the secondary zone from the secondary coil (condenser)
   16209            3 :             if (thisDXCoil.ElecCoolingPower > 0.0) {
   16210            3 :                 TotalHeatRejectionRate = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
   16211              :             } else {
   16212            0 :                 TotalHeatRejectionRate = 0.0;
   16213            0 :                 return;
   16214              :             }
   16215            3 :             thisDXCoil.SecCoilSensibleHeatGainRate = TotalHeatRejectionRate;
   16216            3 :         } break;
   16217            1 :         case HVAC::CoilDX_HeatingEmpirical: {
   16218              :             // evaporator coil in the secondary zone
   16219            1 :             if (thisDXCoil.ElecHeatingPower > 0.0) {
   16220            1 :                 TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
   16221              :             } else {
   16222            0 :                 TotalHeatRemovalRate = 0.0;
   16223            0 :                 thisDXCoil.SecCoilSHR = 0.0;
   16224            0 :                 return;
   16225              :             }
   16226            1 :             thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
   16227            1 :             EvapInletDryBulb = secZoneHB.ZT;
   16228            1 :             EvapInletHumRat = secZoneHB.airHumRat;
   16229            1 :             RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
   16230            1 :             EvapAirMassFlow = RhoAir * thisDXCoil.SecCoilAirFlow;
   16231              :             ;
   16232            1 :             PartLoadRatio = thisDXCoil.CompressorPartLoadRatio;
   16233            1 :             SecCoilRatedSHR = thisDXCoil.SecCoilRatedSHR;
   16234            1 :             if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (PartLoadRatio > 0.0) &&
   16235            1 :                 (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
   16236            1 :                 SecCoilFlowFraction = 1.0;                          // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
   16237            1 :                 CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
   16238            1 :                 EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
   16239            1 :                 EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
   16240            1 :                 SecCoilSHRFT = thisDXCoil.SecCoilSHRFT;
   16241            1 :                 SecCoilSHRFF = thisDXCoil.SecCoilSHRFF;
   16242              :                 // determine the current SHR
   16243            1 :                 SHR = CalcSecondaryDXCoilsSHR(state,
   16244              :                                               DXCoilNum,
   16245              :                                               EvapAirMassFlow,
   16246              :                                               TotalHeatRemovalRate,
   16247              :                                               PartLoadRatio,
   16248              :                                               SecCoilRatedSHR,
   16249              :                                               EvapInletDryBulb,
   16250              :                                               EvapInletHumRat,
   16251              :                                               EvapInletWetBulb,
   16252              :                                               EvapInletEnthalpy,
   16253              :                                               CondInletDryBulb,
   16254              :                                               SecCoilFlowFraction,
   16255              :                                               SecCoilSHRFT,
   16256              :                                               SecCoilSHRFF);
   16257              :                 // Calculate full load output conditions
   16258            1 :                 FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
   16259            1 :                 hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
   16260            1 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
   16261            1 :                 FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   16262              :                 // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
   16263            1 :                 if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
   16264            0 :                     FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName);
   16265            0 :                     FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
   16266              :                     // Adjust SHR for the new outlet condition that balances energy
   16267            0 :                     hTinwout = PsyHFnTdbW(EvapInletDryBulb, FullLoadOutAirHumRat);
   16268            0 :                     SHR = 1.0 - (EvapInletEnthalpy - hTinwout) / ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
   16269            0 :                     SHR = min(SHR, 1.0);
   16270              :                 }
   16271              :                 // calculate the sensible and latent zone heat removal (extraction) rate by the secondary coil
   16272            1 :                 thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
   16273            1 :                 thisDXCoil.SecCoilLatentHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate - thisDXCoil.SecCoilSensibleHeatRemovalRate;
   16274              :             } else {
   16275              :                 // DX coil is off;
   16276            0 :                 thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
   16277            0 :                 thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
   16278            0 :                 thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
   16279            0 :                 SHR = 0.0; // SHR is set to zero if the coil is off
   16280              :             }
   16281            1 :             thisDXCoil.SecCoilSHR = SHR;
   16282            1 :         } break;
   16283            1 :         case HVAC::CoilDX_MultiSpeedHeating: {
   16284            1 :             EvapInletDryBulb = secZoneHB.ZT;
   16285            1 :             EvapInletHumRat = secZoneHB.airHumRat;
   16286            1 :             RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
   16287            1 :             MSSpeedRatio = thisDXCoil.MSSpeedRatio;
   16288            1 :             MSCycRatio = thisDXCoil.MSCycRatio;
   16289            1 :             MSSpeedNumHS = thisDXCoil.MSSpeedNumHS;
   16290            1 :             MSSpeedNumLS = thisDXCoil.MSSpeedNumLS;
   16291            1 :             if (MSSpeedRatio > 0.0) {
   16292            0 :                 EvapAirMassFlow = RhoAir * (thisDXCoil.MSSecCoilAirFlow(MSSpeedNumHS) * MSSpeedRatio +
   16293            0 :                                             thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS) * (1.0 - MSSpeedRatio));
   16294            1 :             } else if (MSCycRatio > 0.0) {
   16295            1 :                 EvapAirMassFlow = RhoAir * thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS);
   16296              :             }
   16297            1 :             if (thisDXCoil.ElecHeatingPower > 0.0) {
   16298            1 :                 TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
   16299              :             } else {
   16300            0 :                 TotalHeatRemovalRate = 0.0;
   16301            0 :                 return;
   16302              :             }
   16303            1 :             thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
   16304            1 :             if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (MSSpeedRatio > 0.0 || MSCycRatio > 0.0) &&
   16305            1 :                 (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
   16306            1 :                 SecCoilFlowFraction = 1.0;                          // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
   16307            1 :                 CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
   16308            1 :                 EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
   16309            1 :                 EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
   16310              :                 // determine the current SHR
   16311            1 :                 if (MSSpeedRatio > 0.0) {
   16312              :                     // calculate SHR for the higher speed
   16313            0 :                     PartLoadRatio = 1.0;
   16314            0 :                     SecCoilFlowFraction = 1.0;
   16315            0 :                     SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumHS);
   16316            0 :                     SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumHS);
   16317            0 :                     SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumHS);
   16318            0 :                     SHRHighSpeed = CalcSecondaryDXCoilsSHR(state,
   16319              :                                                            DXCoilNum,
   16320              :                                                            EvapAirMassFlow,
   16321              :                                                            TotalHeatRemovalRate,
   16322              :                                                            PartLoadRatio,
   16323              :                                                            SecCoilRatedSHR,
   16324              :                                                            EvapInletDryBulb,
   16325              :                                                            EvapInletHumRat,
   16326              :                                                            EvapInletWetBulb,
   16327              :                                                            EvapInletEnthalpy,
   16328              :                                                            CondInletDryBulb,
   16329              :                                                            SecCoilFlowFraction,
   16330              :                                                            SecCoilSHRFT,
   16331              :                                                            SecCoilSHRFF);
   16332              :                     // calculate SHR for the lower speed
   16333            0 :                     SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumLS);
   16334            0 :                     SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumLS);
   16335            0 :                     SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumLS);
   16336            0 :                     SHRLowSpeed = CalcSecondaryDXCoilsSHR(state,
   16337              :                                                           DXCoilNum,
   16338              :                                                           EvapAirMassFlow,
   16339              :                                                           TotalHeatRemovalRate,
   16340              :                                                           PartLoadRatio,
   16341              :                                                           SecCoilRatedSHR,
   16342              :                                                           EvapInletDryBulb,
   16343              :                                                           EvapInletHumRat,
   16344              :                                                           EvapInletWetBulb,
   16345              :                                                           EvapInletEnthalpy,
   16346              :                                                           CondInletDryBulb,
   16347              :                                                           SecCoilFlowFraction,
   16348              :                                                           SecCoilSHRFT,
   16349              :                                                           SecCoilSHRFF);
   16350            0 :                     SHR = SHRHighSpeed * MSSpeedRatio + SHRLowSpeed * (1.0 - MSSpeedRatio);
   16351              : 
   16352            1 :                 } else if (MSCycRatio > 0.0) {
   16353              :                     // calculate SHR for the lower speed
   16354            1 :                     PartLoadRatio = MSCycRatio;
   16355            1 :                     SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumLS);
   16356            1 :                     SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumLS);
   16357            1 :                     SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumLS);
   16358            1 :                     SecCoilFlowFraction = 1.0;
   16359            1 :                     SHRLowSpeed = CalcSecondaryDXCoilsSHR(state,
   16360              :                                                           DXCoilNum,
   16361              :                                                           EvapAirMassFlow,
   16362              :                                                           TotalHeatRemovalRate,
   16363              :                                                           MSCycRatio,
   16364              :                                                           SecCoilRatedSHR,
   16365              :                                                           EvapInletDryBulb,
   16366              :                                                           EvapInletHumRat,
   16367              :                                                           EvapInletWetBulb,
   16368              :                                                           EvapInletEnthalpy,
   16369              :                                                           CondInletDryBulb,
   16370              :                                                           SecCoilFlowFraction,
   16371              :                                                           SecCoilSHRFT,
   16372              :                                                           SecCoilSHRFF);
   16373            1 :                     SHR = SHRLowSpeed;
   16374              :                 }
   16375              :                 // Calculate full load output conditions
   16376            1 :                 FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
   16377            1 :                 hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
   16378            1 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
   16379            1 :                 FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   16380              :                 // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
   16381            1 :                 if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
   16382            0 :                     FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName);
   16383            0 :                     FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
   16384              :                     // Adjust SHR for the new outlet condition that balances energy
   16385            0 :                     hTinwout = PsyHFnTdbW(EvapInletDryBulb, FullLoadOutAirHumRat);
   16386            0 :                     SHR = 1.0 - (EvapInletEnthalpy - hTinwout) / (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
   16387            0 :                     SHR = min(SHR, 1.0);
   16388              :                 }
   16389              :                 // calculate the sensible and latent zone heat removal (extraction) rate by the secondary coil
   16390            1 :                 thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
   16391            1 :                 thisDXCoil.SecCoilLatentHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate - thisDXCoil.SecCoilSensibleHeatRemovalRate;
   16392              :             } else {
   16393              :                 // DX coil is off;
   16394            0 :                 thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
   16395            0 :                 thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
   16396            0 :                 thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
   16397            0 :                 SHR = 0.0; // SHR is set to rated value if the coil is off
   16398              :             }
   16399            1 :             thisDXCoil.SecCoilSHR = SHR;
   16400            1 :         } break;
   16401            0 :         default:
   16402            0 :             break;
   16403              :         }
   16404              : 
   16405              :     } else {
   16406            0 :         thisDXCoil.SecCoilSensibleHeatGainRate = 0.0;
   16407            0 :         thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
   16408            0 :         thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
   16409            0 :         thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
   16410              :     }
   16411              : }
   16412              : 
   16413            3 : Real64 CalcSecondaryDXCoilsSHR(EnergyPlusData &state,
   16414              :                                [[maybe_unused]] int const DXCoilNum,
   16415              :                                Real64 const EvapAirMassFlow,
   16416              :                                Real64 const TotalHeatRemovalRate,
   16417              :                                Real64 const PartLoadRatio,
   16418              :                                Real64 const SecCoilRatedSHR,
   16419              :                                Real64 const EvapInletDryBulb,
   16420              :                                Real64 const EvapInletHumRat,
   16421              :                                Real64 const EvapInletWetBulb,
   16422              :                                Real64 const EvapInletEnthalpy,
   16423              :                                Real64 const CondInletDryBulb,
   16424              :                                Real64 const SecCoilFlowFraction,
   16425              :                                int const SecCoilSHRFT,
   16426              :                                int const SecCoilSHRFF)
   16427              : {
   16428              : 
   16429              :     // SUBROUTINE INFORMATION:
   16430              :     //       AUTHOR         B. Nigusse
   16431              :     //       DATE WRITTEN   February 2015
   16432              : 
   16433              :     // PURPOSE OF THIS SUBROUTINE:
   16434              :     // Calculates secondary coil (evaporator) sensible heat ratio.
   16435              : 
   16436              :     // METHODOLOGY EMPLOYED:
   16437              :     // Energy balance:
   16438              :     //  (1) checks if the secondary coil operation is dry and calculates applicable SHR.
   16439              :     //  (2) determines SHR from user specified rated SHR values and SHR modifier curves for
   16440              :     //      temperature and flow fraction.
   16441              :     //  (3) if secondary coil operates dry then the larger of the user SHR value and dry
   16442              :     //      coil operation SHR is selected.
   16443              : 
   16444              :     // Using/Aliasing
   16445              :     using Curve::CurveValue;
   16446              : 
   16447              :     // SUBROUTINE PARAMETER DEFINITIONS:
   16448            3 :     int constexpr MaxIter(30);
   16449            3 :     Real64 constexpr RelaxationFactor(0.4);
   16450            3 :     Real64 constexpr Tolerance(0.1);
   16451            3 :     Real64 constexpr DryCoilTestEvapInletHumRatReset(0.00001);
   16452              :     static constexpr std::string_view RoutineName("CalcSecondaryDXCoilsSHR");
   16453              : 
   16454              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16455              :     Real64 DryCoilTestEvapInletHumRat;  // evaporator coil inlet humidity ratio test for dry coil
   16456              :     Real64 DryCoilTestEvapInletWetBulb; // evaporator coil inlet dry bulb temperature test for dry coil
   16457              :     Real64 FullLoadOutAirEnth;          // evaporator outlet full load enthalpy [J/kg]
   16458              :     Real64 FullLoadOutAirTemp;          // evaporator outlet air temperature at full load [C]
   16459              :     Real64 hTinwADP;                    // enthalpy of air at secondary coil entering temperature and Humidity ratio at ADP
   16460              :     Real64 SHRadp;                      // Sensible heat ratio
   16461              :     Real64 hADP;                        // enthalpy of air at secondary coil at ADP
   16462              :     Real64 tADP;                        // dry bulb temperature of air at secondary coil at ADP
   16463              :     Real64 wADP;                        // humidity ratio of air at secondary coil at ADP
   16464              :     Real64 HumRatError;                 // humidity ratio error
   16465              :     bool CoilMightBeDry;                // TRUE means the secondary DX coil runs dry
   16466              :     int Counter;                        // iteration counter
   16467              :     bool Converged;                     // convergence flag
   16468              :     Real64 SHR;                         // current time step sensible heat ratio of secondary coil
   16469              : 
   16470            3 :     CoilMightBeDry = false;
   16471            3 :     FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
   16472            3 :     FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, EvapInletHumRat);
   16473            3 :     if (FullLoadOutAirTemp > PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
   16474            3 :         CoilMightBeDry = true;
   16475              :         // find wADP, humidity ratio at apparatus dewpoint and inlet hum rat that would have dry coil
   16476            3 :         DryCoilTestEvapInletHumRat = EvapInletHumRat;
   16477            3 :         DryCoilTestEvapInletWetBulb = EvapInletWetBulb;
   16478            3 :         Counter = 0;
   16479            3 :         Converged = false;
   16480            6 :         while (!Converged) {
   16481              :             // assumes coil bypass factor (CBF) = 0.0
   16482            3 :             hADP = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
   16483            3 :             tADP = PsyTsatFnHPb(state, hADP, state.dataEnvrn->OutBaroPress, RoutineName);
   16484            3 :             wADP = min(EvapInletHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
   16485            3 :             hTinwADP = PsyHFnTdbW(EvapInletDryBulb, wADP);
   16486            3 :             if ((EvapInletEnthalpy - hADP) > 1.e-10) {
   16487            3 :                 SHRadp = min((hTinwADP - hADP) / (EvapInletEnthalpy - hADP), 1.0);
   16488              :             } else {
   16489            0 :                 SHRadp = 1.0;
   16490              :             }
   16491            3 :             if ((wADP > DryCoilTestEvapInletHumRat) || (Counter >= 1 && Counter < MaxIter)) {
   16492            0 :                 if (DryCoilTestEvapInletHumRat <= 0.0) DryCoilTestEvapInletHumRat = DryCoilTestEvapInletHumRatReset;
   16493            0 :                 HumRatError = (DryCoilTestEvapInletHumRat - wADP) / DryCoilTestEvapInletHumRat;
   16494            0 :                 DryCoilTestEvapInletHumRat = RelaxationFactor * wADP + (1.0 - RelaxationFactor) * DryCoilTestEvapInletHumRat;
   16495              :                 DryCoilTestEvapInletWetBulb =
   16496            0 :                     PsyTwbFnTdbWPb(state, EvapInletDryBulb, DryCoilTestEvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
   16497            0 :                 ++Counter;
   16498            0 :                 if (std::abs(HumRatError) <= Tolerance) {
   16499            0 :                     Converged = true;
   16500              :                 } else {
   16501            0 :                     Converged = false;
   16502              :                 }
   16503              :             } else {
   16504            3 :                 Converged = true;
   16505              :             }
   16506              :         }
   16507              :     }
   16508              :     // determine SHR from user specified nominal value and SHR modifier curves
   16509            3 :     SHR = CalcSHRUserDefinedCurves(state, CondInletDryBulb, EvapInletWetBulb, SecCoilFlowFraction, SecCoilSHRFT, SecCoilSHRFF, SecCoilRatedSHR);
   16510            3 :     if (CoilMightBeDry) {
   16511            3 :         if ((EvapInletHumRat < DryCoilTestEvapInletHumRat) && (SHRadp > SHR)) { // coil is dry for sure
   16512            0 :             SHR = 1.0;
   16513            3 :         } else if (SHRadp > SHR) {
   16514            0 :             SHR = SHRadp;
   16515              :         }
   16516              :     }
   16517            3 :     return SHR;
   16518              : }
   16519              : 
   16520        23659 : void CalcVRFCoolingCoil_FluidTCtrl(EnergyPlusData &state,
   16521              :                                    int const DXCoilNum,                    // the number of the DX coil to be simulated
   16522              :                                    HVAC::CompressorOp const compressorOp,  // compressor operation; 1=on, 0=off
   16523              :                                    bool const FirstHVACIteration,          // true if this is the first iteration of HVAC
   16524              :                                    Real64 const PartLoadRatio,             // sensible cooling load / full load sensible cooling capacity
   16525              :                                    HVAC::FanOp const fanOp,                // Allows parent object to control fan operation
   16526              :                                    Real64 const CompCycRatio,              // cycling ratio of VRF condenser
   16527              :                                    ObjexxFCL::Optional_int_const PerfMode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
   16528              :                                    ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
   16529              :                                    Real64 MaxCoolCap                                    // maximum allowed cooling capacity
   16530              : )
   16531              : {
   16532              :     // SUBROUTINE INFORMATION:
   16533              :     //       AUTHOR         Xiufeng Pang, LBNL
   16534              :     //       DATE WRITTEN   Jan 2013
   16535              :     //       MODIFIED       Nov 2015, RP Zhang, LBNL
   16536              : 
   16537              :     // PURPOSE OF THIS SUBROUTINE:
   16538              :     //         Calculates the air-side performance of a direct-expansion, air-cooled
   16539              :     //         VRF terminal unit cooling coil, for the VRF_FluidTCtrl model.
   16540              : 
   16541              :     // METHODOLOGY EMPLOYED:
   16542              :     //         This subroutine is derived from CalcVRFCoolingCoil, and implements the new VRF model for FluidTCtrl.
   16543              : 
   16544              :     // Using/Aliasing
   16545              :     using Curve::CurveValue;
   16546        23659 :     Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
   16547        23659 :     Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
   16548              :     using General::CreateSysTimeIntervalString;
   16549              : 
   16550              :     using namespace HVACVariableRefrigerantFlow;
   16551              : 
   16552              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16553              : 
   16554              :     Real64 AirMassFlow;       // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
   16555              :     Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
   16556              :     // (average flow if cycling fan, full flow if constant fan)
   16557              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
   16558              :     Real64 TotCap;                // gross total cooling capacity at off-rated conditions [W]
   16559              :     Real64 InletAirDryBulbTemp;   // inlet air dry bulb temperature [C]
   16560              :     Real64 InletAirEnthalpy;      // inlet air enthalpy [J/kg]
   16561              :     Real64 InletAirHumRat;        // inlet air humidity ratio [kg/kg]
   16562              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   16563              :     Real64 RatedCBF;      // coil bypass factor at rated conditions
   16564              :     Real64 CBF;           // coil bypass factor at off rated conditions
   16565              :     Real64 A0;            // NTU * air mass flow rate, used in CBF calculation
   16566              :     Real64 PLF;           // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
   16567              :     Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
   16568              :     // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
   16569              :     Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
   16570              :     // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
   16571              :     Real64 CondAirMassFlow;       // Condenser air mass flow rate [kg/s]
   16572              :     Real64 RhoAir;                // Density of air [kg/m3]
   16573              :     Real64 CrankcaseHeatingPower; // power due to crankcase heater
   16574        23659 :     Real64 CompAmbTemp(0.0);      // Ambient temperature at compressor
   16575              :     Real64 AirFlowRatio;          // ratio of compressor on airflow to average timestep airflow
   16576              :     // used when constant fan mode yields different air flow rates when compressor is ON and OFF
   16577              :     // (e.g. Packaged Terminal Heat Pump)
   16578              :     Real64 OutdoorDryBulb;  // Outdoor dry-bulb temperature at condenser (C)
   16579              :     Real64 OutdoorWetBulb;  // Outdoor wet-bulb temperature at condenser (C)
   16580              :     Real64 OutdoorHumRat;   // Outdoor humidity ratio at condenser (kg/kg)
   16581              :     Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
   16582              : 
   16583              :     int Mode;                 // Performance mode for Multimode DX coil; Always 1 for other coil types
   16584              :     Real64 OutletAirTemp;     // Supply air temperature (average value if constant fan, full output if cycling fan)
   16585              :     Real64 OutletAirHumRat;   // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
   16586              :     Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
   16587              :     Real64 ADiff;             // Used for exponential
   16588              : 
   16589              :     // Followings for VRF FluidTCtrl Only
   16590              :     Real64 QCoilReq;       // Coil load (W)
   16591              :     Real64 FanSpdRatio;    // Fan speed ratio
   16592              :     Real64 AirMassFlowMin; // Min air mass flow rate due to OA requirement [kg/s]
   16593              :     Real64 ActualSH;       // Super heating degrees (C)
   16594              :     Real64 ActualSC;       // Sub cooling degrees (C)
   16595              : 
   16596              :     // If Performance mode not present, then set to 1.  Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
   16597        23659 :     if (present(PerfMode)) {
   16598            0 :         Mode = PerfMode;
   16599              :     } else {
   16600        23659 :         Mode = 1;
   16601              :     }
   16602              : 
   16603              :     // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
   16604              :     // during cooling and when no cooling is required (constant fan, fan speed changes)
   16605        23659 :     if (present(OnOffAirFlowRatio)) {
   16606            0 :         AirFlowRatio = OnOffAirFlowRatio;
   16607              :     } else {
   16608        23659 :         AirFlowRatio = 1.0;
   16609              :     }
   16610              : 
   16611        23659 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   16612              : 
   16613              :     // Initialize coil air side parameters
   16614        23659 :     CondInletTemp = 0.0;
   16615        23659 :     CondInletHumRat = 0.0;
   16616        23659 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   16617        23659 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   16618        23659 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   16619        23659 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   16620        23659 :     state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
   16621        23659 :     thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
   16622        23659 :     thisDXCoil.PartLoadRatio = 0.0;
   16623        23659 :     thisDXCoil.BasinHeaterPower = 0.0;
   16624        23659 :     thisDXCoil.EvaporatingTemp = state.dataHVACVarRefFlow->VRF(thisDXCoil.VRFOUPtr).IUEvaporatingTemp;
   16625              : 
   16626        23659 :     if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
   16627            0 :         OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
   16628            0 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
   16629            0 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   16630            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   16631            0 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   16632              :         } else {
   16633            0 :             OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
   16634              :             // If node is not connected to anything, pressure = default, use weather data
   16635            0 :             if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   16636            0 :                 OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   16637            0 :                 OutdoorHumRat = state.dataEnvrn->OutHumRat;
   16638            0 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress;
   16639            0 :                 OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   16640              :             } else {
   16641            0 :                 OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
   16642            0 :                 OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
   16643              :             }
   16644              :         }
   16645              :     } else {
   16646        23659 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   16647        23659 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   16648        23659 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   16649        23659 :         OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   16650              :     }
   16651              : 
   16652        23659 :     if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   16653            0 :         RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
   16654            0 :         CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
   16655              :         // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   16656            0 :         CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
   16657            0 :         CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
   16658            0 :         CompAmbTemp = OutdoorDryBulb;
   16659              :     } else {                            // for air or water-cooled, inlet temp is stored in OutdoorDryBulb temp
   16660        23659 :         CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
   16661        23659 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
   16662            0 :             CompAmbTemp = state.dataEnvrn->OutDryBulbTemp; // for crankcase heater use actual outdoor temp for water-cooled
   16663              :         } else {
   16664        23659 :             CompAmbTemp = OutdoorDryBulb;
   16665              :         }
   16666              :     }
   16667              : 
   16668              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
   16669              :     // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
   16670        23659 :     if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
   16671           32 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   16672           32 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   16673            0 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
   16674              :         }
   16675              :     } else {
   16676        23627 :         CrankcaseHeatingPower = 0.0;
   16677              :     }
   16678              : 
   16679              :     // calculate end time of current time step to determine if error messages should be printed
   16680        23659 :     state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
   16681              : 
   16682              :     // The following checks are not necessary for VRF-FluidTCtrl model. (1) OAT check is already performed in the VRF OU routines (2)
   16683              :     // VRF-FluidTCtrl model is physics based, not system curve based, and thus doesn't require special performance curves for operations at
   16684              :     // low inlet temperatures
   16685              :     //   Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
   16686              :     //   Wait for next time step to print warnings. If simulation iterates, print out
   16687              :     //   the warning for the last iteration only. Must wait for next time step to accomplish this.
   16688              :     //   If a warning occurs and the simulation down shifts, the warning is not valid.
   16689              :     // if ( DXCoil( DXCoilNum ).PrintLowAmbMessage ) { // .AND. &
   16690              :     //     if ( CurrentEndTime > DXCoil( DXCoilNum ).CurrentEndTimeLast && TimeStepSys >= DXCoil( DXCoilNum ).TimeStepSysLast ) {
   16691              :     //         if ( DXCoil( DXCoilNum ).LowAmbErrIndex == 0 ) {
   16692              :     //             ShowWarningMessage(state,  DXCoil( DXCoilNum ).LowAmbBuffer1 );
   16693              :     //             ShowContinueError(state,  DXCoil( DXCoilNum ).LowAmbBuffer2 );
   16694              :     //             ShowContinueError(state,  "... Operation at low inlet temperatures may require special performance curves." );
   16695              :     //         }
   16696              :     //         ShowRecurringWarningErrorAtEnd(state,  DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Low condenser inlet
   16697              :     // temperature error continues...", DXCoil( DXCoilNum ).LowAmbErrIndex, DXCoil( DXCoilNum ).LowTempLast, DXCoil( DXCoilNum ).LowTempLast,
   16698              :     // _,
   16699              :     // "[C]", "[C]" );
   16700              :     //     }
   16701              :     // }
   16702              :     //
   16703              :     // if ( DXCoil( DXCoilNum ).PrintHighAmbMessage ) { // .AND. &
   16704              :     //     if ( CurrentEndTime > DXCoil( DXCoilNum ).CurrentEndTimeLast && TimeStepSys >= DXCoil( DXCoilNum ).TimeStepSysLast ) {
   16705              :     //         if ( DXCoil( DXCoilNum ).HighAmbErrIndex == 0 ) {
   16706              :     //             ShowWarningMessage(state,  DXCoil( DXCoilNum ).HighAmbBuffer1 );
   16707              :     //             ShowContinueError(state,  DXCoil( DXCoilNum ).HighAmbBuffer2 );
   16708              :     //             ShowContinueError(state,  "... Operation at high inlet temperatures may require special performance curves." );
   16709              :     //         }
   16710              :     //         ShowRecurringWarningErrorAtEnd(state,  DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - High condenser inlet
   16711              :     // temperature error continues...", DXCoil( DXCoilNum ).HighAmbErrIndex, DXCoil( DXCoilNum ).HighTempLast, DXCoil( DXCoilNum
   16712              :     // ).HighTempLast,
   16713              :     // _, "[C]", "[C]" );
   16714              :     //     }
   16715              :     // }
   16716              : 
   16717        23659 :     if (thisDXCoil.PrintLowOutTempMessage) {
   16718            0 :         if ((state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime > thisDXCoil.CurrentEndTimeLast) &&
   16719            0 :             (TimeStepSys >= thisDXCoil.TimeStepSysLast)) {
   16720            0 :             if (thisDXCoil.LowOutletTempIndex == 0) {
   16721            0 :                 ShowWarningMessage(state, thisDXCoil.LowOutTempBuffer1);
   16722            0 :                 ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
   16723            0 :                 ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
   16724            0 :                 ShowContinueError(state,
   16725            0 :                                   format("   1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
   16726            0 :                                          thisDXCoil.FullLoadInletAirTempLast));
   16727            0 :                 ShowContinueError(state, "   2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
   16728            0 :                 ShowContinueError(state,
   16729              :                                   "   3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
   16730              :             }
   16731            0 :             ShowRecurringWarningErrorAtEnd(state,
   16732            0 :                                            thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   16733              :                                                "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
   16734              :                                                "Outlet air temperature statistics follow:",
   16735            0 :                                            thisDXCoil.LowOutletTempIndex,
   16736            0 :                                            thisDXCoil.FullLoadOutAirTempLast,
   16737            0 :                                            thisDXCoil.FullLoadOutAirTempLast);
   16738              :         }
   16739              :     }
   16740              : 
   16741              :     // save last system time step and last end time of current time step (used to determine if warning is valid)
   16742        23659 :     thisDXCoil.TimeStepSysLast = TimeStepSys;
   16743        23659 :     thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime;
   16744        23659 :     thisDXCoil.PrintLowAmbMessage = false;
   16745        23659 :     thisDXCoil.PrintLowOutTempMessage = false;
   16746              : 
   16747        23659 :     if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
   16748              :         (compressorOp == HVAC::CompressorOp::On)) { // for cycling fan, reset mass flow to full on rate
   16749              : 
   16750        10299 :         if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
   16751            0 :             ShowFatalError(state, format("{} \"{}\" - Rated total cooling capacity is zero or less.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   16752              :         }
   16753              : 
   16754        10299 :         TotCap = min(MaxCoolCap, thisDXCoil.RatedTotCap(Mode));
   16755              : 
   16756        10299 :         QCoilReq = -PartLoadRatio * TotCap;
   16757        10299 :         if (PartLoadRatio == 0.0) {
   16758            0 :             AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
   16759              :         } else {
   16760        10299 :             AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
   16761              :         }
   16762              : 
   16763              :         // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
   16764        10299 :         ControlVRFIUCoil(state,
   16765              :                          DXCoilNum,
   16766              :                          QCoilReq,
   16767              :                          thisDXCoil.InletAirTemp,
   16768              :                          thisDXCoil.InletAirHumRat,
   16769              :                          thisDXCoil.EvaporatingTemp,
   16770              :                          AirMassFlowMin,
   16771              :                          FanSpdRatio,
   16772              :                          OutletAirHumRat,
   16773              :                          OutletAirTemp,
   16774              :                          OutletAirEnthalpy,
   16775              :                          ActualSH,
   16776              :                          ActualSC);
   16777        10299 :         AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
   16778              : 
   16779        10299 :         AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
   16780        10299 :         VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
   16781              :         // VolFlowperRatedTotCap was checked at the initialization step
   16782              :         // No need to check VolFlowperRatedTotCap at the simulation
   16783              :         // New VRF_FluidTCtrl model implements VAV fan which can vary air flow rate during simulation
   16784              : 
   16785        10299 :         RatedCBF = thisDXCoil.RatedCBF(Mode);
   16786        10299 :         if (RatedCBF > 0.0) {
   16787        10299 :             A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
   16788              :         } else {
   16789            0 :             A0 = 0.0;
   16790              :         }
   16791        10299 :         ADiff = -A0 / AirMassFlow;
   16792        10299 :         if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
   16793         7714 :             CBF = std::exp(ADiff);
   16794              :         } else {
   16795         2585 :             CBF = 0.0;
   16796              :         }
   16797              : 
   16798              :         // The following checks are not necessary for VRF-FluidTCtrl model. (1) OAT check is already performed in the VRF OU routines (2)
   16799              :         // VRF-FluidTCtrl model is physics based, not system curve based, and thus doesn't require special performance curves for operations
   16800              :         // at low inlet temperatures
   16801              :         // // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
   16802              :         // if ( OutdoorDryBulb < DXCoil( DXCoilNum ).MinOATCompressor && ! WarmupFlag ) {
   16803              :         //     DXCoil( DXCoilNum ).PrintLowAmbMessage = true;
   16804              :         //     DXCoil( DXCoilNum ).LowTempLast = OutdoorDryBulb;
   16805              :         //     if ( DXCoil( DXCoilNum ).LowAmbErrIndex == 0 ) {
   16806              :         //         DXCoil( DXCoilNum ).LowAmbBuffer1 = DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Condenser
   16807              :         // inlet temperature below " + RoundSigDigits( DXCoil( DXCoilNum ).MinOATCompressor, 2 ) + " C. Condenser inlet temperature = " +
   16808              :         // RoundSigDigits( OutdoorDryBulb, 2 );
   16809              :         //         DXCoil( DXCoilNum ).LowAmbBuffer2 = " ... Occurrence info = " + EnvironmentName + ", " + CurMnDy + " " +
   16810              :         // CreateSysTimeIntervalString();
   16811              :         //     }
   16812              :         // }
   16813              :         //
   16814              :         // // check boundary for high ambient temperature and post warnings to individual DX coil buffers to print at end of time step
   16815              :         // if ( OutdoorDryBulb > DXCoil( DXCoilNum ).MaxOATCompressor && ! WarmupFlag ) {
   16816              :         //     DXCoil( DXCoilNum ).PrintHighAmbMessage = true;
   16817              :         //     DXCoil( DXCoilNum ).HighTempLast = OutdoorDryBulb;
   16818              :         //     if ( DXCoil( DXCoilNum ).HighAmbErrIndex == 0 ) {
   16819              :         //         DXCoil( DXCoilNum ).HighAmbBuffer1 = DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Condenser
   16820              :         // inlet temperature above " + RoundSigDigits( DXCoil( DXCoilNum ).MaxOATCompressor, 2 ) + " C. Condenser temperature = " +
   16821              :         // RoundSigDigits( OutdoorDryBulb, 2 );         DXCoil( DXCoilNum ).HighAmbBuffer2 = " ... Occurrence info = " + EnvironmentName + ",
   16822              :         // "
   16823              :         // + CurMnDy + " " + CreateSysTimeIntervalString();
   16824              :         //     }
   16825              :         // }
   16826              : 
   16827              :         //  Get total capacity modifying factor (function of temperature) for off-rated conditions
   16828              :         //  InletAirHumRat may be modified in this ADP/BF loop, use temporary varible for calculations
   16829              : 
   16830              :         // commented, not used issue #6950
   16831              :         // InletAirHumRatTemp = InletAirHumRat;
   16832              : 
   16833              :         //// Calculate apparatus dew point conditions using TotCap and CBF
   16834              :         // hDelta = TotCap / AirMassFlow;
   16835              :         //// there is an issue here with using CBF to calculate the ADP enthalpy.
   16836              :         //// at low loads the bypass factor increases significantly.
   16837              :         // hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
   16838              :         // tADP = PsyTsatFnHPb(hADP, OutdoorPressure, RoutineName);
   16839              :         ////  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   16840              :         ////  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   16841              :         // wADP = min(InletAirHumRat, PsyWFnTdbH(tADP, hADP, RoutineName));
   16842              :         // hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   16843              :         // if ((InletAirEnthalpy - hADP) > 1.e-10) {
   16844              :         //    SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   16845              :         //} else {
   16846              :         //    SHR = 1.0;
   16847              :         //}
   16848              :         // commented, not used issue #6950 ends here
   16849              : 
   16850        10299 :         if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
   16851            0 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
   16852              :         } else {
   16853        10299 :             PLF = 1.0;
   16854              :         }
   16855              : 
   16856        10299 :         if (PLF < 0.7) {
   16857            0 :             if (thisDXCoil.ErrIndex2 == 0) {
   16858            0 :                 ShowWarningMessage(
   16859              :                     state,
   16860            0 :                     format(
   16861            0 :                         "The PLF curve value for the DX cooling coil {} ={:.3R} for part-load ratio ={:.3R}", thisDXCoil.Name, PLF, PartLoadRatio));
   16862            0 :                 ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   16863            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
   16864              :             }
   16865            0 :             ShowRecurringWarningErrorAtEnd(
   16866            0 :                 state, thisDXCoil.Name + ", DX cooling coil PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
   16867            0 :             PLF = 0.7;
   16868              :         }
   16869              : 
   16870        10299 :         thisDXCoil.PartLoadRatio = PartLoadRatio;
   16871        10299 :         thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
   16872        10299 :         if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
   16873            0 :             if (thisDXCoil.ErrIndex3 == 0) {
   16874            0 :                 ShowWarningMessage(state,
   16875            0 :                                    format("The runtime fraction for DX cooling coil {} exceeded 1.0. [{:.4R}].",
   16876            0 :                                           thisDXCoil.Name,
   16877            0 :                                           thisDXCoil.CoolingCoilRuntimeFraction));
   16878            0 :                 ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
   16879            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
   16880            0 :                 ShowContinueErrorTimeStamp(state, "");
   16881              :             }
   16882            0 :             ShowRecurringWarningErrorAtEnd(state,
   16883            0 :                                            thisDXCoil.Name + ", DX cooling coil runtime fraction > 1.0 warning continues...",
   16884            0 :                                            thisDXCoil.ErrIndex3,
   16885            0 :                                            thisDXCoil.CoolingCoilRuntimeFraction,
   16886            0 :                                            thisDXCoil.CoolingCoilRuntimeFraction);
   16887            0 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   16888        10299 :         } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
   16889            0 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   16890              :         }
   16891              : 
   16892              :         // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
   16893        10299 :         if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = thisDXCoil.CoolingCoilRuntimeFraction;
   16894              : 
   16895              :         // Check for saturation error and modify temperature at constant enthalpy
   16896        10299 :         if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) {
   16897           18 :             OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
   16898              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   16899              :             //   IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
   16900              :             //    FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
   16901           18 :             OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
   16902              :         }
   16903              : 
   16904              :         // Store actual outlet conditions when DX coil is ON for use in heat recovery module
   16905        10299 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = OutletAirTemp;
   16906        10299 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = OutletAirHumRat;
   16907              : 
   16908              :         // Add warning message for cold cooling coil (OutletAirTemp < 2 C)
   16909        10299 :         if (OutletAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
   16910            0 :             thisDXCoil.PrintLowOutTempMessage = true;
   16911            0 :             thisDXCoil.FullLoadOutAirTempLast = OutletAirTemp;
   16912            0 :             if (thisDXCoil.LowOutletTempIndex == 0) {
   16913            0 :                 thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
   16914            0 :                 thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
   16915              :                                                       "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
   16916            0 :                                                       thisDXCoil.DXCoilType,
   16917            0 :                                                       thisDXCoil.Name,
   16918            0 :                                                       OutletAirTemp);
   16919            0 :                 thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + " " +
   16920            0 :                                                CreateSysTimeIntervalString(state);
   16921              :             }
   16922              :         }
   16923              : 
   16924              :         // Coil total/sensible/latent cooling rates
   16925        10299 :         CalcComponentSensibleLatentOutput(AirMassFlow * PartLoadRatio,
   16926              :                                           InletAirDryBulbTemp,
   16927              :                                           InletAirHumRat,
   16928              :                                           OutletAirTemp,
   16929              :                                           OutletAirHumRat,
   16930        10299 :                                           thisDXCoil.SensCoolingEnergyRate,
   16931        10299 :                                           thisDXCoil.LatCoolingEnergyRate,
   16932        10299 :                                           thisDXCoil.TotalCoolingEnergyRate);
   16933              : 
   16934              :         // Coil outlet conditions
   16935        10299 :         thisDXCoil.OutletAirTemp = OutletAirTemp;
   16936        10299 :         thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   16937        10299 :         thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   16938              : 
   16939              :         // Coil SH/SC
   16940        10299 :         thisDXCoil.ActualSH = ActualSH;
   16941        10299 :         thisDXCoil.ActualSC = ActualSC;
   16942              : 
   16943              :     } else {
   16944              :         // DX coil is off; just pass through conditions
   16945              : 
   16946        13360 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   16947        13360 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   16948        13360 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   16949              : 
   16950        13360 :         thisDXCoil.ElecCoolingPower = 0.0;
   16951        13360 :         thisDXCoil.TotalCoolingEnergyRate = 0.0;
   16952        13360 :         thisDXCoil.SensCoolingEnergyRate = 0.0;
   16953        13360 :         thisDXCoil.LatCoolingEnergyRate = 0.0;
   16954        13360 :         thisDXCoil.EvapCondPumpElecPower = 0.0;
   16955        13360 :         thisDXCoil.EvapWaterConsumpRate = 0.0;
   16956              : 
   16957        13360 :         thisDXCoil.ActualSH = 999.0;
   16958        13360 :         thisDXCoil.ActualSC = 999.0;
   16959              : 
   16960              :         // Reset globals when DX coil is OFF for use in heat recovery module
   16961        13360 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
   16962        13360 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
   16963              : 
   16964              :     } // end of on/off
   16965              : 
   16966              :     // set water system demand request (if needed)
   16967        23659 :     if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
   16968            0 :         state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
   16969            0 :             thisDXCoil.EvapWaterConsumpRate;
   16970              :     }
   16971              : 
   16972        23659 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   16973        23659 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   16974        23659 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
   16975        23659 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   16976        23659 :     thisDXCoil.CondInletTemp = CondInletTemp;
   16977        23659 :     state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
   16978        23659 :     state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   16979        23659 : }
   16980              : 
   16981        23659 : void CalcVRFHeatingCoil_FluidTCtrl(EnergyPlusData &state,
   16982              :                                    HVAC::CompressorOp const compressorOp,               // compressor operation; 1=on, 0=off
   16983              :                                    int const DXCoilNum,                                 // the number of the DX heating coil to be simulated
   16984              :                                    Real64 const PartLoadRatio,                          // sensible cooling load / full load sensible cooling capacity
   16985              :                                    HVAC::FanOp const fanOp,                             // Allows parent object to control fan mode
   16986              :                                    ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
   16987              :                                    ObjexxFCL::Optional<Real64 const> MaxHeatCap         // maximum allowed heating capacity
   16988              : )
   16989              : {
   16990              :     // SUBROUTINE INFORMATION:
   16991              :     //       AUTHOR         Xiufeng Pang (XP), LBNL
   16992              :     //       DATE WRITTEN   Mar 2013
   16993              :     //       MODIFIED       Nov 2015, RP Zhang, LBNL
   16994              : 
   16995              :     // PURPOSE OF THIS SUBROUTINE:
   16996              :     //         Calculates the air-side performance of a direct-expansion, air-cooled
   16997              :     //         VRF terminal unit heating coil, for the new VRF model.
   16998              : 
   16999              :     // METHODOLOGY EMPLOYED:
   17000              :     //         This subroutine is derived from CalcVRFCoolingCoil, and implements the new VRF model for FluidTCtrl.
   17001              : 
   17002              :     // Using/Aliasing
   17003              :     using Curve::CurveValue;
   17004              : 
   17005              :     using namespace HVACVariableRefrigerantFlow;
   17006              : 
   17007              :     // INTERFACE BLOCK SPECIFICATIONS
   17008              :     static constexpr std::string_view RoutineNameFullLoad("CalcVRFHeatingCoil_FluidTCtrl:fullload");
   17009              : 
   17010              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   17011              :     Real64 AirMassFlow;           // dry air mass flow rate through coil [kg/s]
   17012              :     Real64 AirMassFlowRatio;      // Ratio of actual air mass flow to rated air mass flow
   17013              :     Real64 AirVolumeFlowRate;     // Air volume flow rate across the cooling coil [m3/s]
   17014              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W]
   17015              :     Real64 TotCap;                // gross total cooling capacity at off-rated conditions [W]
   17016              :     Real64 TotCapAdj;             // adjusted total cooling capacity at off-rated conditions [W]
   17017              :     // on the type of curve
   17018              :     Real64 InletAirDryBulbTemp;  // inlet air dry bulb temperature [C]
   17019              :     Real64 InletAirWetBulbC;     // wetbulb temperature of inlet air [C]
   17020              :     Real64 InletAirEnthalpy;     // inlet air enthalpy [J/kg]
   17021              :     Real64 InletAirHumRat;       // inlet air humidity ratio [kg/kg]
   17022              :     Real64 FullLoadOutAirEnth;   // outlet full load enthalpy [J/kg]
   17023              :     Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
   17024              :     Real64 FullLoadOutAirTemp;   // outlet air temperature at full load [C]
   17025              :     Real64 FullLoadOutAirRH;     // outlet air relative humidity at full load
   17026        23659 :     Real64 EIRTempModFac(0.0);   // EIR modifier (function of entering drybulb, outside drybulb) depending on the
   17027              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   17028              :     // type of curve
   17029              :     // Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering wetbulb, outside drybulb)
   17030              :     Real64 EIRFlowModFac;             // EIR modifier (function of actual supply air flow vs rated flow)
   17031              :     Real64 EIR;                       // EIR at part load and off rated conditions
   17032              :     Real64 PLF;                       // Part load factor, accounts for thermal lag at compressor startup
   17033              :     Real64 PLRHeating;                // PartLoadRatio in heating
   17034              :     Real64 OutdoorCoilT;              // Outdoor coil temperature (C)
   17035              :     Real64 OutdoorCoildw;             // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
   17036              :     Real64 FractionalDefrostTime;     // Fraction of time step system is in defrost
   17037              :     Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
   17038              :     Real64 InputPowerMultiplier;      // Multiplier for power when system is in defrost
   17039              :     Real64 LoadDueToDefrost;          // Additional load due to defrost
   17040              :     Real64 CrankcaseHeatingPower;     // power due to crankcase heater
   17041              :     Real64 OutdoorDryBulb;            // Outdoor dry-bulb temperature at condenser (C)
   17042              :     Real64 OutdoorWetBulb;            // Outdoor wet-bulb temperature at condenser (C)
   17043              :     Real64 OutdoorHumRat;             // Outdoor humidity ratio at condenser (kg/kg)
   17044              :     Real64 OutdoorPressure;           // Outdoor barometric pressure at condenser (Pa)
   17045        23659 :     constexpr int Mode(1);            // Performance mode for MultiMode DX coil. Always 1 for other coil types
   17046              :     Real64 AirFlowRatio;              // Ratio of compressor on airflow to average timestep airflow
   17047              :     Real64 OutletAirTemp;             // Supply air temperature (average value if constant fan, full output if cycling fan)
   17048              :     Real64 OutletAirHumRat;           // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
   17049              :     Real64 OutletAirEnthalpy;         // Supply air enthalpy (average value if constant fan, full output if cycling fan)
   17050              : 
   17051              :     // Followings for VRF FluidTCtrl Only
   17052              :     Real64 QCoilReq;       // Coil load (W)
   17053              :     Real64 FanSpdRatio;    // Fan Speed Ratio
   17054              :     Real64 AirMassFlowMin; // Min air mass flow rate due to OA requirement [kg/s]
   17055              :     Real64 ActualSH;       // Actual Super Heating
   17056              :     Real64 ActualSC;       // Actual Sub Cooling
   17057              : 
   17058        23659 :     if (present(OnOffAirFlowRatio)) {
   17059            0 :         AirFlowRatio = OnOffAirFlowRatio;
   17060              :     } else {
   17061        23659 :         AirFlowRatio = 1.0;
   17062              :     }
   17063              : 
   17064              :     // Air cooled condenser
   17065        23659 :     OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   17066        23659 :     OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   17067        23659 :     OutdoorHumRat = state.dataEnvrn->OutHumRat;
   17068        23659 :     OutdoorPressure = state.dataEnvrn->OutBaroPress;
   17069              : 
   17070        23659 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   17071              : 
   17072        23659 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   17073        23659 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   17074        23659 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   17075        23659 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   17076        23659 :     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   17077        23659 :     PLRHeating = 0.0;
   17078        23659 :     thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
   17079        23659 :     thisDXCoil.CondensingTemp = state.dataHVACVarRefFlow->VRF(thisDXCoil.VRFOUPtr).IUCondensingTemp;
   17080              : 
   17081              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
   17082        23659 :     if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
   17083           32 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   17084           32 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   17085            0 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
   17086              :         }
   17087              :     } else {
   17088        23627 :         CrankcaseHeatingPower = 0.0;
   17089              :     }
   17090              : 
   17091        32212 :     if ((AirMassFlow > 0.0) && (compressorOp == HVAC::CompressorOp::On) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
   17092         8553 :         (OutdoorDryBulb > thisDXCoil.MinOATCompressor)) {
   17093              : 
   17094         8553 :         TotCap = thisDXCoil.RatedTotCap(Mode);
   17095         8553 :         HeatingCapacityMultiplier = 1.0;
   17096              :         // Modify total heating capacity based on defrost heating capacity multiplier
   17097              :         // MaxHeatCap passed from parent object VRF Condenser and is used to limit capacity of TU's to that available from condenser
   17098         8553 :         if (present(MaxHeatCap)) {
   17099         8547 :             TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
   17100         8547 :             TotCap = min(MaxHeatCap, TotCap);
   17101              :         } else {
   17102            6 :             TotCapAdj = TotCap * HeatingCapacityMultiplier;
   17103              :         }
   17104              : 
   17105         8553 :         QCoilReq = PartLoadRatio * TotCap;
   17106         8553 :         if (PartLoadRatio == 0.0) {
   17107            0 :             AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
   17108              :         } else {
   17109         8553 :             AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
   17110              :         }
   17111              : 
   17112              :         // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
   17113         8553 :         ControlVRFIUCoil(state,
   17114              :                          DXCoilNum,
   17115              :                          QCoilReq,
   17116              :                          thisDXCoil.InletAirTemp,
   17117              :                          thisDXCoil.InletAirHumRat,
   17118              :                          thisDXCoil.CondensingTemp,
   17119              :                          AirMassFlowMin,
   17120              :                          FanSpdRatio,
   17121              :                          OutletAirHumRat,
   17122              :                          OutletAirTemp,
   17123              :                          OutletAirEnthalpy,
   17124              :                          ActualSH,
   17125              :                          ActualSC);
   17126         8553 :         AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
   17127              : 
   17128         8553 :         AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
   17129              :         // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   17130         8553 :         VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
   17131              :         // VolFlowperRatedTotCap was checked at the initialization step
   17132              :         // No need to check VolFlowperRatedTotCap at the simulation
   17133              :         // New VRF_FluidTCtrl model implements VAV fan which can vary air flow rate during simulation
   17134              : 
   17135         8553 :         AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
   17136              : 
   17137              :         // Calculating adjustment factors for defrost
   17138              :         // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
   17139         8553 :         OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
   17140         8553 :         OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
   17141              : 
   17142              :         // Initializing defrost adjustment factors
   17143         8553 :         LoadDueToDefrost = 0.0;
   17144         8553 :         FractionalDefrostTime = 0.0;
   17145         8553 :         InputPowerMultiplier = 1.0;
   17146              : 
   17147              :         // Calculate full load outlet conditions
   17148         8553 :         FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
   17149         8553 :         FullLoadOutAirHumRat = InletAirHumRat;
   17150         8553 :         FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   17151         8553 :         FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
   17152              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   17153              :         //  FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
   17154         8553 :         if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
   17155            0 :             FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
   17156              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   17157              :             //    FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
   17158            0 :             FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
   17159              :         }
   17160              : 
   17161              :         // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
   17162              :         // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
   17163              :         // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   17164              :         // advised to use the bi-quaratic curve if sufficient manufacturer data is available.
   17165         8553 :         if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
   17166            0 :             if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 1) {
   17167            0 :                 EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), OutdoorDryBulb);
   17168              :             } else {
   17169            0 :                 EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
   17170              :             }
   17171            0 :             EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
   17172              :         } else {
   17173         8553 :             EIRTempModFac = 1.0;
   17174         8553 :             EIRFlowModFac = 1.0;
   17175              :         }
   17176         8553 :         EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
   17177              : 
   17178              :         // Calculate PLRHeating: modified PartLoadRatio due to defrost ( reverse-cycle defrost only )
   17179         8553 :         if (TotCap > 0.0) {
   17180         8553 :             PLRHeating = min(1.0, (PartLoadRatio + LoadDueToDefrost / TotCap));
   17181              :         } else {
   17182            0 :             PLRHeating = min(1.0, PartLoadRatio);
   17183              :         }
   17184              : 
   17185         8553 :         if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
   17186            0 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PLRHeating); // Calculate part-load factor
   17187              :         } else {
   17188         8553 :             PLF = 1.0;
   17189              :         }
   17190              : 
   17191         8553 :         if (PLF < 0.7) {
   17192            0 :             if (thisDXCoil.PLRErrIndex == 0) {
   17193            0 :                 ShowWarningMessage(
   17194              :                     state,
   17195            0 :                     format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
   17196            0 :                 ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   17197            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   17198            0 :                 ShowContinueErrorTimeStamp(state, "");
   17199              :             }
   17200            0 :             ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
   17201            0 :             PLF = 0.7;
   17202              :         }
   17203              : 
   17204         8553 :         thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
   17205         8553 :         if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
   17206            0 :             if (thisDXCoil.ErrIndex4 == 0) {
   17207            0 :                 ShowWarningMessage(state,
   17208            0 :                                    format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
   17209            0 :                                           thisDXCoil.Name,
   17210            0 :                                           thisDXCoil.HeatingCoilRuntimeFraction));
   17211            0 :                 ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
   17212            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   17213            0 :                 ShowContinueErrorTimeStamp(state, "");
   17214              :             }
   17215            0 :             ShowRecurringWarningErrorAtEnd(state,
   17216            0 :                                            thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
   17217            0 :                                            thisDXCoil.ErrIndex4,
   17218            0 :                                            thisDXCoil.HeatingCoilRuntimeFraction,
   17219            0 :                                            thisDXCoil.HeatingCoilRuntimeFraction);
   17220            0 :             thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   17221         8553 :         } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
   17222            0 :             thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   17223              :         }
   17224              : 
   17225              :         // if cycling fan, send coil part-load fraction to on / off fan via HVACDataGlobals
   17226         8553 :         if (fanOp == HVAC::FanOp::Cycling) state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
   17227         8553 :         thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
   17228              : 
   17229              :         // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
   17230              :         // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
   17231         8553 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   17232         8553 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
   17233              :         } else {
   17234            0 :             thisDXCoil.CrankcaseHeaterPower =
   17235            0 :                 CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
   17236            0 :                                                    state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
   17237              :         }
   17238              : 
   17239         8553 :         thisDXCoil.OutletAirTemp = OutletAirTemp;
   17240         8553 :         thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   17241         8553 :         thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   17242         8553 :         thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
   17243         8553 :         thisDXCoil.ActualSH = ActualSH;
   17244         8553 :         thisDXCoil.ActualSC = ActualSC;
   17245         8553 :         thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy) * PartLoadRatio;
   17246         8553 :         thisDXCoil.DefrostPower = thisDXCoil.DefrostPower * thisDXCoil.HeatingCoilRuntimeFraction;
   17247              : 
   17248              :     } else {
   17249              :         // DX coil is off; just pass through conditions
   17250              : 
   17251        15106 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   17252        15106 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   17253        15106 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   17254              : 
   17255        15106 :         thisDXCoil.ElecHeatingPower = 0.0;
   17256        15106 :         thisDXCoil.TotalHeatingEnergyRate = 0.0;
   17257        15106 :         thisDXCoil.DefrostPower = 0.0;
   17258              : 
   17259              :         // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
   17260              :         // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
   17261        15106 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   17262        15106 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
   17263              :         } else {
   17264            0 :             thisDXCoil.CrankcaseHeaterPower =
   17265            0 :                 CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
   17266              :         }
   17267        15106 :         thisDXCoil.CompressorPartLoadRatio = 0.0;
   17268              : 
   17269        15106 :         thisDXCoil.ActualSH = 999.0;
   17270        15106 :         thisDXCoil.ActualSC = 999.0;
   17271              :     } // end of on/off if - else
   17272              : 
   17273        23659 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   17274        23659 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   17275        23659 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   17276        23659 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
   17277        23659 :     state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
   17278        23659 :     state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
   17279        23659 :     state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
   17280              : 
   17281              :     // calc secondary coil if specified
   17282        23659 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   17283            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   17284              :     }
   17285        23659 : }
   17286              : 
   17287        90388 : void ControlVRFIUCoil(EnergyPlusData &state,
   17288              :                       int const CoilIndex,     // index to VRFTU coil
   17289              :                       Real64 const QCoil,      // coil load
   17290              :                       Real64 const Tin,        // inlet air temperature
   17291              :                       Real64 const Win,        // inlet air humidity ratio
   17292              :                       Real64 const TeTc,       // evaporating or condensing temperature
   17293              :                       Real64 const OAMassFlow, // mass flow rate of outdoor air
   17294              :                       Real64 &FanSpdRatio,     // fan speed ratio: actual flow rate / rated flow rate
   17295              :                       Real64 &Wout,            // outlet air humidity ratio
   17296              :                       Real64 &Tout,            // outlet air temperature
   17297              :                       Real64 &Hout,            // outlet air enthalpy
   17298              :                       Real64 &SHact,           // actual SH
   17299              :                       Real64 &SCact            // actual SC
   17300              : )
   17301              : {
   17302              :     // SUBROUTINE INFORMATION:
   17303              :     //       AUTHOR         Xiufeng Pang, LBNL
   17304              :     //       DATE WRITTEN   Feb 2013
   17305              :     //       MODIFIED       Nov 2015, RP Zhang, LBNL
   17306              :     //
   17307              :     // PURPOSE OF THIS SUBROUTINE:
   17308              :     //       Analyze the VRF Indoor Unit operations given coil loads.
   17309              :     //       Calculated parameters include: (1) Fan Speed Ratio (2) SH/SC, (3) Coil Outlet conditions
   17310              :     //
   17311              :     // METHODOLOGY EMPLOYED:
   17312              :     //       A new physics based VRF model applicable for Fluid Temperature Control.
   17313              :     //
   17314              :     // USE STATEMENTS:
   17315              :     using Psychrometrics::PsyHFnTdbW;
   17316              : 
   17317              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   17318        90388 :     int MaxIter(500);              // Max iteration numbers (-)
   17319              :     int SolFla;                    // Solving flag for SolveRoot (-)
   17320        90388 :     int constexpr FlagCoolMode(0); // Flag for cooling mode
   17321        90388 :     int constexpr FlagHeatMode(1); // Flag for heating mode
   17322              :     Real64 BF;                     // Bypass factor (-)
   17323              :     Real64 C1Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17324              :     Real64 C2Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17325              :     Real64 C3Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17326              :     Real64 C1Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17327              :     Real64 C2Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17328              :     Real64 C3Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17329              :     Real64 CoilOnOffRatio;         // coil on/off ratio: time coil is on divided by total time
   17330              :     Real64 deltaT;                 // Difference between evaporating/condensing temperature and coil surface temperature (C)
   17331              :     Real64 FanSpdRatioMin;         // Min fan speed ratio, below which the cycling will be activated (-)
   17332              :     Real64 FanSpdRatioMax;         // Max fan speed ratio (-)
   17333              :     Real64 Garate;                 // Nominal air mass flow rate (m3/s)
   17334              :     Real64 MaxSH;                  // Max super heating degrees (C)
   17335              :     Real64 MaxSC;                  // Max subcooling degrees (C)
   17336              :     Real64 QinSenMin1;             // Coil capacity at minimum fan speed, corresponding to real SH (W)
   17337              :     Real64 QinSenMin2;             // Coil capacity at minimum fan speed, corresponding to corresponds maximum SH (W)
   17338              :     Real64 QinSenPerFlowRate;      // Coil capacity per air mass flow rate(W-s/kg)
   17339              :     Real64 QCoilSenCoolingLoad;    // Coil sensible cooling load (W)
   17340              :     Real64 QCoilSenHeatingLoad;    // Coil sensible heating load (W)
   17341              :     Real64 Ratio1;                 // Fan speed ratio (-)
   17342              :     Real64 RHsat;                  // Relative humidity of the air at saturated condition(-)
   17343              :     Real64 SH;                     // Super heating degrees (C)
   17344              :     Real64 SC;                     // Subcooling degrees (C)
   17345              :     Real64 Ts_1;                   // Air temperature at the coil surface, corresponding to SH (C)
   17346              :     Real64 Ts_2;                   // Air temperature at the coil surface, corresponding to MaxSH (C)
   17347              :     Real64 To_1;                   // Air temperature at the coil outlet, corresponding to SH (C)
   17348              :     Real64 To_2;                   // Air temperature at the coil outlet, corresponding to MaxSH (C)
   17349              :     Real64 Ts;                     // Air temperature at the coil surface (C)
   17350              :     Real64 Ws;                     // Air humidity ratio at the coil surface (kg/kg)
   17351              : 
   17352        90388 :     RHsat = 0.98; // Saturated RH
   17353        90388 :     MaxSH = 15;
   17354        90388 :     MaxSC = 20;
   17355        90388 :     Garate = state.dataDXCoils->DXCoil(CoilIndex).RatedAirMassFlowRate(1);
   17356        90388 :     FanSpdRatioMin = min(OAMassFlow / Garate, 1.0); // ensure that coil flow rate is higher than OA flow rate
   17357              : 
   17358        90388 :     if (QCoil == 0) {
   17359              :         // No Heating or Cooling
   17360            0 :         FanSpdRatio = OAMassFlow / Garate;
   17361            0 :         CoilOnOffRatio = 0.0;
   17362              : 
   17363            0 :         SHact = 999.0;
   17364            0 :         SCact = 999.0;
   17365            0 :         Tout = Tin;
   17366            0 :         Hout = PsyHFnTdbW(Tin, Win);
   17367            0 :         Wout = Win;
   17368              : 
   17369        90388 :     } else if (QCoil < 0) {
   17370              :         // Cooling Mode
   17371              : 
   17372              :         // Obtain coil cooling loads
   17373        47821 :         QCoilSenCoolingLoad = -QCoil;
   17374              : 
   17375              :         // Coefficients describing coil performance
   17376        47821 :         SH = state.dataDXCoils->DXCoil(CoilIndex).SH;
   17377        47821 :         C1Tevap = state.dataDXCoils->DXCoil(CoilIndex).C1Te;
   17378        47821 :         C2Tevap = state.dataDXCoils->DXCoil(CoilIndex).C2Te;
   17379        47821 :         C3Tevap = state.dataDXCoils->DXCoil(CoilIndex).C3Te;
   17380        47821 :         BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUEvap;
   17381              : 
   17382              :         // Coil sensible heat transfer_minimum value
   17383        47821 :         CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, SH, BF, QinSenPerFlowRate, Ts_1);
   17384        47821 :         To_1 = Tin - QinSenPerFlowRate / 1005;
   17385        47821 :         QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
   17386              : 
   17387        47821 :         CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, MaxSH, BF, QinSenPerFlowRate, Ts_2);
   17388        47821 :         To_2 = Tin - QinSenPerFlowRate / 1005;
   17389        47821 :         QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
   17390              : 
   17391        47821 :         if (QCoilSenCoolingLoad > QinSenMin1) {
   17392              :             // Increase fan speed to meet room sensible load; SH is not updated
   17393        45830 :             FanSpdRatioMax = 1.0;
   17394       130189 :             auto f = [QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
   17395       130189 :                 return FanSpdResidualCool(FanSpdRto, QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF);
   17396        45830 :             };
   17397        45830 :             General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
   17398        45830 :             if (SolFla < 0) Ratio1 = FanSpdRatioMax; // over capacity
   17399        45830 :             FanSpdRatio = Ratio1;
   17400        45830 :             CoilOnOffRatio = 1.0;
   17401              : 
   17402        45830 :             Tout = To_1; // Since SH is not updated
   17403        45830 :             Ws = PsyWFnTdbRhPb(state, Ts_1, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
   17404        45830 :             if (Ws < Win) {
   17405        45829 :                 Wout = Win - (Win - Ws) * (1 - BF);
   17406              :             } else {
   17407            1 :                 Wout = Win;
   17408              :             }
   17409        45830 :             Hout = PsyHFnTdbW(Tout, Wout);
   17410        45830 :             SCact = 999.0;
   17411        45830 :             SHact = SH;
   17412              : 
   17413              :         } else {
   17414              :             // Low load modification algorithm
   17415              :             // Need to increase SH to further reduce coil capacity
   17416              :             // May further implement coil cycling control if SC modification is not enough
   17417              : 
   17418         1991 :             FanSpdRatio = FanSpdRatioMin;
   17419              : 
   17420         1991 :             CoilOnOffRatio = 1.0;
   17421              : 
   17422         1991 :             Tout = Tin - QCoilSenCoolingLoad / 1005.0 / FanSpdRatioMin / Garate;
   17423         1991 :             Ts = Tin - (Tin - Tout) / (1 - BF);
   17424         1991 :             deltaT = Ts - TeTc;
   17425              : 
   17426              :             // Update SH
   17427         1991 :             if (C3Tevap <= 0.0) {
   17428         1991 :                 if (C2Tevap > 0.0) {
   17429         1991 :                     SHact = (deltaT - C1Tevap) / C2Tevap;
   17430              :                 } else {
   17431            0 :                     SHact = 998.0;
   17432              :                 }
   17433              :             } else {
   17434            0 :                 SHact = (-C2Tevap + sqrt(pow_2(C2Tevap) - 4 * C3Tevap * (C1Tevap - deltaT))) / 2 / C3Tevap;
   17435              :             }
   17436              : 
   17437         1991 :             Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
   17438         1991 :             if (Ws < Win) {
   17439         1776 :                 Wout = Win - (Win - Ws) * (1 - BF);
   17440              :             } else {
   17441          215 :                 Wout = Win;
   17442              :             }
   17443              : 
   17444         1991 :             if (SHact > MaxSH) {
   17445              :                 // Further implement On/Off Control
   17446          791 :                 SHact = MaxSH;
   17447          791 :                 CoilOnOffRatio = QCoilSenCoolingLoad / QinSenMin2;
   17448              : 
   17449          791 :                 Ts = Ts_2;
   17450          791 :                 Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
   17451          791 :                 if (Ws < Win) {
   17452          791 :                     Wout = Win - (Win - Ws) * (1 - BF);
   17453              :                 } else {
   17454            0 :                     Wout = Win;
   17455              :                 }
   17456              : 
   17457              :                 // outlet air temperature and humidity ratio is time-weighted
   17458          791 :                 Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
   17459          791 :                 Wout = CoilOnOffRatio * Wout + (1 - CoilOnOffRatio) * Win;
   17460              :             }
   17461              : 
   17462         1991 :             Hout = PsyHFnTdbW(Tout, Wout);
   17463         1991 :             SCact = 999.0;
   17464              :         }
   17465              : 
   17466        42567 :     } else if (QCoil > 0) {
   17467              :         // Heating Mode
   17468              : 
   17469              :         // Obtain zonal heating loads
   17470        42567 :         QCoilSenHeatingLoad = QCoil;
   17471              : 
   17472              :         // Coefficients describing coil performance
   17473        42567 :         SC = state.dataDXCoils->DXCoil(CoilIndex).SC;
   17474        42567 :         C1Tcond = state.dataDXCoils->DXCoil(CoilIndex).C1Tc;
   17475        42567 :         C2Tcond = state.dataDXCoils->DXCoil(CoilIndex).C2Tc;
   17476        42567 :         C3Tcond = state.dataDXCoils->DXCoil(CoilIndex).C3Tc;
   17477        42567 :         BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUCond;
   17478              : 
   17479              :         // Coil sensible heat transfer_minimum value
   17480        42567 :         CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, SC, BF, QinSenPerFlowRate, Ts_1);
   17481        42567 :         To_1 = QinSenPerFlowRate / 1005 + Tin;
   17482        42567 :         QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
   17483              : 
   17484        42567 :         CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, MaxSC, BF, QinSenPerFlowRate, Ts_2);
   17485        42567 :         To_2 = QinSenPerFlowRate / 1005 + Tin;
   17486        42567 :         QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
   17487              : 
   17488        42567 :         if (QCoilSenHeatingLoad > QinSenMin1) {
   17489              :             // Modulate fan speed to meet room sensible load; SC is not updated
   17490        42271 :             FanSpdRatioMax = 1.0;
   17491       126812 :             auto f = [QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
   17492       126812 :                 return FanSpdResidualHeat(FanSpdRto, QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF);
   17493        42271 :             };
   17494        42271 :             General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
   17495              :             // this will likely cause problems eventually, -1 and -2 mean different things
   17496        42271 :             if (SolFla < 0) Ratio1 = FanSpdRatioMax; // over capacity
   17497        42271 :             FanSpdRatio = Ratio1;
   17498        42271 :             CoilOnOffRatio = 1.0;
   17499              : 
   17500        42271 :             Tout = Tin + (Ts_1 - Tin) * (1 - BF);
   17501        42271 :             Wout = Win;
   17502        42271 :             Hout = PsyHFnTdbW(Tout, Wout);
   17503        42271 :             SHact = 999.0;
   17504        42271 :             SCact = SC;
   17505              : 
   17506              :         } else {
   17507              :             // Low load modification algorithm
   17508              :             // Need to increase SC to further reduce coil heating capacity
   17509              :             // May further implement coil cycling control if SC modification is not enough
   17510              : 
   17511          296 :             FanSpdRatio = FanSpdRatioMin;
   17512          296 :             CoilOnOffRatio = 1.0;
   17513              : 
   17514          296 :             Tout = Tin + QCoilSenHeatingLoad / 1005.0 / FanSpdRatio / Garate;
   17515          296 :             Ts = Tin + (Tout - Tin) / (1 - BF);
   17516          296 :             deltaT = TeTc - Ts;
   17517              : 
   17518              :             // Update SC
   17519          296 :             if (C3Tcond <= 0.0) {
   17520            0 :                 if (C2Tcond > 0.0) {
   17521            0 :                     SCact = (deltaT - C1Tcond) / C2Tcond;
   17522              :                 } else {
   17523            0 :                     SCact = 998.0;
   17524              :                 }
   17525              :             } else {
   17526          296 :                 SCact = (-C2Tcond + sqrt(pow_2(C2Tcond) - 4 * C3Tcond * (C1Tcond - deltaT))) / 2 / C3Tcond;
   17527              :             }
   17528              : 
   17529          296 :             if (SCact > MaxSC) {
   17530              :                 // Implement On/Off Control
   17531           77 :                 SCact = MaxSC;
   17532           77 :                 CoilOnOffRatio = QCoilSenHeatingLoad / QinSenMin2;
   17533              :                 // outlet air temperature is time-weighted
   17534           77 :                 Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
   17535              :             }
   17536          296 :             Wout = Win;
   17537          296 :             Hout = PsyHFnTdbW(Tout, Wout);
   17538          296 :             SHact = 999.0;
   17539              :         }
   17540              :     }
   17541        90388 : }
   17542              : 
   17543       180788 : void CalcVRFCoilSenCap(EnergyPlusData &state,
   17544              :                        int const OperationMode, // mode 0 for cooling, 1 for heating
   17545              :                        int const CoilNum,       // index to VRFTU cooling or heating coil
   17546              :                        Real64 const Tinlet,     // dry bulb temperature of air entering the coil
   17547              :                        Real64 const TeTc,       // evaporating or condensing temperature
   17548              :                        Real64 const SHSC,       // SH at cooling /SC at heating
   17549              :                        Real64 const BF,         // Bypass factor
   17550              :                        Real64 &Q_sen,           // VRF coil sensible capacity per air mass flow rate
   17551              :                        Real64 &T_coil_surf      // Air temperature at coil surface
   17552              : )
   17553              : {
   17554              :     // SUBROUTINE INFORMATION:
   17555              :     //       AUTHOR         Rongpeng Zhang, LBNL
   17556              :     //       DATE WRITTEN   Jul 2015
   17557              :     //
   17558              :     // PURPOSE OF THIS SUBROUTINE:
   17559              :     //        Calculate the VRF coil sensible capacity per air mass flow rate, given:
   17560              :     //        (1) refrigerant temperature (Te or Tc), (2) SH or SC, and (3) inlet air temperature.
   17561              :     //
   17562              :     // METHODOLOGY EMPLOYED:
   17563              :     //        A new physics based VRF model appliable for Fluid Temperature Control.
   17564              :     //
   17565              : 
   17566       180788 :     int constexpr FlagCoolMode(0); // Flag for cooling mode
   17567       180788 :     int constexpr FlagHeatMode(1); // Flag for heating mode
   17568              :     Real64 C1Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17569              :     Real64 C2Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17570              :     Real64 C3Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17571              :     Real64 C1Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17572              :     Real64 C2Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17573              :     Real64 C3Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17574              :     Real64 deltaT;                 // Difference between Te/Tc and coil surface temperature (C)
   17575              :     Real64 SH;                     // Super heating at cooling mode(C)
   17576              :     Real64 SC;                     // Subcooling at heating mode (C)
   17577              :     Real64 T_coil_in;              // Air temperature at coil inlet (C)
   17578              :     Real64 T_coil_out;             // Air temperature at coil outlet (C)
   17579              : 
   17580       180788 :     if (OperationMode == FlagCoolMode) {
   17581              :         // Cooling: OperationMode 0
   17582              : 
   17583        95654 :         C1Tevap = state.dataDXCoils->DXCoil(CoilNum).C1Te;
   17584        95654 :         C2Tevap = state.dataDXCoils->DXCoil(CoilNum).C2Te;
   17585        95654 :         C3Tevap = state.dataDXCoils->DXCoil(CoilNum).C3Te;
   17586        95654 :         SH = SHSC;
   17587        95654 :         T_coil_in = Tinlet;
   17588              : 
   17589              :         // Coil surface temperature
   17590        95654 :         deltaT = C3Tevap * SH * SH + C2Tevap * SH + C1Tevap;
   17591        95654 :         T_coil_surf = TeTc + deltaT;
   17592              : 
   17593              :         // Outlet air temperature
   17594        95654 :         T_coil_out = T_coil_in - (T_coil_in - T_coil_surf) * (1 - BF);
   17595              : 
   17596              :         // Coil sensilbe heat transfer per mass flow rate
   17597        95654 :         Q_sen = max(1005 * (T_coil_in - T_coil_out), 0.0);
   17598              : 
   17599        85134 :     } else if (OperationMode == FlagHeatMode) {
   17600              :         // Heating: OperationMode 1
   17601              : 
   17602        85134 :         C1Tcond = state.dataDXCoils->DXCoil(CoilNum).C1Tc;
   17603        85134 :         C2Tcond = state.dataDXCoils->DXCoil(CoilNum).C2Tc;
   17604        85134 :         C3Tcond = state.dataDXCoils->DXCoil(CoilNum).C3Tc;
   17605        85134 :         SC = SHSC;
   17606        85134 :         T_coil_in = Tinlet;
   17607              : 
   17608              :         // Coil surface temperature
   17609        85134 :         deltaT = C3Tcond * SC * SC + C2Tcond * SC + C1Tcond;
   17610        85134 :         T_coil_surf = TeTc - deltaT;
   17611              : 
   17612              :         // Coil outlet air temperature
   17613        85134 :         T_coil_out = T_coil_in + (T_coil_surf - T_coil_in) * (1 - BF);
   17614              : 
   17615              :         // Coil sensilbe heat transfer_minimum value
   17616        85134 :         Q_sen = max(1005 * (T_coil_out - T_coil_in), 0.0);
   17617              :     }
   17618       180788 : }
   17619              : 
   17620            6 : void CalcVRFCoilCapModFac(EnergyPlusData &state,
   17621              :                           int const OperationMode,                   // mode 0 for cooling, 1 for heating
   17622              :                           ObjexxFCL::Optional<int const> CoilIndex,  // index to VRFTU cooling or heating coil
   17623              :                           ObjexxFCL::Optional<std::string> CoilName, // name of VRFTU cooling or heating coil
   17624              :                           Real64 const Tinlet,                       // dry bulb temperature of air entering the coil
   17625              :                           ObjexxFCL::Optional<Real64 const> TeTc,    // evaporating or condensing temperature
   17626              :                           ObjexxFCL::Optional<Real64 const> SHSC,    // SH at cooling /SC at heating
   17627              :                           ObjexxFCL::Optional<Real64 const> BF,      // Bypass factor
   17628              :                           Real64 &CapModFac                          // Coil capacity modification factor
   17629              : )
   17630              : {
   17631              :     // SUBROUTINE INFORMATION:
   17632              :     //       AUTHOR         Rongpeng Zhang, LBNL
   17633              :     //       DATE WRITTEN   Jul 2015
   17634              :     //
   17635              :     // PURPOSE OF THIS SUBROUTINE:
   17636              :     //        Calculate the VRF coil capacity modification factor, which is the ratio of
   17637              :     //        the capacity at real conditions and that at rated conditions.
   17638              :     //        This is used for the coil sizing subroutine.
   17639              :     //
   17640              :     // METHODOLOGY EMPLOYED:
   17641              :     //        A new physics based VRF model applicable for Fluid Temperature Control.
   17642              :     //
   17643              : 
   17644            6 :     bool ErrorsFound(false);       // Flag for errors
   17645            6 :     int constexpr FlagCoolMode(0); // Flag for cooling mode
   17646            6 :     int constexpr FlagHeatMode(1); // Flag for heating mode
   17647            6 :     Real64 constexpr SH_rate(3);   // Super heating at cooling mode, default 3(C)
   17648            6 :     Real64 constexpr SC_rate(5);   // Subcooling at heating mode, default 5 (C)
   17649            6 :     Real64 constexpr Te_rate(6);   // Evaporating temperature at cooling mode, default 6 (C)
   17650            6 :     Real64 constexpr Tc_rate(44);  // Condensing temperature at heating mode, default 44 (C)
   17651              :     int CoilNum;                   // index to VRFTU cooling or heating coil
   17652              :     Real64 BF_real;                // Bypass factor (-)
   17653              :     Real64 BFC_rate;               // Bypass factor at cooling mode (-)
   17654              :     Real64 BFH_rate;               // Bypass factor at heating mode (-)
   17655              :     Real64 SHSC_real;              // Super heating or Subcooling (C)
   17656              :     Real64 TeTc_real;              // Evaporating temperature or condensing temperature (C)
   17657              :     Real64 Ts;                     // Air temperature at coil surface (C)
   17658              :     Real64 Q_real;                 // Coil capacity at given condition (W)
   17659              :     Real64 Q_rate;                 // Coil capacity at rated condition (W)
   17660              : 
   17661            6 :     if (present(CoilIndex)) {
   17662            0 :         CoilNum = CoilIndex;
   17663              :     } else {
   17664            6 :         GetDXCoilIndex(state, CoilName, CoilNum, ErrorsFound, "", true);
   17665              :     }
   17666              : 
   17667            6 :     BFC_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUEvap;
   17668            6 :     BFH_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUCond;
   17669              : 
   17670            6 :     if (OperationMode == FlagCoolMode) {
   17671              :         // Cooling: OperationMode 0
   17672              : 
   17673            6 :         if (present(BF)) {
   17674            0 :             BF_real = BF;
   17675              :         } else {
   17676            6 :             BF_real = BFC_rate;
   17677              :         }
   17678            6 :         if (present(TeTc)) {
   17679            0 :             TeTc_real = TeTc;
   17680              :         } else {
   17681            6 :             TeTc_real = Te_rate;
   17682              :         }
   17683            6 :         if (present(SHSC)) {
   17684            0 :             SHSC_real = SHSC;
   17685              :         } else {
   17686            6 :             SHSC_real = SH_rate;
   17687              :         }
   17688              : 
   17689              :         // Coil capacity at rated conditions
   17690            6 :         CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, 26, Te_rate, SH_rate, BFC_rate, Q_rate, Ts);
   17691              : 
   17692              :         // Coil capacity at given conditions
   17693            6 :         CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, Tinlet, TeTc_real, SHSC_real, BF_real, Q_real, Ts);
   17694              : 
   17695            6 :         if (Q_rate > 0) {
   17696            6 :             CapModFac = Q_real / Q_rate;
   17697              :         } else {
   17698            0 :             CapModFac = 1.0;
   17699              :         }
   17700              : 
   17701            0 :     } else if (OperationMode == FlagHeatMode) {
   17702              :         // Heating: OperationMode 1
   17703              : 
   17704            0 :         if (present(BF)) {
   17705            0 :             BF_real = BF;
   17706              :         } else {
   17707            0 :             BF_real = BFH_rate;
   17708              :         }
   17709            0 :         if (present(TeTc)) {
   17710            0 :             TeTc_real = TeTc;
   17711              :         } else {
   17712            0 :             TeTc_real = Tc_rate;
   17713              :         }
   17714            0 :         if (present(SHSC)) {
   17715            0 :             SHSC_real = SHSC;
   17716              :         } else {
   17717            0 :             SHSC_real = SC_rate;
   17718              :         }
   17719              : 
   17720              :         // Coil capacity at rated conditions
   17721            0 :         CalcVRFCoilSenCap(state, FlagHeatMode, CoilNum, 20, Tc_rate, SC_rate, BFH_rate, Q_rate, Ts);
   17722              : 
   17723              :         // Coil capacity at given conditions
   17724            0 :         CalcVRFCoilSenCap(state, FlagHeatMode, CoilNum, Tinlet, TeTc_real, SHSC_real, BF_real, Q_real, Ts);
   17725              : 
   17726            0 :         if (Q_rate > 0) {
   17727            0 :             CapModFac = Q_real / Q_rate;
   17728              :         } else {
   17729            0 :             CapModFac = 1.0;
   17730              :         }
   17731              :     }
   17732            6 : }
   17733              : 
   17734       130190 : Real64 FanSpdResidualCool(
   17735              :     Real64 const FanSpdRto, Real64 const QCoilSenCoolingLoad, Real64 const Ts_1, Real64 const Tin, Real64 const Garate, Real64 const BF)
   17736              : {
   17737              :     // FUNCTION INFORMATION:
   17738              :     //       AUTHOR         Xiufeng Pang (XP)
   17739              :     //       DATE WRITTEN   Mar 2013
   17740              :     //       MODIFIED       Nov 2015, RP Zhang, LBNL
   17741              :     //
   17742              :     // PURPOSE OF THIS FUNCTION:
   17743              :     //       Calculates residual function (desired zone cooling load - actual coil cooling capacity)
   17744              :     //       This is used to modify the fan speed to adjust the coil cooling capacity to match
   17745              :     //       the zone cooling load.
   17746              :     //
   17747       130190 :     Real64 ZnSenLoad = QCoilSenCoolingLoad;
   17748              :     // +-100 W minimum zone load?
   17749       130190 :     if (std::abs(ZnSenLoad) < 100.0) ZnSenLoad = sign(100.0, ZnSenLoad);
   17750       130190 :     Real64 Tout = Tin - (Tin - Ts_1) * (1 - BF);
   17751       130190 :     Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tin - Tout);
   17752       130190 :     return (TotCap - ZnSenLoad) / ZnSenLoad;
   17753              : }
   17754              : 
   17755       126813 : Real64 FanSpdResidualHeat(Real64 FanSpdRto, Real64 QCoilSenHeatingLoad, Real64 Ts_1, Real64 Tin, Real64 Garate, Real64 BF)
   17756              : {
   17757              : 
   17758              :     // FUNCTION INFORMATION:
   17759              :     //       AUTHOR         Xiufeng Pang (XP)
   17760              :     //       DATE WRITTEN   Mar 2013
   17761              :     //       MODIFIED       Nov 2015, RP Zhang, LBNL
   17762              :     //
   17763              :     // PURPOSE OF THIS FUNCTION:
   17764              :     //       Calculates residual function (desired zone heating load - actual heating coil capacity)
   17765              :     //       This is used to modify the fan speed to adjust the coil heating capacity to match
   17766              :     //       the zone heating load.
   17767              :     //
   17768              : 
   17769       126813 :     Real64 ZnSenLoad = QCoilSenHeatingLoad;
   17770              :     // +-100 W minimum zone load?
   17771       126813 :     if (std::abs(ZnSenLoad) < 100.0) ZnSenLoad = sign(100.0, ZnSenLoad);
   17772       126813 :     Real64 Tout = Tin + (Ts_1 - Tin) * (1 - BF);
   17773       126813 :     Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tout - Tin);
   17774       126813 :     return (TotCap - ZnSenLoad) / ZnSenLoad;
   17775              : }
   17776              : 
   17777            4 : void SetMSHPDXCoilHeatRecoveryFlag(EnergyPlusData &state, int const DXCoilNum)
   17778              : {
   17779              : 
   17780              :     // SUBROUTINE INFORMATION:
   17781              :     //       AUTHOR         L. Gu
   17782              :     //       DATE WRITTEN   Sep. 2015
   17783              : 
   17784              :     // PURPOSE OF THIS SUBROUTINE:
   17785              :     // Set the heat recovery flag true when the parent object requests heat recovery.
   17786              : 
   17787            4 :     if (state.dataDXCoils->DXCoil(DXCoilNum).FuelType != Constant::eFuel::Electricity) {
   17788            2 :         state.dataDXCoils->DXCoil(DXCoilNum).MSHPHeatRecActive = true;
   17789              :     }
   17790            4 : }
   17791              : 
   17792            4 : void SetDXCoilAirLoopNumber(EnergyPlusData &state, std::string const &CoilName, int const AirLoopNum)
   17793              : {
   17794              :     // SUBROUTINE INFORMATION:
   17795              :     //       AUTHOR         L. Gu
   17796              :     //       DATE WRITTEN   March, 2018
   17797              : 
   17798              :     // PURPOSE OF THIS SUBROUTINE:
   17799              :     // Set AirLoopNum for AFN model with multiple AirLoops
   17800              : 
   17801              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   17802              :     int WhichCoil;
   17803              : 
   17804            4 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   17805            1 :         GetDXCoils(state);
   17806            1 :         state.dataDXCoils->GetCoilsInputFlag = false;
   17807              :     }
   17808              : 
   17809            4 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   17810            4 :     if (WhichCoil != 0) {
   17811            2 :         state.dataDXCoils->DXCoil(WhichCoil).AirLoopNum = AirLoopNum;
   17812              :     } else {
   17813            2 :         ShowSevereError(state, format("SetDXCoilAirLoopNumber: Could not find Coil \"Name=\"{}\"", CoilName));
   17814              :     }
   17815            4 : } // must match coil names for the coil type
   17816              : 
   17817            1 : void DisableLatentDegradation(EnergyPlusData &state, int const DXCoilNum)
   17818              : {
   17819              :     // SUBROUTINE INFORMATION:
   17820              :     //       AUTHOR         L. Gu
   17821              :     //       DATE WRITTEN   JUne, 2019
   17822              : 
   17823              :     // PURPOSE OF THIS SUBROUTINE:
   17824              :     // Disable latent degradation when direct solution is used.
   17825              : 
   17826            1 :     state.dataDXCoils->DXCoil(DXCoilNum).Twet_Rated(1) = 0.0;
   17827            1 : }
   17828              : 
   17829              : } // namespace EnergyPlus::DXCoils
        

Generated by: LCOV version 2.0-1