LCOV - code coverage report
Current view: top level - EnergyPlus - DXCoils.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 66.3 % 8948 5930
Test Date: 2025-06-02 12:03:30 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           85 :             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           85 :             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        38583 :         CompCycRatio = CompCyclingRatio;
     198              :     } else {
     199       482921 :         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              : 
     343          250 :     } break;
     344          199 :     case HVAC::CoilDX_MultiSpeedHeating: {
     345          199 :         if (present(SpeedNum)) {
     346          199 :             CalcMultiSpeedDXCoilHeating(state,
     347              :                                         DXCoilNum,
     348              :                                         SpeedRatio,
     349              :                                         CycRatio,
     350              :                                         SpeedNum,
     351              :                                         fanOp,
     352              :                                         SingleModeOper); // Autodesk:OPTIONAL fanOp used without PRESENT check
     353              :         }
     354              : 
     355          199 :     } break;
     356            0 :     default: {
     357            0 :         ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
     358            0 :         ShowContinueError(state, format("Invalid DX Coil Type={}", state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType));
     359            0 :         ShowFatalError(state, "Preceding condition causes termination.");
     360            0 :     } break;
     361              :     }
     362              : 
     363              :     // Update the unit outlet nodes
     364        17558 :     UpdateDXCoil(state, DXCoilNum);
     365              : 
     366              :     // Report the result of the simulation
     367        17558 :     ReportDXCoil(state, DXCoilNum);
     368        17558 : }
     369              : 
     370            0 : void SimDXCoilMultiMode(EnergyPlusData &state,
     371              :                         std::string_view CompName,                              // name of the fan coil unit
     372              :                         [[maybe_unused]] HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off !unused1208
     373              :                         bool const FirstHVACIteration,                          // true if first hvac iteration
     374              :                         Real64 const PartLoadRatio,                             // part load ratio
     375              :                         HVAC::CoilMode const DehumidMode,                       // dehumidification mode (0=normal, 1=enhanced)
     376              :                         int &CompIndex,
     377              :                         HVAC::FanOp const fanOp // allows parent object to control fan mode
     378              : )
     379              : {
     380              : 
     381              :     // SUBROUTINE INFORMATION:
     382              :     //       AUTHOR         M. J. Witte (based on SimDXCoilMultiSpeed by Fred Buhl)
     383              :     //       DATE WRITTEN   February 2005
     384              :     //       MODIFIED       April 2010, Chandan sharma, added basin heater
     385              : 
     386              :     // PURPOSE OF THIS SUBROUTINE:
     387              :     // Manages the simulation of a DX coil with multiple performance modes, such as
     388              :     // multiple stages, or sub-cool reheat for humidity control.
     389              : 
     390              :     // Using/Aliasing
     391              : 
     392              :     // SUBROUTINE PARAMETER DEFINITIONS:
     393              :     static constexpr std::string_view RoutineName("SimDXCoilMultiMode");
     394              : 
     395              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     396              :     int DXCoilNum; // index of coil being simulated
     397              :     int PerfMode;  // Performance mode for MultiMode DX coil; Always 1 for other coil types
     398              :     // 1-2=normal mode: 1=stage 1 only, 2=stage 1&2
     399              :     // 3-4=enhanced dehumidification mode: 3=stage 1 only, 4=stage 1&2
     400              :     Real64 AirMassFlow; // Dry air mass flow rate through coil [kg/s]
     401              : 
     402              :     Real64 S1OutletAirTemp;     // Stage 1   Outlet air dry bulb temp [C]
     403              :     Real64 S1OutletAirHumRat;   // Stage 1   Outlet air humidity ratio [kgWater/kgDryAir]
     404              :     Real64 S1OutletAirEnthalpy; // Stage 1   Outlet air enthalpy
     405              :     Real64 S1PLR;               // Stage 1   Ratio of actual sensible cooling load to
     406              :     //           steady-state sensible cooling capacity
     407              :     Real64 S1TotalCoolingEnergyRate; // Stage 1   Total cooling rate [W]
     408              :     Real64 S1SensCoolingEnergyRate;  // Stage 1   Sensible cooling rate [W]
     409              :     Real64 S1LatCoolingEnergyRate;   // Stage 1   Latent cooling rate [W]
     410              :     Real64 S1ElecCoolingPower;       // Stage 1   Electric power input [W]
     411            0 :     Real64 S1RuntimeFraction(0.0);   // Stage 1   Run time fraction (overlaps with stage1&2 run time)
     412              :     Real64 S1EvapCondPumpElecPower;  // Stage 1   Evaporative condenser pump electric power input [W]
     413              :     Real64 S1EvapWaterConsumpRate;   // Stage 1   Evap condenser water consumption rate [m3/s]
     414              :     Real64 S1CrankcaseHeaterPower;   // Stage 1   Report variable for average crankcase heater power [W]
     415              :     Real64 S1FFullLoadOutAirTemp;    // Stage 1   Full load outlet temperature [C]
     416              :     Real64 S1FullLoadOutAirHumRat;   // Stage 1   Full load outlet humidity ratio [kgWater/kgDryAir]
     417              : 
     418              :     Real64 S12OutletAirTemp;     // Stage 1&2 Outlet air dry bulb temp [C]
     419              :     Real64 S12OutletAirHumRat;   // Stage 1&2 Outlet air humidity ratio [kgWater/kgDryAir]
     420              :     Real64 S12OutletAirEnthalpy; // Stage 1&2 Outlet air enthalpy
     421              :     //                                       !           steady-state sensible cooling capacity
     422              :     Real64 S12TotalCoolingEnergyRate; // Stage 1&2 Total cooling rate [W]
     423              :     Real64 S12SensCoolingEnergyRate;  // Stage 1&2 Sensible cooling rate [W]
     424              :     Real64 S12LatCoolingEnergyRate;   // Stage 1&2 Latent cooling rate [W]
     425              :     Real64 S12ElecCoolingPower;       // Stage 1&2 Electric power input [W]
     426              :     Real64 S12ElecCoolFullLoadPower;  // Stage 1&2 Electric power input at full load (PLR=1) [W]
     427            0 :     Real64 S12RuntimeFraction(0.0);   // Stage 1&2 Run time fraction (overlaps with stage1 run time)
     428              :     Real64 S12EvapCondPumpElecPower;  // Stage 1&2 Evaporative condenser pump electric power input [W]
     429              :     Real64 S12EvapWaterConsumpRate;   // Stage 1&2 Evap condenser water consumption rate [m3/s]
     430              :     Real64 S12CrankcaseHeaterPower;   // Stage 1&2 Report variable for average crankcase heater power [W]
     431              :     Real64 S2PLR;                     // Stage 2   Ratio of actual sensible cooling load to
     432              :     //           steady-state sensible cooling capacity
     433              :     Real64 TSat;      // calculation to avoid calling psych routines twice
     434              :     Real64 NodePress; // Pressure at condenser inlet node (Pa)
     435              : 
     436              :     // First time SimDXCoil is called, get the input for all the DX coils (condensing units)
     437            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
     438            0 :         GetDXCoils(state);
     439            0 :         state.dataDXCoils->GetCoilsInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
     440              :     }
     441              : 
     442              :     //  find correct DX Coil
     443            0 :     if (CompIndex == 0) {
     444            0 :         DXCoilNum = Util::FindItemInList(CompName, state.dataDXCoils->DXCoil);
     445            0 :         if (DXCoilNum == 0) {
     446            0 :             ShowFatalError(state, format("DX Coil not found={}", CompName));
     447              :         }
     448            0 :         CompIndex = DXCoilNum;
     449              :     } else {
     450            0 :         DXCoilNum = CompIndex;
     451            0 :         if (DXCoilNum > state.dataDXCoils->NumDXCoils || DXCoilNum < 1) {
     452            0 :             ShowFatalError(state,
     453            0 :                            format("SimDXCoilMultiMode: Invalid CompIndex passed={}, Number of DX Coils={}, Coil name={}",
     454              :                                   DXCoilNum,
     455            0 :                                   state.dataDXCoils->NumDXCoils,
     456              :                                   CompName));
     457              :         }
     458            0 :         if (state.dataDXCoils->CheckEquipName(DXCoilNum)) {
     459            0 :             if ((CompName != "") && (CompName != state.dataDXCoils->DXCoil(DXCoilNum).Name)) {
     460            0 :                 ShowFatalError(state,
     461            0 :                                format("SimDXCoilMultiMode: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
     462              :                                       DXCoilNum,
     463              :                                       CompName,
     464            0 :                                       state.dataDXCoils->DXCoil(DXCoilNum).Name));
     465              :             }
     466            0 :             state.dataDXCoils->CheckEquipName(DXCoilNum) = false;
     467              :         }
     468              :     }
     469              : 
     470              :     // Initialize the DX coil unit
     471            0 :     InitDXCoil(state, DXCoilNum);
     472              : 
     473            0 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
     474              :     // Select the correct unit type
     475            0 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
     476              :         // Initialize local variables
     477            0 :         S1RuntimeFraction = 0.0;
     478            0 :         S1OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
     479            0 :         S1OutletAirHumRat = thisDXCoil.InletAirHumRat;
     480            0 :         S1OutletAirTemp = thisDXCoil.InletAirTemp;
     481            0 :         S1ElecCoolingPower = 0.0;
     482            0 :         S1TotalCoolingEnergyRate = 0.0;
     483            0 :         S1SensCoolingEnergyRate = 0.0;
     484            0 :         S1LatCoolingEnergyRate = 0.0;
     485            0 :         S1CrankcaseHeaterPower = 0.0;
     486            0 :         S1EvapWaterConsumpRate = 0.0;
     487            0 :         S1EvapCondPumpElecPower = 0.0;
     488              : 
     489            0 :         S12RuntimeFraction = 0.0;
     490            0 :         S12OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
     491            0 :         S12OutletAirHumRat = thisDXCoil.InletAirHumRat;
     492            0 :         S12OutletAirTemp = thisDXCoil.InletAirTemp;
     493            0 :         S12ElecCoolingPower = 0.0;
     494            0 :         S12TotalCoolingEnergyRate = 0.0;
     495            0 :         S12SensCoolingEnergyRate = 0.0;
     496            0 :         S12LatCoolingEnergyRate = 0.0;
     497            0 :         S12CrankcaseHeaterPower = 0.0;
     498            0 :         S12EvapWaterConsumpRate = 0.0;
     499            0 :         S12EvapCondPumpElecPower = 0.0;
     500              : 
     501            0 :         thisDXCoil.DehumidificationMode = DehumidMode;
     502            0 :         if ((int)DehumidMode > thisDXCoil.NumDehumidModes) {
     503            0 :             ShowFatalError(state,
     504            0 :                            format("{} \"{}\" - Requested enhanced dehumidification mode not available.", thisDXCoil.DXCoilType, thisDXCoil.Name));
     505              :         }
     506              : 
     507              :         // If a single-stage coil OR If part load is zero,
     508              :         // run stage 1 at zero part load to set leaving conditions
     509            0 :         if ((thisDXCoil.NumCapacityStages == 1) || (PartLoadRatio <= 0.0)) {
     510              :             // Run stage 1 at its part load
     511            0 :             PerfMode = (int)DehumidMode * 2 + 1; // This.  This is not good.  Don't do math on enums.
     512            0 :             CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadRatio, fanOp, PerfMode);
     513            0 :             S1PLR = PartLoadRatio;
     514            0 :             S2PLR = 0.0;
     515              :         } else {
     516              :             // If a two-stage coil
     517              :             // Run stage 1 at full load
     518            0 :             PerfMode = (int)DehumidMode * 2 + 1;
     519            0 :             CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
     520            0 :             S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
     521            0 :             if (S1SensCoolingEnergyRate > 0.0) {
     522            0 :                 S1PLR = PartLoadRatio;
     523              :             } else {
     524            0 :                 S1PLR = 0.0;
     525              :             }
     526              :             // Run stage 1+2 at full load
     527            0 :             if (thisDXCoil.NumCapacityStages >= 2) {
     528            0 :                 PerfMode = (int)DehumidMode * 2 + 2;
     529            0 :                 CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, 1.0, fanOp, PerfMode);
     530            0 :                 S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
     531            0 :                 S12ElecCoolFullLoadPower = thisDXCoil.ElecCoolingPower;
     532              :             }
     533              : 
     534              :             // Determine run-time fractions for each stage based on sensible capacities
     535              :             //   Relationships:
     536              :             //     Stage 1   PLR1=   Load/Cap1
     537              :             //     Stage1+2  PLR12=  Load/Cap12
     538              :             //     Stage 2   PLR2=   (Load-Cap1)/(Cap2)
     539              :             //     PLR = Load/(Cap1+Cap2)
     540              :             //     Load= PLR*(Cap1+Cap2)
     541              :             //     PLR1= MIN(1,(PLR*(Cap1+Cap2)/Cap1))
     542              :             //     PLR2= MIN(1,((PLR*(Cap1+Cap2)-Cap1)/Cap2))
     543              : 
     544            0 :             if (S1SensCoolingEnergyRate > 0.0) {
     545            0 :                 S1PLR = PartLoadRatio * S12SensCoolingEnergyRate / S1SensCoolingEnergyRate;
     546              :             } else {
     547            0 :                 S1PLR = 0.0;
     548              :             }
     549            0 :             S1PLR = min(1.0, S1PLR);
     550            0 :             S1PLR = max(0.0, S1PLR);
     551            0 :             if ((S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) > 0.0) {
     552            0 :                 S2PLR = (PartLoadRatio * S12SensCoolingEnergyRate - S1SensCoolingEnergyRate) / (S12SensCoolingEnergyRate - S1SensCoolingEnergyRate);
     553              :             } else {
     554            0 :                 S2PLR = 0.0;
     555              :             }
     556            0 :             S2PLR = min(1.0, S2PLR);
     557            0 :             S2PLR = max(0.0, S2PLR);
     558              : 
     559              :             // Run stage 1 at its part load
     560            0 :             PerfMode = (int)DehumidMode * 2 + 1;
     561            0 :             CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, S1PLR, fanOp, PerfMode);
     562              :         }
     563              :         // For stage-1 only operation, all outputs are set by CalcDoe2DXCoil.
     564              :         // No further adjustments are necessary.
     565              : 
     566              :         // Run stage 2 if needed and available
     567            0 :         if ((S2PLR > 0.0) && (thisDXCoil.NumCapacityStages >= 2)) {
     568              :             // Store stage 1 outputs
     569            0 :             S1RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
     570            0 :             S1OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
     571            0 :             S1OutletAirHumRat = thisDXCoil.OutletAirHumRat;
     572            0 :             S1OutletAirTemp = thisDXCoil.OutletAirTemp;
     573            0 :             S1ElecCoolingPower = thisDXCoil.ElecCoolingPower;
     574            0 :             S1TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
     575            0 :             S1SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
     576            0 :             S1LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
     577            0 :             S1CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
     578            0 :             S1EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
     579            0 :             S1EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
     580              : 
     581              :             // Save first stage full load outlet conditions to pass to heat recovery
     582            0 :             S1FFullLoadOutAirTemp = state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
     583            0 :             S1FullLoadOutAirHumRat = state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum);
     584              : 
     585              :             // Run stage 1+2 at its part load
     586            0 :             PerfMode = (int)DehumidMode * 2 + 2;
     587            0 :             CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, FirstHVACIteration, S2PLR, fanOp, PerfMode);
     588            0 :             S12RuntimeFraction = thisDXCoil.CoolingCoilRuntimeFraction;
     589            0 :             S12OutletAirEnthalpy = thisDXCoil.OutletAirEnthalpy;
     590            0 :             S12OutletAirHumRat = thisDXCoil.OutletAirHumRat;
     591            0 :             S12OutletAirTemp = thisDXCoil.OutletAirTemp;
     592            0 :             S12ElecCoolingPower = thisDXCoil.ElecCoolingPower;
     593            0 :             S12TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate;
     594            0 :             S12SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate;
     595            0 :             S12LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate;
     596            0 :             S12CrankcaseHeaterPower = thisDXCoil.CrankcaseHeaterPower;
     597            0 :             S12EvapWaterConsumpRate = thisDXCoil.EvapWaterConsumpRate;
     598            0 :             S12EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecPower;
     599              : 
     600              :             // Determine combined performance
     601            0 :             thisDXCoil.OutletAirEnthalpy = (1.0 - S2PLR) * S1OutletAirEnthalpy + S2PLR * S12OutletAirEnthalpy;
     602            0 :             thisDXCoil.OutletAirHumRat = (1.0 - S2PLR) * S1OutletAirHumRat + S2PLR * S12OutletAirHumRat;
     603            0 :             thisDXCoil.OutletAirTemp = PsyTdbFnHW(thisDXCoil.OutletAirEnthalpy, thisDXCoil.OutletAirHumRat);
     604              :             // Check for saturation error and modify temperature at constant enthalpy
     605            0 :             if (thisDXCoil.CondenserInletNodeNum(PerfMode) != 0) {
     606            0 :                 NodePress = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(PerfMode)).Press;
     607              :                 // If node is not connected to anything, pressure = default, use weather data
     608            0 :                 if (NodePress == state.dataLoopNodes->DefaultNodeValues.Press) {
     609            0 :                     NodePress = state.dataEnvrn->OutBaroPress;
     610              :                 }
     611            0 :                 TSat = PsyTsatFnHPb(state, thisDXCoil.OutletAirEnthalpy, NodePress, RoutineName);
     612            0 :                 if (thisDXCoil.OutletAirTemp < TSat) {
     613            0 :                     thisDXCoil.OutletAirTemp = TSat;
     614              :                 }
     615            0 :                 thisDXCoil.OutletAirHumRat = PsyWFnTdbH(state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirEnthalpy, RoutineName);
     616              :             } else {
     617            0 :                 TSat = PsyTsatFnHPb(state, thisDXCoil.OutletAirEnthalpy, state.dataEnvrn->OutBaroPress, RoutineName);
     618            0 :                 if (thisDXCoil.OutletAirTemp < TSat) {
     619            0 :                     thisDXCoil.OutletAirTemp = TSat;
     620              :                 }
     621              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
     622              :                 //      IF(DXCoil(DXCoilNum)%OutletAirTemp .LT. PsyTsatFnHPb(DXCoil(DXCoilNum)%OutletAirEnthalpy, &
     623              :                 //                 Node(DXCoil(DXCoilNum)%AirInNode)%Press)) THEN
     624              :                 //        DXCoil(DXCoilNum)%OutletAirTemp = PsyTsatFnHPb(DXCoil(DXCoilNum)%OutletAirEnthalpy, &
     625              :                 //                 Node(DXCoil(DXCoilNum)%AirInNode)%Press)
     626            0 :                 thisDXCoil.OutletAirHumRat = PsyWFnTdbH(state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirEnthalpy, RoutineName);
     627              :             }
     628              : 
     629              :             //      DXCoil(DXCoilNum)%ElecCoolingPower = (1-S12RuntimeFraction)*S1ElecCoolingPower &
     630              :             //                                             +S12RuntimeFraction*S12ElecCoolingPower
     631              :             //  S12ElecCoolingPower overstates S1 portion of power, because it is also adjust by S12PLR
     632              :             //  So, must make an adjustment for S12ElecCoolingPower/S12ElecCoolFullLoadPower
     633              :             //  when subtracting off S1ElecCoolingPower
     634            0 :             if (S12ElecCoolFullLoadPower > 0.0) {
     635            0 :                 thisDXCoil.ElecCoolingPower =
     636            0 :                     S1RuntimeFraction * S1ElecCoolingPower +
     637            0 :                     S12RuntimeFraction * (S12ElecCoolingPower - S1ElecCoolingPower * S12ElecCoolingPower / S12ElecCoolFullLoadPower);
     638              :             } else {
     639            0 :                 thisDXCoil.ElecCoolingPower = 0.0;
     640              :             }
     641              : 
     642            0 :             thisDXCoil.CoolingCoilRuntimeFraction = S1RuntimeFraction;
     643              : 
     644            0 :             AirMassFlow = thisDXCoil.InletAirMassFlowRate;
     645            0 :             CalcComponentSensibleLatentOutput(AirMassFlow,
     646              :                                               thisDXCoil.InletAirTemp,
     647              :                                               thisDXCoil.InletAirHumRat,
     648              :                                               thisDXCoil.OutletAirTemp,
     649              :                                               thisDXCoil.OutletAirHumRat,
     650            0 :                                               thisDXCoil.SensCoolingEnergyRate,
     651            0 :                                               thisDXCoil.LatCoolingEnergyRate,
     652            0 :                                               thisDXCoil.TotalCoolingEnergyRate);
     653              : 
     654            0 :             thisDXCoil.EvapWaterConsumpRate = (1.0 - S12RuntimeFraction) * S1EvapWaterConsumpRate + S12RuntimeFraction * S12EvapWaterConsumpRate;
     655            0 :             thisDXCoil.EvapCondPumpElecPower = (1.0 - S12RuntimeFraction) * S1EvapCondPumpElecPower + S12RuntimeFraction * S12EvapCondPumpElecPower;
     656              : 
     657              :             // Stage 1 runtime sets the crankcase heater power
     658            0 :             thisDXCoil.CrankcaseHeaterPower = S1CrankcaseHeaterPower;
     659              : 
     660            0 :             state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
     661            0 :             state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
     662              : 
     663              :             //     calculate average full load outlet conditions for second stage operation
     664            0 :             state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) =
     665            0 :                 (1.0 - S2PLR) * S1FFullLoadOutAirTemp + S2PLR * state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum);
     666            0 :             state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) =
     667            0 :                 (1.0 - S2PLR) * S1FullLoadOutAirHumRat + S2PLR * state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum);
     668              : 
     669              :         } // End if stage 2 is operating
     670              : 
     671              :         //   set the part load ratio and heat reclaim capacity for use by desuperheater heating coils
     672            0 :         thisDXCoil.PartLoadRatio = S1PLR;
     673            0 :         state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = S1PLR;
     674              : 
     675              :         //   Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
     676            0 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
     677              : 
     678            0 :         thisDXCoil.CoolingCoilStg2RuntimeFrac = S12RuntimeFraction;
     679              : 
     680              :         //   Calculate basin heater power
     681            0 :         CalcBasinHeaterPowerForMultiModeDXCoil(state, DXCoilNum, DehumidMode);
     682              :     } else {
     683            0 :         ShowSevereError(state, format("Error detected in DX Coil={}", CompName));
     684            0 :         ShowContinueError(state, format("Invalid DX Coil Type={}", thisDXCoil.DXCoilType));
     685            0 :         ShowFatalError(state, "Preceding condition causes termination.");
     686              :     }
     687              : 
     688              :     // Update the unit outlet nodes
     689            0 :     UpdateDXCoil(state, DXCoilNum);
     690              : 
     691              :     // Report the result of the simulation
     692            0 :     ReportDXCoil(state, DXCoilNum);
     693            0 : }
     694              : 
     695          135 : void GetDXCoils(EnergyPlusData &state)
     696              : {
     697              : 
     698              :     // SUBROUTINE INFORMATION:
     699              :     //       AUTHOR         Fred Buhl
     700              :     //       DATE WRITTEN   May 2000
     701              :     //       MODIFIED       Aug 2000, Don Shirey, Sept 2000, Feb/Oct 2001, Sept 2003, Jan/July 2004
     702              :     //                      Feb 2005, M. J. Witte, GARD Analytics, Inc., Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
     703              :     //                      May 2005, Rich Raustad, FSEC, Added COIL:DX:HeatPumpWaterHeater
     704              :     //                      Jun 2007, L. Gu, FSEC, Added new coil type COIL:DX:MULTISPEED:COOLING and COIL:DX:MULTISPEED:HEATING
     705              :     //                      Apr 2010, Chandan Sharma, FSEC, added basin heater inputs
     706              :     //                      Jul 2015, RP Zhang, XF Pang, LBNL, Added new coil type for VRF-FluidTemperatureControl Model
     707              : 
     708              :     // PURPOSE OF THIS SUBROUTINE:
     709              :     // Obtains input data for DX coils and stores it in DX coil data structure
     710              : 
     711              :     // METHODOLOGY EMPLOYED:
     712              :     // Uses "Get" routines to read in data.
     713              : 
     714              :     // Using/Aliasing
     715              :     using BranchNodeConnections::TestCompSet;
     716              :     using Curve::checkCurveIsNormalizedToOne;
     717              :     using Curve::CurveValue;
     718              :     using Curve::GetCurveIndex;
     719              :     using DataSizing::AutoSize;
     720              :     using EMSManager::ManageEMS;
     721              : 
     722              :     using GlobalNames::VerifyUniqueCoilName;
     723              :     using NodeInputManager::GetOnlySingleNode;
     724              :     using OutAirNodeManager::CheckOutAirNodeNumber;
     725              :     using WaterManager::SetupTankDemandComponent;
     726              :     using WaterManager::SetupTankSupplyComponent;
     727              : 
     728              :     // SUBROUTINE PARAMETER DEFINITIONS:
     729              :     static constexpr std::string_view RoutineName("GetDXCoils: "); // include trailing blank space
     730              :     static constexpr std::string_view routineName = "GetDXCoils";  // include trailing blank space
     731              : 
     732          135 :     constexpr Real64 minOATCompDXCooling = -25.0; // min OAT for compressor operation for DX cooling coils
     733              : 
     734              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     735              :     int DXCoilIndex;                 // loop index
     736              :     int DXCoilNum;                   // current DX coil number
     737              :     int NumAlphas;                   // Number of alphas in input
     738              :     int NumNumbers;                  // Number of numeric items in input
     739          135 :     Array1D_string Alphas2;          // Alpha input items for object
     740          135 :     Array1D<Real64> Numbers2;        // Numeric input items for object
     741          135 :     Array1D_string cAlphaFields2;    // Alpha field names
     742          135 :     Array1D_string cNumericFields2;  // Numeric field names
     743          135 :     Array1D_bool lAlphaBlanks2;      // Logical array, alpha field input BLANK = .TRUE.
     744          135 :     Array1D_bool lNumericBlanks2;    // Logical array, numeric field input BLANK = .TRUE.
     745              :     int NumAlphas2;                  // Number of alphas in input for performance object
     746              :     int NumNumbers2;                 // Number of numeric items in input for performance object
     747              :     int IOStatus;                    // Input status returned from GetObjectItem
     748          135 :     bool ErrorsFound(false);         // Set to true if errors in input, fatal at end of routine
     749              :     int DXHPWaterHeaterCoilNum;      // Loop index for 1,NumDXHeatPumpWaterHeaterCoils
     750              :     int CapacityStageNum;            // Loop index for 1,Number of capacity stages
     751              :     int DehumidModeNum;              // Loop index for 1,Number of enhanced dehumidification modes
     752              :     int PerfModeNum;                 // Performance mode index
     753              :     int PerfObjectNum;               // Item number for performance object
     754              :     int AlphaIndex;                  // Index for current alpha field
     755          135 :     std::string CurrentModuleObject; // Object type for getting and error messages
     756          135 :     std::string PerfObjectType;      // Performance object type for getting and error messages
     757          135 :     std::string PerfObjectName;      // Performance object name for getting and error messages
     758              :     Real64 InletAirTemp;             // Used to pass proper inlet air temp to HPWH DX coil performance curves
     759              :     Real64 InletWaterTemp;           // Used to pass proper inlet water temp to HPWH DX coil performance curves
     760              :     int I;                           // Index of speeds
     761              :     Real64 CurveVal;                 // Used to verify modifier curves equal 1 at rated conditions
     762          135 :     Array1D_string Alphas;           // Alpha input items for object
     763          135 :     Array1D_string cAlphaFields;     // Alpha field names
     764          135 :     Array1D_string cNumericFields;   // Numeric field names
     765          135 :     Array1D<Real64> Numbers;         // Numeric input items for object
     766          135 :     Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     767          135 :     Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     768          135 :     int MaxNumbers(0);               // Maximum number of numeric input fields
     769          135 :     int MaxAlphas(0);                // Maximum number of alpha input fields
     770          135 :     int TotalArgs(0);                // Total number of alpha and numeric arguments (max) for a
     771              :     //   certain object in the input file
     772              :     Real64 MinCurveVal; // used for testing PLF curve output
     773              :     Real64 MinCurvePLR; // used for testing PLF curve output
     774              :     Real64 MaxCurveVal; // used for testing PLF curve output
     775              :     Real64 MaxCurvePLR; // used for testing PLF curve output
     776              :     Real64 CurveInput;  // index used for testing PLF curve output
     777              : 
     778              :     // find number of each type of DX coil and calculate the total number
     779          135 :     state.dataDXCoils->NumDoe2DXCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:SingleSpeed");
     780          135 :     state.dataDXCoils->NumDXHeatingCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:SingleSpeed");
     781          135 :     state.dataDXCoils->NumDXMulSpeedCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoSpeed");
     782          270 :     state.dataDXCoils->NumDXMulModeCoils =
     783          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode");
     784          270 :     state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils =
     785          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped));
     786          270 :     state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils =
     787          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped));
     788          135 :     state.dataDXCoils->NumDXMulSpeedCoolCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:DX:MultiSpeed");
     789          135 :     state.dataDXCoils->NumDXMulSpeedHeatCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:DX:MultiSpeed");
     790          270 :     state.dataDXCoils->NumVRFCoolingCoils =
     791          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling));
     792          270 :     state.dataDXCoils->NumVRFHeatingCoils =
     793          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating));
     794          270 :     state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils =
     795          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling));
     796          270 :     state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils =
     797          135 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating));
     798              : 
     799          135 :     state.dataDXCoils->NumDXCoils = state.dataDXCoils->NumDoe2DXCoils + state.dataDXCoils->NumDXHeatingCoils + state.dataDXCoils->NumDXMulSpeedCoils +
     800          135 :                                     state.dataDXCoils->NumDXMulModeCoils + state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils +
     801          135 :                                     state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils + state.dataDXCoils->NumDXMulSpeedCoolCoils +
     802          135 :                                     state.dataDXCoils->NumDXMulSpeedHeatCoils + state.dataDXCoils->NumVRFCoolingCoils +
     803          135 :                                     state.dataDXCoils->NumVRFHeatingCoils + state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils +
     804          135 :                                     state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils;
     805              : 
     806              :     // Determine max number of alpha and numeric arguments for all objects being read, in order to allocate local arrays
     807          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
     808          135 :     MaxNumbers = NumNumbers;
     809          135 :     MaxAlphas = NumAlphas;
     810          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:SingleSpeed", TotalArgs, NumAlphas, NumNumbers);
     811          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     812          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     813          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:TwoSpeed", TotalArgs, NumAlphas, NumNumbers);
     814          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     815          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     816          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     817              :         state, "Coil:Cooling:DX:TwoStageWithHumidityControlMode", 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_HeatPumpWaterHeaterPumped), TotalArgs, NumAlphas, NumNumbers);
     822          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     823          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     824          270 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     825          135 :         state, HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped), TotalArgs, NumAlphas, NumNumbers);
     826          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     827          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     828          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:DX:MultiSpeed", TotalArgs, NumAlphas, NumNumbers);
     829          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     830          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     831          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:DX:MultiSpeed", 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_Cooling), 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_Heating), 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_Cooling), TotalArgs, NumAlphas, NumNumbers);
     844          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     845          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     846          270 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     847          135 :         state, HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating), TotalArgs, NumAlphas, NumNumbers);
     848          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     849          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     850          135 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "CoilPerformance:DX:Cooling", TotalArgs, NumAlphas, NumNumbers);
     851          135 :     MaxNumbers = max(MaxNumbers, NumNumbers);
     852          135 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     853              : 
     854          135 :     Alphas.allocate(MaxAlphas);
     855          135 :     cAlphaFields.allocate(MaxAlphas);
     856          135 :     cNumericFields.allocate(MaxNumbers);
     857          135 :     Numbers.dimension(MaxNumbers, 0.0);
     858          135 :     lAlphaBlanks.dimension(MaxAlphas, true);
     859          135 :     lNumericBlanks.dimension(MaxNumbers, true);
     860              : 
     861          135 :     Alphas2.allocate(MaxAlphas);
     862          135 :     cAlphaFields2.allocate(MaxAlphas);
     863          135 :     cNumericFields2.allocate(MaxNumbers);
     864          135 :     Numbers2.dimension(MaxNumbers, 0.0);
     865          135 :     lAlphaBlanks2.dimension(MaxAlphas, true);
     866          135 :     lNumericBlanks2.dimension(MaxNumbers, true);
     867              : 
     868              :     // allocate the data structure
     869              : 
     870              :     // Derived types
     871          135 :     state.dataDXCoils->DXCoil.allocate(state.dataDXCoils->NumDXCoils);
     872          135 :     state.dataDXCoils->DXCoilNumericFields.allocate(state.dataDXCoils->NumDXCoils);
     873          135 :     state.dataHeatBal->HeatReclaimDXCoil.allocate(state.dataDXCoils->NumDXCoils);
     874          135 :     state.dataDXCoils->CheckEquipName.dimension(state.dataDXCoils->NumDXCoils, true);
     875              : 
     876              :     // Module level variable arrays
     877          135 :     state.dataDXCoils->DXCoilOutletTemp.allocate(state.dataDXCoils->NumDXCoils);
     878          135 :     state.dataDXCoils->DXCoilOutletHumRat.allocate(state.dataDXCoils->NumDXCoils);
     879          135 :     state.dataDXCoils->DXCoilPartLoadRatio.allocate(state.dataDXCoils->NumDXCoils);
     880          135 :     state.dataDXCoils->DXCoilFanOp.allocate(state.dataDXCoils->NumDXCoils);
     881          135 :     state.dataDXCoils->DXCoilFullLoadOutAirTemp.allocate(state.dataDXCoils->NumDXCoils);
     882          135 :     state.dataDXCoils->DXCoilFullLoadOutAirHumRat.allocate(state.dataDXCoils->NumDXCoils);
     883          135 :     state.dataDXCoils->DXCoilTotalCooling.allocate(state.dataDXCoils->NumDXCoils);
     884          135 :     state.dataDXCoils->DXCoilTotalHeating.allocate(state.dataDXCoils->NumDXCoils);
     885          135 :     state.dataDXCoils->DXCoilCoolInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
     886          135 :     state.dataDXCoils->DXCoilHeatInletAirDBTemp.allocate(state.dataDXCoils->NumDXCoils);
     887          135 :     state.dataDXCoils->DXCoilHeatInletAirWBTemp.allocate(state.dataDXCoils->NumDXCoils);
     888              : 
     889              :     // initialize the module level arrays
     890          135 :     state.dataDXCoils->DXCoilOutletTemp = 0.0;
     891          135 :     state.dataDXCoils->DXCoilOutletHumRat = 0.0;
     892          135 :     state.dataDXCoils->DXCoilPartLoadRatio = 0.0;
     893          135 :     state.dataDXCoils->DXCoilFanOp = HVAC::FanOp::Invalid;
     894          135 :     state.dataDXCoils->DXCoilFullLoadOutAirTemp = 0.0;
     895          135 :     state.dataDXCoils->DXCoilFullLoadOutAirHumRat = 0.0;
     896              : 
     897              :     // initialize the coil counter
     898          135 :     DXCoilNum = 0;
     899              : 
     900              :     // Loop over the Doe2 DX Coils and get & load the data
     901          135 :     CurrentModuleObject = "Coil:Cooling:DX:SingleSpeed";
     902          197 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilIndex) {
     903              : 
     904           62 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     905              :                                                                  CurrentModuleObject,
     906              :                                                                  DXCoilIndex,
     907              :                                                                  Alphas,
     908              :                                                                  NumAlphas,
     909              :                                                                  Numbers,
     910              :                                                                  NumNumbers,
     911              :                                                                  IOStatus,
     912              :                                                                  lNumericBlanks,
     913              :                                                                  lAlphaBlanks,
     914              :                                                                  cAlphaFields,
     915              :                                                                  cNumericFields);
     916              : 
     917           62 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
     918              : 
     919           62 :         ++DXCoilNum;
     920              :         // allocate single performance mode for numeric field strings used for sizing routine
     921           62 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
     922           62 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
     923           62 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
     924              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
     925           62 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
     926              : 
     927           62 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
     928           62 :         thisDXCoil.Name = Alphas(1);
     929              :         // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
     930           62 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
     931           62 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
     932           62 :         thisDXCoil.DXCoilType = CurrentModuleObject;
     933           62 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingSingleSpeed;
     934           62 :         if (lAlphaBlanks(2)) {
     935           10 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
     936           52 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
     937            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
     938            0 :             ErrorsFound = true;
     939              :         }
     940           62 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
     941           62 :         thisDXCoil.RatedSHR(1) = Numbers(2);
     942           62 :         thisDXCoil.RatedCOP(1) = Numbers(3);
     943           62 :         if (thisDXCoil.RatedCOP(1) <= 0.0) {
     944            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
     945            0 :             ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(3), Numbers(3)));
     946            0 :             ErrorsFound = true;
     947              :         }
     948              : 
     949           62 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
     950           62 :         thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
     951           62 :         thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
     952              : 
     953           62 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
     954           62 :                                                  Alphas(3),
     955              :                                                  ErrorsFound,
     956              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
     957           62 :                                                  Alphas(1),
     958              :                                                  DataLoopNode::NodeFluidType::Air,
     959              :                                                  DataLoopNode::ConnectionType::Inlet,
     960              :                                                  NodeInputManager::CompFluidStream::Primary,
     961              :                                                  ObjectIsNotParent);
     962              : 
     963          124 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
     964           62 :                                                   Alphas(4),
     965              :                                                   ErrorsFound,
     966              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
     967           62 :                                                   Alphas(1),
     968              :                                                   DataLoopNode::NodeFluidType::Air,
     969              :                                                   DataLoopNode::ConnectionType::Outlet,
     970              :                                                   NodeInputManager::CompFluidStream::Primary,
     971              :                                                   ObjectIsNotParent);
     972              : 
     973           62 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
     974              : 
     975           62 :         thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
     976           62 :         if (thisDXCoil.CCapFTemp(1) == 0) {
     977            0 :             if (lAlphaBlanks(5)) {
     978            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
     979            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
     980              :             } else {
     981            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
     982            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
     983              :             }
     984            0 :             ErrorsFound = true;
     985              :         } else {
     986              :             // Verify Curve Object, only legal type is BiQuadratic
     987          186 :             ErrorsFound |= Curve::CheckCurveDims(state,
     988           62 :                                                  thisDXCoil.CCapFTemp(1), // Curve index
     989              :                                                  {2},                     // Valid dimensions
     990              :                                                  RoutineName,             // Routine name
     991              :                                                  CurrentModuleObject,     // Object Type
     992              :                                                  thisDXCoil.Name,         // Object Name
     993           62 :                                                  cAlphaFields(5));        // Field Name
     994              : 
     995           62 :             if (!ErrorsFound) {
     996           62 :                 checkCurveIsNormalizedToOne(state,
     997          186 :                                             std::string{RoutineName} + CurrentModuleObject,
     998           62 :                                             thisDXCoil.Name,
     999           62 :                                             thisDXCoil.CCapFTemp(1),
    1000           62 :                                             cAlphaFields(5),
    1001           62 :                                             Alphas(5),
    1002              :                                             RatedInletWetBulbTemp,
    1003              :                                             RatedOutdoorAirTemp);
    1004              :             }
    1005              :         }
    1006              : 
    1007           62 :         thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
    1008           62 :         if (thisDXCoil.CCapFFlow(1) == 0) {
    1009            0 :             if (lAlphaBlanks(6)) {
    1010            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1011            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
    1012              :             } else {
    1013            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1014            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
    1015              :             }
    1016            0 :             ErrorsFound = true;
    1017              :         } else {
    1018              :             // Verify Curve Object, only legal type is Quadratic
    1019          186 :             ErrorsFound |= Curve::CheckCurveDims(state,
    1020           62 :                                                  thisDXCoil.CCapFFlow(1), // Curve index
    1021              :                                                  {1},                     // Valid dimensions
    1022              :                                                  RoutineName,             // Routine name
    1023              :                                                  CurrentModuleObject,     // Object Type
    1024              :                                                  thisDXCoil.Name,         // Object Name
    1025           62 :                                                  cAlphaFields(6));        // Field Name
    1026              : 
    1027           62 :             if (!ErrorsFound) {
    1028           62 :                 checkCurveIsNormalizedToOne(
    1029          248 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
    1030              :             }
    1031              :         }
    1032              : 
    1033           62 :         thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
    1034           62 :         if (thisDXCoil.EIRFTemp(1) == 0) {
    1035            0 :             if (lAlphaBlanks(7)) {
    1036            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1037            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
    1038              :             } else {
    1039            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1040            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
    1041              :             }
    1042            0 :             ErrorsFound = true;
    1043              :         } else {
    1044              :             // Verify Curve Object, only legal type is BiQuadratic
    1045          186 :             ErrorsFound |= Curve::CheckCurveDims(state,
    1046           62 :                                                  thisDXCoil.EIRFTemp(1), // Curve index
    1047              :                                                  {2},                    // Valid dimensions
    1048              :                                                  RoutineName,            // Routine name
    1049              :                                                  CurrentModuleObject,    // Object Type
    1050              :                                                  thisDXCoil.Name,        // Object Name
    1051           62 :                                                  cAlphaFields(7));       // Field Name
    1052              : 
    1053           62 :             if (!ErrorsFound) {
    1054           62 :                 checkCurveIsNormalizedToOne(state,
    1055          186 :                                             std::string{RoutineName} + CurrentModuleObject,
    1056           62 :                                             thisDXCoil.Name,
    1057           62 :                                             thisDXCoil.EIRFTemp(1),
    1058           62 :                                             cAlphaFields(7),
    1059           62 :                                             Alphas(7),
    1060              :                                             RatedInletWetBulbTemp,
    1061              :                                             RatedOutdoorAirTemp);
    1062              :             }
    1063              :         }
    1064              : 
    1065           62 :         thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
    1066           62 :         if (thisDXCoil.EIRFFlow(1) == 0) {
    1067            0 :             if (lAlphaBlanks(8)) {
    1068            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1069            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
    1070              :             } else {
    1071            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1072            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
    1073              :             }
    1074            0 :             ErrorsFound = true;
    1075              :         } else {
    1076              :             // Verify Curve Object, only legal type is Quadratic
    1077          186 :             ErrorsFound |= Curve::CheckCurveDims(state,
    1078           62 :                                                  thisDXCoil.EIRFFlow(1), // Curve index
    1079              :                                                  {1},                    // Valid dimensions
    1080              :                                                  RoutineName,            // Routine name
    1081              :                                                  CurrentModuleObject,    // Object Type
    1082              :                                                  thisDXCoil.Name,        // Object Name
    1083           62 :                                                  cAlphaFields(8));       // Field Name
    1084              : 
    1085           62 :             if (!ErrorsFound) {
    1086           62 :                 checkCurveIsNormalizedToOne(
    1087          248 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
    1088              :             }
    1089              :         }
    1090              : 
    1091           62 :         thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
    1092           62 :         if (thisDXCoil.PLFFPLR(1) == 0) {
    1093            0 :             if (lAlphaBlanks(9)) {
    1094            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1095            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
    1096              :             } else {
    1097            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1098            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
    1099              :             }
    1100            0 :             ErrorsFound = true;
    1101              :         } else {
    1102              :             // Verify Curve Object, only legal types are Quadratic or Cubic
    1103          186 :             ErrorsFound |= Curve::CheckCurveDims(state,
    1104           62 :                                                  thisDXCoil.PLFFPLR(1), // Curve index
    1105              :                                                  {1},                   // Valid dimensions
    1106              :                                                  RoutineName,           // Routine name
    1107              :                                                  CurrentModuleObject,   // Object Type
    1108              :                                                  thisDXCoil.Name,       // Object Name
    1109           62 :                                                  cAlphaFields(9));      // Field Name
    1110              : 
    1111           62 :             if (!ErrorsFound) {
    1112              :                 //     Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    1113           62 :                 MinCurveVal = 999.0;
    1114           62 :                 MaxCurveVal = -999.0;
    1115           62 :                 CurveInput = 0.0;
    1116         6262 :                 while (CurveInput <= 1.0) {
    1117         6200 :                     CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
    1118         6200 :                     if (CurveVal < MinCurveVal) {
    1119           62 :                         MinCurveVal = CurveVal;
    1120           62 :                         MinCurvePLR = CurveInput;
    1121              :                     }
    1122         6200 :                     if (CurveVal > MaxCurveVal) {
    1123         4568 :                         MaxCurveVal = CurveVal;
    1124         4568 :                         MaxCurvePLR = CurveInput;
    1125              :                     }
    1126         6200 :                     CurveInput += 0.01;
    1127              :                 }
    1128           62 :                 if (MinCurveVal < 0.7) {
    1129            0 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1130            0 :                     ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFields(9), Alphas(9)));
    1131            0 :                     ShowContinueError(state,
    1132            0 :                                       format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    1133            0 :                     ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    1134            0 :                     Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
    1135              :                 }
    1136              : 
    1137           62 :                 if (MaxCurveVal > 1.0) {
    1138            2 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1139            2 :                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
    1140            4 :                     ShowContinueError(state,
    1141            4 :                                       format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    1142            4 :                     ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    1143            2 :                     Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
    1144              :                 }
    1145              :             }
    1146              :         }
    1147              : 
    1148              :         // Set minimum OAT for compressor operation
    1149           62 :         thisDXCoil.MinOATCompressor = Numbers(7);
    1150           62 :         if (NumNumbers < 6) {
    1151            0 :             thisDXCoil.MinOATCompressor = minOATCompDXCooling; // input field is after min fields and won't default if field not included
    1152              :         }
    1153              : 
    1154           62 :         thisDXCoil.Twet_Rated(1) = Numbers(8);
    1155           62 :         thisDXCoil.Gamma_Rated(1) = Numbers(9);
    1156           62 :         thisDXCoil.MaxONOFFCyclesperHour(1) = Numbers(10);
    1157           62 :         thisDXCoil.LatentCapacityTimeConstant(1) = Numbers(11);
    1158              : 
    1159              :         // Numbers (7) through (11) must all be greater than zero to use the latent capacity degradation model
    1160           76 :         if ((Numbers(8) > 0.0 || Numbers(9) > 0.0 || Numbers(10) > 0.0 || Numbers(11) > 0.0) &&
    1161           14 :             (Numbers(8) <= 0.0 || Numbers(9) <= 0.0 || Numbers(10) <= 0.0 || Numbers(11) <= 0.0)) {
    1162            0 :             ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1163            0 :             ShowContinueError(state, "...At least one of the four input parameters for the latent capacity degradation model");
    1164            0 :             ShowContinueError(state, "...is set to zero. Therefore, the latent degradation model will not be used for this simulation.");
    1165              :         }
    1166              : 
    1167              :         // outdoor condenser node
    1168           62 :         if (lAlphaBlanks(10)) {
    1169           48 :             thisDXCoil.CondenserInletNodeNum(1) = 0;
    1170              :         } else {
    1171           28 :             thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
    1172           14 :                                                                     Alphas(10),
    1173              :                                                                     ErrorsFound,
    1174              :                                                                     DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed,
    1175           14 :                                                                     thisDXCoil.Name,
    1176              :                                                                     DataLoopNode::NodeFluidType::Air,
    1177              :                                                                     DataLoopNode::ConnectionType::OutsideAirReference,
    1178              :                                                                     NodeInputManager::CompFluidStream::Primary,
    1179              :                                                                     ObjectIsNotParent);
    1180              : 
    1181           14 :             if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
    1182            4 :                 ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1183            8 :                 ShowContinueError(
    1184              :                     state,
    1185            8 :                     format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(10), Alphas(10)));
    1186           12 :                 ShowContinueError(
    1187              :                     state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
    1188              :             }
    1189              :         }
    1190              : 
    1191           62 :         if ((Util::SameString(Alphas(11), "AirCooled")) || lAlphaBlanks(11)) {
    1192           48 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
    1193           14 :         } else if (Util::SameString(Alphas(11), "EvaporativelyCooled")) {
    1194           14 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
    1195           14 :             thisDXCoil.ReportEvapCondVars = true;
    1196              :         } else {
    1197            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1198            0 :             ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(11), Alphas(11)));
    1199            0 :             ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
    1200            0 :             ErrorsFound = true;
    1201              :         }
    1202              : 
    1203           62 :         thisDXCoil.EvapCondEffect(1) = Numbers(12);
    1204           62 :         if (thisDXCoil.EvapCondEffect(1) < 0.0 || thisDXCoil.EvapCondEffect(1) > 1.0) {
    1205            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1206            0 :             ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields(11)));
    1207            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(12)));
    1208            0 :             ErrorsFound = true;
    1209              :         }
    1210              : 
    1211           62 :         thisDXCoil.EvapCondAirFlow(1) = Numbers(13);
    1212           62 :         if (thisDXCoil.EvapCondAirFlow(1) < 0.0 && thisDXCoil.EvapCondAirFlow(1) != AutoSize) {
    1213            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1214            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(12)));
    1215            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(13)));
    1216            0 :             ErrorsFound = true;
    1217              :         }
    1218              : 
    1219           62 :         thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(14);
    1220           62 :         if (thisDXCoil.EvapCondPumpElecNomPower(1) < 0.0 && thisDXCoil.EvapCondPumpElecNomPower(1) != AutoSize) {
    1221            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1222            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(13)));
    1223            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(14)));
    1224            0 :             ErrorsFound = true;
    1225              :         }
    1226              : 
    1227              :         // Set crankcase heater capacity
    1228           62 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(15);
    1229           62 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    1230            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1231            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(14)));
    1232            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(15)));
    1233            0 :             ErrorsFound = true;
    1234              :         }
    1235              : 
    1236              :         // Set crankcase heater cutout temperature
    1237           62 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(16);
    1238              : 
    1239           62 :         if (thisDXCoil.RatedCOP(1) > 0.0) {
    1240           62 :             thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
    1241              :         }
    1242              : 
    1243              :         // A12, \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
    1244           62 :         if (!lAlphaBlanks(12)) {
    1245            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(12));
    1246            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    1247            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(12), Alphas(12)));
    1248            0 :                 ErrorsFound = true;
    1249              :             } else {
    1250            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    1251              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    1252              :                                                      {1},                                          // Valid dimensions
    1253              :                                                      RoutineName,                                  // Routine name
    1254              :                                                      CurrentModuleObject,                          // Object Type
    1255              :                                                      thisDXCoil.Name,                              // Object Name
    1256            2 :                                                      cAlphaFields(12));                            // Field Name
    1257              :             }
    1258              :         }
    1259              : 
    1260              :         // Get Water System tank connections
    1261              :         //  A13, \field Name of Water Storage Tank for Supply
    1262           62 :         thisDXCoil.EvapWaterSupplyName = Alphas(13);
    1263           62 :         if (lAlphaBlanks(13)) {
    1264           62 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
    1265              :         } else {
    1266            0 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
    1267            0 :             SetupTankDemandComponent(state,
    1268              :                                      thisDXCoil.Name,
    1269              :                                      CurrentModuleObject,
    1270              :                                      thisDXCoil.EvapWaterSupplyName,
    1271              :                                      ErrorsFound,
    1272            0 :                                      thisDXCoil.EvapWaterSupTankID,
    1273            0 :                                      thisDXCoil.EvapWaterTankDemandARRID);
    1274              :         }
    1275              : 
    1276              :         // A14; \field Name of Water Storage Tank for Condensate Collection
    1277           62 :         thisDXCoil.CondensateCollectName = Alphas(14);
    1278           62 :         if (lAlphaBlanks(14)) {
    1279           62 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    1280              :         } else {
    1281            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    1282            0 :             SetupTankSupplyComponent(state,
    1283              :                                      thisDXCoil.Name,
    1284              :                                      CurrentModuleObject,
    1285              :                                      thisDXCoil.CondensateCollectName,
    1286              :                                      ErrorsFound,
    1287            0 :                                      thisDXCoil.CondensateTankID,
    1288            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    1289              :         }
    1290              : 
    1291              :         //   Basin heater power as a function of temperature must be greater than or equal to 0
    1292           62 :         thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(17);
    1293           62 :         if (Numbers(17) < 0.0) {
    1294            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1295            0 :             ShowContinueError(state, format("...{} must be >= 0.0.", cNumericFields(16)));
    1296            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(17)));
    1297            0 :             ErrorsFound = true;
    1298              :         }
    1299              : 
    1300           62 :         thisDXCoil.BasinHeaterSetPointTemp = Numbers(18);
    1301           62 :         if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    1302            3 :             if (NumNumbers < 18) {
    1303            1 :                 thisDXCoil.BasinHeaterSetPointTemp = 2.0;
    1304              :             }
    1305            3 :             if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
    1306            0 :                 ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1307            0 :                 ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(17)));
    1308            0 :                 ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(18)));
    1309              :             }
    1310              :         }
    1311              : 
    1312           62 :         if (!lAlphaBlanks(15)) {
    1313            0 :             if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(15))) == nullptr) {
    1314            0 :                 ShowWarningItemNotFound(
    1315            0 :                     state, eoh, cAlphaFields(15), Alphas(15), "Basin heater will be available to operate throughout the simulation.");
    1316              :             }
    1317              :         }
    1318              : 
    1319           62 :         if (!lAlphaBlanks(16) && NumAlphas > 15) {
    1320            0 :             thisDXCoil.SHRFTemp(1) = GetCurveIndex(state, Alphas(16)); // convert curve name to number
    1321            0 :             if (thisDXCoil.SHRFTemp(1) == 0) {
    1322            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1323            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
    1324              :             } else {
    1325              :                 // Verify Curve Object, only legal type is BiQuadratic
    1326            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    1327            0 :                                                      thisDXCoil.SHRFTemp(1), // Curve index
    1328              :                                                      {2},                    // Valid dimensions
    1329              :                                                      RoutineName,            // Routine name
    1330              :                                                      CurrentModuleObject,    // Object Type
    1331              :                                                      thisDXCoil.Name,        // Object Name
    1332            0 :                                                      cAlphaFields(16));      // Field Name
    1333              :             }
    1334              :         }
    1335              : 
    1336           62 :         if (!lAlphaBlanks(17) && NumAlphas > 16) {
    1337            2 :             thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
    1338            2 :             if (thisDXCoil.SHRFTemp(1) == 0) {
    1339            2 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1340            2 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
    1341              :             } else {
    1342              :                 // Verify Curve Object, only legal type is Quadratic and Cubic
    1343            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    1344            0 :                                                      thisDXCoil.SHRFFlow(1), // Curve index
    1345              :                                                      {1},                    // Valid dimensions
    1346              :                                                      RoutineName,            // Routine name
    1347              :                                                      CurrentModuleObject,    // Object Type
    1348              :                                                      thisDXCoil.Name,        // Object Name
    1349            0 :                                                      cAlphaFields(17));      // Field Name
    1350              :             }
    1351              :         }
    1352              : 
    1353           62 :         if (thisDXCoil.SHRFTemp(1) > 0 && thisDXCoil.SHRFFlow(1) > 0) {
    1354            0 :             thisDXCoil.UserSHRCurveExists = true;
    1355              :         }
    1356              :         // get User Input flag for ASHRAE Standard 127 Standard Ratings Reporting
    1357           62 :         if (lAlphaBlanks(18)) {
    1358           62 :             thisDXCoil.ASHRAE127StdRprt = false;
    1359              :         } else {
    1360            0 :             if (Alphas(18) == "YES" || Alphas(18) == "Yes") {
    1361            0 :                 thisDXCoil.ASHRAE127StdRprt = true;
    1362              :             } else {
    1363            0 :                 thisDXCoil.ASHRAE127StdRprt = false;
    1364              :             }
    1365              :         }
    1366              :         // A19; \field Zone Name for Condenser Placement
    1367           62 :         if (!lAlphaBlanks(19) && NumAlphas > 18) {
    1368            0 :             thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(19), state.dataHeatBal->Zone);
    1369              : 
    1370            0 :             if (thisDXCoil.SecZonePtr > 0) {
    1371            0 :                 SetupZoneInternalGain(state,
    1372              :                                       thisDXCoil.SecZonePtr,
    1373              :                                       thisDXCoil.Name,
    1374              :                                       DataHeatBalance::IntGainType::SecCoolingDXCoilSingleSpeed,
    1375              :                                       &thisDXCoil.SecCoilSensibleHeatGainRate);
    1376            0 :                 thisDXCoil.IsSecondaryDXCoilInZone = true;
    1377              :             } else {
    1378            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1379            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(19), Alphas(19)));
    1380              :             }
    1381              :         }
    1382              : 
    1383              :     } // end of the Doe2 DX coil loop
    1384              : 
    1385          135 :     if (ErrorsFound) {
    1386            0 :         ShowFatalError(state,
    1387            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    1388              :     }
    1389              : 
    1390              :     // Loop over the Multimode DX Coils and get & load the data
    1391          135 :     CurrentModuleObject = "Coil:Cooling:DX:TwoStageWithHumidityControlMode";
    1392          137 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulModeCoils; ++DXCoilIndex) {
    1393              : 
    1394            2 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1395              :                                                                  CurrentModuleObject,
    1396              :                                                                  DXCoilIndex,
    1397              :                                                                  Alphas,
    1398              :                                                                  NumAlphas,
    1399              :                                                                  Numbers,
    1400              :                                                                  NumNumbers,
    1401              :                                                                  IOStatus,
    1402              :                                                                  lNumericBlanks,
    1403              :                                                                  lAlphaBlanks,
    1404              :                                                                  cAlphaFields,
    1405              :                                                                  cNumericFields);
    1406              : 
    1407            2 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    1408            2 :         ++DXCoilNum;
    1409              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    1410            2 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    1411              : 
    1412            2 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    1413            2 :         thisDXCoil.Name = Alphas(1);
    1414              :         // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
    1415            2 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
    1416            2 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
    1417            2 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    1418            2 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoStageWHumControl;
    1419            2 :         if (lAlphaBlanks(2)) {
    1420            2 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    1421            0 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    1422            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    1423            0 :             ErrorsFound = true;
    1424              :         }
    1425              : 
    1426            2 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    1427            2 :                                                  Alphas(3),
    1428              :                                                  ErrorsFound,
    1429              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
    1430            2 :                                                  Alphas(1),
    1431              :                                                  DataLoopNode::NodeFluidType::Air,
    1432              :                                                  DataLoopNode::ConnectionType::Inlet,
    1433              :                                                  NodeInputManager::CompFluidStream::Primary,
    1434              :                                                  ObjectIsNotParent);
    1435              : 
    1436            4 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    1437            2 :                                                   Alphas(4),
    1438              :                                                   ErrorsFound,
    1439              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoStageWithHumidityControlMode,
    1440            2 :                                                   Alphas(1),
    1441              :                                                   DataLoopNode::NodeFluidType::Air,
    1442              :                                                   DataLoopNode::ConnectionType::Outlet,
    1443              :                                                   NodeInputManager::CompFluidStream::Primary,
    1444              :                                                   ObjectIsNotParent);
    1445              : 
    1446            2 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    1447              : 
    1448              :         // A5; \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
    1449            2 :         if (!lAlphaBlanks(5)) {
    1450            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
    1451            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    1452            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
    1453            0 :                 ErrorsFound = true;
    1454              :             } else {
    1455            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    1456              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    1457              :                                                      {1},                                          // Valid dimensions
    1458              :                                                      RoutineName,                                  // Routine name
    1459              :                                                      CurrentModuleObject,                          // Object Type
    1460              :                                                      thisDXCoil.Name,                              // Object Name
    1461            2 :                                                      cAlphaFields(5));                             // Field Name
    1462              :             }
    1463              :         }
    1464              : 
    1465              :         // Set crankcase heater capacity
    1466            2 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(1);
    1467            2 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    1468            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1469            0 :             ShowContinueError(state, format("...{} must be >= 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
    1470            0 :             ErrorsFound = true;
    1471              :         }
    1472              : 
    1473              :         // Set crankcase heater cutout temperature
    1474            2 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(2);
    1475              : 
    1476              :         //  Number of capacity stages
    1477            2 :         thisDXCoil.NumCapacityStages = Numbers(3);
    1478              :         //  Check if requested number of capacity stages exceeds limits
    1479            2 :         if ((thisDXCoil.NumCapacityStages > MaxCapacityStages) || (thisDXCoil.NumCapacityStages < 1)) {
    1480            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1481            0 :             ShowContinueError(state, format("...illegal {} = {}", cNumericFields(3), thisDXCoil.NumCapacityStages));
    1482            0 :             ShowContinueError(state, format("...Valid range is 1 to {}", MaxCapacityStages));
    1483            0 :             ErrorsFound = true;
    1484              :         }
    1485              : 
    1486              :         //  Number of enhanced dehumidification modes
    1487            2 :         thisDXCoil.NumDehumidModes = Numbers(4);
    1488              :         //  Check if requested number of enhanced dehumidification modes exceeds limits
    1489            2 :         if ((thisDXCoil.NumDehumidModes > MaxDehumidModes) || (thisDXCoil.NumDehumidModes < 0)) {
    1490            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1491            0 :             ShowContinueError(state, format("...illegal {} = {}", cNumericFields(4), thisDXCoil.NumDehumidModes));
    1492            0 :             ShowContinueError(state, format("...Valid range is 0 to {}", MaxDehumidModes));
    1493            0 :             ErrorsFound = true;
    1494              :         }
    1495              : 
    1496              :         //  Set starting alpha index for coil performance inputs
    1497            2 :         AlphaIndex = 6;
    1498              :         // allocate performance modes for numeric field strings used for sizing routine
    1499            4 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(
    1500            2 :             thisDXCoil.NumDehumidModes * 2 + thisDXCoil.NumCapacityStages * 2); // not sure this math is correct, ask MW
    1501              : 
    1502              :         //  Loop through capacity stages and dehumidification modes
    1503            6 :         for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
    1504           12 :             for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
    1505              :                 //  Check if sufficient number of fields entered
    1506            8 :                 if ((AlphaIndex + 1) > NumAlphas) {
    1507            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1508            0 :                     ShowContinueError(state, "...not enough remaining fields for specified Number of Operating Modes.");
    1509            0 :                     ShowContinueError(state, "...Need additional Coil Performance Object Type and Coil Performance Object Name fields.");
    1510            0 :                     ErrorsFound = true;
    1511              :                 } else {
    1512            8 :                     PerfObjectType = Alphas(AlphaIndex);
    1513            8 :                     PerfObjectName = Alphas(AlphaIndex + 1);
    1514            8 :                     PerfModeNum = DehumidModeNum * 2 + CapacityStageNum;
    1515            8 :                     thisDXCoil.CoilPerformanceType(PerfModeNum) = PerfObjectType;
    1516            8 :                     if (Util::SameString(PerfObjectType, "CoilPerformance:DX:Cooling")) {
    1517            8 :                         thisDXCoil.CoilPerformanceType_Num(PerfModeNum) = HVAC::CoilPerfDX_CoolBypassEmpirical;
    1518              :                     } else {
    1519            0 :                         ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1520            0 :                         ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(AlphaIndex), PerfObjectType));
    1521            0 :                         ShowContinueError(state, "Must be \"CoilPerformance:DX:Cooling\".");
    1522            0 :                         ErrorsFound = true;
    1523              :                     }
    1524            8 :                     thisDXCoil.CoilPerformanceName(PerfModeNum) = PerfObjectName;
    1525              :                     // Get for CoilPerformance object
    1526            8 :                     PerfObjectNum = state.dataInputProcessing->inputProcessor->getObjectItemNum(state, PerfObjectType, PerfObjectName);
    1527            8 :                     if (PerfObjectNum > 0) {
    1528              : 
    1529            8 :                         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1530              :                                                                                  PerfObjectType,
    1531              :                                                                                  PerfObjectNum,
    1532              :                                                                                  Alphas2,
    1533              :                                                                                  NumAlphas2,
    1534              :                                                                                  Numbers2,
    1535              :                                                                                  NumNumbers2,
    1536              :                                                                                  IOStatus,
    1537              :                                                                                  lNumericBlanks2,
    1538              :                                                                                  lAlphaBlanks2,
    1539              :                                                                                  cAlphaFields2,
    1540              :                                                                                  cNumericFields2);
    1541              : 
    1542              :                         // allocate performance mode numeric field strings used for sizing routine
    1543            8 :                         state.dataDXCoils->DXCoilNumericFields(DXCoilNum)
    1544            8 :                             .PerfMode(PerfModeNum)
    1545            8 :                             .FieldNames.allocate(NumNumbers2); // use MaxNumbers here??
    1546            8 :                         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(PerfModeNum).FieldNames = cNumericFields2;
    1547              : 
    1548            8 :                         thisDXCoil.RatedTotCap(PerfModeNum) = Numbers2(1);
    1549            8 :                         thisDXCoil.RatedSHR(PerfModeNum) = Numbers2(2);
    1550            8 :                         thisDXCoil.RatedCOP(PerfModeNum) = Numbers2(3);
    1551              :                         // Rated flow is immediately adjusted for bypass fraction if not autosized
    1552            8 :                         thisDXCoil.BypassedFlowFrac(PerfModeNum) = Numbers2(5);
    1553            8 :                         thisDXCoil.RatedAirVolFlowRate(PerfModeNum) = Numbers2(4);
    1554            8 :                         if (thisDXCoil.RatedAirVolFlowRate(PerfModeNum) != AutoSize) {
    1555            0 :                             thisDXCoil.RatedAirVolFlowRate(PerfModeNum) *= (1.0 - thisDXCoil.BypassedFlowFrac(PerfModeNum));
    1556              :                         }
    1557              : 
    1558            8 :                         thisDXCoil.CCapFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(2)); // convert curve name to number
    1559            8 :                         if (thisDXCoil.CCapFTemp(PerfModeNum) == 0) {
    1560            0 :                             if (lAlphaBlanks2(2)) {
    1561            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1562            0 :                                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(2)));
    1563              :                             } else {
    1564            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1565            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(2), Alphas2(2)));
    1566              :                             }
    1567            0 :                             ErrorsFound = true;
    1568              :                         } else {
    1569              :                             // Verify Curve Object, only legal type is BiQuadratic
    1570           24 :                             ErrorsFound |= Curve::CheckCurveDims(state,
    1571            8 :                                                                  thisDXCoil.CCapFTemp(PerfModeNum), // Curve index
    1572              :                                                                  {2},                               // Valid dimensions
    1573              :                                                                  RoutineName,                       // Routine name
    1574              :                                                                  CurrentModuleObject,               // Object Type
    1575              :                                                                  thisDXCoil.Name,                   // Object Name
    1576            8 :                                                                  cAlphaFields2(2));                 // Field Name
    1577              : 
    1578            8 :                             if (!ErrorsFound) {
    1579            8 :                                 checkCurveIsNormalizedToOne(state,
    1580           24 :                                                             std::string{RoutineName} + CurrentModuleObject,
    1581            8 :                                                             thisDXCoil.Name,
    1582            8 :                                                             thisDXCoil.CCapFTemp(PerfModeNum),
    1583            8 :                                                             cAlphaFields2(2),
    1584            8 :                                                             Alphas2(2),
    1585              :                                                             RatedInletWetBulbTemp,
    1586              :                                                             RatedOutdoorAirTemp);
    1587              :                             }
    1588              :                         }
    1589              : 
    1590            8 :                         thisDXCoil.CCapFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(3)); // convert curve name to number
    1591            8 :                         if (thisDXCoil.CCapFFlow(PerfModeNum) == 0) {
    1592            0 :                             if (lAlphaBlanks2(3)) {
    1593            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1594            0 :                                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(3)));
    1595              :                             } else {
    1596            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1597            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(3), Alphas2(3)));
    1598              :                             }
    1599            0 :                             ErrorsFound = true;
    1600              :                         } else {
    1601              :                             // Verify Curve Object, only legal type is Quadratic
    1602           24 :                             ErrorsFound |= Curve::CheckCurveDims(state,
    1603            8 :                                                                  thisDXCoil.CCapFFlow(PerfModeNum), // Curve index
    1604              :                                                                  {1},                               // Valid dimensions
    1605              :                                                                  RoutineName,                       // Routine name
    1606              :                                                                  CurrentModuleObject,               // Object Type
    1607              :                                                                  thisDXCoil.Name,                   // Object Name
    1608            8 :                                                                  cAlphaFields2(3));                 // Field Name
    1609              : 
    1610            8 :                             if (!ErrorsFound) {
    1611            8 :                                 checkCurveIsNormalizedToOne(state,
    1612           24 :                                                             std::string{RoutineName} + CurrentModuleObject,
    1613            8 :                                                             thisDXCoil.Name,
    1614            8 :                                                             thisDXCoil.CCapFFlow(PerfModeNum),
    1615            8 :                                                             cAlphaFields2(3),
    1616            8 :                                                             Alphas2(3),
    1617              :                                                             1.0);
    1618              :                             }
    1619              :                         }
    1620              : 
    1621            8 :                         thisDXCoil.EIRFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(4)); // convert curve name to number
    1622            8 :                         if (thisDXCoil.EIRFTemp(PerfModeNum) == 0) {
    1623            0 :                             if (lAlphaBlanks2(4)) {
    1624            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1625            0 :                                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(4)));
    1626              :                             } else {
    1627            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1628            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(4), Alphas2(4)));
    1629              :                             }
    1630            0 :                             ErrorsFound = true;
    1631              :                         } else {
    1632              :                             // Verify Curve Object, only legal type is BiQuadratic
    1633           24 :                             ErrorsFound |= Curve::CheckCurveDims(state,
    1634            8 :                                                                  thisDXCoil.EIRFTemp(PerfModeNum), // Curve index
    1635              :                                                                  {2},                              // Valid dimensions
    1636              :                                                                  RoutineName,                      // Routine name
    1637              :                                                                  CurrentModuleObject,              // Object Type
    1638              :                                                                  thisDXCoil.Name,                  // Object Name
    1639            8 :                                                                  cAlphaFields2(4));                // Field Name
    1640              : 
    1641            8 :                             if (!ErrorsFound) {
    1642            8 :                                 checkCurveIsNormalizedToOne(state,
    1643           24 :                                                             std::string{RoutineName} + CurrentModuleObject,
    1644            8 :                                                             thisDXCoil.Name,
    1645            8 :                                                             thisDXCoil.EIRFTemp(PerfModeNum),
    1646            8 :                                                             cAlphaFields2(4),
    1647            8 :                                                             Alphas2(4),
    1648              :                                                             RatedInletWetBulbTemp,
    1649              :                                                             RatedOutdoorAirTemp);
    1650              :                             }
    1651              :                         }
    1652              : 
    1653            8 :                         thisDXCoil.EIRFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(5)); // convert curve name to number
    1654            8 :                         if (thisDXCoil.EIRFFlow(PerfModeNum) == 0) {
    1655            0 :                             if (lAlphaBlanks2(5)) {
    1656            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1657            0 :                                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(5)));
    1658              :                             } else {
    1659            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1660            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(5), Alphas2(5)));
    1661              :                             }
    1662            0 :                             ErrorsFound = true;
    1663              :                         } else {
    1664              :                             // Verify Curve Object, only legal type is Quadratic
    1665           24 :                             ErrorsFound |= Curve::CheckCurveDims(state,
    1666            8 :                                                                  thisDXCoil.EIRFFlow(PerfModeNum), // Curve index
    1667              :                                                                  {1},                              // Valid dimensions
    1668              :                                                                  RoutineName,                      // Routine name
    1669              :                                                                  CurrentModuleObject,              // Object Type
    1670              :                                                                  thisDXCoil.Name,                  // Object Name
    1671            8 :                                                                  cAlphaFields2(5));                // Field Name
    1672              : 
    1673            8 :                             if (!ErrorsFound) {
    1674            8 :                                 checkCurveIsNormalizedToOne(state,
    1675           24 :                                                             std::string{RoutineName} + CurrentModuleObject,
    1676            8 :                                                             thisDXCoil.Name,
    1677            8 :                                                             thisDXCoil.EIRFFlow(PerfModeNum),
    1678            8 :                                                             cAlphaFields2(5),
    1679            8 :                                                             Alphas2(5),
    1680              :                                                             1.0);
    1681              :                             }
    1682              :                         }
    1683              : 
    1684            8 :                         thisDXCoil.PLFFPLR(PerfModeNum) = GetCurveIndex(state, Alphas2(6)); // convert curve name to number
    1685            8 :                         if (thisDXCoil.PLFFPLR(PerfModeNum) == 0) {
    1686            0 :                             if (lAlphaBlanks2(6)) {
    1687            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1688            0 :                                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields2(6)));
    1689              :                             } else {
    1690            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1691            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(6), Alphas2(6)));
    1692              :                             }
    1693            0 :                             ErrorsFound = true;
    1694              :                         } else {
    1695              :                             // Verify Curve Object, only legal types are Quadratic or Cubic
    1696           24 :                             ErrorsFound |= Curve::CheckCurveDims(state,
    1697            8 :                                                                  thisDXCoil.PLFFPLR(PerfModeNum), // Curve index
    1698              :                                                                  {1},                             // Valid dimensions
    1699              :                                                                  RoutineName,                     // Routine name
    1700              :                                                                  CurrentModuleObject,             // Object Type
    1701              :                                                                  thisDXCoil.Name,                 // Object Name
    1702            8 :                                                                  cAlphaFields2(6));               // Field Name
    1703              : 
    1704            8 :                             if (!ErrorsFound) {
    1705              :                                 //             Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    1706            8 :                                 MinCurveVal = 999.0;
    1707            8 :                                 MaxCurveVal = -999.0;
    1708            8 :                                 CurveInput = 0.0;
    1709          808 :                                 while (CurveInput <= 1.0) {
    1710          800 :                                     CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(PerfModeNum), CurveInput);
    1711          800 :                                     if (CurveVal < MinCurveVal) {
    1712            8 :                                         MinCurveVal = CurveVal;
    1713            8 :                                         MinCurvePLR = CurveInput;
    1714              :                                     }
    1715          800 :                                     if (CurveVal > MaxCurveVal) {
    1716            8 :                                         MaxCurveVal = CurveVal;
    1717            8 :                                         MaxCurvePLR = CurveInput;
    1718              :                                     }
    1719          800 :                                     CurveInput += 0.01;
    1720              :                                 }
    1721            8 :                                 if (MinCurveVal < 0.7) {
    1722            0 :                                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1723            0 :                                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields2(6), Alphas2(6)));
    1724            0 :                                     ShowContinueError(
    1725              :                                         state,
    1726            0 :                                         format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    1727            0 :                                     ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    1728            0 :                                     Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 0.7);
    1729              :                                 }
    1730              : 
    1731            8 :                                 if (MaxCurveVal > 1.0) {
    1732            0 :                                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1733            0 :                                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields2(6), Alphas2(6)));
    1734            0 :                                     ShowContinueError(
    1735              :                                         state,
    1736            0 :                                         format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    1737            0 :                                     ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    1738            0 :                                     Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 1.0);
    1739              :                                 }
    1740              :                             }
    1741              :                         }
    1742              : 
    1743            8 :                         thisDXCoil.Twet_Rated(PerfModeNum) = Numbers2(6);
    1744            8 :                         thisDXCoil.Gamma_Rated(PerfModeNum) = Numbers2(7);
    1745            8 :                         thisDXCoil.MaxONOFFCyclesperHour(PerfModeNum) = Numbers2(8);
    1746            8 :                         thisDXCoil.LatentCapacityTimeConstant(PerfModeNum) = Numbers2(9);
    1747              :                         // Numbers2 (6) through (9) must all be greater than zero to use the latent capacity degradation model
    1748            8 :                         if ((Numbers2(6) > 0.0 || Numbers2(7) > 0.0 || Numbers2(8) > 0.0 || Numbers2(9) > 0.0) &&
    1749            0 :                             (Numbers2(6) <= 0.0 || Numbers2(7) <= 0.0 || Numbers2(8) <= 0.0 || Numbers2(9) <= 0.0)) {
    1750            0 :                             ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, PerfObjectType, PerfObjectName));
    1751            0 :                             ShowContinueError(state, "...At least one of the four input parameters for the latent capacity degradation model");
    1752            0 :                             ShowContinueError(state,
    1753              :                                               "...is set to zero. Therefore, the latent degradation model will not be used for this simulation.");
    1754              :                         }
    1755              : 
    1756              :                         // outdoor condenser node
    1757            8 :                         if (lAlphaBlanks2(7)) {
    1758            8 :                             thisDXCoil.CondenserInletNodeNum(PerfModeNum) = 0;
    1759              :                         } else {
    1760            0 :                             thisDXCoil.CondenserInletNodeNum(PerfModeNum) =
    1761            0 :                                 GetOnlySingleNode(state,
    1762            0 :                                                   Alphas2(7),
    1763              :                                                   ErrorsFound,
    1764            0 :                                                   (DataLoopNode::ConnectionObjectType)getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC,
    1765            0 :                                                                                                    Util::makeUPPER(PerfObjectType)),
    1766              :                                                   PerfObjectName,
    1767              :                                                   DataLoopNode::NodeFluidType::Air,
    1768              :                                                   DataLoopNode::ConnectionType::OutsideAirReference,
    1769              :                                                   NodeInputManager::CompFluidStream::Primary,
    1770              :                                                   ObjectIsNotParent);
    1771            0 :                             if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(PerfModeNum))) {
    1772            0 :                                 ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, PerfObjectType, PerfObjectName));
    1773            0 :                                 ShowContinueError(state, format("may not be valid {}=\"{}\".", cAlphaFields2(7), Alphas2(7)));
    1774            0 :                                 ShowContinueError(state, "node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
    1775            0 :                                 ShowContinueError(state,
    1776              :                                                   "This node needs to be included in an air system or the coil model will not be valid, and the "
    1777              :                                                   "simulation continues");
    1778              :                             }
    1779              :                         }
    1780            8 :                         if ((Util::SameString(Alphas2(8), "AirCooled")) || lAlphaBlanks2(8)) {
    1781            8 :                             thisDXCoil.CondenserType(PerfModeNum) = DataHeatBalance::RefrigCondenserType::Air;
    1782            0 :                         } else if (Util::SameString(Alphas2(8), "EvaporativelyCooled")) {
    1783            0 :                             thisDXCoil.CondenserType(PerfModeNum) = DataHeatBalance::RefrigCondenserType::Evap;
    1784            0 :                             thisDXCoil.ReportEvapCondVars = true;
    1785              :                         } else {
    1786            0 :                             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1787            0 :                             ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields2(8), Alphas2(8)));
    1788            0 :                             ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
    1789            0 :                             ErrorsFound = true;
    1790              :                         }
    1791              : 
    1792            8 :                         thisDXCoil.EvapCondEffect(PerfModeNum) = Numbers2(10);
    1793            8 :                         if (thisDXCoil.EvapCondEffect(PerfModeNum) < 0.0 || thisDXCoil.EvapCondEffect(PerfModeNum) > 1.0) {
    1794            0 :                             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1795            0 :                             ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields2(10)));
    1796            0 :                             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(10)));
    1797            0 :                             ErrorsFound = true;
    1798              :                         }
    1799              : 
    1800            8 :                         thisDXCoil.EvapCondAirFlow(PerfModeNum) = Numbers2(11);
    1801            8 :                         if (thisDXCoil.EvapCondAirFlow(PerfModeNum) < 0.0 && thisDXCoil.EvapCondAirFlow(PerfModeNum) != AutoSize) {
    1802            0 :                             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1803            0 :                             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields2(11)));
    1804            0 :                             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(11)));
    1805            0 :                             ErrorsFound = true;
    1806              :                         }
    1807              : 
    1808            8 :                         thisDXCoil.EvapCondPumpElecNomPower(PerfModeNum) = Numbers2(12);
    1809            8 :                         if (thisDXCoil.EvapCondPumpElecNomPower(PerfModeNum) < 0.0 && thisDXCoil.EvapCondAirFlow(PerfModeNum) != AutoSize) {
    1810            0 :                             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, PerfObjectType, PerfObjectName));
    1811            0 :                             ShowContinueError(state, format("...{} cannot be less than zero.", cNumericFields2(12)));
    1812            0 :                             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers2(12)));
    1813            0 :                             ErrorsFound = true;
    1814              :                         }
    1815              : 
    1816            8 :                         thisDXCoil.RatedEIR(PerfModeNum) = 1.0 / thisDXCoil.RatedCOP(PerfModeNum);
    1817              : 
    1818              :                         // read in user specified SHR modifier curves
    1819            8 :                         if (!lAlphaBlanks2(9) && NumAlphas2 > 8) {
    1820            0 :                             thisDXCoil.SHRFTemp(PerfModeNum) = GetCurveIndex(state, Alphas2(9)); // convert curve name to number
    1821            0 :                             if (thisDXCoil.SHRFTemp(PerfModeNum) == 0) {
    1822            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1823            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(9), Alphas2(9)));
    1824              :                             } else {
    1825              :                                 // Verify Curve Object, only legal type is BiQuadratic
    1826            0 :                                 ErrorsFound |= Curve::CheckCurveDims(state,
    1827            0 :                                                                      thisDXCoil.SHRFTemp(PerfModeNum), // Curve index
    1828              :                                                                      {2},                              // Valid dimensions
    1829              :                                                                      RoutineName,                      // Routine name
    1830              :                                                                      CurrentModuleObject,              // Object Type
    1831              :                                                                      thisDXCoil.Name,                  // Object Name
    1832            0 :                                                                      cAlphaFields2(9));                // Field Name
    1833              :                             }
    1834              :                         }
    1835              : 
    1836            8 :                         if (!lAlphaBlanks2(10) && NumAlphas2 > 9) {
    1837            0 :                             thisDXCoil.SHRFFlow(PerfModeNum) = GetCurveIndex(state, Alphas2(10)); // convert curve name to number
    1838            0 :                             if (thisDXCoil.SHRFTemp(PerfModeNum) == 0) {
    1839            0 :                                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1840            0 :                                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields2(10), Alphas2(10)));
    1841              :                             } else {
    1842              :                                 // Verify Curve Object, only legal type is BiQuadratic
    1843            0 :                                 ErrorsFound |= Curve::CheckCurveDims(state,
    1844            0 :                                                                      thisDXCoil.SHRFFlow(PerfModeNum), // Curve index
    1845              :                                                                      {1},                              // Valid dimensions
    1846              :                                                                      RoutineName,                      // Routine name
    1847              :                                                                      CurrentModuleObject,              // Object Type
    1848              :                                                                      thisDXCoil.Name,                  // Object Name
    1849            0 :                                                                      cAlphaFields2(10));               // Field Name
    1850              :                             }
    1851              :                         }
    1852            8 :                         if (thisDXCoil.SHRFTemp(PerfModeNum) > 0 && thisDXCoil.SHRFFlow(PerfModeNum) > 0) {
    1853            0 :                             thisDXCoil.UserSHRCurveExists = true;
    1854              :                         } else {
    1855            8 :                             thisDXCoil.UserSHRCurveExists = false;
    1856              :                         }
    1857              : 
    1858              :                     } else { // invalid performance object
    1859            0 :                         ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1860            0 :                         ShowContinueError(state, format("... not found {}=\"{}\".", PerfObjectType, PerfObjectName));
    1861            0 :                         ErrorsFound = true;
    1862              :                     } // end of valid performance object check
    1863            8 :                     AlphaIndex += 2;
    1864              :                 } // end of sufficient number of fields entered check
    1865              :             } // End of multimode DX capacity stages loop
    1866              :             // Warn if inputs entered for unused capacity stages
    1867            4 :             for (CapacityStageNum = (thisDXCoil.NumCapacityStages + 1); CapacityStageNum <= MaxCapacityStages; ++CapacityStageNum) {
    1868            0 :                 if ((AlphaIndex <= NumAlphas) && ((!Alphas(AlphaIndex).empty()) || (!Alphas(AlphaIndex + 1).empty()))) {
    1869            0 :                     ShowWarningError(state, format("{}{}=\"{}\":", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1870            0 :                     ShowContinueError(state, format("...Capacity Stage {} not active. Therefore,{}", CapacityStageNum, cAlphaFields(AlphaIndex)));
    1871            0 :                     ShowContinueError(state, format("... and {} fields will be ignored.", cAlphaFields(AlphaIndex + 1)));
    1872              :                 }
    1873            0 :                 AlphaIndex += 2;
    1874              :             } // End of unused capacity stages loop
    1875              :         } // End of multimode DX dehumidification modes loo
    1876              : 
    1877              :         // Get Water System tank connections
    1878              :         //  A14, \field Name of Water Storage Tank for Supply
    1879            2 :         thisDXCoil.EvapWaterSupplyName = Alphas(14);
    1880            2 :         if (lAlphaBlanks(14)) {
    1881            2 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
    1882              :         } else {
    1883            0 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
    1884            0 :             SetupTankDemandComponent(state,
    1885              :                                      thisDXCoil.Name,
    1886              :                                      CurrentModuleObject,
    1887              :                                      thisDXCoil.EvapWaterSupplyName,
    1888              :                                      ErrorsFound,
    1889            0 :                                      thisDXCoil.EvapWaterSupTankID,
    1890            0 :                                      thisDXCoil.EvapWaterTankDemandARRID);
    1891              :         }
    1892              : 
    1893              :         // A15; \field Name of Water Storage Tank for Condensate Collection
    1894            2 :         thisDXCoil.CondensateCollectName = Alphas(15);
    1895            2 :         if (lAlphaBlanks(15)) {
    1896            2 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    1897              :         } else {
    1898            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    1899            0 :             SetupTankSupplyComponent(state,
    1900              :                                      thisDXCoil.Name,
    1901              :                                      CurrentModuleObject,
    1902              :                                      thisDXCoil.CondensateCollectName,
    1903              :                                      ErrorsFound,
    1904            0 :                                      thisDXCoil.CondensateTankID,
    1905            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    1906              :         }
    1907              : 
    1908              :         // Set minimum OAT for compressor operation
    1909            2 :         thisDXCoil.MinOATCompressor = Numbers(5);
    1910            2 :         if (NumNumbers < 5) {
    1911            0 :             thisDXCoil.MinOATCompressor = minOATCompDXCooling; // input field is after min fields and won't default if field not included
    1912              :         }
    1913              : 
    1914              :         // Basin heater power as a function of temperature must be greater than or equal to 0
    1915            2 :         thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(6);
    1916            2 :         if (Numbers(6) < 0.0) {
    1917            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1918            0 :             ShowContinueError(state, format("...{} must be >= 0.", cNumericFields(6)));
    1919            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(6)));
    1920            0 :             ErrorsFound = true;
    1921              :         }
    1922              : 
    1923            2 :         thisDXCoil.BasinHeaterSetPointTemp = Numbers(7);
    1924            2 :         if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    1925            0 :             if (NumNumbers < 7) {
    1926            0 :                 thisDXCoil.BasinHeaterSetPointTemp = 2.0;
    1927              :             }
    1928            0 :             if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
    1929            0 :                 ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    1930            0 :                 ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(7)));
    1931            0 :                 ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(7)));
    1932              :             }
    1933              :         }
    1934              : 
    1935            2 :         if (!lAlphaBlanks(16)) {
    1936            0 :             if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(16))) == nullptr) {
    1937            0 :                 ShowWarningItemNotFound(
    1938            0 :                     state, eoh, cAlphaFields(16), Alphas(16), "Basin heater will be available to operate throughout the simulation.");
    1939              :             }
    1940              :         }
    1941              : 
    1942              :     } // end of the Multimode DX coil loop
    1943              : 
    1944          135 :     if (ErrorsFound) {
    1945            0 :         ShowFatalError(state,
    1946            0 :                        format("{}Errors found in getting {} input.  Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    1947              :     }
    1948              : 
    1949              :     //************* Read Heat Pump (DX Heating Coil) Input **********
    1950          135 :     CurrentModuleObject = "Coil:Heating:DX:SingleSpeed";
    1951          147 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXHeatingCoils; ++DXCoilIndex) {
    1952              : 
    1953           12 :         ++DXCoilNum;
    1954              : 
    1955           12 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1956              :                                                                  CurrentModuleObject,
    1957              :                                                                  DXCoilIndex,
    1958              :                                                                  Alphas,
    1959              :                                                                  NumAlphas,
    1960              :                                                                  Numbers,
    1961              :                                                                  NumNumbers,
    1962              :                                                                  IOStatus,
    1963              :                                                                  lNumericBlanks,
    1964              :                                                                  lAlphaBlanks,
    1965              :                                                                  cAlphaFields,
    1966              :                                                                  cNumericFields);
    1967              : 
    1968           12 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    1969              :         // allocate single performance mode for numeric field strings used for sizing routine
    1970           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    1971           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    1972           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    1973              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    1974           12 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    1975              : 
    1976           12 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    1977           12 :         thisDXCoil.Name = Alphas(1);
    1978           12 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    1979           12 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatingEmpirical;
    1980           12 :         if (lAlphaBlanks(2)) {
    1981            3 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    1982            9 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    1983            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    1984            0 :             ErrorsFound = true;
    1985              :         }
    1986              : 
    1987           12 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    1988           12 :                                                  Alphas(3),
    1989              :                                                  ErrorsFound,
    1990              :                                                  DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
    1991           12 :                                                  Alphas(1),
    1992              :                                                  DataLoopNode::NodeFluidType::Air,
    1993              :                                                  DataLoopNode::ConnectionType::Inlet,
    1994              :                                                  NodeInputManager::CompFluidStream::Primary,
    1995              :                                                  ObjectIsNotParent);
    1996              : 
    1997           24 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    1998           12 :                                                   Alphas(4),
    1999              :                                                   ErrorsFound,
    2000              :                                                   DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
    2001           12 :                                                   Alphas(1),
    2002              :                                                   DataLoopNode::NodeFluidType::Air,
    2003              :                                                   DataLoopNode::ConnectionType::Outlet,
    2004              :                                                   NodeInputManager::CompFluidStream::Primary,
    2005              :                                                   ObjectIsNotParent);
    2006              : 
    2007           12 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    2008              : 
    2009           12 :         thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
    2010           12 :         if (thisDXCoil.CCapFTemp(1) == 0) {
    2011            0 :             if (lAlphaBlanks(5)) {
    2012            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2013            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
    2014              :             } else {
    2015            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2016            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
    2017              :             }
    2018            0 :             ErrorsFound = true;
    2019              :         } else {
    2020              :             // only legal types are Quadratic, BiQuadratic and Cubic
    2021           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2022           12 :                                                  thisDXCoil.CCapFTemp(1), // Curve index
    2023              :                                                  {1, 2},                  // Valid dimensions  // MULTIPLECURVEDIMS
    2024              :                                                  RoutineName,             // Routine name
    2025              :                                                  CurrentModuleObject,     // Object Type
    2026              :                                                  thisDXCoil.Name,         // Object Name
    2027           12 :                                                  cAlphaFields(5));        // Field Name
    2028              : 
    2029           12 :             if (!ErrorsFound) {
    2030           12 :                 if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
    2031            7 :                     checkCurveIsNormalizedToOne(state,
    2032           21 :                                                 std::string{RoutineName} + CurrentModuleObject,
    2033            7 :                                                 thisDXCoil.Name,
    2034            7 :                                                 thisDXCoil.CCapFTemp(1),
    2035            7 :                                                 cAlphaFields(5),
    2036            7 :                                                 Alphas(5),
    2037              :                                                 RatedOutdoorAirTempHeat);
    2038              :                 } else {
    2039            5 :                     checkCurveIsNormalizedToOne(state,
    2040           15 :                                                 std::string{RoutineName} + CurrentModuleObject,
    2041            5 :                                                 thisDXCoil.Name,
    2042            5 :                                                 thisDXCoil.CCapFTemp(1),
    2043            5 :                                                 cAlphaFields(5),
    2044            5 :                                                 Alphas(5),
    2045              :                                                 RatedInletAirTempHeat,
    2046              :                                                 RatedOutdoorAirTempHeat);
    2047              :                 }
    2048              :             }
    2049              :         }
    2050              : 
    2051           12 :         thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
    2052           12 :         if (thisDXCoil.CCapFFlow(1) == 0) {
    2053            0 :             if (lAlphaBlanks(6)) {
    2054            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2055            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
    2056              :             } else {
    2057            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2058            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
    2059              :             }
    2060            0 :             ErrorsFound = true;
    2061              :         } else {
    2062              :             // Verify Curve Object, only legal type is Quadratic
    2063           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2064           12 :                                                  thisDXCoil.CCapFFlow(1), // Curve index
    2065              :                                                  {1},                     // Valid dimensions
    2066              :                                                  RoutineName,             // Routine name
    2067              :                                                  CurrentModuleObject,     // Object Type
    2068              :                                                  thisDXCoil.Name,         // Object Name
    2069           12 :                                                  cAlphaFields(6));        // Field Name
    2070              : 
    2071           12 :             if (!ErrorsFound) {
    2072           12 :                 checkCurveIsNormalizedToOne(
    2073           48 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
    2074              :             }
    2075              :         }
    2076              : 
    2077           12 :         thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
    2078           12 :         if (thisDXCoil.EIRFTemp(1) == 0) {
    2079            0 :             if (lAlphaBlanks(7)) {
    2080            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2081            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
    2082              :             } else {
    2083            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2084            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
    2085              :             }
    2086            0 :             ErrorsFound = true;
    2087              :         } else {
    2088              :             // only legal types are Quadratic, BiQuadratic and Cubic
    2089           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2090           12 :                                                  thisDXCoil.EIRFTemp(1), // Curve index
    2091              :                                                  {1, 2},                 // Valid dimensions  // MULTIPLECURVEDIMS
    2092              :                                                  RoutineName,            // Routine name
    2093              :                                                  CurrentModuleObject,    // Object Type
    2094              :                                                  thisDXCoil.Name,        // Object Name
    2095           12 :                                                  cAlphaFields(7));       // Field Name
    2096              : 
    2097           12 :             if (!ErrorsFound) {
    2098           12 :                 if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(1))->numDims == 1) {
    2099            7 :                     checkCurveIsNormalizedToOne(state,
    2100           21 :                                                 std::string{RoutineName} + CurrentModuleObject,
    2101            7 :                                                 thisDXCoil.Name,
    2102            7 :                                                 thisDXCoil.EIRFTemp(1),
    2103            7 :                                                 cAlphaFields(7),
    2104            7 :                                                 Alphas(7),
    2105              :                                                 RatedOutdoorAirTempHeat);
    2106              :                 } else {
    2107            5 :                     checkCurveIsNormalizedToOne(state,
    2108           15 :                                                 std::string{RoutineName} + CurrentModuleObject,
    2109            5 :                                                 thisDXCoil.Name,
    2110            5 :                                                 thisDXCoil.EIRFTemp(1),
    2111            5 :                                                 cAlphaFields(7),
    2112            5 :                                                 Alphas(7),
    2113              :                                                 RatedInletAirTempHeat,
    2114              :                                                 RatedOutdoorAirTempHeat);
    2115              :                 }
    2116              :             }
    2117              :         }
    2118              : 
    2119           12 :         thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
    2120           12 :         if (thisDXCoil.EIRFFlow(1) == 0) {
    2121            0 :             if (lAlphaBlanks(8)) {
    2122            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2123            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
    2124              :             } else {
    2125            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2126            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
    2127              :             }
    2128            0 :             ErrorsFound = true;
    2129              :         } else {
    2130              :             // Verify Curve Object, only legal type is Quadratic or Cubic
    2131           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2132           12 :                                                  thisDXCoil.EIRFFlow(1), // Curve index
    2133              :                                                  {1},                    // Valid dimensions
    2134              :                                                  RoutineName,            // Routine name
    2135              :                                                  CurrentModuleObject,    // Object Type
    2136              :                                                  thisDXCoil.Name,        // Object Name
    2137           12 :                                                  cAlphaFields(8));       // Field Name
    2138              : 
    2139           12 :             if (!ErrorsFound) {
    2140           12 :                 checkCurveIsNormalizedToOne(
    2141           48 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
    2142              :             }
    2143              :         }
    2144              : 
    2145           12 :         thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
    2146           12 :         if (thisDXCoil.PLFFPLR(1) == 0) {
    2147            0 :             if (lAlphaBlanks(9)) {
    2148            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2149            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
    2150              :             } else {
    2151            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2152            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
    2153              :             }
    2154            0 :             ErrorsFound = true;
    2155              :         } else {
    2156              :             // Verify Curve Object, only legal types are Quadratic or Cubic
    2157           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2158           12 :                                                  thisDXCoil.PLFFPLR(1), // Curve index
    2159              :                                                  {1},                   // Valid dimensions
    2160              :                                                  RoutineName,           // Routine name
    2161              :                                                  CurrentModuleObject,   // Object Type
    2162              :                                                  thisDXCoil.Name,       // Object Name
    2163           12 :                                                  cAlphaFields(9));      // Field Name
    2164              : 
    2165           12 :             if (!ErrorsFound) {
    2166              :                 //     Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    2167           12 :                 MinCurveVal = 999.0;
    2168           12 :                 MaxCurveVal = -999.0;
    2169           12 :                 CurveInput = 0.0;
    2170         1212 :                 while (CurveInput <= 1.0) {
    2171         1200 :                     CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
    2172         1200 :                     if (CurveVal < MinCurveVal) {
    2173           12 :                         MinCurveVal = CurveVal;
    2174           12 :                         MinCurvePLR = CurveInput;
    2175              :                     }
    2176         1200 :                     if (CurveVal > MaxCurveVal) {
    2177          854 :                         MaxCurveVal = CurveVal;
    2178          854 :                         MaxCurvePLR = CurveInput;
    2179              :                     }
    2180         1200 :                     CurveInput += 0.01;
    2181              :                 }
    2182           12 :                 if (MinCurveVal < 0.7) {
    2183            0 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2184            0 :                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
    2185            0 :                     ShowContinueError(state,
    2186            0 :                                       format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    2187            0 :                     ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    2188            0 :                     Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
    2189              :                 }
    2190              : 
    2191           12 :                 if (MaxCurveVal > 1.0) {
    2192            0 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2193            0 :                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
    2194            0 :                     ShowContinueError(state,
    2195            0 :                                       format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    2196            0 :                     ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    2197            0 :                     Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
    2198              :                 }
    2199              :             }
    2200              :         }
    2201              : 
    2202              :         // Only required for reverse cycle heat pumps
    2203           12 :         thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(10)); // convert curve name to number
    2204              :         // A11; \field Crankcase Heater Capacity Function of Outdoor Temperature Curve Name
    2205           12 :         if (!lAlphaBlanks(11)) {
    2206            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
    2207            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    2208            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(11), Alphas(11)));
    2209            0 :                 ErrorsFound = true;
    2210              :             } else {
    2211            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2212              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    2213              :                                                      {1},                                          // Valid dimensions
    2214              :                                                      RoutineName,                                  // Routine name
    2215              :                                                      CurrentModuleObject,                          // Object Type
    2216              :                                                      thisDXCoil.Name,                              // Object Name
    2217            2 :                                                      cAlphaFields(11));                            // Field Name
    2218              :             }
    2219              :         }
    2220              : 
    2221           12 :         if (Util::SameString(Alphas(12), "ReverseCycle")) {
    2222              : 
    2223            3 :             if (thisDXCoil.DefrostEIRFT == 0) {
    2224            0 :                 if (lAlphaBlanks(10)) {
    2225            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2226            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(10)));
    2227            0 :                     ShowContinueError(state, format("...field is required because {} is \"ReverseCycle\".", cAlphaFields(12)));
    2228              :                 } else {
    2229            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2230            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
    2231              :                 }
    2232            0 :                 ErrorsFound = true;
    2233              :             } else {
    2234              :                 // Verify Curve Object, only legal type is BiQuadratic
    2235            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2236              :                                                      thisDXCoil.DefrostEIRFT, // Curve index
    2237              :                                                      {2},                     // Valid dimensions
    2238              :                                                      RoutineName,             // Routine name
    2239              :                                                      CurrentModuleObject,     // Object Type
    2240              :                                                      thisDXCoil.Name,         // Object Name
    2241            3 :                                                      cAlphaFields(10));       // Field Name
    2242              : 
    2243            3 :                 if (!ErrorsFound) {
    2244            3 :                     checkCurveIsNormalizedToOne(state,
    2245            9 :                                                 std::string{RoutineName} + CurrentModuleObject,
    2246            3 :                                                 thisDXCoil.Name,
    2247              :                                                 thisDXCoil.DefrostEIRFT,
    2248            3 :                                                 cAlphaFields(10),
    2249            3 :                                                 Alphas(10),
    2250              :                                                 RatedInletAirTempHeat,
    2251              :                                                 RatedOutdoorAirTempHeat);
    2252              :                 }
    2253              :             }
    2254              :         }
    2255              : 
    2256           12 :         if (Util::SameString(Alphas(12), "ReverseCycle")) {
    2257            3 :             thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
    2258              :         }
    2259           12 :         if (Util::SameString(Alphas(12), "Resistive")) {
    2260            9 :             thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
    2261              :         }
    2262              : 
    2263           12 :         if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
    2264            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2265            0 :             ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(12), Alphas(12)));
    2266            0 :             ShowContinueError(state, "...valid values for this field are ReverseCycle or Resistive.");
    2267            0 :             ErrorsFound = true;
    2268              :         }
    2269              : 
    2270           12 :         if (Util::SameString(Alphas(13), "Timed")) {
    2271           11 :             thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
    2272              :         }
    2273           12 :         if (Util::SameString(Alphas(13), "OnDemand")) {
    2274            1 :             thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
    2275              :         }
    2276           12 :         if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
    2277            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2278            0 :             ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(13), Alphas(13)));
    2279            0 :             ShowContinueError(state, "...valid values for this field are Timed or OnDemand.");
    2280            0 :             ErrorsFound = true;
    2281              :         }
    2282              : 
    2283           12 :         thisDXCoil.RatedSHR(1) = 1.0;
    2284           12 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    2285           12 :         thisDXCoil.RatedCOP(1) = Numbers(2);
    2286           12 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
    2287           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(4);
    2288           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(5);
    2289              : 
    2290              :         // Set minimum OAT for heat pump compressor operation
    2291           12 :         thisDXCoil.MinOATCompressor = Numbers(6);
    2292              : 
    2293           12 :         thisDXCoil.OATempCompressorOn = Numbers(7);
    2294              : 
    2295           12 :         if (lNumericBlanks(7) || lNumericBlanks(6)) { //??TBD:BPS 6 or 5 | 7 or 6
    2296           12 :             thisDXCoil.OATempCompressorOnOffBlank = true;
    2297              :         } else {
    2298            0 :             thisDXCoil.OATempCompressorOnOffBlank = false;
    2299              :         }
    2300              : 
    2301           12 :         if (thisDXCoil.OATempCompressorOn < thisDXCoil.MinOATCompressor) {
    2302            3 :             thisDXCoil.OATempCompressorOn = thisDXCoil.MinOATCompressor;
    2303              :         }
    2304              : 
    2305              :         // Set maximum outdoor temp for defrost to occur
    2306           12 :         thisDXCoil.MaxOATDefrost = Numbers(8);
    2307              : 
    2308              :         // Set crankcase heater capacity
    2309           12 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(9);
    2310           12 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    2311            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2312            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(8)));
    2313            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(9)));
    2314            0 :             ErrorsFound = true;
    2315              :         }
    2316              : 
    2317              :         // Set crankcase heater cutout temperature
    2318           12 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(10);
    2319              : 
    2320              :         // Set defrost time period
    2321           12 :         thisDXCoil.DefrostTime = Numbers(11);
    2322           12 :         if (thisDXCoil.DefrostTime == 0.0 && thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
    2323            0 :             ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2324            0 :             ShowContinueError(state, format("...{} = 0.0 for defrost control = TIMED.", cNumericFields(11)));
    2325              :         }
    2326              : 
    2327              :         // Set defrost capacity (for resistive defrost)
    2328           12 :         thisDXCoil.DefrostCapacity = Numbers(12);
    2329           12 :         if (thisDXCoil.DefrostCapacity == 0.0 && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
    2330            0 :             ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2331            0 :             ShowContinueError(state, format("...{} = 0.0 for defrost strategy = RESISTIVE.", cNumericFields(12)));
    2332              :         }
    2333              : 
    2334              :         // Set Region number for calculating HSPF
    2335           12 :         thisDXCoil.RegionNum = Numbers(13);
    2336              : 
    2337           12 :         if (lNumericBlanks(13)) {
    2338           11 :             thisDXCoil.RegionNum = 4;
    2339              :         }
    2340              : 
    2341           12 :         thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
    2342              : 
    2343              :         // A14 is optional evaporator node name
    2344           12 :         if (lAlphaBlanks(14)) {
    2345           12 :             thisDXCoil.CondenserInletNodeNum(1) = 0;
    2346              :         } else {
    2347            0 :             thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
    2348            0 :                                                                     Alphas(14),
    2349              :                                                                     ErrorsFound,
    2350              :                                                                     DataLoopNode::ConnectionObjectType::CoilHeatingDXSingleSpeed,
    2351            0 :                                                                     thisDXCoil.Name,
    2352              :                                                                     DataLoopNode::NodeFluidType::Air,
    2353              :                                                                     DataLoopNode::ConnectionType::OutsideAirReference,
    2354              :                                                                     NodeInputManager::CompFluidStream::Primary,
    2355              :                                                                     ObjectIsNotParent);
    2356              :             // warn if not an outdoor node, but allow
    2357            0 :             if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
    2358            0 :                 ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2359            0 :                 ShowContinueError(
    2360              :                     state,
    2361            0 :                     format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(14), Alphas(14)));
    2362            0 :                 ShowContinueError(
    2363              :                     state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
    2364              :             }
    2365              :         }
    2366              : 
    2367              :         // A14, \field Zone Name for Evaporator Placement
    2368           12 :         if (!lAlphaBlanks(15) && NumAlphas > 14) {
    2369            0 :             thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(15), state.dataHeatBal->Zone);
    2370            0 :             if (thisDXCoil.SecZonePtr > 0) {
    2371            0 :                 SetupZoneInternalGain(state,
    2372              :                                       thisDXCoil.SecZonePtr,
    2373              :                                       thisDXCoil.Name,
    2374              :                                       DataHeatBalance::IntGainType::SecHeatingDXCoilSingleSpeed,
    2375              :                                       &thisDXCoil.SecCoilSensibleHeatRemovalRate,
    2376              :                                       nullptr,
    2377              :                                       nullptr,
    2378              :                                       &thisDXCoil.SecCoilLatentHeatRemovalRate);
    2379            0 :                 thisDXCoil.IsSecondaryDXCoilInZone = true;
    2380              :             } else {
    2381            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2382            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15), Alphas(15)));
    2383              :             }
    2384              :         }
    2385           12 :         if (thisDXCoil.SecZonePtr > 0) {
    2386              :             // N14, \field Secondary Coil Air Flow Rate
    2387            0 :             if (!lNumericBlanks(13)) {
    2388            0 :                 thisDXCoil.SecCoilAirFlow = Numbers(14);
    2389              :             }
    2390              :             // N15, \field Secondary Coil Fan Flow Scaling Factor
    2391            0 :             if (!lNumericBlanks(15)) {
    2392            0 :                 thisDXCoil.SecCoilAirFlowScalingFactor = Numbers(15);
    2393              :             }
    2394              :             // N16, \field Nominal Sensible Heat Ratio of Secondary Coil
    2395            0 :             if (!lNumericBlanks(16)) {
    2396            0 :                 thisDXCoil.SecCoilRatedSHR = Numbers(16);
    2397              :             } else {
    2398            0 :                 thisDXCoil.SecCoilRatedSHR = 1.0;
    2399              :             }
    2400              :             // A16, \field Sensible Heat Ratio Modifier Function of Temperature Curve Name
    2401            0 :             if (!lAlphaBlanks(16)) {
    2402            0 :                 thisDXCoil.SecCoilSHRFT = GetCurveIndex(state, Alphas(16));
    2403            0 :                 if (thisDXCoil.SecCoilSHRFT == 0) {
    2404            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2405            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
    2406              :                 }
    2407              :             }
    2408              :             // A17; \field Sensible Heat Ratio Function of Flow Fraction Curve Name
    2409            0 :             if (!lAlphaBlanks(17)) {
    2410            0 :                 thisDXCoil.SecCoilSHRFF = GetCurveIndex(state, Alphas(17));
    2411            0 :                 if (thisDXCoil.SecCoilSHRFF == 0) {
    2412            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2413            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
    2414              :                 }
    2415              :             }
    2416              :         }
    2417              : 
    2418              :     } // end of the DX heating coil loop
    2419              : 
    2420          135 :     if (ErrorsFound) {
    2421            0 :         ShowFatalError(state,
    2422            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    2423              :     }
    2424              : 
    2425          135 :     CurrentModuleObject = "Coil:Cooling:DX:TwoSpeed";
    2426          147 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoils; ++DXCoilIndex) {
    2427              : 
    2428           12 :         ++DXCoilNum;
    2429              : 
    2430           12 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    2431              :                                                                  CurrentModuleObject,
    2432              :                                                                  DXCoilIndex,
    2433              :                                                                  Alphas,
    2434              :                                                                  NumAlphas,
    2435              :                                                                  Numbers,
    2436              :                                                                  NumNumbers,
    2437              :                                                                  IOStatus,
    2438              :                                                                  lNumericBlanks,
    2439              :                                                                  lAlphaBlanks,
    2440              :                                                                  cAlphaFields,
    2441              :                                                                  cNumericFields);
    2442              : 
    2443           12 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    2444              : 
    2445              :         // allocate single performance mode for numeric field strings used for sizing routine
    2446           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    2447           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    2448           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    2449              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    2450           12 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    2451              : 
    2452           12 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    2453           12 :         thisDXCoil.Name = Alphas(1);
    2454              :         // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
    2455           12 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
    2456           12 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
    2457           12 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    2458           12 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_CoolingTwoSpeed;
    2459           12 :         if (lAlphaBlanks(2)) {
    2460            2 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    2461           10 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    2462            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    2463            0 :             ErrorsFound = true;
    2464              :         }
    2465           12 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    2466           12 :         thisDXCoil.RatedSHR(1) = Numbers(2);
    2467           12 :         thisDXCoil.RatedCOP(1) = Numbers(3);
    2468           12 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(4);
    2469              : 
    2470           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate(1) = Numbers(5);
    2471           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1) = Numbers(6);
    2472              : 
    2473           12 :         if (!lNumericBlanks(7)) {
    2474            5 :             thisDXCoil.InternalStaticPressureDrop = Numbers(7);
    2475            5 :             thisDXCoil.RateWithInternalStaticAndFanObject = true;
    2476              :         } else {
    2477            7 :             thisDXCoil.InternalStaticPressureDrop = -999.0;
    2478            7 :             thisDXCoil.RateWithInternalStaticAndFanObject = false;
    2479              :         }
    2480              : 
    2481           12 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    2482           12 :                                                  Alphas(3),
    2483              :                                                  ErrorsFound,
    2484              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
    2485           12 :                                                  Alphas(1),
    2486              :                                                  DataLoopNode::NodeFluidType::Air,
    2487              :                                                  DataLoopNode::ConnectionType::Inlet,
    2488              :                                                  NodeInputManager::CompFluidStream::Primary,
    2489              :                                                  ObjectIsNotParent);
    2490              : 
    2491           24 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    2492           12 :                                                   Alphas(4),
    2493              :                                                   ErrorsFound,
    2494              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
    2495           12 :                                                   Alphas(1),
    2496              :                                                   DataLoopNode::NodeFluidType::Air,
    2497              :                                                   DataLoopNode::ConnectionType::Outlet,
    2498              :                                                   NodeInputManager::CompFluidStream::Primary,
    2499              :                                                   ObjectIsNotParent);
    2500              : 
    2501           12 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    2502              : 
    2503           12 :         thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(5)); // convert curve name to number
    2504           12 :         if (thisDXCoil.CCapFTemp(1) == 0) {
    2505            0 :             if (lAlphaBlanks(5)) {
    2506            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2507            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
    2508              :             } else {
    2509            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2510            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
    2511              :             }
    2512            0 :             ErrorsFound = true;
    2513              :         } else {
    2514              :             // Verify Curve Object, only legal type is BiQuadratic
    2515           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2516           12 :                                                  thisDXCoil.CCapFTemp(1), // Curve index
    2517              :                                                  {2},                     // Valid dimensions
    2518              :                                                  RoutineName,             // Routine name
    2519              :                                                  CurrentModuleObject,     // Object Type
    2520              :                                                  thisDXCoil.Name,         // Object Name
    2521           12 :                                                  cAlphaFields(5));        // Field Name
    2522              : 
    2523           12 :             if (!ErrorsFound) {
    2524           12 :                 checkCurveIsNormalizedToOne(state,
    2525           36 :                                             std::string{RoutineName} + CurrentModuleObject,
    2526           12 :                                             thisDXCoil.Name,
    2527           12 :                                             thisDXCoil.CCapFTemp(1),
    2528           12 :                                             cAlphaFields(5),
    2529           12 :                                             Alphas(5),
    2530              :                                             RatedInletWetBulbTemp,
    2531              :                                             RatedOutdoorAirTemp);
    2532              :             }
    2533              :         }
    2534              : 
    2535           12 :         thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
    2536           12 :         if (thisDXCoil.CCapFFlow(1) == 0) {
    2537            0 :             if (lAlphaBlanks(6)) {
    2538            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2539            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
    2540              :             } else {
    2541            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2542            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
    2543              :             }
    2544            0 :             ErrorsFound = true;
    2545              :         } else {
    2546              :             // Verify Curve Object, only legal type is Quadratic
    2547           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2548           12 :                                                  thisDXCoil.CCapFFlow(1), // Curve index
    2549              :                                                  {1},                     // Valid dimensions
    2550              :                                                  RoutineName,             // Routine name
    2551              :                                                  CurrentModuleObject,     // Object Type
    2552              :                                                  thisDXCoil.Name,         // Object Name
    2553           12 :                                                  cAlphaFields(6));        // Field Name
    2554              : 
    2555           12 :             if (!ErrorsFound) {
    2556           12 :                 checkCurveIsNormalizedToOne(
    2557           48 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
    2558              :             }
    2559              :         }
    2560              : 
    2561           12 :         thisDXCoil.EIRFTemp(1) = GetCurveIndex(state, Alphas(7)); // convert curve name to number
    2562           12 :         if (thisDXCoil.EIRFTemp(1) == 0) {
    2563            0 :             if (lAlphaBlanks(7)) {
    2564            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2565            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(7)));
    2566              :             } else {
    2567            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2568            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
    2569              :             }
    2570            0 :             ErrorsFound = true;
    2571              :         } else {
    2572              :             // Verify Curve Object, only legal type is BiQuadratic
    2573           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2574           12 :                                                  thisDXCoil.EIRFTemp(1), // Curve index
    2575              :                                                  {2},                    // Valid dimensions
    2576              :                                                  RoutineName,            // Routine name
    2577              :                                                  CurrentModuleObject,    // Object Type
    2578              :                                                  thisDXCoil.Name,        // Object Name
    2579           12 :                                                  cAlphaFields(7));       // Field Name
    2580              : 
    2581           12 :             if (!ErrorsFound) {
    2582           12 :                 checkCurveIsNormalizedToOne(state,
    2583           36 :                                             std::string{RoutineName} + CurrentModuleObject,
    2584           12 :                                             thisDXCoil.Name,
    2585           12 :                                             thisDXCoil.EIRFTemp(1),
    2586           12 :                                             cAlphaFields(7),
    2587           12 :                                             Alphas(7),
    2588              :                                             RatedInletWetBulbTemp,
    2589              :                                             RatedOutdoorAirTemp);
    2590              :             }
    2591              :         }
    2592              : 
    2593           12 :         thisDXCoil.EIRFFlow(1) = GetCurveIndex(state, Alphas(8)); // convert curve name to number
    2594           12 :         if (thisDXCoil.EIRFFlow(1) == 0) {
    2595            0 :             if (lAlphaBlanks(8)) {
    2596            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2597            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(8)));
    2598              :             } else {
    2599            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2600            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
    2601              :             }
    2602            0 :             ErrorsFound = true;
    2603              :         } else {
    2604              :             // Verify Curve Object, only legal type is Quadratic
    2605           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2606           12 :                                                  thisDXCoil.EIRFFlow(1), // Curve index
    2607              :                                                  {1},                    // Valid dimensions
    2608              :                                                  RoutineName,            // Routine name
    2609              :                                                  CurrentModuleObject,    // Object Type
    2610              :                                                  thisDXCoil.Name,        // Object Name
    2611           12 :                                                  cAlphaFields(8));       // Field Name
    2612              : 
    2613           12 :             if (!ErrorsFound) {
    2614           12 :                 checkCurveIsNormalizedToOne(
    2615           48 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.EIRFFlow(1), cAlphaFields(8), Alphas(8), 1.0);
    2616              :             }
    2617              :         }
    2618              : 
    2619           12 :         thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(9)); // convert curve name to number
    2620           12 :         if (thisDXCoil.PLFFPLR(1) == 0) {
    2621            0 :             if (lAlphaBlanks(9)) {
    2622            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2623            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(9)));
    2624              :             } else {
    2625            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2626            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
    2627              :             }
    2628            0 :             ErrorsFound = true;
    2629              :         } else {
    2630              :             // Verify Curve Object, only legal types are Quadratic or Cubic
    2631           36 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2632           12 :                                                  thisDXCoil.PLFFPLR(1), // Curve index
    2633              :                                                  {1},                   // Valid dimensions
    2634              :                                                  RoutineName,           // Routine name
    2635              :                                                  CurrentModuleObject,   // Object Type
    2636              :                                                  thisDXCoil.Name,       // Object Name
    2637           12 :                                                  cAlphaFields(9));      // Field Name
    2638              : 
    2639           12 :             if (!ErrorsFound) {
    2640              :                 //     Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    2641           12 :                 MinCurveVal = 999.0;
    2642           12 :                 MaxCurveVal = -999.0;
    2643           12 :                 CurveInput = 0.0;
    2644         1212 :                 while (CurveInput <= 1.0) {
    2645         1200 :                     CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
    2646         1200 :                     if (CurveVal < MinCurveVal) {
    2647           12 :                         MinCurveVal = CurveVal;
    2648           12 :                         MinCurvePLR = CurveInput;
    2649              :                     }
    2650         1200 :                     if (CurveVal > MaxCurveVal) {
    2651         1052 :                         MaxCurveVal = CurveVal;
    2652         1052 :                         MaxCurvePLR = CurveInput;
    2653              :                     }
    2654         1200 :                     CurveInput += 0.01;
    2655              :                 }
    2656           12 :                 if (MinCurveVal < 0.7) {
    2657            0 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2658            0 :                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
    2659            0 :                     ShowContinueError(state,
    2660            0 :                                       format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    2661            0 :                     ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    2662            0 :                     Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
    2663              :                 }
    2664              : 
    2665           12 :                 if (MaxCurveVal > 1.0) {
    2666            0 :                     ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2667            0 :                     ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), Alphas(9)));
    2668            0 :                     ShowContinueError(state,
    2669            0 :                                       format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    2670            0 :                     ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    2671            0 :                     Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
    2672              :                 }
    2673              :             }
    2674              :         }
    2675              : 
    2676           12 :         thisDXCoil.RatedEIR(1) = 1.0 / thisDXCoil.RatedCOP(1);
    2677              : 
    2678           12 :         thisDXCoil.RatedTotCap2 = Numbers(8);
    2679           12 :         thisDXCoil.RatedSHR2 = Numbers(9);
    2680           12 :         thisDXCoil.RatedCOP2 = Numbers(10);
    2681           12 :         thisDXCoil.RatedAirVolFlowRate2 = Numbers(11);
    2682              : 
    2683           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate_LowSpeed(1) = Numbers(12);
    2684           12 :         thisDXCoil.FanPowerPerEvapAirFlowRate_2023_LowSpeed(1) = Numbers(13);
    2685              : 
    2686           12 :         if (lNumericBlanks(14)) {
    2687           11 :             thisDXCoil.MinOATCompressor = -25.0;
    2688              :         } else {
    2689            1 :             thisDXCoil.MinOATCompressor = Numbers(14);
    2690              :         }
    2691              : 
    2692           12 :         thisDXCoil.CCapFTemp2 = GetCurveIndex(state, Alphas(10)); // convert curve name to number
    2693           12 :         if (thisDXCoil.CCapFTemp2 == 0) {
    2694            0 :             if (lAlphaBlanks(10)) {
    2695            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2696            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(10)));
    2697              :             } else {
    2698            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2699            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
    2700              :             }
    2701            0 :             ErrorsFound = true;
    2702              :         } else {
    2703              :             // Verify Curve Object, only legal type is BiQuadratic
    2704           24 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2705              :                                                  thisDXCoil.CCapFTemp2, // Curve index
    2706              :                                                  {2},                   // Valid dimensions
    2707              :                                                  RoutineName,           // Routine name
    2708              :                                                  CurrentModuleObject,   // Object Type
    2709              :                                                  thisDXCoil.Name,       // Object Name
    2710           12 :                                                  cAlphaFields(10));     // Field Name
    2711              : 
    2712           12 :             if (!ErrorsFound) {
    2713           12 :                 checkCurveIsNormalizedToOne(state,
    2714           36 :                                             std::string{RoutineName} + CurrentModuleObject,
    2715           12 :                                             thisDXCoil.Name,
    2716              :                                             thisDXCoil.CCapFTemp2,
    2717           12 :                                             cAlphaFields(10),
    2718           12 :                                             Alphas(10),
    2719              :                                             RatedInletWetBulbTemp,
    2720              :                                             RatedOutdoorAirTemp);
    2721              :             }
    2722              :         }
    2723              : 
    2724           12 :         thisDXCoil.EIRFTemp2 = GetCurveIndex(state, Alphas(11)); // convert curve name to number
    2725           12 :         if (thisDXCoil.EIRFTemp2 == 0) {
    2726            0 :             if (lAlphaBlanks(11)) {
    2727            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2728            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(11)));
    2729              :             } else {
    2730            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2731            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
    2732              :             }
    2733            0 :             ErrorsFound = true;
    2734              :         } else {
    2735              :             // Verify Curve Object, only legal type is BiQuadratic
    2736           24 :             ErrorsFound |= Curve::CheckCurveDims(state,
    2737              :                                                  thisDXCoil.EIRFTemp2, // Curve index
    2738              :                                                  {2},                  // Valid dimensions
    2739              :                                                  RoutineName,          // Routine name
    2740              :                                                  CurrentModuleObject,  // Object Type
    2741              :                                                  thisDXCoil.Name,      // Object Name
    2742           12 :                                                  cAlphaFields(11));    // Field Name
    2743              : 
    2744           12 :             if (!ErrorsFound) {
    2745           12 :                 checkCurveIsNormalizedToOne(state,
    2746           36 :                                             std::string{RoutineName} + CurrentModuleObject,
    2747           12 :                                             thisDXCoil.Name,
    2748              :                                             thisDXCoil.EIRFTemp2,
    2749           12 :                                             cAlphaFields(11),
    2750           12 :                                             Alphas(11),
    2751              :                                             RatedInletWetBulbTemp,
    2752              :                                             RatedOutdoorAirTemp);
    2753              :             }
    2754              :         }
    2755              : 
    2756              :         // outdoor condenser node
    2757           12 :         if (lAlphaBlanks(12)) {
    2758            6 :             thisDXCoil.CondenserInletNodeNum(1) = 0;
    2759              :         } else {
    2760           12 :             thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
    2761            6 :                                                                     Alphas(12),
    2762              :                                                                     ErrorsFound,
    2763              :                                                                     DataLoopNode::ConnectionObjectType::CoilCoolingDXTwoSpeed,
    2764            6 :                                                                     thisDXCoil.Name,
    2765              :                                                                     DataLoopNode::NodeFluidType::Air,
    2766              :                                                                     DataLoopNode::ConnectionType::OutsideAirReference,
    2767              :                                                                     NodeInputManager::CompFluidStream::Primary,
    2768              :                                                                     ObjectIsNotParent);
    2769            6 :             if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
    2770            4 :                 ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2771            8 :                 ShowContinueError(
    2772              :                     state,
    2773            8 :                     format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(12), Alphas(12)));
    2774           12 :                 ShowContinueError(
    2775              :                     state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
    2776              :             }
    2777              :         }
    2778              : 
    2779           12 :         if ((Util::SameString(Alphas(13), "AirCooled")) || lAlphaBlanks(13)) {
    2780           10 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
    2781            2 :         } else if (Util::SameString(Alphas(13), "EvaporativelyCooled")) {
    2782            2 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
    2783            2 :             thisDXCoil.ReportEvapCondVars = true;
    2784              :         } else {
    2785            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2786            0 :             ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(13), Alphas(13)));
    2787            0 :             ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
    2788            0 :             ErrorsFound = true;
    2789              :         }
    2790              : 
    2791           12 :         thisDXCoil.EvapCondEffect(1) = Numbers(15);
    2792           12 :         if (thisDXCoil.EvapCondEffect(1) < 0.0 || thisDXCoil.EvapCondEffect(1) > 1.0) {
    2793            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2794            0 :             ShowContinueError(state, format("...{} cannot be < 0.0 or > 1.0.", cNumericFields(15)));
    2795            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(15)));
    2796            0 :             ErrorsFound = true;
    2797              :         }
    2798              : 
    2799           12 :         thisDXCoil.EvapCondAirFlow(1) = Numbers(16);
    2800           12 :         if (thisDXCoil.EvapCondAirFlow(1) < 0.0 && thisDXCoil.EvapCondAirFlow(1) != AutoSize) {
    2801            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2802            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(16)));
    2803            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(16)));
    2804            0 :             ErrorsFound = true;
    2805              :         }
    2806              : 
    2807           12 :         thisDXCoil.EvapCondPumpElecNomPower(1) = Numbers(17);
    2808           12 :         if (thisDXCoil.EvapCondPumpElecNomPower(1) < 0.0 && thisDXCoil.EvapCondPumpElecNomPower(1) != AutoSize) {
    2809            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2810            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(17)));
    2811            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(17)));
    2812            0 :             ErrorsFound = true;
    2813              :         }
    2814              : 
    2815           12 :         thisDXCoil.EvapCondEffect2 = Numbers(18);
    2816           12 :         if (thisDXCoil.EvapCondEffect2 < 0.0 || thisDXCoil.EvapCondEffect2 > 1.0) {
    2817            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2818            0 :             ShowContinueError(state, format("...{} cannot be cannot be < 0.0 or > 1.0.", cNumericFields(18)));
    2819            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(18)));
    2820            0 :             ErrorsFound = true;
    2821              :         }
    2822              : 
    2823           12 :         thisDXCoil.EvapCondAirFlow2 = Numbers(19);
    2824           12 :         if (thisDXCoil.EvapCondAirFlow2 < 0.0 && thisDXCoil.EvapCondAirFlow2 != AutoSize) {
    2825            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2826            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(19)));
    2827            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(19)));
    2828            0 :             ErrorsFound = true;
    2829              :         }
    2830              : 
    2831           12 :         thisDXCoil.EvapCondPumpElecNomPower2 = Numbers(20);
    2832           12 :         if (thisDXCoil.EvapCondPumpElecNomPower2 < 0.0 && thisDXCoil.EvapCondPumpElecNomPower2 != AutoSize) {
    2833            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2834            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(20)));
    2835            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(20)));
    2836            0 :             ErrorsFound = true;
    2837              :         }
    2838              : 
    2839           12 :         thisDXCoil.RatedEIR2 = 1.0 / thisDXCoil.RatedCOP2;
    2840              : 
    2841              :         // Get Water System tank connections
    2842              :         //  A14, \field Name of Water Storage Tank for Supply
    2843           12 :         thisDXCoil.EvapWaterSupplyName = Alphas(14);
    2844           12 :         if (lAlphaBlanks(14)) {
    2845           12 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
    2846              :         } else {
    2847            0 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
    2848            0 :             SetupTankDemandComponent(state,
    2849              :                                      thisDXCoil.Name,
    2850              :                                      CurrentModuleObject,
    2851              :                                      thisDXCoil.EvapWaterSupplyName,
    2852              :                                      ErrorsFound,
    2853            0 :                                      thisDXCoil.EvapWaterSupTankID,
    2854            0 :                                      thisDXCoil.EvapWaterTankDemandARRID);
    2855              :         }
    2856              : 
    2857              :         // A15; \field Name of Water Storage Tank for Condensate Collection
    2858           12 :         thisDXCoil.CondensateCollectName = Alphas(15);
    2859           12 :         if (lAlphaBlanks(15)) {
    2860           12 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    2861              :         } else {
    2862            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    2863            0 :             SetupTankSupplyComponent(state,
    2864              :                                      thisDXCoil.Name,
    2865              :                                      CurrentModuleObject,
    2866              :                                      thisDXCoil.CondensateCollectName,
    2867              :                                      ErrorsFound,
    2868            0 :                                      thisDXCoil.CondensateTankID,
    2869            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    2870              :         }
    2871              : 
    2872              :         // Basin heater power as a function of temperature must be greater than or equal to 0
    2873           12 :         thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(21);
    2874           12 :         if (Numbers(21) < 0.0) {
    2875            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2876            0 :             ShowContinueError(state, format("...{} must be >= 0.0.", cNumericFields(21)));
    2877            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(21)));
    2878            0 :             ErrorsFound = true;
    2879              :         }
    2880              : 
    2881           12 :         thisDXCoil.BasinHeaterSetPointTemp = Numbers(22);
    2882           12 :         if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    2883            4 :             if (NumNumbers < 22) {
    2884            0 :                 thisDXCoil.BasinHeaterSetPointTemp = 2.0;
    2885              :             }
    2886            4 :             if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
    2887            0 :                 ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2888            0 :                 ShowContinueError(state, format("...{} is < 2 {{C}}. Freezing could occur.", cNumericFields(22)));
    2889            0 :                 ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(22)));
    2890              :             }
    2891              :         }
    2892              : 
    2893           12 :         if (!lAlphaBlanks(16)) {
    2894            1 :             if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(16))) == nullptr) {
    2895            2 :                 ShowWarningItemNotFound(
    2896            1 :                     state, eoh, cAlphaFields(16), Alphas(16), "Basin heater will be available to operate throughout the simulation.");
    2897              :             }
    2898              :         }
    2899              : 
    2900           12 :         if (!lAlphaBlanks(17) && NumAlphas > 16) {
    2901            0 :             thisDXCoil.SHRFTemp(1) = GetCurveIndex(state, Alphas(17)); // convert curve name to number
    2902              :             // DXCoil(DXCoilNum)%SHRFTemp2 = DXCoil(DXCoilNum)%SHRFTemp(1)
    2903            0 :             if (thisDXCoil.SHRFTemp(1) == 0) {
    2904            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2905            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
    2906              :             } else {
    2907              :                 // Verify Curve Object, only legal type is BiQuadratic
    2908            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2909            0 :                                                      thisDXCoil.SHRFTemp(1), // Curve index
    2910              :                                                      {2},                    // Valid dimensions
    2911              :                                                      RoutineName,            // Routine name
    2912              :                                                      CurrentModuleObject,    // Object Type
    2913              :                                                      thisDXCoil.Name,        // Object Name
    2914            0 :                                                      cAlphaFields(17));      // Field Name
    2915              :             }
    2916              :         }
    2917              : 
    2918           12 :         if (!lAlphaBlanks(18) && NumAlphas > 17) {
    2919            0 :             thisDXCoil.SHRFFlow(1) = GetCurveIndex(state, Alphas(18)); // convert curve name to number
    2920              :             // DXCoil(DXCoilNum)%SHRFFlow2 = DXCoil(DXCoilNum)%SHRFFlow(1)
    2921            0 :             if (thisDXCoil.SHRFFlow(1) == 0) {
    2922            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2923            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(18), Alphas(18)));
    2924              :             } else {
    2925              :                 // Verify Curve Object, only legal type is BiQuadratic
    2926            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2927            0 :                                                      thisDXCoil.SHRFFlow(1), // Curve index
    2928              :                                                      {1},                    // Valid dimensions
    2929              :                                                      RoutineName,            // Routine name
    2930              :                                                      CurrentModuleObject,    // Object Type
    2931              :                                                      thisDXCoil.Name,        // Object Name
    2932            0 :                                                      cAlphaFields(18));      // Field Name
    2933              :             }
    2934              :         }
    2935              : 
    2936           12 :         if (!lAlphaBlanks(19) && NumAlphas > 18) {
    2937            0 :             thisDXCoil.SHRFTemp2 = GetCurveIndex(state, Alphas(19)); // convert curve name to number
    2938            0 :             if (thisDXCoil.SHRFTemp2 == 0) {
    2939            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2940            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(19), Alphas(19)));
    2941              :             } else {
    2942              :                 // Verify Curve Object, only legal type is BiQuadratic
    2943            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2944              :                                                      thisDXCoil.SHRFTemp2, // Curve index
    2945              :                                                      {2},                  // Valid dimensions
    2946              :                                                      RoutineName,          // Routine name
    2947              :                                                      CurrentModuleObject,  // Object Type
    2948              :                                                      thisDXCoil.Name,      // Object Name
    2949            0 :                                                      cAlphaFields(19));    // Field Name
    2950              :             }
    2951              :         }
    2952              : 
    2953           12 :         if (!lAlphaBlanks(20) && NumAlphas > 19) {
    2954            0 :             thisDXCoil.SHRFFlow2 = GetCurveIndex(state, Alphas(20)); // convert curve name to number
    2955            0 :             if (thisDXCoil.SHRFTemp2 == 0) {
    2956            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2957            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(20), Alphas(20)));
    2958              :             } else {
    2959              :                 // Verify Curve Object, only legal type is BiQuadratic
    2960            0 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    2961              :                                                      thisDXCoil.SHRFFlow2, // Curve index
    2962              :                                                      {1},                  // Valid dimensions
    2963              :                                                      RoutineName,          // Routine name
    2964              :                                                      CurrentModuleObject,  // Object Type
    2965              :                                                      thisDXCoil.Name,      // Object Name
    2966            0 :                                                      cAlphaFields(20));    // Field Name
    2967              :             }
    2968              :         }
    2969           12 :         if (thisDXCoil.SHRFTemp(1) > 0 && thisDXCoil.SHRFFlow(1) > 0 && thisDXCoil.SHRFTemp2 > 0 && thisDXCoil.SHRFFlow2 > 0) {
    2970            0 :             thisDXCoil.UserSHRCurveExists = true;
    2971              :         } else {
    2972           12 :             thisDXCoil.UserSHRCurveExists = false;
    2973              :         }
    2974              :         // A21; \field Zone Name for Condenser Placement
    2975           12 :         if (!lAlphaBlanks(21) && NumAlphas > 20) {
    2976            0 :             thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(21), state.dataHeatBal->Zone);
    2977            0 :             if (thisDXCoil.SecZonePtr > 0) {
    2978            0 :                 SetupZoneInternalGain(state,
    2979              :                                       thisDXCoil.SecZonePtr,
    2980              :                                       thisDXCoil.Name,
    2981              :                                       DataHeatBalance::IntGainType::SecCoolingDXCoilTwoSpeed,
    2982              :                                       &thisDXCoil.SecCoilSensibleHeatGainRate);
    2983            0 :                 thisDXCoil.IsSecondaryDXCoilInZone = true;
    2984              :             } else {
    2985            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    2986            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(21), Alphas(21)));
    2987              :             }
    2988              :         }
    2989              :     }
    2990              : 
    2991          135 :     if (ErrorsFound) {
    2992            0 :         ShowFatalError(state,
    2993            0 :                        format("{}Errors found in getting {} input.  Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    2994              :     }
    2995              : 
    2996              :     // Loop over the Pumped DX Water Heater Coils and get & load the data
    2997          135 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterPumped);
    2998          144 :     for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterPumpedCoils; ++DXHPWaterHeaterCoilNum) {
    2999              : 
    3000            9 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    3001              :                                                                  CurrentModuleObject,
    3002              :                                                                  DXHPWaterHeaterCoilNum,
    3003              :                                                                  Alphas,
    3004              :                                                                  NumAlphas,
    3005              :                                                                  Numbers,
    3006              :                                                                  NumNumbers,
    3007              :                                                                  IOStatus,
    3008              :                                                                  lNumericBlanks,
    3009              :                                                                  lAlphaBlanks,
    3010              :                                                                  cAlphaFields,
    3011              :                                                                  cNumericFields);
    3012              : 
    3013            9 :         ++DXCoilNum;
    3014              : 
    3015              :         // allocate single performance mode for numeric field strings used for sizing routine
    3016            9 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    3017            9 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    3018            9 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    3019              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    3020            9 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    3021              : 
    3022            9 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    3023            9 :         thisDXCoil.Name = Alphas(1);
    3024            9 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    3025            9 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterPumped;
    3026            9 :         thisDXCoil.availSched = Sched::GetScheduleAlwaysOff(state); // heat pump water heater DX coil has no schedule
    3027              : 
    3028              :         // Store the HPWH DX coil heating capacity in RatedTotCap2. After backing off pump and fan heat,
    3029              :         // move to RatedTotCap() for use by DX coil
    3030            9 :         thisDXCoil.RatedTotCap2 = Numbers(1);
    3031            9 :         if (thisDXCoil.RatedTotCap2 <= 0.0) {
    3032            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3033            0 :             ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
    3034            0 :             ErrorsFound = true;
    3035              :         }
    3036              : 
    3037            9 :         thisDXCoil.RatedCOP(1) = Numbers(2);
    3038            9 :         if (thisDXCoil.RatedCOP(1) <= 0.0) {
    3039            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3040            0 :             ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(2), Numbers(2)));
    3041            0 :             ErrorsFound = true;
    3042              :         }
    3043              : 
    3044            9 :         thisDXCoil.RatedSHR(1) = Numbers(3);
    3045            9 :         if (thisDXCoil.RatedSHR(1) <= 0.0 || thisDXCoil.RatedSHR(1) > 1.0) {
    3046            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3047            0 :             ShowContinueError(state, format("...{} must be > 0 and <= 1.  entered value=[{:.3T}].", cNumericFields(3), Numbers(3)));
    3048              : 
    3049            0 :             ErrorsFound = true;
    3050              :         }
    3051              : 
    3052            9 :         thisDXCoil.RatedInletDBTemp = Numbers(4);
    3053            9 :         if (thisDXCoil.RatedInletDBTemp <= 5.0) {
    3054            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3055            0 :             ShowContinueError(state, format("...{} must be > 5 {{C}}.  entered value=[{:.1T}].", cNumericFields(4), Numbers(4)));
    3056            0 :             ErrorsFound = true;
    3057              :         }
    3058              : 
    3059            9 :         thisDXCoil.RatedInletWBTemp = Numbers(5);
    3060            9 :         if (thisDXCoil.RatedInletWBTemp <= 5.0) {
    3061            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3062            0 :             ShowContinueError(state, format("...{} must be > 5 {{C}}.  entered value=[{:.1T}].", cNumericFields(5), Numbers(5)));
    3063            0 :             ErrorsFound = true;
    3064              :         }
    3065              : 
    3066            9 :         thisDXCoil.RatedInletWaterTemp = Numbers(6);
    3067            9 :         if (thisDXCoil.RatedInletWaterTemp <= 25.0) {
    3068            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3069            0 :             ShowContinueError(state, format("...{} must be > 25 {{C}}.  entered value=[{:.1T}].", cNumericFields(6), Numbers(6)));
    3070            0 :             ErrorsFound = true;
    3071              :         }
    3072              : 
    3073            9 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
    3074            9 :         if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
    3075            0 :             if (thisDXCoil.RatedAirVolFlowRate(1) <= 0.0) {
    3076            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3077            0 :                 ShowContinueError(state, format("...{} must be > 0.0.  entered value=[{:.3T}].", cNumericFields(7), Numbers(7)));
    3078            0 :                 ErrorsFound = true;
    3079              :             }
    3080              :         }
    3081              : 
    3082            9 :         thisDXCoil.RatedHPWHCondWaterFlow = Numbers(8);
    3083              :         // move to init
    3084            9 :         if (thisDXCoil.RatedHPWHCondWaterFlow != Constant::AutoCalculate) {
    3085            0 :             if (thisDXCoil.RatedHPWHCondWaterFlow <= 0.0) {
    3086            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3087            0 :                 ShowContinueError(state, format("...{} must be > 0.0  entered value=[{:.3T}].", cNumericFields(8), Numbers(8)));
    3088            0 :                 ErrorsFound = true;
    3089              :             }
    3090              :             //   check the range of flow rate to be >= 1 gpm/ton and <= 5 gpm/ton
    3091            0 :             if (thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2 < 1.79405e-8 ||
    3092            0 :                 thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2 > 8.97024e-8) {
    3093            0 :                 ShowWarningError(state, format("{}{}=\"{}\", outside range", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3094            0 :                 ShowContinueError(state,
    3095            0 :                                   format("...{} per watt of {} is outside the recommended range of >= 1.79405E-8 m3/s/W (0.083 gpm/MBH) and <= "
    3096              :                                          "8.97024E-8 m3/s/W (0.417 gpm/MBH).",
    3097              :                                          cNumericFields(8),
    3098              :                                          cNumericFields(1)));
    3099            0 :                 ShowContinueError(
    3100            0 :                     state, format("...Entered Flow rate per watt = [{:.10T}].", (thisDXCoil.RatedHPWHCondWaterFlow / thisDXCoil.RatedTotCap2)));
    3101              :             }
    3102              :         }
    3103              : 
    3104            9 :         if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
    3105              :             //  initialized to TRUE on allocate
    3106            9 :             if (Util::SameString(Alphas(2), "No")) {
    3107            9 :                 thisDXCoil.FanPowerIncludedInCOP = false;
    3108              :             }
    3109              :         } else {
    3110            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3111            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(2), Alphas(2)));
    3112            0 :             ShowContinueError(state, "Valid choices are Yes or No.");
    3113            0 :             ErrorsFound = true;
    3114              :         }
    3115              : 
    3116            9 :         if (Util::SameString(Alphas(3), "Yes") || Util::SameString(Alphas(3), "No")) {
    3117              :             //  initialized to FALSE on allocate
    3118            9 :             if (Util::SameString(Alphas(3), "Yes")) {
    3119            0 :                 thisDXCoil.CondPumpPowerInCOP = true;
    3120              :             }
    3121              :         } else {
    3122            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3123            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(3), Alphas(3)));
    3124            0 :             ShowContinueError(state, "Valid choices are Yes or No.");
    3125            0 :             ErrorsFound = true;
    3126              :         }
    3127              : 
    3128            9 :         if (Util::SameString(Alphas(4), "Yes") || Util::SameString(Alphas(4), "No")) {
    3129              :             //  initialized to FALSE on allocate
    3130            9 :             if (Util::SameString(Alphas(4), "Yes")) {
    3131            0 :                 thisDXCoil.CondPumpHeatInCapacity = true;
    3132              :             }
    3133              :         } else {
    3134            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3135            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(4), Alphas(4)));
    3136            0 :             ShowContinueError(state, "Valid choices are Yes or No.");
    3137            0 :             ErrorsFound = true;
    3138              :         }
    3139              : 
    3140            9 :         thisDXCoil.HPWHCondPumpElecNomPower = Numbers(9);
    3141            9 :         if (thisDXCoil.HPWHCondPumpElecNomPower < 0.0) {
    3142            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3143            0 :             ShowContinueError(state, format("...{} must be >= 0.0  entered value=[{:.3T}].", cNumericFields(9), Numbers(9)));
    3144            0 :             ErrorsFound = true;
    3145              :         }
    3146              : 
    3147            9 :         thisDXCoil.HPWHCondPumpFracToWater = Numbers(10);
    3148            9 :         if (thisDXCoil.HPWHCondPumpFracToWater <= 0.0 || thisDXCoil.HPWHCondPumpFracToWater > 1.0) {
    3149            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3150            0 :             ShowContinueError(state, format("...{} must be >= 0 and <= 1.  entered value=[{:.3T}].", cNumericFields(10), Numbers(10)));
    3151            0 :             ErrorsFound = true;
    3152              :         }
    3153              : 
    3154              :         // Air nodes
    3155            9 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    3156            9 :                                                  Alphas(5),
    3157              :                                                  ErrorsFound,
    3158              :                                                  DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
    3159            9 :                                                  Alphas(1),
    3160              :                                                  DataLoopNode::NodeFluidType::Air,
    3161              :                                                  DataLoopNode::ConnectionType::Inlet,
    3162              :                                                  NodeInputManager::CompFluidStream::Primary,
    3163              :                                                  ObjectIsNotParent);
    3164              : 
    3165           18 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    3166            9 :                                                   Alphas(6),
    3167              :                                                   ErrorsFound,
    3168              :                                                   DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
    3169            9 :                                                   Alphas(1),
    3170              :                                                   DataLoopNode::NodeFluidType::Air,
    3171              :                                                   DataLoopNode::ConnectionType::Outlet,
    3172              :                                                   NodeInputManager::CompFluidStream::Primary,
    3173              :                                                   ObjectIsNotParent);
    3174              : 
    3175            9 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(5), Alphas(6), "Air Nodes");
    3176              : 
    3177              :         // Check if the air inlet node is OA node, to justify whether the coil is placed in zone or not
    3178            9 :         thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
    3179              : 
    3180              :         // Water nodes
    3181            9 :         thisDXCoil.WaterInNode = GetOnlySingleNode(state,
    3182            9 :                                                    Alphas(7),
    3183              :                                                    ErrorsFound,
    3184              :                                                    DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
    3185            9 :                                                    Alphas(1),
    3186              :                                                    DataLoopNode::NodeFluidType::Water,
    3187              :                                                    DataLoopNode::ConnectionType::Inlet,
    3188              :                                                    NodeInputManager::CompFluidStream::Secondary,
    3189              :                                                    ObjectIsNotParent);
    3190              : 
    3191           18 :         thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
    3192            9 :                                                     Alphas(8),
    3193              :                                                     ErrorsFound,
    3194              :                                                     DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpPumped,
    3195            9 :                                                     Alphas(1),
    3196              :                                                     DataLoopNode::NodeFluidType::Water,
    3197              :                                                     DataLoopNode::ConnectionType::Outlet,
    3198              :                                                     NodeInputManager::CompFluidStream::Secondary,
    3199              :                                                     ObjectIsNotParent);
    3200              : 
    3201            9 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(7), Alphas(8), "Water Nodes");
    3202              : 
    3203            9 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(11);
    3204            9 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    3205            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3206            0 :             ShowContinueError(state, format("...{} must be >= 0.0  entered value=[{:.1T}].", cNumericFields(11), Numbers(11)));
    3207            0 :             ErrorsFound = true;
    3208              :         }
    3209              : 
    3210            9 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(12);
    3211            9 :         if (thisDXCoil.MaxOATCrankcaseHeater < 0.0) {
    3212            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3213            0 :             ShowContinueError(state, format("...{} must be >= 0 {{C}}.  entered value=[{:.1T}].", cNumericFields(12), Numbers(12)));
    3214            0 :             ErrorsFound = true;
    3215              :         }
    3216              : 
    3217            9 :         if (!lAlphaBlanks(9)) {
    3218            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(9));
    3219            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    3220            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(9), Alphas(9)));
    3221            0 :                 ErrorsFound = true;
    3222              :             } else {
    3223            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3224              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    3225              :                                                      {1},                                          // Valid dimensions
    3226              :                                                      RoutineName,                                  // Routine name
    3227              :                                                      CurrentModuleObject,                          // Object Type
    3228              :                                                      thisDXCoil.Name,                              // Object Name
    3229            2 :                                                      cAlphaFields(9));                             // Field Name
    3230              :             }
    3231              :         }
    3232              : 
    3233            9 :         thisDXCoil.InletAirTemperatureType = static_cast<HVAC::OATType>(getEnumValue(HVAC::oatTypeNamesUC, Alphas(10)));
    3234              : 
    3235              :         // set rated inlet air temperature for curve object verification
    3236            9 :         if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
    3237            9 :             InletAirTemp = thisDXCoil.RatedInletWBTemp;
    3238              :         } else {
    3239            0 :             InletAirTemp = thisDXCoil.RatedInletDBTemp;
    3240              :         }
    3241              :         // set rated water temperature for curve object verification
    3242            9 :         InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
    3243              : 
    3244            9 :         if (!lAlphaBlanks(11)) {
    3245            9 :             thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(11));
    3246            9 :             if (thisDXCoil.HCapFTemp == 0) {
    3247            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3248            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
    3249            0 :                 ErrorsFound = true;
    3250              :             } else {
    3251              :                 // Verify Curve Object, only legal types are BiQuadratic or Cubic
    3252           18 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3253              :                                                      thisDXCoil.HCapFTemp, // Curve index
    3254              :                                                      {1, 2},               // Valid dimensions  // MULTIPLECURVEDIMS
    3255              :                                                      RoutineName,          // Routine name
    3256              :                                                      CurrentModuleObject,  // Object Type
    3257              :                                                      thisDXCoil.Name,      // Object Name
    3258            9 :                                                      cAlphaFields(11));    // Field Name
    3259              : 
    3260            9 :                 if (!ErrorsFound) {
    3261            9 :                     if (state.dataCurveManager->curves(thisDXCoil.HCapFTemp)->numDims == 1) {
    3262            2 :                         checkCurveIsNormalizedToOne(state,
    3263            6 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3264            2 :                                                     thisDXCoil.Name,
    3265              :                                                     thisDXCoil.HCapFTemp,
    3266            2 :                                                     cAlphaFields(11),
    3267            2 :                                                     Alphas(11),
    3268              :                                                     InletAirTemp);
    3269              :                     } else {
    3270            7 :                         checkCurveIsNormalizedToOne(state,
    3271           21 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3272            7 :                                                     thisDXCoil.Name,
    3273              :                                                     thisDXCoil.HCapFTemp,
    3274            7 :                                                     cAlphaFields(11),
    3275            7 :                                                     Alphas(11),
    3276              :                                                     InletAirTemp,
    3277              :                                                     InletWaterTemp);
    3278              :                     }
    3279              :                 }
    3280              :             }
    3281              :         }
    3282              : 
    3283            9 :         if (!lAlphaBlanks(12)) {
    3284            2 :             thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(12));
    3285            2 :             if (thisDXCoil.HCapFAirFlow == 0) {
    3286            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3287            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(12), Alphas(12)));
    3288            0 :                 ErrorsFound = true;
    3289              :             } else {
    3290              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3291            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3292              :                                                      thisDXCoil.HCapFAirFlow, // Curve index
    3293              :                                                      {1},                     // Valid dimensions
    3294              :                                                      RoutineName,             // Routine name
    3295              :                                                      CurrentModuleObject,     // Object Type
    3296              :                                                      thisDXCoil.Name,         // Object Name
    3297            2 :                                                      cAlphaFields(12));       // Field Name
    3298              : 
    3299            2 :                 if (!ErrorsFound) {
    3300            2 :                     checkCurveIsNormalizedToOne(state,
    3301            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3302            2 :                                                 thisDXCoil.Name,
    3303              :                                                 thisDXCoil.HCapFAirFlow,
    3304            2 :                                                 cAlphaFields(12),
    3305            2 :                                                 Alphas(12),
    3306              :                                                 1.0);
    3307              :                 }
    3308              :             }
    3309              :         }
    3310              : 
    3311            9 :         if (!lAlphaBlanks(13)) {
    3312            2 :             thisDXCoil.HCapFWaterFlow = GetCurveIndex(state, Alphas(13));
    3313            2 :             if (thisDXCoil.HCapFWaterFlow == 0) {
    3314            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3315            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(13), Alphas(13)));
    3316            0 :                 ErrorsFound = true;
    3317              :             } else {
    3318              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3319            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3320              :                                                      thisDXCoil.HCapFWaterFlow, // Curve index
    3321              :                                                      {1},                       // Valid dimensions
    3322              :                                                      RoutineName,               // Routine name
    3323              :                                                      CurrentModuleObject,       // Object Type
    3324              :                                                      thisDXCoil.Name,           // Object Name
    3325            2 :                                                      cAlphaFields(13));         // Field Name
    3326              : 
    3327            2 :                 if (!ErrorsFound) {
    3328            2 :                     checkCurveIsNormalizedToOne(state,
    3329            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3330            2 :                                                 thisDXCoil.Name,
    3331              :                                                 thisDXCoil.HCapFWaterFlow,
    3332            2 :                                                 cAlphaFields(13),
    3333            2 :                                                 Alphas(13),
    3334              :                                                 1.0);
    3335              :                 }
    3336              :             }
    3337              :         }
    3338              : 
    3339            9 :         if (!lAlphaBlanks(14)) {
    3340            9 :             thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(14));
    3341            9 :             if (thisDXCoil.HCOPFTemp == 0) {
    3342            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3343            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14), Alphas(14)));
    3344            0 :                 ErrorsFound = true;
    3345              :             } else {
    3346              :                 // Verify Curve Object, only legal types are BiQuadratic or Cubic
    3347           18 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3348              :                                                      thisDXCoil.HCOPFTemp, // Curve index
    3349              :                                                      {1, 2},               // Valid dimensions  // MULTIPLECURVEDIMS
    3350              :                                                      RoutineName,          // Routine name
    3351              :                                                      CurrentModuleObject,  // Object Type
    3352              :                                                      thisDXCoil.Name,      // Object Name
    3353            9 :                                                      cAlphaFields(14));    // Field Name
    3354              : 
    3355            9 :                 if (!ErrorsFound) {
    3356            9 :                     if (state.dataCurveManager->curves(thisDXCoil.HCOPFTemp)->numDims == 1) {
    3357            0 :                         checkCurveIsNormalizedToOne(state,
    3358            0 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3359            0 :                                                     thisDXCoil.Name,
    3360              :                                                     thisDXCoil.HCOPFTemp,
    3361            0 :                                                     cAlphaFields(14),
    3362            0 :                                                     Alphas(14),
    3363              :                                                     InletAirTemp);
    3364              :                     } else {
    3365            9 :                         checkCurveIsNormalizedToOne(state,
    3366           27 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3367            9 :                                                     thisDXCoil.Name,
    3368              :                                                     thisDXCoil.HCOPFTemp,
    3369            9 :                                                     cAlphaFields(14),
    3370            9 :                                                     Alphas(14),
    3371              :                                                     InletAirTemp,
    3372              :                                                     InletWaterTemp);
    3373              :                     }
    3374              :                 }
    3375              :             }
    3376              :         }
    3377              : 
    3378            9 :         if (!lAlphaBlanks(15)) {
    3379            2 :             thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(15));
    3380            2 :             if (thisDXCoil.HCOPFAirFlow == 0) {
    3381            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3382            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15), Alphas(15)));
    3383            0 :                 ErrorsFound = true;
    3384              :             } else {
    3385              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3386            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3387              :                                                      thisDXCoil.HCOPFAirFlow, // Curve index
    3388              :                                                      {1},                     // Valid dimensions
    3389              :                                                      RoutineName,             // Routine name
    3390              :                                                      CurrentModuleObject,     // Object Type
    3391              :                                                      thisDXCoil.Name,         // Object Name
    3392            2 :                                                      cAlphaFields(15));       // Field Name
    3393              : 
    3394            2 :                 if (!ErrorsFound) {
    3395            2 :                     checkCurveIsNormalizedToOne(state,
    3396            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3397            2 :                                                 thisDXCoil.Name,
    3398              :                                                 thisDXCoil.HCOPFAirFlow,
    3399            2 :                                                 cAlphaFields(15),
    3400            2 :                                                 Alphas(15),
    3401              :                                                 1.0);
    3402              :                 }
    3403              :             }
    3404              :         }
    3405              : 
    3406            9 :         if (!lAlphaBlanks(16)) {
    3407            2 :             thisDXCoil.HCOPFWaterFlow = GetCurveIndex(state, Alphas(16));
    3408            2 :             if (thisDXCoil.HCOPFWaterFlow == 0) {
    3409            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3410            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16), Alphas(16)));
    3411            0 :                 ErrorsFound = true;
    3412              :             } else {
    3413              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3414            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3415              :                                                      thisDXCoil.HCOPFWaterFlow, // Curve index
    3416              :                                                      {1},                       // Valid dimensions
    3417              :                                                      RoutineName,               // Routine name
    3418              :                                                      CurrentModuleObject,       // Object Type
    3419              :                                                      thisDXCoil.Name,           // Object Name
    3420            2 :                                                      cAlphaFields(16));         // Field Name
    3421              : 
    3422            2 :                 if (!ErrorsFound) {
    3423            2 :                     checkCurveIsNormalizedToOne(state,
    3424            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3425            2 :                                                 thisDXCoil.Name,
    3426              :                                                 thisDXCoil.HCOPFWaterFlow,
    3427            2 :                                                 cAlphaFields(16),
    3428            2 :                                                 Alphas(16),
    3429              :                                                 1.0);
    3430              :                 }
    3431              :             }
    3432              :         }
    3433              : 
    3434            9 :         if (!lAlphaBlanks(17)) {
    3435            9 :             thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(17));
    3436            9 :             if (thisDXCoil.PLFFPLR(1) == 0) {
    3437            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3438            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17), Alphas(17)));
    3439            0 :                 ErrorsFound = true;
    3440              :             } else {
    3441              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3442           27 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3443            9 :                                                      thisDXCoil.PLFFPLR(1), // Curve index
    3444              :                                                      {1},                   // Valid dimensions
    3445              :                                                      RoutineName,           // Routine name
    3446              :                                                      CurrentModuleObject,   // Object Type
    3447              :                                                      thisDXCoil.Name,       // Object Name
    3448            9 :                                                      cAlphaFields(17));     // Field Name
    3449              : 
    3450            9 :                 if (!ErrorsFound) {
    3451              :                     //       Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    3452            9 :                     MinCurveVal = 999.0;
    3453            9 :                     MaxCurveVal = -999.0;
    3454            9 :                     CurveInput = 0.0;
    3455          909 :                     while (CurveInput <= 1.0) {
    3456          900 :                         CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
    3457          900 :                         if (CurveVal < MinCurveVal) {
    3458            9 :                             MinCurveVal = CurveVal;
    3459            9 :                             MinCurvePLR = CurveInput;
    3460              :                         }
    3461          900 :                         if (CurveVal > MaxCurveVal) {
    3462          702 :                             MaxCurveVal = CurveVal;
    3463          702 :                             MaxCurvePLR = CurveInput;
    3464              :                         }
    3465          900 :                         CurveInput += 0.01;
    3466              :                     }
    3467            9 :                     if (MinCurveVal < 0.7) {
    3468            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3469            0 :                         ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(17), Alphas(17)));
    3470            0 :                         ShowContinueError(state,
    3471            0 :                                           format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    3472            0 :                         ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    3473            0 :                         Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
    3474              :                     }
    3475              : 
    3476            9 :                     if (MaxCurveVal > 1.0) {
    3477            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3478            0 :                         ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(17), Alphas(17)));
    3479            0 :                         ShowContinueError(state,
    3480            0 :                                           format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    3481            0 :                         ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    3482            0 :                         Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
    3483              :                     }
    3484              :                 }
    3485              :             }
    3486              :         }
    3487              : 
    3488              :         // assume compressor resides at the inlet to the DX Coil
    3489            9 :         thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
    3490              : 
    3491              :         // set condenser type as HPWH
    3492            9 :         thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
    3493              : 
    3494              :     } // end of the DX water heater coil loop
    3495              : 
    3496          135 :     if (ErrorsFound) {
    3497            0 :         ShowFatalError(state,
    3498            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    3499              :     }
    3500              :     // Loop over the Wrapped DX Water Heater Coils and get & load the data
    3501          135 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilDX_HeatPumpWaterHeaterWrapped);
    3502          142 :     for (DXHPWaterHeaterCoilNum = 1; DXHPWaterHeaterCoilNum <= state.dataDXCoils->NumDXHeatPumpWaterHeaterWrappedCoils; ++DXHPWaterHeaterCoilNum) {
    3503              : 
    3504            7 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    3505              :                                                                  CurrentModuleObject,
    3506              :                                                                  DXHPWaterHeaterCoilNum,
    3507              :                                                                  Alphas,
    3508              :                                                                  NumAlphas,
    3509              :                                                                  Numbers,
    3510              :                                                                  NumNumbers,
    3511              :                                                                  IOStatus,
    3512              :                                                                  lNumericBlanks,
    3513              :                                                                  lAlphaBlanks,
    3514              :                                                                  cAlphaFields,
    3515              :                                                                  cNumericFields);
    3516              : 
    3517            7 :         ++DXCoilNum;
    3518              : 
    3519              :         // allocate single performance mode for numeric field strings used for sizing routine
    3520            7 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    3521            7 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    3522            7 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    3523              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    3524            7 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    3525              : 
    3526            7 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    3527            7 :         thisDXCoil.Name = Alphas(1);
    3528            7 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    3529            7 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_HeatPumpWaterHeaterWrapped;
    3530            7 :         thisDXCoil.availSched = Sched::GetScheduleAlwaysOff(state); // heat pump water heater DX coil has no schedule
    3531              : 
    3532              :         // Store the HPWH DX coil heating capacity in RatedTotCap2. After backing off pump and fan heat,
    3533              :         // move to RatedTotCap() for use by DX coil
    3534            7 :         thisDXCoil.RatedTotCap2 = Numbers(1);
    3535            7 :         if (thisDXCoil.RatedTotCap2 <= 0.0) {
    3536            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3537            0 :             ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(1), Numbers(1)));
    3538            0 :             ErrorsFound = true;
    3539              :         }
    3540              : 
    3541            7 :         thisDXCoil.RatedCOP(1) = Numbers(2);
    3542            7 :         if (thisDXCoil.RatedCOP(1) <= 0.0) {
    3543            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3544            0 :             ShowContinueError(state, format("...{} must be > 0.0, entered value=[{:.2T}].", cNumericFields(2), Numbers(2)));
    3545            0 :             ErrorsFound = true;
    3546              :         }
    3547              : 
    3548            7 :         thisDXCoil.RatedSHR(1) = Numbers(3);
    3549            7 :         if (thisDXCoil.RatedSHR(1) <= 0.0 || thisDXCoil.RatedSHR(1) > 1.0) {
    3550            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3551            0 :             ShowContinueError(state, format("...{} must be > 0 and <= 1.  entered value=[{:.3T}].", cNumericFields(3), Numbers(3)));
    3552              : 
    3553            0 :             ErrorsFound = true;
    3554              :         }
    3555              : 
    3556            7 :         thisDXCoil.RatedInletDBTemp = Numbers(4);
    3557            7 :         if (thisDXCoil.RatedInletDBTemp <= 5.0) {
    3558            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3559            0 :             ShowContinueError(state, format("...{} must be > 5 {{C}}.  entered value=[{:.1T}].", cNumericFields(4), Numbers(4)));
    3560            0 :             ErrorsFound = true;
    3561              :         }
    3562              : 
    3563            7 :         thisDXCoil.RatedInletWBTemp = Numbers(5);
    3564            7 :         if (thisDXCoil.RatedInletWBTemp <= 5.0) {
    3565            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3566            0 :             ShowContinueError(state, format("...{} must be > 5 {{C}}.  entered value=[{:.1T}].", cNumericFields(5), Numbers(5)));
    3567            0 :             ErrorsFound = true;
    3568              :         }
    3569              : 
    3570            7 :         thisDXCoil.RatedInletWaterTemp = Numbers(6);
    3571            7 :         if (thisDXCoil.RatedInletWaterTemp <= 25.0) {
    3572            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3573            0 :             ShowContinueError(state, format("...{} must be > 25 {{C}}.  entered value=[{:.1T}].", cNumericFields(6), Numbers(6)));
    3574            0 :             ErrorsFound = true;
    3575              :         }
    3576              : 
    3577            7 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(7);
    3578            7 :         if (thisDXCoil.RatedAirVolFlowRate(1) != Constant::AutoCalculate) {
    3579            7 :             if (thisDXCoil.RatedAirVolFlowRate(1) <= 0.0) {
    3580            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3581            0 :                 ShowContinueError(state, format("...{} must be > 0.0.  entered value=[{:.3T}].", cNumericFields(7), Numbers(7)));
    3582            0 :                 ErrorsFound = true;
    3583              :             }
    3584              :         }
    3585              : 
    3586            7 :         if (Util::SameString(Alphas(2), "Yes") || Util::SameString(Alphas(2), "No")) {
    3587              :             //  initialized to TRUE on allocate
    3588            7 :             if (Util::SameString(Alphas(2), "No")) {
    3589            0 :                 thisDXCoil.FanPowerIncludedInCOP = false;
    3590              :             }
    3591              :         } else {
    3592            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3593            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(2), Alphas(2)));
    3594            0 :             ShowContinueError(state, "Valid choices are Yes or No.");
    3595            0 :             ErrorsFound = true;
    3596              :         }
    3597              : 
    3598              :         // Air nodes
    3599            7 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    3600            7 :                                                  Alphas(3),
    3601              :                                                  ErrorsFound,
    3602              :                                                  DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
    3603            7 :                                                  Alphas(1),
    3604              :                                                  DataLoopNode::NodeFluidType::Air,
    3605              :                                                  DataLoopNode::ConnectionType::Inlet,
    3606              :                                                  NodeInputManager::CompFluidStream::Primary,
    3607              :                                                  ObjectIsNotParent);
    3608              : 
    3609           14 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    3610            7 :                                                   Alphas(4),
    3611              :                                                   ErrorsFound,
    3612              :                                                   DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
    3613            7 :                                                   Alphas(1),
    3614              :                                                   DataLoopNode::NodeFluidType::Air,
    3615              :                                                   DataLoopNode::ConnectionType::Outlet,
    3616              :                                                   NodeInputManager::CompFluidStream::Primary,
    3617              :                                                   ObjectIsNotParent);
    3618              : 
    3619            7 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    3620              : 
    3621              :         // Check if the air inlet node is OA node, to justify whether the coil is placed in zone or not
    3622            7 :         thisDXCoil.IsDXCoilInZone = !CheckOutAirNodeNumber(state, thisDXCoil.AirInNode);
    3623              : 
    3624            7 :         std::string const DummyCondenserInletName("DUMMY CONDENSER INLET " + thisDXCoil.Name);
    3625            7 :         std::string const DummyCondenserOutletName("DUMMY CONDENSER OUTLET " + thisDXCoil.Name);
    3626            7 :         thisDXCoil.WaterInNode = GetOnlySingleNode(state,
    3627              :                                                    DummyCondenserInletName,
    3628              :                                                    ErrorsFound,
    3629              :                                                    DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
    3630            7 :                                                    Alphas(1),
    3631              :                                                    DataLoopNode::NodeFluidType::Water,
    3632              :                                                    DataLoopNode::ConnectionType::Inlet,
    3633              :                                                    NodeInputManager::CompFluidStream::Secondary,
    3634              :                                                    ObjectIsNotParent);
    3635              : 
    3636           14 :         thisDXCoil.WaterOutNode = GetOnlySingleNode(state,
    3637              :                                                     DummyCondenserOutletName,
    3638              :                                                     ErrorsFound,
    3639              :                                                     DataLoopNode::ConnectionObjectType::CoilWaterHeatingAirToWaterHeatPumpWrapped,
    3640            7 :                                                     Alphas(1),
    3641              :                                                     DataLoopNode::NodeFluidType::Water,
    3642              :                                                     DataLoopNode::ConnectionType::Outlet,
    3643              :                                                     NodeInputManager::CompFluidStream::Secondary,
    3644              :                                                     ObjectIsNotParent);
    3645              : 
    3646            7 :         TestCompSet(state, CurrentModuleObject, Alphas(1), DummyCondenserInletName, DummyCondenserOutletName, "Water Nodes");
    3647              : 
    3648            7 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(8);
    3649            7 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    3650            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3651            0 :             ShowContinueError(state, format("...{} must be >= 0.0  entered value=[{:.1T}].", cNumericFields(8), Numbers(8)));
    3652            0 :             ErrorsFound = true;
    3653              :         }
    3654              : 
    3655            7 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(9);
    3656            7 :         if (thisDXCoil.MaxOATCrankcaseHeater < 0.0) {
    3657            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3658            0 :             ShowContinueError(state, format("...{} must be >= 0 {{C}}.  entered value=[{:.1T}].", cNumericFields(9), Numbers(9)));
    3659            0 :             ErrorsFound = true;
    3660              :         }
    3661              : 
    3662              :         // Coil:WaterHeating:AirToWaterHeatPump:Wrapped
    3663            7 :         if (!lAlphaBlanks(5)) {
    3664            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
    3665            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    3666            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
    3667            0 :                 ErrorsFound = true;
    3668              :             } else {
    3669            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3670              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    3671              :                                                      {1},                                          // Valid dimensions
    3672              :                                                      RoutineName,                                  // Routine name
    3673              :                                                      CurrentModuleObject,                          // Object Type
    3674              :                                                      thisDXCoil.Name,                              // Object Name
    3675            2 :                                                      cAlphaFields(5));                             // Field Name
    3676              :             }
    3677              :         }
    3678              : 
    3679            7 :         if (Util::SameString(Alphas(6), "DryBulbTemperature")) {
    3680            0 :             thisDXCoil.InletAirTemperatureType = HVAC::OATType::DryBulb;
    3681            7 :         } else if (Util::SameString(Alphas(6), "WetBulbTemperature")) {
    3682            7 :             thisDXCoil.InletAirTemperatureType = HVAC::OATType::WetBulb;
    3683              :         } else {
    3684              :             //   wrong temperature type selection
    3685            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3686            0 :             ShowContinueError(state, format("...{} must be DryBulbTemperature or WetBulbTemperature.", cAlphaFields(6)));
    3687            0 :             ShowContinueError(state, format("...entered value=\"{}\".", Alphas(6)));
    3688            0 :             ErrorsFound = true;
    3689              :         }
    3690              : 
    3691              :         // set rated inlet air temperature for curve object verification
    3692            7 :         if (thisDXCoil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
    3693            7 :             InletAirTemp = thisDXCoil.RatedInletWBTemp;
    3694              :         } else {
    3695            0 :             InletAirTemp = thisDXCoil.RatedInletDBTemp;
    3696              :         }
    3697              :         // set rated water temperature for curve object verification
    3698            7 :         InletWaterTemp = thisDXCoil.RatedInletWaterTemp;
    3699              : 
    3700            7 :         if (!lAlphaBlanks(7)) {
    3701            7 :             thisDXCoil.HCapFTemp = GetCurveIndex(state, Alphas(7));
    3702            7 :             if (thisDXCoil.HCapFTemp == 0) {
    3703            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3704            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(7), Alphas(7)));
    3705            0 :                 ErrorsFound = true;
    3706              :             } else {
    3707              :                 // Verify Curve Object, only legal types are BiQuadratic or Cubic
    3708           14 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3709              :                                                      thisDXCoil.HCapFTemp, // Curve index
    3710              :                                                      {1, 2},               // Valid dimensions  // MULTIPLECURVEDIMS
    3711              :                                                      RoutineName,          // Routine name
    3712              :                                                      CurrentModuleObject,  // Object Type
    3713              :                                                      thisDXCoil.Name,      // Object Name
    3714            7 :                                                      cAlphaFields(7));     // Field Name
    3715              : 
    3716            7 :                 if (!ErrorsFound) {
    3717            7 :                     if (state.dataCurveManager->curves(thisDXCoil.HCapFTemp)->numDims == 1) {
    3718            0 :                         checkCurveIsNormalizedToOne(state,
    3719            0 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3720            0 :                                                     thisDXCoil.Name,
    3721              :                                                     thisDXCoil.HCapFTemp,
    3722            0 :                                                     cAlphaFields(7),
    3723            0 :                                                     Alphas(7),
    3724              :                                                     InletAirTemp);
    3725              :                     } else {
    3726            7 :                         checkCurveIsNormalizedToOne(state,
    3727           21 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3728            7 :                                                     thisDXCoil.Name,
    3729              :                                                     thisDXCoil.HCapFTemp,
    3730            7 :                                                     cAlphaFields(7),
    3731            7 :                                                     Alphas(7),
    3732              :                                                     InletAirTemp,
    3733              :                                                     InletWaterTemp);
    3734              :                     }
    3735              :                 }
    3736              :             }
    3737              :         }
    3738              : 
    3739            7 :         if (!lAlphaBlanks(8)) {
    3740            2 :             thisDXCoil.HCapFAirFlow = GetCurveIndex(state, Alphas(8));
    3741            2 :             if (thisDXCoil.HCapFAirFlow == 0) {
    3742            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3743            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(8), Alphas(8)));
    3744            0 :                 ErrorsFound = true;
    3745              :             } else {
    3746              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3747            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3748              :                                                      thisDXCoil.HCapFAirFlow, // Curve index
    3749              :                                                      {1},                     // Valid dimensions
    3750              :                                                      RoutineName,             // Routine name
    3751              :                                                      CurrentModuleObject,     // Object Type
    3752              :                                                      thisDXCoil.Name,         // Object Name
    3753            2 :                                                      cAlphaFields(8));        // Field Name
    3754              : 
    3755            2 :                 if (!ErrorsFound) {
    3756            2 :                     checkCurveIsNormalizedToOne(state,
    3757            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3758            2 :                                                 thisDXCoil.Name,
    3759              :                                                 thisDXCoil.HCapFAirFlow,
    3760            2 :                                                 cAlphaFields(8),
    3761            2 :                                                 Alphas(8),
    3762              :                                                 1.0);
    3763              :                 }
    3764              :             }
    3765              :         }
    3766              : 
    3767            7 :         if (!lAlphaBlanks(9)) {
    3768            7 :             thisDXCoil.HCOPFTemp = GetCurveIndex(state, Alphas(9));
    3769            7 :             if (thisDXCoil.HCOPFTemp == 0) {
    3770            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3771            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(9), Alphas(9)));
    3772            0 :                 ErrorsFound = true;
    3773              :             } else {
    3774              :                 // Verify Curve Object, only legal types are BiQuadratic or Cubic
    3775           14 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3776              :                                                      thisDXCoil.HCOPFTemp, // Curve index
    3777              :                                                      {1, 2},               // Valid dimensions  // MULTIPLECURVEDIMS
    3778              :                                                      RoutineName,          // Routine name
    3779              :                                                      CurrentModuleObject,  // Object Type
    3780              :                                                      thisDXCoil.Name,      // Object Name
    3781            7 :                                                      cAlphaFields(9));     // Field Name
    3782              : 
    3783            7 :                 if (!ErrorsFound) {
    3784            7 :                     if (state.dataCurveManager->curves(thisDXCoil.HCOPFTemp)->numDims == 1) {
    3785            0 :                         checkCurveIsNormalizedToOne(state,
    3786            0 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3787            0 :                                                     thisDXCoil.Name,
    3788              :                                                     thisDXCoil.HCOPFTemp,
    3789            0 :                                                     cAlphaFields(9),
    3790            0 :                                                     Alphas(9),
    3791              :                                                     InletAirTemp);
    3792              :                     } else {
    3793            7 :                         checkCurveIsNormalizedToOne(state,
    3794           21 :                                                     std::string{RoutineName} + CurrentModuleObject,
    3795            7 :                                                     thisDXCoil.Name,
    3796              :                                                     thisDXCoil.HCOPFTemp,
    3797            7 :                                                     cAlphaFields(9),
    3798            7 :                                                     Alphas(9),
    3799              :                                                     InletAirTemp,
    3800              :                                                     InletWaterTemp);
    3801              :                     }
    3802              :                 }
    3803              :             }
    3804              :         }
    3805              : 
    3806            7 :         if (!lAlphaBlanks(10)) {
    3807            2 :             thisDXCoil.HCOPFAirFlow = GetCurveIndex(state, Alphas(10));
    3808            2 :             if (thisDXCoil.HCOPFAirFlow == 0) {
    3809            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3810            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(10), Alphas(10)));
    3811            0 :                 ErrorsFound = true;
    3812              :             } else {
    3813              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3814            4 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3815              :                                                      thisDXCoil.HCOPFAirFlow, // Curve index
    3816              :                                                      {1},                     // Valid dimensions
    3817              :                                                      RoutineName,             // Routine name
    3818              :                                                      CurrentModuleObject,     // Object Type
    3819              :                                                      thisDXCoil.Name,         // Object Name
    3820            2 :                                                      cAlphaFields(10));       // Field Name
    3821              : 
    3822            2 :                 if (!ErrorsFound) {
    3823            2 :                     checkCurveIsNormalizedToOne(state,
    3824            6 :                                                 std::string{RoutineName} + CurrentModuleObject,
    3825            2 :                                                 thisDXCoil.Name,
    3826              :                                                 thisDXCoil.HCOPFAirFlow,
    3827            2 :                                                 cAlphaFields(10),
    3828            2 :                                                 Alphas(10),
    3829              :                                                 1.0);
    3830              :                 }
    3831              :             }
    3832              :         }
    3833              : 
    3834            7 :         if (!lAlphaBlanks(11)) {
    3835            4 :             thisDXCoil.PLFFPLR(1) = GetCurveIndex(state, Alphas(11));
    3836            4 :             if (thisDXCoil.PLFFPLR(1) == 0) {
    3837            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3838            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(11), Alphas(11)));
    3839            0 :                 ErrorsFound = true;
    3840              :             } else {
    3841              :                 // Verify Curve Object, only legal types are Cubic or Quadratic
    3842           12 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    3843            4 :                                                      thisDXCoil.PLFFPLR(1), // Curve index
    3844              :                                                      {1},                   // Valid dimensions
    3845              :                                                      RoutineName,           // Routine name
    3846              :                                                      CurrentModuleObject,   // Object Type
    3847              :                                                      thisDXCoil.Name,       // Object Name
    3848            4 :                                                      cAlphaFields(11));     // Field Name
    3849              : 
    3850            4 :                 if (!ErrorsFound) {
    3851              :                     //       Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    3852            4 :                     MinCurveVal = 999.0;
    3853            4 :                     MaxCurveVal = -999.0;
    3854            4 :                     CurveInput = 0.0;
    3855          404 :                     while (CurveInput <= 1.0) {
    3856          400 :                         CurveVal = CurveValue(state, thisDXCoil.PLFFPLR(1), CurveInput);
    3857          400 :                         if (CurveVal < MinCurveVal) {
    3858            4 :                             MinCurveVal = CurveVal;
    3859            4 :                             MinCurvePLR = CurveInput;
    3860              :                         }
    3861          400 :                         if (CurveVal > MaxCurveVal) {
    3862            4 :                             MaxCurveVal = CurveVal;
    3863            4 :                             MaxCurvePLR = CurveInput;
    3864              :                         }
    3865          400 :                         CurveInput += 0.01;
    3866              :                     }
    3867            4 :                     if (MinCurveVal < 0.7) {
    3868            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3869            0 :                         ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(11), Alphas(11)));
    3870            0 :                         ShowContinueError(state,
    3871            0 :                                           format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    3872            0 :                         ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    3873            0 :                         Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 0.7);
    3874              :                     }
    3875              : 
    3876            4 :                     if (MaxCurveVal > 1.0) {
    3877            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3878            0 :                         ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(11), Alphas(11)));
    3879            0 :                         ShowContinueError(state,
    3880            0 :                                           format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    3881            0 :                         ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    3882            0 :                         Curve::SetCurveOutputMaxValue(state, thisDXCoil.PLFFPLR(1), ErrorsFound, 1.0);
    3883              :                     }
    3884              :                 }
    3885              :             }
    3886              :         }
    3887              : 
    3888              :         // assume compressor resides at the inlet to the DX Coil
    3889            7 :         thisDXCoil.CondenserInletNodeNum(1) = thisDXCoil.AirInNode;
    3890              : 
    3891              :         // set condenser type as HPWH
    3892            7 :         thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::WaterHeater;
    3893              : 
    3894            7 :     } // end of the DX water heater wrapped coil loop
    3895              : 
    3896          135 :     if (ErrorsFound) {
    3897            0 :         ShowFatalError(state,
    3898            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    3899              :     }
    3900              : 
    3901              :     // DX Multispeed cooling coil
    3902          135 :     CurrentModuleObject = "Coil:Cooling:DX:MultiSpeed";
    3903          163 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedCoolCoils; ++DXCoilIndex) {
    3904              : 
    3905           28 :         ++DXCoilNum;
    3906              : 
    3907           28 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    3908              :                                                                  CurrentModuleObject,
    3909              :                                                                  DXCoilIndex,
    3910              :                                                                  Alphas,
    3911              :                                                                  NumAlphas,
    3912              :                                                                  Numbers,
    3913              :                                                                  NumNumbers,
    3914              :                                                                  IOStatus,
    3915              :                                                                  lNumericBlanks,
    3916              :                                                                  lAlphaBlanks,
    3917              :                                                                  cAlphaFields,
    3918              :                                                                  cNumericFields);
    3919              : 
    3920           28 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    3921              :         // allocate single performance mode for numeric field strings used for sizing routine (all fields are in this object)
    3922           28 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    3923           28 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    3924           28 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    3925              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    3926           28 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    3927              : 
    3928           28 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    3929           28 :         thisDXCoil.Name = Alphas(1);
    3930              :         // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
    3931           28 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
    3932           28 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
    3933           28 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    3934           28 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedCooling;
    3935           28 :         if (lAlphaBlanks(2)) {
    3936           18 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    3937           10 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    3938            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    3939            0 :             ErrorsFound = true;
    3940              :         }
    3941              : 
    3942           28 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    3943           28 :                                                  Alphas(3),
    3944              :                                                  ErrorsFound,
    3945              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
    3946           28 :                                                  Alphas(1),
    3947              :                                                  DataLoopNode::NodeFluidType::Air,
    3948              :                                                  DataLoopNode::ConnectionType::Inlet,
    3949              :                                                  NodeInputManager::CompFluidStream::Primary,
    3950              :                                                  ObjectIsNotParent);
    3951              : 
    3952           56 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    3953           28 :                                                   Alphas(4),
    3954              :                                                   ErrorsFound,
    3955              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
    3956           28 :                                                   Alphas(1),
    3957              :                                                   DataLoopNode::NodeFluidType::Air,
    3958              :                                                   DataLoopNode::ConnectionType::Outlet,
    3959              :                                                   NodeInputManager::CompFluidStream::Primary,
    3960              :                                                   ObjectIsNotParent);
    3961              : 
    3962           28 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    3963              : 
    3964              :         // outdoor condenser node
    3965           28 :         if (lAlphaBlanks(5)) {
    3966           15 :             thisDXCoil.CondenserInletNodeNum(1) = 0;
    3967              :         } else {
    3968           26 :             thisDXCoil.CondenserInletNodeNum(1) = GetOnlySingleNode(state,
    3969           13 :                                                                     Alphas(5),
    3970              :                                                                     ErrorsFound,
    3971              :                                                                     DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed,
    3972           13 :                                                                     thisDXCoil.Name,
    3973              :                                                                     DataLoopNode::NodeFluidType::Air,
    3974              :                                                                     DataLoopNode::ConnectionType::OutsideAirReference,
    3975              :                                                                     NodeInputManager::CompFluidStream::Primary,
    3976              :                                                                     ObjectIsNotParent);
    3977           13 :             if (!CheckOutAirNodeNumber(state, thisDXCoil.CondenserInletNodeNum(1))) {
    3978            4 :                 ShowWarningError(state, format("{}{}=\"{}\", may be invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3979            8 :                 ShowContinueError(
    3980            8 :                     state, format("{}=\"{}\", node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.", cAlphaFields(5), Alphas(5)));
    3981           12 :                 ShowContinueError(
    3982              :                     state, "This node needs to be included in an air system or the coil model will not be valid, and the simulation continues");
    3983              :             }
    3984              :         }
    3985              : 
    3986           28 :         if ((Util::SameString(Alphas(6), "AirCooled")) || lAlphaBlanks(6)) {
    3987           28 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Air;
    3988            0 :         } else if (Util::SameString(Alphas(6), "EvaporativelyCooled")) {
    3989            0 :             thisDXCoil.CondenserType(1) = DataHeatBalance::RefrigCondenserType::Evap;
    3990            0 :             thisDXCoil.ReportEvapCondVars = true;
    3991              :         } else {
    3992            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    3993            0 :             ShowContinueError(state, format("...{}=\"{}\":", cAlphaFields(6), Alphas(6)));
    3994            0 :             ShowContinueError(state, "...must be AirCooled or EvaporativelyCooled.");
    3995            0 :             ErrorsFound = true;
    3996              :         }
    3997              : 
    3998              :         // Get Water System tank connections
    3999              :         //  A8, \field Name of Water Storage Tank for Supply
    4000           28 :         thisDXCoil.EvapWaterSupplyName = Alphas(7);
    4001           28 :         if (lAlphaBlanks(7)) {
    4002           28 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromMains;
    4003              :         } else {
    4004            0 :             thisDXCoil.EvapWaterSupplyMode = EvapWaterSupply::FromTank;
    4005            0 :             SetupTankDemandComponent(state,
    4006              :                                      thisDXCoil.Name,
    4007              :                                      CurrentModuleObject,
    4008              :                                      thisDXCoil.EvapWaterSupplyName,
    4009              :                                      ErrorsFound,
    4010            0 :                                      thisDXCoil.EvapWaterSupTankID,
    4011            0 :                                      thisDXCoil.EvapWaterTankDemandARRID);
    4012              :         }
    4013              : 
    4014              :         // A9; \field Name of Water Storage Tank for Condensate Collection
    4015           28 :         thisDXCoil.CondensateCollectName = Alphas(8);
    4016           28 :         if (lAlphaBlanks(8)) {
    4017           28 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    4018              :         } else {
    4019            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    4020            0 :             SetupTankSupplyComponent(state,
    4021              :                                      thisDXCoil.Name,
    4022              :                                      CurrentModuleObject,
    4023              :                                      thisDXCoil.CondensateCollectName,
    4024              :                                      ErrorsFound,
    4025            0 :                                      thisDXCoil.CondensateTankID,
    4026            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    4027              :         }
    4028              : 
    4029              :         // Set minimum OAT for compressor operation
    4030           28 :         thisDXCoil.MinOATCompressor = Numbers(1);
    4031              : 
    4032              :         // Set crankcase heater capacity
    4033           28 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(2);
    4034           28 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    4035            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4036            0 :             ShowContinueError(state, format("...{} cannot be < 0.0.", cNumericFields(2)));
    4037            0 :             ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(2)));
    4038            0 :             ErrorsFound = true;
    4039              :         }
    4040              : 
    4041              :         // Set crankcase heater cutout temperature
    4042           28 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(3);
    4043              : 
    4044           28 :         if (Util::SameString(Alphas(9), "Yes")) {
    4045            0 :             thisDXCoil.PLRImpact = true;
    4046           28 :         } else if (Util::SameString(Alphas(9), "No")) {
    4047           28 :             thisDXCoil.PLRImpact = false;
    4048              :         } else {
    4049            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4050            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(9), Alphas(9)));
    4051            0 :             ShowContinueError(state, "The allowed choices are Yes or No.");
    4052            0 :             ErrorsFound = true;
    4053              :         }
    4054              : 
    4055           28 :         if (Util::SameString(Alphas(10), "Yes")) {
    4056            0 :             thisDXCoil.LatentImpact = true;
    4057           28 :         } else if (Util::SameString(Alphas(10), "No")) {
    4058           28 :             thisDXCoil.LatentImpact = false;
    4059              :         } else {
    4060            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4061            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(10), Alphas(10)));
    4062            0 :             ShowContinueError(state, "The allowed choices are Yes or No.");
    4063            0 :             ErrorsFound = true;
    4064              :         }
    4065              : 
    4066              :         //   Basin heater power as a function of temperature must be greater than or equal to 0
    4067           28 :         thisDXCoil.BasinHeaterPowerFTempDiff = Numbers(4);
    4068           28 :         if (Numbers(4) < 0.0) {
    4069            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4070            0 :             ShowContinueError(state, format("...{} must be >= 0.0, entered value=[{:.3T}].", cNumericFields(4), Numbers(4)));
    4071            0 :             ErrorsFound = true;
    4072              :         }
    4073              : 
    4074           28 :         thisDXCoil.BasinHeaterSetPointTemp = Numbers(5);
    4075           28 :         if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    4076            0 :             if (NumNumbers < 5) {
    4077            0 :                 thisDXCoil.BasinHeaterSetPointTemp = 2.0;
    4078              :             }
    4079            0 :             if (thisDXCoil.BasinHeaterSetPointTemp < 2.0) {
    4080            0 :                 ShowWarningError(state, format("{}{}=\"{}\", freeze possible", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4081            0 :                 ShowContinueError(state, format("...{} is less than 2 {{C}}. Freezing could occur.", cNumericFields(5)));
    4082            0 :                 ShowContinueError(state, format("...entered value=[{:.2T}].", Numbers(5)));
    4083              :             }
    4084              :         }
    4085              : 
    4086           28 :         if (!lAlphaBlanks(11)) {
    4087            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(11));
    4088            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    4089            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(11), Alphas(11)));
    4090            0 :                 ErrorsFound = true;
    4091              :             } else {
    4092            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4093              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    4094              :                                                      {1},                                          // Valid dimensions
    4095              :                                                      RoutineName,                                  // Routine name
    4096              :                                                      CurrentModuleObject,                          // Object Type
    4097              :                                                      thisDXCoil.Name,                              // Object Name
    4098            2 :                                                      cAlphaFields(11));                            // Field Name
    4099              :             }
    4100              :         }
    4101              : 
    4102           28 :         if (!lAlphaBlanks(12)) {
    4103            0 :             if ((thisDXCoil.basinHeaterSched = Sched::GetSchedule(state, Alphas(12))) == nullptr) {
    4104            0 :                 ShowWarningItemNotFound(
    4105            0 :                     state, eoh, cAlphaFields(12), Alphas(12), "Basin heater will be available to operate throughout the simulation.");
    4106              :             }
    4107              :         }
    4108              : 
    4109              :         // A13; \field Fuel type, Validate fuel type input
    4110           28 :         thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(13)));
    4111              : 
    4112           28 :         thisDXCoil.NumOfSpeeds = Numbers(6); // Number of speeds
    4113           28 :         if (thisDXCoil.NumOfSpeeds < 2) {
    4114            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4115            0 :             ShowContinueError(state, format("...{} must be >= 2. entered number is {:.0T}", cNumericFields(6), Numbers(6)));
    4116            0 :             ErrorsFound = true;
    4117              :         }
    4118              : 
    4119              :         // Allocate arrays based on the number of speeds
    4120           28 :         thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
    4121           28 :         thisDXCoil.MSErrIndex = 0;
    4122           28 :         thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
    4123           28 :         thisDXCoil.MSRatedTotCapDes.allocate(thisDXCoil.NumOfSpeeds);
    4124           28 :         thisDXCoil.MSRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
    4125           28 :         thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
    4126           28 :         thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4127           28 :         thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4128           28 :         thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
    4129           28 :         thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
    4130           28 :         thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
    4131           28 :         thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
    4132           28 :         thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
    4133           28 :         thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
    4134           28 :         thisDXCoil.MSEvapCondEffect.allocate(thisDXCoil.NumOfSpeeds);
    4135           28 :         thisDXCoil.MSEvapCondAirFlow.allocate(thisDXCoil.NumOfSpeeds);
    4136           28 :         thisDXCoil.MSEvapCondPumpElecNomPower.allocate(thisDXCoil.NumOfSpeeds);
    4137           28 :         thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
    4138           28 :         thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
    4139           28 :         thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
    4140           28 :         thisDXCoil.MSTwet_Rated.allocate(thisDXCoil.NumOfSpeeds);
    4141           28 :         thisDXCoil.MSGamma_Rated.allocate(thisDXCoil.NumOfSpeeds);
    4142           28 :         thisDXCoil.MSMaxONOFFCyclesperHour.allocate(thisDXCoil.NumOfSpeeds);
    4143           28 :         thisDXCoil.MSLatentCapacityTimeConstant.allocate(thisDXCoil.NumOfSpeeds);
    4144           28 :         thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4145           28 :         thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
    4146              : 
    4147          107 :         for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
    4148           79 :             thisDXCoil.MSRatedTotCap(I) = Numbers(7 + (I - 1) * 14);
    4149           79 :             thisDXCoil.MSRatedSHR(I) = Numbers(8 + (I - 1) * 14);
    4150           79 :             thisDXCoil.MSRatedCOP(I) = Numbers(9 + (I - 1) * 14);
    4151           79 :             thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(10 + (I - 1) * 14);
    4152           79 :             thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(11 + (I - 1) * 14);
    4153           79 :             thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(12 + (I - 1) * 14);
    4154              : 
    4155           79 :             thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
    4156           79 :             if (thisDXCoil.MSCCapFTemp(I) == 0) {
    4157            0 :                 if (lAlphaBlanks(14 + (I - 1) * 6)) {
    4158            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4159            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(14 + (I - 1) * 6)));
    4160              :                 } else {
    4161            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4162            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14 + (I - 1) * 6), Alphas(14 + (I - 1) * 6)));
    4163              :                 }
    4164            0 :                 ErrorsFound = true;
    4165              :             } else {
    4166              :                 // Verify Curve Object, only legal type is BiQuadratic
    4167          237 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4168           79 :                                                      thisDXCoil.MSCCapFTemp(I),       // Curve index
    4169              :                                                      {2},                             // Valid dimensions
    4170              :                                                      RoutineName,                     // Routine name
    4171              :                                                      CurrentModuleObject,             // Object Type
    4172              :                                                      thisDXCoil.Name,                 // Object Name
    4173           79 :                                                      cAlphaFields(14 + (I - 1) * 6)); // Field Name
    4174              : 
    4175           79 :                 if (!ErrorsFound) {
    4176           76 :                     checkCurveIsNormalizedToOne(state,
    4177          228 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4178           76 :                                                 thisDXCoil.Name,
    4179           76 :                                                 thisDXCoil.MSCCapFTemp(I),
    4180           76 :                                                 cAlphaFields(14 + (I - 1) * 6),
    4181           76 :                                                 Alphas(14 + (I - 1) * 6),
    4182              :                                                 RatedInletWetBulbTemp,
    4183              :                                                 RatedOutdoorAirTemp);
    4184              :                 }
    4185              :             }
    4186              : 
    4187           79 :             thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
    4188           79 :             if (thisDXCoil.MSCCapFFlow(I) == 0) {
    4189            0 :                 if (lAlphaBlanks(15 + (I - 1) * 6)) {
    4190            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4191            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(15 + (I - 1) * 6)));
    4192              :                 } else {
    4193            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4194            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
    4195              :                 }
    4196            0 :                 ErrorsFound = true;
    4197              :             } else {
    4198              :                 // Verify Curve Object, only legal type is Quadratic
    4199          237 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4200           79 :                                                      thisDXCoil.MSCCapFFlow(I),       // Curve index
    4201              :                                                      {1},                             // Valid dimensions
    4202              :                                                      RoutineName,                     // Routine name
    4203              :                                                      CurrentModuleObject,             // Object Type
    4204              :                                                      thisDXCoil.Name,                 // Object Name
    4205           79 :                                                      cAlphaFields(15 + (I - 1) * 6)); // Field Name
    4206              : 
    4207           79 :                 if (!ErrorsFound) {
    4208           76 :                     checkCurveIsNormalizedToOne(state,
    4209          228 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4210           76 :                                                 thisDXCoil.Name,
    4211           76 :                                                 thisDXCoil.MSCCapFFlow(I),
    4212           76 :                                                 cAlphaFields(15 + (I - 1) * 6),
    4213           76 :                                                 Alphas(15 + (I - 1) * 6),
    4214              :                                                 1.0);
    4215              :                 }
    4216              :             }
    4217              : 
    4218           79 :             thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
    4219           79 :             if (thisDXCoil.MSEIRFTemp(I) == 0) {
    4220            0 :                 if (lAlphaBlanks(16 + (I - 1) * 6)) {
    4221            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4222            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(16 + (I - 1) * 6)));
    4223              :                 } else {
    4224            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4225            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(16 + (I - 1) * 6), Alphas(16 + (I - 1) * 6)));
    4226              :                 }
    4227            0 :                 ErrorsFound = true;
    4228              :             } else {
    4229              :                 // Verify Curve Object, only legal type is BiQuadratic
    4230          237 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4231           79 :                                                      thisDXCoil.MSEIRFTemp(I),        // Curve index
    4232              :                                                      {2},                             // Valid dimensions
    4233              :                                                      RoutineName,                     // Routine name
    4234              :                                                      CurrentModuleObject,             // Object Type
    4235              :                                                      thisDXCoil.Name,                 // Object Name
    4236           79 :                                                      cAlphaFields(16 + (I - 1) * 6)); // Field Name
    4237              : 
    4238           79 :                 if (!ErrorsFound) {
    4239           76 :                     checkCurveIsNormalizedToOne(state,
    4240          228 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4241           76 :                                                 thisDXCoil.Name,
    4242           76 :                                                 thisDXCoil.MSEIRFTemp(I),
    4243           76 :                                                 cAlphaFields(16 + (I - 1) * 6),
    4244           76 :                                                 Alphas(16 + (I - 1) * 6),
    4245              :                                                 RatedInletWetBulbTemp,
    4246              :                                                 RatedOutdoorAirTemp);
    4247              :                 }
    4248              :             }
    4249              : 
    4250           79 :             thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(17 + (I - 1) * 6)); // convert curve name to number
    4251           79 :             if (thisDXCoil.MSEIRFFlow(I) == 0) {
    4252            0 :                 if (lAlphaBlanks(17 + (I - 1) * 6)) {
    4253            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4254            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(17 + (I - 1) * 6)));
    4255              :                 } else {
    4256            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4257            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(17 + (I - 1) * 6), Alphas(17 + (I - 1) * 6)));
    4258              :                 }
    4259            0 :                 ErrorsFound = true;
    4260              :             } else {
    4261              :                 // Verify Curve Object, only legal type is Quadratic
    4262          237 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4263           79 :                                                      thisDXCoil.MSEIRFFlow(I),        // Curve index
    4264              :                                                      {1},                             // Valid dimensions
    4265              :                                                      RoutineName,                     // Routine name
    4266              :                                                      CurrentModuleObject,             // Object Type
    4267              :                                                      thisDXCoil.Name,                 // Object Name
    4268           79 :                                                      cAlphaFields(17 + (I - 1) * 6)); // Field Name
    4269              : 
    4270           79 :                 if (!ErrorsFound) {
    4271           76 :                     checkCurveIsNormalizedToOne(state,
    4272          228 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4273           76 :                                                 thisDXCoil.Name,
    4274           76 :                                                 thisDXCoil.MSEIRFFlow(I),
    4275           76 :                                                 cAlphaFields(17 + (I - 1) * 6),
    4276           76 :                                                 Alphas(17 + (I - 1) * 6),
    4277              :                                                 1.0);
    4278              :                 }
    4279              :             }
    4280              : 
    4281           79 :             thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(18 + (I - 1) * 6)); // convert curve name to number
    4282           79 :             if (thisDXCoil.MSPLFFPLR(I) == 0) {
    4283            4 :                 if (lAlphaBlanks(18 + (I - 1) * 6)) {
    4284            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4285            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(18 + (I - 1) * 6)));
    4286              :                 } else {
    4287            4 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4288            4 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(18 + (I - 1) * 6), Alphas(18 + (I - 1) * 6)));
    4289              :                 }
    4290            4 :                 ErrorsFound = true;
    4291              :             } else {
    4292              :                 // Verify Curve Object, only legal types are Quadratic or Cubic
    4293          225 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4294           75 :                                                      thisDXCoil.MSPLFFPLR(I),         // Curve index
    4295              :                                                      {1},                             // Valid dimensions
    4296              :                                                      RoutineName,                     // Routine name
    4297              :                                                      CurrentModuleObject,             // Object Type
    4298              :                                                      thisDXCoil.Name,                 // Object Name
    4299           75 :                                                      cAlphaFields(18 + (I - 1) * 6)); // Field Name
    4300              : 
    4301           75 :                 if (!ErrorsFound) {
    4302              :                     //       Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    4303           75 :                     MinCurveVal = 999.0;
    4304           75 :                     MaxCurveVal = -999.0;
    4305           75 :                     CurveInput = 0.0;
    4306         7575 :                     while (CurveInput <= 1.0) {
    4307         7500 :                         CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
    4308         7500 :                         if (CurveVal < MinCurveVal) {
    4309           75 :                             MinCurveVal = CurveVal;
    4310           75 :                             MinCurvePLR = CurveInput;
    4311              :                         }
    4312         7500 :                         if (CurveVal > MaxCurveVal) {
    4313         6256 :                             MaxCurveVal = CurveVal;
    4314         6256 :                             MaxCurvePLR = CurveInput;
    4315              :                         }
    4316         7500 :                         CurveInput += 0.01;
    4317              :                     }
    4318           75 :                     if (MinCurveVal < 0.7) {
    4319            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4320            0 :                         ShowContinueError(state,
    4321            0 :                                           format("...{} = {} has out of range value.", cAlphaFields2(18 + (I - 1) * 6), Alphas2(18 + (I - 1) * 6)));
    4322            0 :                         ShowContinueError(state,
    4323            0 :                                           format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    4324            0 :                         ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    4325            0 :                         Curve::SetCurveOutputMinValue(state, thisDXCoil.PLFFPLR(PerfModeNum), ErrorsFound, 0.7);
    4326              :                     }
    4327              : 
    4328           75 :                     if (MaxCurveVal > 1.0) {
    4329            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4330            0 :                         ShowContinueError(state,
    4331            0 :                                           format("...{} = {} has out of range value.", cAlphaFields2(18 + (I - 1) * 6), Alphas2(18 + (I - 1) * 6)));
    4332            0 :                         ShowContinueError(state,
    4333            0 :                                           format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    4334            0 :                         ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    4335            0 :                         Curve::SetCurveOutputMaxValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 1.0);
    4336              :                     }
    4337              :                 }
    4338              :             }
    4339              : 
    4340              :             // read data for latent degradation
    4341           79 :             thisDXCoil.MSTwet_Rated(I) = Numbers(13 + (I - 1) * 14);
    4342           79 :             if (thisDXCoil.MSTwet_Rated(I) < 0.0) {
    4343            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4344            0 :                 ShowContinueError(
    4345            0 :                     state, format("...{} cannot be < 0.0, entered value=[{:.4T}].", cNumericFields(13 + (I - 1) * 14), thisDXCoil.MSTwet_Rated(I)));
    4346            0 :                 ErrorsFound = true;
    4347              :             }
    4348           79 :             thisDXCoil.MSGamma_Rated(I) = Numbers(14 + (I - 1) * 14);
    4349           79 :             if (thisDXCoil.MSGamma_Rated(I) < 0.0) {
    4350            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4351            0 :                 ShowContinueError(
    4352            0 :                     state, format("...{} cannot be < 0.0, entered value=[{:.4T}].", cNumericFields(14 + (I - 1) * 14), thisDXCoil.MSGamma_Rated(I)));
    4353            0 :                 ErrorsFound = true;
    4354              :             }
    4355           79 :             thisDXCoil.MSMaxONOFFCyclesperHour(I) = Numbers(15 + (I - 1) * 14);
    4356           79 :             if (thisDXCoil.Gamma_Rated(I) < 0.0) {
    4357            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4358            0 :                 ShowContinueError(state,
    4359            0 :                                   format("...{} cannot be < 0.0, entered value=[{:.2T}].",
    4360            0 :                                          cNumericFields(15 + (I - 1) * 14),
    4361              :                                          thisDXCoil.MSMaxONOFFCyclesperHour(I)));
    4362            0 :                 ErrorsFound = true;
    4363              :             }
    4364           79 :             thisDXCoil.MSLatentCapacityTimeConstant(I) = Numbers(16 + (I - 1) * 14);
    4365           79 :             if (thisDXCoil.Gamma_Rated(I) < 0.0) {
    4366            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4367            0 :                 ShowContinueError(state,
    4368            0 :                                   format("...{} cannot be < 0.0, entered value=[{:.2T}].",
    4369            0 :                                          cNumericFields(16 + (I - 1) * 14),
    4370              :                                          thisDXCoil.MSLatentCapacityTimeConstant(I)));
    4371            0 :                 ErrorsFound = true;
    4372              :             }
    4373              : 
    4374           79 :             thisDXCoil.MSWasteHeatFrac(I) = Numbers(17 + (I - 1) * 14);
    4375              : 
    4376              :             // Read waste heat modifier curve name
    4377           79 :             thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(19 + (I - 1) * 6)); // convert curve name to number
    4378           79 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
    4379           16 :                 if (thisDXCoil.MSWasteHeat(I) > 0) {
    4380              :                     // Verify Curve Object, only legal types are BiQuadratic
    4381           48 :                     ErrorsFound |= Curve::CheckCurveDims(state,
    4382           16 :                                                          thisDXCoil.MSWasteHeat(I),       // Curve index
    4383              :                                                          {2},                             // Valid dimensions
    4384              :                                                          RoutineName,                     // Routine name
    4385              :                                                          CurrentModuleObject,             // Object Type
    4386              :                                                          thisDXCoil.Name,                 // Object Name
    4387           16 :                                                          cAlphaFields(19 + (I - 1) * 6)); // Field Name
    4388              : 
    4389           16 :                     if (!ErrorsFound) {
    4390           16 :                         CurveVal = CurveValue(state, thisDXCoil.MSWasteHeat(I), RatedOutdoorAirTemp, RatedInletAirTemp);
    4391           16 :                         if (CurveVal > 1.10 || CurveVal < 0.90) {
    4392            0 :                             ShowWarningError(state, format("{}{}=\"{}\", curve values", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4393            0 :                             ShowContinueError(state, format("{} = {}", cAlphaFields(19 + (I - 1) * 6), Alphas(19 + (I - 1) * 6)));
    4394            0 :                             ShowContinueError(
    4395            0 :                                 state, format("...{} output is not equal to 1.0 (+ or - 10%) at rated conditions.", cAlphaFields(19 + (I - 1) * 6)));
    4396            0 :                             ShowContinueError(state, format("...Curve output at rated conditions = {:.3T}", CurveVal));
    4397              :                         }
    4398              :                     }
    4399              :                 }
    4400              :             }
    4401              : 
    4402           79 :             thisDXCoil.MSEvapCondEffect(I) = Numbers(18 + (I - 1) * 14);
    4403           79 :             if (thisDXCoil.MSEvapCondEffect(I) < 0.0 || thisDXCoil.MSEvapCondEffect(I) > 1.0) {
    4404            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4405            0 :                 ShowContinueError(
    4406              :                     state,
    4407            0 :                     format("...{} cannot be < 0.0 or > 1.0, entered value=[{:.3T}].", cNumericFields(18 + (I - 1) * 14), Numbers(18 + (I - 1) * 14)));
    4408            0 :                 ErrorsFound = true;
    4409              :             }
    4410              : 
    4411           79 :             thisDXCoil.MSEvapCondAirFlow(I) = Numbers(19 + (I - 1) * 14);
    4412           79 :             if (thisDXCoil.MSEvapCondAirFlow(I) < 0.0 && thisDXCoil.MSEvapCondAirFlow(I) != AutoSize) {
    4413            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4414            0 :                 ShowContinueError(
    4415            0 :                     state, format("...{} cannot be < 0.0, entered value=[{:.3T}].", cNumericFields(19 + (I - 1) * 14), Numbers(19 + (I - 1) * 14)));
    4416            0 :                 ErrorsFound = true;
    4417              :             }
    4418              : 
    4419           79 :             thisDXCoil.MSEvapCondPumpElecNomPower(I) = Numbers(20 + (I - 1) * 14);
    4420           79 :             if (thisDXCoil.MSEvapCondPumpElecNomPower(I) < 0.0 && thisDXCoil.MSEvapCondPumpElecNomPower(I) != AutoSize) {
    4421            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4422            0 :                 ShowContinueError(
    4423            0 :                     state, format("...{} cannot be < 0.0, entered value=[{:.3T}].", cNumericFields(20 + (I - 1) * 14), Numbers(20 + (I - 1) * 14)));
    4424            0 :                 ErrorsFound = true;
    4425              :             }
    4426              :         }
    4427              :         // A38; \field Zone Name for Condenser Placement
    4428           28 :         if (!lAlphaBlanks(38) && NumAlphas > 37) {
    4429            0 :             thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(38), state.dataHeatBal->Zone);
    4430            0 :             if (thisDXCoil.SecZonePtr > 0) {
    4431            0 :                 SetupZoneInternalGain(state,
    4432              :                                       thisDXCoil.SecZonePtr,
    4433              :                                       thisDXCoil.Name,
    4434              :                                       DataHeatBalance::IntGainType::SecCoolingDXCoilMultiSpeed,
    4435              :                                       &thisDXCoil.SecCoilSensibleHeatGainRate);
    4436            0 :                 thisDXCoil.IsSecondaryDXCoilInZone = true;
    4437              :             } else {
    4438            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4439            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(38), Alphas(38)));
    4440              :             }
    4441              :         }
    4442              :     }
    4443              : 
    4444          135 :     if (ErrorsFound) {
    4445            3 :         ShowFatalError(state,
    4446            3 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    4447              :     }
    4448              : 
    4449              :     // DX multispeed heating coil
    4450          134 :     CurrentModuleObject = "Coil:Heating:DX:MultiSpeed";
    4451          148 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumDXMulSpeedHeatCoils; ++DXCoilIndex) {
    4452              : 
    4453           14 :         ++DXCoilNum;
    4454              : 
    4455           14 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    4456              :                                                                  CurrentModuleObject,
    4457              :                                                                  DXCoilIndex,
    4458              :                                                                  Alphas,
    4459              :                                                                  NumAlphas,
    4460              :                                                                  Numbers,
    4461              :                                                                  NumNumbers,
    4462              :                                                                  IOStatus,
    4463              :                                                                  lNumericBlanks,
    4464              :                                                                  lAlphaBlanks,
    4465              :                                                                  cAlphaFields,
    4466              :                                                                  cNumericFields);
    4467              : 
    4468           14 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    4469              : 
    4470              :         // *** will have to circle back to this one to fix since the multispeed coil has all fields in this coil object ***
    4471              :         // allocate single performance mode for numeric field strings used for sizing routine
    4472           14 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    4473           14 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    4474           14 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    4475              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    4476           14 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    4477              : 
    4478           14 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    4479           14 :         thisDXCoil.Name = Alphas(1);
    4480              :         // Initialize DataHeatBalance heat reclaim variable name for use by heat reclaim coils
    4481           14 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name = thisDXCoil.Name;
    4482           14 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).SourceType = CurrentModuleObject;
    4483           14 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    4484           14 :         thisDXCoil.DXCoilType_Num = HVAC::CoilDX_MultiSpeedHeating;
    4485           14 :         if (lAlphaBlanks(2)) {
    4486            8 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    4487            6 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    4488            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    4489            0 :             ErrorsFound = true;
    4490              :         }
    4491              : 
    4492           14 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    4493           14 :                                                  Alphas(3),
    4494              :                                                  ErrorsFound,
    4495              :                                                  DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
    4496           14 :                                                  Alphas(1),
    4497              :                                                  DataLoopNode::NodeFluidType::Air,
    4498              :                                                  DataLoopNode::ConnectionType::Inlet,
    4499              :                                                  NodeInputManager::CompFluidStream::Primary,
    4500              :                                                  ObjectIsNotParent);
    4501              : 
    4502           28 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    4503           14 :                                                   Alphas(4),
    4504              :                                                   ErrorsFound,
    4505              :                                                   DataLoopNode::ConnectionObjectType::CoilHeatingDXMultiSpeed,
    4506           14 :                                                   Alphas(1),
    4507              :                                                   DataLoopNode::NodeFluidType::Air,
    4508              :                                                   DataLoopNode::ConnectionType::Outlet,
    4509              :                                                   NodeInputManager::CompFluidStream::Primary,
    4510              :                                                   ObjectIsNotParent);
    4511              : 
    4512           14 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    4513              : 
    4514              :         // Set minimum OAT for heat pump compressor operation
    4515           14 :         thisDXCoil.MinOATCompressor = Numbers(1);
    4516              : 
    4517              :         // set Minimum Outdoor Dry-Bulb Temperature for Compressor Operation
    4518           14 :         thisDXCoil.OATempCompressorOn = Numbers(2);
    4519              :         // Set crankcase heater capacity
    4520           14 :         thisDXCoil.CrankcaseHeaterCapacity = Numbers(3);
    4521           14 :         if (thisDXCoil.CrankcaseHeaterCapacity < 0.0) {
    4522            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4523            0 :             ShowContinueError(state, format("...{} cannot be < 0.0, entered value=[{:.2T}].", cNumericFields(3), Numbers(3)));
    4524            0 :             ErrorsFound = true;
    4525              :         }
    4526              : 
    4527              :         // Set crankcase heater cutout temperature
    4528           14 :         thisDXCoil.MaxOATCrankcaseHeater = Numbers(4);
    4529              : 
    4530           14 :         if (!lAlphaBlanks(5)) {
    4531            2 :             thisDXCoil.CrankcaseHeaterCapacityCurveIndex = Curve::GetCurveIndex(state, Alphas(5));
    4532            2 :             if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex == 0) { // can't find the curve
    4533            0 :                 ShowSevereError(state, format("{} = {}:  {} not found = {}", CurrentModuleObject, thisDXCoil.Name, cAlphaFields(5), Alphas(5)));
    4534            0 :                 ErrorsFound = true;
    4535              :             } else {
    4536            6 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4537              :                                                      thisDXCoil.CrankcaseHeaterCapacityCurveIndex, // Curve index
    4538              :                                                      {1},                                          // Valid dimensions
    4539              :                                                      RoutineName,                                  // Routine name
    4540              :                                                      CurrentModuleObject,                          // Object Type
    4541              :                                                      thisDXCoil.Name,                              // Object Name
    4542            2 :                                                      cAlphaFields(5));                             // Field Name
    4543              :             }
    4544              :         }
    4545              : 
    4546              :         // Only required for reverse cycle heat pumps
    4547           14 :         thisDXCoil.DefrostEIRFT = GetCurveIndex(state, Alphas(6)); // convert curve name to number
    4548           14 :         if (Util::SameString(Alphas(7), "ReverseCycle")) {
    4549           13 :             if (thisDXCoil.DefrostEIRFT == 0) {
    4550            0 :                 if (lAlphaBlanks(6)) {
    4551            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4552            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
    4553              :                 } else {
    4554            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4555            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
    4556              :                 }
    4557            0 :                 ErrorsFound = true;
    4558              :             } else {
    4559              :                 // Verify Curve Object, only legal type is BiQuadratic
    4560           26 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4561              :                                                      thisDXCoil.DefrostEIRFT, // Curve index
    4562              :                                                      {2},                     // Valid dimensions
    4563              :                                                      RoutineName,             // Routine name
    4564              :                                                      CurrentModuleObject,     // Object Type
    4565              :                                                      thisDXCoil.Name,         // Object Name
    4566           13 :                                                      cAlphaFields(6));        // Field Name
    4567              : 
    4568           13 :                 if (!ErrorsFound) {
    4569           13 :                     checkCurveIsNormalizedToOne(state,
    4570           39 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4571           13 :                                                 thisDXCoil.Name,
    4572              :                                                 thisDXCoil.DefrostEIRFT,
    4573           13 :                                                 cAlphaFields(6),
    4574           13 :                                                 Alphas(6),
    4575              :                                                 RatedInletWetBulbTempHeat,
    4576              :                                                 RatedOutdoorAirTempHeat);
    4577              :                 }
    4578              :             }
    4579              :         }
    4580              : 
    4581           14 :         if (Util::SameString(Alphas(7), "ReverseCycle")) {
    4582           13 :             thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::ReverseCycle;
    4583              :         }
    4584           14 :         if (Util::SameString(Alphas(7), "Resistive")) {
    4585            1 :             thisDXCoil.DefrostStrategy = StandardRatings::DefrostStrat::Resistive;
    4586              :         }
    4587           14 :         if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Invalid) {
    4588            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4589            0 :             ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(7), Alphas(7)));
    4590            0 :             ShowContinueError(state, "...valid values for this field are ReverseCycle or Resistive.");
    4591            0 :             ErrorsFound = true;
    4592              :         }
    4593              : 
    4594           14 :         if (Util::SameString(Alphas(8), "Timed")) {
    4595            3 :             thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::Timed;
    4596              :         }
    4597           14 :         if (Util::SameString(Alphas(8), "OnDemand")) {
    4598           11 :             thisDXCoil.DefrostControl = StandardRatings::HPdefrostControl::OnDemand;
    4599              :         }
    4600           14 :         if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Invalid) {
    4601            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4602            0 :             ShowContinueError(state, format("...illegal {}=\"{}\".", cAlphaFields(8), Alphas(8)));
    4603            0 :             ShowContinueError(state, "...valid values for this field are Timed or OnDemand.");
    4604            0 :             ErrorsFound = true;
    4605              :         }
    4606              : 
    4607              :         // Set maximum outdoor temp for defrost to occur
    4608           14 :         thisDXCoil.MaxOATDefrost = Numbers(5);
    4609              : 
    4610              :         // Set defrost time period
    4611           14 :         thisDXCoil.DefrostTime = Numbers(6);
    4612           14 :         if (thisDXCoil.DefrostTime == 0.0 && thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
    4613            0 :             ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4614            0 :             ShowContinueError(state, format("...{} = 0.0 for defrost control = TIMED.", cNumericFields(5)));
    4615              :         }
    4616              : 
    4617              :         // Set defrost capacity (for resistive defrost)
    4618           14 :         thisDXCoil.DefrostCapacity = Numbers(7);
    4619           14 :         if (thisDXCoil.DefrostCapacity == 0.0 && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
    4620            0 :             ShowWarningError(state, format("{}{}=\"{}\", ", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4621            0 :             ShowContinueError(state, format("...{} = 0.0 for defrost strategy = RESISTIVE.", cNumericFields(7)));
    4622              :         }
    4623              : 
    4624           14 :         if (Util::SameString(Alphas(9), "Yes")) {
    4625            0 :             thisDXCoil.PLRImpact = true;
    4626           14 :         } else if (Util::SameString(Alphas(9), "No")) {
    4627           14 :             thisDXCoil.PLRImpact = false;
    4628              :         } else {
    4629            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4630            0 :             ShowContinueError(state, format(",,,invalid choice for {}.  Entered choice = {}", cAlphaFields(9), Alphas(9)));
    4631            0 :             ShowContinueError(state, "The allowed choices are Yes or No.");
    4632            0 :             ErrorsFound = true;
    4633              :         }
    4634              : 
    4635              :         // A10; \field Fuel type, Validate fuel type input
    4636           14 :         thisDXCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(10)));
    4637              : 
    4638           14 :         thisDXCoil.RegionNum = Numbers(8);   // Region Number for HSPF Calc
    4639           14 :         thisDXCoil.NumOfSpeeds = Numbers(9); // Number of speeds
    4640           14 :         if (thisDXCoil.NumOfSpeeds < 2) {
    4641            0 :             ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4642            0 :             ShowContinueError(state, format("...{} must be >= 2. entered number is {:.0T}", cNumericFields(9), Numbers(9)));
    4643            0 :             ErrorsFound = true;
    4644              :         }
    4645              : 
    4646              :         // Allocate arrays based on the number of speeds
    4647           14 :         thisDXCoil.MSErrIndex.allocate(thisDXCoil.NumOfSpeeds);
    4648           14 :         thisDXCoil.MSErrIndex = 0;
    4649           14 :         thisDXCoil.MSRatedTotCap.allocate(thisDXCoil.NumOfSpeeds);
    4650           14 :         thisDXCoil.MSRatedCOP.allocate(thisDXCoil.NumOfSpeeds);
    4651           14 :         thisDXCoil.MSRatedAirVolFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4652           14 :         thisDXCoil.MSRatedAirMassFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4653           14 :         thisDXCoil.MSRatedAirMassFlowRate = 1.0; // avoid divide by 0, will get overwritten in InitDXCoil
    4654           14 :         thisDXCoil.MSCCapFTemp.allocate(thisDXCoil.NumOfSpeeds);
    4655           14 :         thisDXCoil.MSCCapFFlow.allocate(thisDXCoil.NumOfSpeeds);
    4656           14 :         thisDXCoil.MSEIRFTemp.allocate(thisDXCoil.NumOfSpeeds);
    4657           14 :         thisDXCoil.MSEIRFFlow.allocate(thisDXCoil.NumOfSpeeds);
    4658           14 :         thisDXCoil.MSWasteHeat.allocate(thisDXCoil.NumOfSpeeds);
    4659           14 :         thisDXCoil.MSPLFFPLR.allocate(thisDXCoil.NumOfSpeeds);
    4660           14 :         thisDXCoil.MSRatedCBF.allocate(thisDXCoil.NumOfSpeeds);
    4661           14 :         thisDXCoil.MSWasteHeatFrac.allocate(thisDXCoil.NumOfSpeeds);
    4662           14 :         thisDXCoil.MSFanPowerPerEvapAirFlowRate.allocate(thisDXCoil.NumOfSpeeds);
    4663           14 :         thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023.allocate(thisDXCoil.NumOfSpeeds);
    4664           14 :         thisDXCoil.MSSecCoilSHRFT.allocate(thisDXCoil.NumOfSpeeds);
    4665           14 :         thisDXCoil.MSSecCoilSHRFF.allocate(thisDXCoil.NumOfSpeeds);
    4666           14 :         thisDXCoil.MSSecCoilAirFlow.allocate(thisDXCoil.NumOfSpeeds);
    4667           14 :         thisDXCoil.MSSecCoilAirFlowScalingFactor.allocate(thisDXCoil.NumOfSpeeds);
    4668           14 :         thisDXCoil.MSSecCoilRatedSHR.allocate(thisDXCoil.NumOfSpeeds);
    4669              : 
    4670           14 :         thisDXCoil.RatedSHR(1) = 1.0;
    4671              : 
    4672           48 :         for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
    4673           34 :             thisDXCoil.MSRatedTotCap(I) = Numbers(10 + (I - 1) * 6);
    4674           34 :             thisDXCoil.MSRatedCOP(I) = Numbers(11 + (I - 1) * 6);
    4675           34 :             thisDXCoil.MSRatedAirVolFlowRate(I) = Numbers(12 + (I - 1) * 6);
    4676           34 :             thisDXCoil.MSFanPowerPerEvapAirFlowRate(I) = Numbers(13 + (I - 1) * 6);
    4677           34 :             thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023(I) = Numbers(14 + (I - 1) * 6);
    4678           34 :             thisDXCoil.MSWasteHeatFrac(I) = Numbers(15 + (I - 1) * 6);
    4679              : 
    4680           34 :             thisDXCoil.MSCCapFTemp(I) = GetCurveIndex(state, Alphas(11 + (I - 1) * 6)); // convert curve name to number
    4681           34 :             if (thisDXCoil.MSCCapFTemp(I) == 0) {
    4682            0 :                 ShowSevereError(state,
    4683            0 :                                 format("{}, \"{}\" {} not found:{}",
    4684              :                                        CurrentModuleObject,
    4685            0 :                                        thisDXCoil.Name,
    4686            0 :                                        cAlphaFields(11 + (I - 1) * 6),
    4687            0 :                                        Alphas(11 + (I - 1) * 6)));
    4688            0 :                 ErrorsFound = true;
    4689              :             } else {
    4690              :                 // only legal types are Quadratic, BiQuadratic and Cubic
    4691          102 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4692           34 :                                                      thisDXCoil.MSCCapFTemp(I),       // Curve index
    4693              :                                                      {1, 2},                          // Valid dimensions  // MULTIPLECURVEDIMS
    4694              :                                                      RoutineName,                     // Routine name
    4695              :                                                      CurrentModuleObject,             // Object Type
    4696              :                                                      thisDXCoil.Name,                 // Object Name
    4697           34 :                                                      cAlphaFields(11 + (I - 1) * 6)); // Field Name
    4698              : 
    4699           34 :                 if (!ErrorsFound) {
    4700           34 :                     if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(I))->numDims == 1) {
    4701            8 :                         checkCurveIsNormalizedToOne(state,
    4702           24 :                                                     std::string{RoutineName} + CurrentModuleObject,
    4703            8 :                                                     thisDXCoil.Name,
    4704            8 :                                                     thisDXCoil.MSCCapFTemp(I),
    4705            8 :                                                     cAlphaFields(11 + (I - 1) * 6),
    4706            8 :                                                     Alphas(11 + (I - 1) * 6),
    4707              :                                                     RatedOutdoorAirTempHeat);
    4708              :                     } else {
    4709           26 :                         checkCurveIsNormalizedToOne(state,
    4710           78 :                                                     std::string{RoutineName} + CurrentModuleObject,
    4711           26 :                                                     thisDXCoil.Name,
    4712           26 :                                                     thisDXCoil.MSCCapFTemp(I),
    4713           26 :                                                     cAlphaFields(11 + (I - 1) * 6),
    4714           26 :                                                     Alphas(11 + (I - 1) * 6),
    4715              :                                                     RatedInletAirTempHeat,
    4716              :                                                     RatedOutdoorAirTempHeat);
    4717              :                     }
    4718              :                 }
    4719              :             }
    4720              : 
    4721           34 :             thisDXCoil.MSCCapFFlow(I) = GetCurveIndex(state, Alphas(12 + (I - 1) * 6)); // convert curve name to number
    4722           34 :             if (thisDXCoil.MSCCapFFlow(I) == 0) {
    4723            0 :                 if (lAlphaBlanks(12 + (I - 1) * 6)) {
    4724            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4725            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(12 + (I - 1) * 6)));
    4726              :                 } else {
    4727            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4728            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(12 + (I - 1) * 6), Alphas(12 + (I - 1) * 6)));
    4729              :                 }
    4730            0 :                 ErrorsFound = true;
    4731              :             } else {
    4732              :                 // Verify Curve Object, only legal type is Quadratic
    4733          102 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4734           34 :                                                      thisDXCoil.MSCCapFFlow(I),       // Curve index
    4735              :                                                      {1},                             // Valid dimensions
    4736              :                                                      RoutineName,                     // Routine name
    4737              :                                                      CurrentModuleObject,             // Object Type
    4738              :                                                      thisDXCoil.Name,                 // Object Name
    4739           34 :                                                      cAlphaFields(12 + (I - 1) * 6)); // Field Name
    4740              : 
    4741           34 :                 if (!ErrorsFound) {
    4742           34 :                     checkCurveIsNormalizedToOne(state,
    4743          102 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4744           34 :                                                 thisDXCoil.Name,
    4745           34 :                                                 thisDXCoil.MSCCapFFlow(I),
    4746           34 :                                                 cAlphaFields(12 + (I - 1) * 6),
    4747           34 :                                                 Alphas(12 + (I - 1) * 6),
    4748              :                                                 1.0);
    4749              :                 }
    4750              :             }
    4751              : 
    4752           34 :             thisDXCoil.MSEIRFTemp(I) = GetCurveIndex(state, Alphas(13 + (I - 1) * 6)); // convert curve name to number
    4753           34 :             if (thisDXCoil.MSEIRFTemp(I) == 0) {
    4754            0 :                 if (lAlphaBlanks(13 + (I - 1) * 6)) {
    4755            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4756            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(13 + (I - 1) * 6)));
    4757              :                 } else {
    4758            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4759            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(13 + (I - 1) * 6), Alphas(13 + (I - 1) * 6)));
    4760              :                 }
    4761            0 :                 ErrorsFound = true;
    4762              :             } else {
    4763              :                 // only legal types are Quadratic, BiQuadratic and Cubic
    4764          102 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4765           34 :                                                      thisDXCoil.MSEIRFTemp(I),        // Curve index
    4766              :                                                      {1, 2},                          // Valid dimensions  // MULTIPLECURVEDIMS
    4767              :                                                      RoutineName,                     // Routine name
    4768              :                                                      CurrentModuleObject,             // Object Type
    4769              :                                                      thisDXCoil.Name,                 // Object Name
    4770           34 :                                                      cAlphaFields(13 + (I - 1) * 6)); // Field Name
    4771              : 
    4772           34 :                 if (!ErrorsFound) {
    4773           34 :                     if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(I))->numDims == 1) {
    4774            8 :                         checkCurveIsNormalizedToOne(state,
    4775           24 :                                                     std::string{RoutineName} + CurrentModuleObject,
    4776            8 :                                                     thisDXCoil.Name,
    4777            8 :                                                     thisDXCoil.MSEIRFTemp(I),
    4778            8 :                                                     cAlphaFields(13 + (I - 1) * 6),
    4779            8 :                                                     Alphas(13 + (I - 1) * 6),
    4780              :                                                     RatedOutdoorAirTempHeat);
    4781              :                     } else {
    4782           26 :                         checkCurveIsNormalizedToOne(state,
    4783           78 :                                                     std::string{RoutineName} + CurrentModuleObject,
    4784           26 :                                                     thisDXCoil.Name,
    4785           26 :                                                     thisDXCoil.MSEIRFTemp(I),
    4786           26 :                                                     cAlphaFields(13 + (I - 1) * 6),
    4787           26 :                                                     Alphas(13 + (I - 1) * 6),
    4788              :                                                     RatedInletAirTempHeat,
    4789              :                                                     RatedOutdoorAirTempHeat);
    4790              :                     }
    4791              :                 }
    4792              :             }
    4793              : 
    4794           34 :             thisDXCoil.MSEIRFFlow(I) = GetCurveIndex(state, Alphas(14 + (I - 1) * 6)); // convert curve name to number
    4795           34 :             if (thisDXCoil.MSEIRFFlow(I) == 0) {
    4796            0 :                 if (lAlphaBlanks(14 + (I - 1) * 6)) {
    4797            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4798            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(14 + (I - 1) * 6)));
    4799              :                 } else {
    4800            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4801            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(14 + (I - 1) * 6), Alphas(14 + (I - 1) * 6)));
    4802              :                 }
    4803            0 :                 ErrorsFound = true;
    4804              :             } else {
    4805              :                 // Verify Curve Object, only legal type is Quadratic
    4806          102 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4807           34 :                                                      thisDXCoil.MSEIRFFlow(I),        // Curve index
    4808              :                                                      {1},                             // Valid dimensions
    4809              :                                                      RoutineName,                     // Routine name
    4810              :                                                      CurrentModuleObject,             // Object Type
    4811              :                                                      thisDXCoil.Name,                 // Object Name
    4812           34 :                                                      cAlphaFields(14 + (I - 1) * 6)); // Field Name
    4813              : 
    4814           34 :                 if (!ErrorsFound) {
    4815           34 :                     checkCurveIsNormalizedToOne(state,
    4816          102 :                                                 std::string{RoutineName} + CurrentModuleObject,
    4817           34 :                                                 thisDXCoil.Name,
    4818           34 :                                                 thisDXCoil.MSEIRFFlow(I),
    4819           34 :                                                 cAlphaFields(14 + (I - 1) * 6),
    4820           34 :                                                 Alphas(14 + (I - 1) * 6),
    4821              :                                                 1.0);
    4822              :                 }
    4823              :             }
    4824              : 
    4825           34 :             thisDXCoil.MSPLFFPLR(I) = GetCurveIndex(state, Alphas(15 + (I - 1) * 6)); // convert curve name to number
    4826           34 :             if (thisDXCoil.MSPLFFPLR(I) == 0) {
    4827            0 :                 if (lAlphaBlanks(15 + (I - 1) * 6)) {
    4828            0 :                     ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4829            0 :                     ShowContinueError(state, format("...required {} is blank.", cAlphaFields(15 + (I - 1) * 6)));
    4830              :                 } else {
    4831            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4832            0 :                     ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
    4833              :                 }
    4834            0 :                 ErrorsFound = true;
    4835              :             } else {
    4836              :                 // Verify Curve Object, only legal types are Quadratic or Cubic
    4837          102 :                 ErrorsFound |= Curve::CheckCurveDims(state,
    4838           34 :                                                      thisDXCoil.MSPLFFPLR(I),         // Curve index
    4839              :                                                      {1},                             // Valid dimensions
    4840              :                                                      RoutineName,                     // Routine name
    4841              :                                                      CurrentModuleObject,             // Object Type
    4842              :                                                      thisDXCoil.Name,                 // Object Name
    4843           34 :                                                      cAlphaFields(15 + (I - 1) * 6)); // Field Name
    4844              : 
    4845           34 :                 if (!ErrorsFound) {
    4846              :                     //       Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
    4847           34 :                     MinCurveVal = 999.0;
    4848           34 :                     MaxCurveVal = -999.0;
    4849           34 :                     CurveInput = 0.0;
    4850         3434 :                     while (CurveInput <= 1.0) {
    4851         3400 :                         CurveVal = CurveValue(state, thisDXCoil.MSPLFFPLR(I), CurveInput);
    4852         3400 :                         if (CurveVal < MinCurveVal) {
    4853           34 :                             MinCurveVal = CurveVal;
    4854           34 :                             MinCurvePLR = CurveInput;
    4855              :                         }
    4856         3400 :                         if (CurveVal > MaxCurveVal) {
    4857         2944 :                             MaxCurveVal = CurveVal;
    4858         2944 :                             MaxCurvePLR = CurveInput;
    4859              :                         }
    4860         3400 :                         CurveInput += 0.01;
    4861              :                     }
    4862           34 :                     if (MinCurveVal < 0.7) {
    4863            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4864            0 :                         ShowContinueError(state,
    4865            0 :                                           format("...{} = {} has out of range value.", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
    4866            0 :                         ShowContinueError(state,
    4867            0 :                                           format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
    4868            0 :                         ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
    4869            0 :                         Curve::SetCurveOutputMinValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 0.7);
    4870              :                     }
    4871              : 
    4872           34 :                     if (MaxCurveVal > 1.0) {
    4873            0 :                         ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4874            0 :                         ShowContinueError(state,
    4875            0 :                                           format("...{} = {} has out of range value.", cAlphaFields(15 + (I - 1) * 6), Alphas(15 + (I - 1) * 6)));
    4876            0 :                         ShowContinueError(state,
    4877            0 :                                           format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
    4878            0 :                         ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
    4879            0 :                         Curve::SetCurveOutputMaxValue(state, thisDXCoil.MSPLFFPLR(I), ErrorsFound, 1.0);
    4880              :                     }
    4881              :                 }
    4882              :             }
    4883              : 
    4884              :             // Read waste heat modifier curve name
    4885           34 :             thisDXCoil.MSWasteHeat(I) = GetCurveIndex(state, Alphas(16 + (I - 1) * 6)); // convert curve name to number
    4886           34 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
    4887           12 :                 if (thisDXCoil.MSWasteHeat(I) > 0) {
    4888              :                     // Verify Curve Object, only legal types are BiQuadratic
    4889           24 :                     ErrorsFound |= Curve::CheckCurveDims(state,
    4890            8 :                                                          thisDXCoil.MSWasteHeat(I),       // Curve index
    4891              :                                                          {2},                             // Valid dimensions
    4892              :                                                          RoutineName,                     // Routine name
    4893              :                                                          CurrentModuleObject,             // Object Type
    4894              :                                                          thisDXCoil.Name,                 // Object Name
    4895            8 :                                                          cAlphaFields(16 + (I - 1) * 6)); // Field Name
    4896              : 
    4897            8 :                     if (!ErrorsFound) {
    4898            8 :                         checkCurveIsNormalizedToOne(state,
    4899           24 :                                                     std::string{RoutineName} + CurrentModuleObject,
    4900            8 :                                                     thisDXCoil.Name,
    4901            8 :                                                     thisDXCoil.MSWasteHeat(I),
    4902            8 :                                                     cAlphaFields(16 + (I - 1) * 6),
    4903            8 :                                                     Alphas(16 + (I - 1) * 6),
    4904              :                                                     RatedOutdoorAirTempHeat,
    4905              :                                                     RatedInletAirTempHeat);
    4906              :                     }
    4907              :                 }
    4908              :             }
    4909              :         }
    4910              :         // A35; \field Zone Name for Condenser Placement
    4911           14 :         if (!lAlphaBlanks(35) && NumAlphas > 34) {
    4912            0 :             thisDXCoil.SecZonePtr = Util::FindItemInList(Alphas(35), state.dataHeatBal->Zone);
    4913            0 :             if (thisDXCoil.SecZonePtr > 0) {
    4914            0 :                 SetupZoneInternalGain(state,
    4915              :                                       thisDXCoil.SecZonePtr,
    4916              :                                       thisDXCoil.Name,
    4917              :                                       DataHeatBalance::IntGainType::SecHeatingDXCoilMultiSpeed,
    4918              :                                       &thisDXCoil.SecCoilSensibleHeatRemovalRate,
    4919              :                                       nullptr,
    4920              :                                       nullptr,
    4921              :                                       &thisDXCoil.SecCoilLatentHeatRemovalRate);
    4922            0 :                 thisDXCoil.IsSecondaryDXCoilInZone = true;
    4923              :             } else {
    4924            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4925            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(35), Alphas(35)));
    4926              :             }
    4927              :         }
    4928           14 :         if (thisDXCoil.SecZonePtr > 0) {
    4929            0 :             for (I = 1; I <= thisDXCoil.NumOfSpeeds; ++I) {
    4930            0 :                 thisDXCoil.MSSecCoilAirFlow(I) = Numbers(34 + (I - 1) * 3);
    4931            0 :                 thisDXCoil.MSSecCoilAirFlowScalingFactor(I) = Numbers(35 + (I - 1) * 3);
    4932            0 :                 thisDXCoil.MSSecCoilRatedSHR(I) = Numbers(36 + (I - 1) * 3);
    4933              :                 // Read SHR modifier curve function of temperature
    4934            0 :                 if (!lAlphaBlanks(36 + (I - 1) * 2)) {
    4935            0 :                     thisDXCoil.MSSecCoilSHRFT(I) = GetCurveIndex(state, Alphas(36 + (I - 1) * 2)); // convert curve name to number
    4936            0 :                     if (thisDXCoil.MSSecCoilSHRFT(I) == 0) {
    4937            0 :                         ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4938            0 :                         ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(36 + (I - 1) * 2), Alphas(36 + (I - 1) * 2)));
    4939              :                     }
    4940              :                 }
    4941              :                 // Read SHR modifier curve function of flow fraction
    4942            0 :                 if (!lAlphaBlanks(36 + (I - 1) * 2)) {
    4943            0 :                     thisDXCoil.MSSecCoilSHRFF(I) = GetCurveIndex(state, Alphas(36 + (I - 1) * 2)); // convert curve name to number
    4944            0 :                     if (thisDXCoil.MSSecCoilSHRFF(I) == 0) {
    4945            0 :                         ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    4946            0 :                         ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(36 + (I - 1) * 2), Alphas(36 + (I - 1) * 2)));
    4947              :                     }
    4948              :                 }
    4949              :             }
    4950              :         }
    4951              :     }
    4952              : 
    4953              :     // Loop over the VRF Cooling Coils and get & load the data
    4954          134 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Cooling);
    4955          158 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingCoils; ++DXCoilIndex) {
    4956              : 
    4957           24 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    4958              :                                                                  CurrentModuleObject,
    4959              :                                                                  DXCoilIndex,
    4960              :                                                                  Alphas,
    4961              :                                                                  NumAlphas,
    4962              :                                                                  Numbers,
    4963              :                                                                  NumNumbers,
    4964              :                                                                  IOStatus,
    4965              :                                                                  lNumericBlanks,
    4966              :                                                                  lAlphaBlanks,
    4967              :                                                                  cAlphaFields,
    4968              :                                                                  cNumericFields);
    4969              : 
    4970           24 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    4971              : 
    4972           24 :         ++DXCoilNum;
    4973              : 
    4974              :         // allocate single performance mode for numeric field strings used for sizing routine
    4975           24 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    4976           24 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    4977           24 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    4978              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    4979           24 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    4980              : 
    4981           24 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    4982           24 :         thisDXCoil.Name = Alphas(1);
    4983           24 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    4984           24 :         thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Cooling;
    4985              : 
    4986           24 :         if (lAlphaBlanks(2)) {
    4987            2 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    4988           22 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    4989            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    4990            0 :             ErrorsFound = true;
    4991              :         }
    4992           24 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    4993           24 :         thisDXCoil.RatedSHR(1) = Numbers(2);
    4994           24 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(3);
    4995              : 
    4996           24 :         thisDXCoil.CCapFTemp(1) = GetCurveIndex(state, Alphas(3));
    4997              :         // Verify Curve Object, only legal type is Linear, Quadratic, Cubic, or BiQuadratic
    4998           72 :         ErrorsFound |= Curve::CheckCurveDims(state,
    4999           24 :                                              thisDXCoil.CCapFTemp(1), // Curve index
    5000              :                                              {1, 2},                  // Valid dimensions  // MULTIPLECURVEDIMS
    5001              :                                              RoutineName,             // Routine name
    5002              :                                              CurrentModuleObject,     // Object Type
    5003              :                                              thisDXCoil.Name,         // Object Name
    5004           24 :                                              cAlphaFields(3));        // Field Name
    5005              : 
    5006           24 :         if (!ErrorsFound) {
    5007           24 :             if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
    5008           23 :                 checkCurveIsNormalizedToOne(state,
    5009           69 :                                             std::string{RoutineName} + CurrentModuleObject,
    5010           23 :                                             thisDXCoil.Name,
    5011           23 :                                             thisDXCoil.CCapFTemp(1),
    5012           23 :                                             cAlphaFields(3),
    5013           23 :                                             Alphas(3),
    5014              :                                             RatedInletWetBulbTemp);
    5015              :             } else {
    5016            1 :                 checkCurveIsNormalizedToOne(state,
    5017            3 :                                             std::string{RoutineName} + CurrentModuleObject,
    5018            1 :                                             thisDXCoil.Name,
    5019            1 :                                             thisDXCoil.CCapFTemp(1),
    5020            1 :                                             cAlphaFields(3),
    5021            1 :                                             Alphas(3),
    5022              :                                             RatedInletWetBulbTemp,
    5023              :                                             RatedOutdoorAirTemp);
    5024              :             }
    5025              :         }
    5026              : 
    5027           24 :         thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(4)); // convert curve name to number
    5028           24 :         if (thisDXCoil.CCapFFlow(1) == 0) {
    5029            0 :             if (lAlphaBlanks(4)) {
    5030            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5031            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(4)));
    5032              :             } else {
    5033            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5034            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(4), Alphas(4)));
    5035              :             }
    5036            0 :             ErrorsFound = true;
    5037              :         } else {
    5038              :             // Verify Curve Object, only legal type is Linear, Quadratic or Cubic
    5039           72 :             ErrorsFound |= Curve::CheckCurveDims(state,
    5040           24 :                                                  thisDXCoil.CCapFFlow(1), // Curve index
    5041              :                                                  {1},                     // Valid dimensions
    5042              :                                                  RoutineName,             // Routine name
    5043              :                                                  CurrentModuleObject,     // Object Type
    5044              :                                                  thisDXCoil.Name,         // Object Name
    5045           24 :                                                  cAlphaFields(4));        // Field Name
    5046              : 
    5047           24 :             if (!ErrorsFound) {
    5048           24 :                 checkCurveIsNormalizedToOne(
    5049           96 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(4), Alphas(4), 1.0);
    5050              :             }
    5051              :         }
    5052              : 
    5053           24 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    5054           24 :                                                  Alphas(5),
    5055              :                                                  ErrorsFound,
    5056              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
    5057           24 :                                                  Alphas(1),
    5058              :                                                  DataLoopNode::NodeFluidType::Air,
    5059              :                                                  DataLoopNode::ConnectionType::Inlet,
    5060              :                                                  NodeInputManager::CompFluidStream::Primary,
    5061              :                                                  ObjectIsNotParent);
    5062              : 
    5063           48 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    5064           24 :                                                   Alphas(6),
    5065              :                                                   ErrorsFound,
    5066              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlow,
    5067           24 :                                                   Alphas(1),
    5068              :                                                   DataLoopNode::NodeFluidType::Air,
    5069              :                                                   DataLoopNode::ConnectionType::Outlet,
    5070              :                                                   NodeInputManager::CompFluidStream::Primary,
    5071              :                                                   ObjectIsNotParent);
    5072              : 
    5073           24 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(5), Alphas(6), "Air Nodes");
    5074              : 
    5075           24 :         thisDXCoil.CondensateCollectName = Alphas(7);
    5076           24 :         if (lAlphaBlanks(7)) {
    5077           24 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    5078              :         } else {
    5079            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    5080            0 :             SetupTankSupplyComponent(state,
    5081              :                                      thisDXCoil.Name,
    5082              :                                      CurrentModuleObject,
    5083              :                                      thisDXCoil.CondensateCollectName,
    5084              :                                      ErrorsFound,
    5085            0 :                                      thisDXCoil.CondensateTankID,
    5086            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    5087              :         }
    5088              :     }
    5089              : 
    5090          134 :     if (ErrorsFound) {
    5091            0 :         ShowFatalError(state,
    5092            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    5093              :     }
    5094              : 
    5095              :     // Loop over the VRF Heating Coils and get & load the data
    5096          134 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_Heating);
    5097          157 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingCoils; ++DXCoilIndex) {
    5098              : 
    5099           23 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    5100              :                                                                  CurrentModuleObject,
    5101              :                                                                  DXCoilIndex,
    5102              :                                                                  Alphas,
    5103              :                                                                  NumAlphas,
    5104              :                                                                  Numbers,
    5105              :                                                                  NumNumbers,
    5106              :                                                                  IOStatus,
    5107              :                                                                  lNumericBlanks,
    5108              :                                                                  lAlphaBlanks,
    5109              :                                                                  cAlphaFields,
    5110              :                                                                  cNumericFields);
    5111              : 
    5112           23 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    5113           23 :         ++DXCoilNum;
    5114              : 
    5115              :         // allocate single performance mode for numeric field strings used for sizing routine
    5116           23 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    5117           23 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    5118           23 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    5119              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    5120           23 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    5121              : 
    5122           23 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    5123           23 :         thisDXCoil.Name = Alphas(1);
    5124           23 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    5125           23 :         thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_Heating;
    5126           23 :         if (lAlphaBlanks(2)) {
    5127            2 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    5128           21 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    5129            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    5130            0 :             ErrorsFound = true;
    5131              :         }
    5132           23 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    5133           23 :         thisDXCoil.RatedAirVolFlowRate(1) = Numbers(2);
    5134              : 
    5135           23 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    5136           23 :                                                  Alphas(3),
    5137              :                                                  ErrorsFound,
    5138              :                                                  DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
    5139           23 :                                                  Alphas(1),
    5140              :                                                  DataLoopNode::NodeFluidType::Air,
    5141              :                                                  DataLoopNode::ConnectionType::Inlet,
    5142              :                                                  NodeInputManager::CompFluidStream::Primary,
    5143              :                                                  ObjectIsNotParent);
    5144              : 
    5145           46 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    5146           23 :                                                   Alphas(4),
    5147              :                                                   ErrorsFound,
    5148              :                                                   DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlow,
    5149           23 :                                                   Alphas(1),
    5150              :                                                   DataLoopNode::NodeFluidType::Air,
    5151              :                                                   DataLoopNode::ConnectionType::Outlet,
    5152              :                                                   NodeInputManager::CompFluidStream::Primary,
    5153              :                                                   ObjectIsNotParent);
    5154              : 
    5155           23 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    5156              : 
    5157           23 :         thisDXCoil.CCapFTemp = GetCurveIndex(state, Alphas(5));
    5158           23 :         if (thisDXCoil.CCapFTemp(1) == 0) {
    5159            0 :             if (lAlphaBlanks(5)) {
    5160            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5161            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
    5162              :             } else {
    5163            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5164            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
    5165              :             }
    5166            0 :             ErrorsFound = true;
    5167              :         } else {
    5168           69 :             ErrorsFound |= Curve::CheckCurveDims(state,
    5169           23 :                                                  thisDXCoil.CCapFTemp(1), // Curve index
    5170              :                                                  {1, 2},                  // Valid dimensions  // MULTIPLECURVEDIMS
    5171              :                                                  RoutineName,             // Routine name
    5172              :                                                  CurrentModuleObject,     // Object Type
    5173              :                                                  thisDXCoil.Name,         // Object Name
    5174           23 :                                                  cAlphaFields(5));        // Field Name
    5175              : 
    5176           23 :             if (!ErrorsFound) {
    5177           23 :                 if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(1))->numDims == 1) {
    5178           23 :                     checkCurveIsNormalizedToOne(state,
    5179           69 :                                                 std::string{RoutineName} + CurrentModuleObject,
    5180           23 :                                                 thisDXCoil.Name,
    5181           23 :                                                 thisDXCoil.CCapFTemp(1),
    5182           23 :                                                 cAlphaFields(5),
    5183           23 :                                                 Alphas(5),
    5184              :                                                 RatedInletAirTempHeat);
    5185              :                 } else {
    5186              :                     // 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
    5187              :                     // GetInput.
    5188              :                 }
    5189              :             }
    5190              :         }
    5191              : 
    5192           23 :         thisDXCoil.CCapFFlow(1) = GetCurveIndex(state, Alphas(6)); // convert curve name to number
    5193           23 :         if (thisDXCoil.CCapFFlow(1) == 0) {
    5194            0 :             if (lAlphaBlanks(6)) {
    5195            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5196            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(6)));
    5197              :             } else {
    5198            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5199            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(6), Alphas(6)));
    5200              :             }
    5201            0 :             ErrorsFound = true;
    5202              :         } else {
    5203              :             // Verify Curve Object, only legal type is Quadratic
    5204           69 :             ErrorsFound |= Curve::CheckCurveDims(state,
    5205           23 :                                                  thisDXCoil.CCapFFlow(1), // Curve index
    5206              :                                                  {1},                     // Valid dimensions
    5207              :                                                  RoutineName,             // Routine name
    5208              :                                                  CurrentModuleObject,     // Object Type
    5209              :                                                  thisDXCoil.Name,         // Object Name
    5210           23 :                                                  cAlphaFields(6));        // Field Name
    5211              : 
    5212           23 :             if (!ErrorsFound) {
    5213           23 :                 checkCurveIsNormalizedToOne(
    5214           92 :                     state, std::string{RoutineName} + CurrentModuleObject, thisDXCoil.Name, thisDXCoil.CCapFFlow(1), cAlphaFields(6), Alphas(6), 1.0);
    5215              :             }
    5216              :         }
    5217              :     }
    5218              : 
    5219          134 :     if (ErrorsFound) {
    5220            0 :         ShowFatalError(state,
    5221            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    5222              :     }
    5223              : 
    5224              :     // Loop over the VRF Cooling Coils for VRF FluidTCtrl Model_zrp 2015
    5225          134 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Cooling);
    5226          146 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFCoolingFluidTCtrlCoils; ++DXCoilIndex) {
    5227              : 
    5228           12 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    5229              :                                                                  CurrentModuleObject,
    5230              :                                                                  DXCoilIndex,
    5231              :                                                                  Alphas,
    5232              :                                                                  NumAlphas,
    5233              :                                                                  Numbers,
    5234              :                                                                  NumNumbers,
    5235              :                                                                  IOStatus,
    5236              :                                                                  lNumericBlanks,
    5237              :                                                                  lAlphaBlanks,
    5238              :                                                                  cAlphaFields,
    5239              :                                                                  cNumericFields);
    5240              : 
    5241           12 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    5242           12 :         ++DXCoilNum;
    5243              : 
    5244              :         // allocate single performance mode for numeric field strings used for sizing routine
    5245           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    5246           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    5247           12 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    5248              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    5249           12 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    5250              : 
    5251           12 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    5252           12 :         thisDXCoil.Name = Alphas(1);
    5253           12 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    5254           12 :         thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Cooling;
    5255           12 :         if (lAlphaBlanks(2)) {
    5256            3 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    5257            9 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    5258            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    5259            0 :             ErrorsFound = true;
    5260              :         }
    5261              : 
    5262           12 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    5263           12 :                                                  Alphas(3),
    5264              :                                                  ErrorsFound,
    5265              :                                                  DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
    5266           12 :                                                  Alphas(1),
    5267              :                                                  DataLoopNode::NodeFluidType::Air,
    5268              :                                                  DataLoopNode::ConnectionType::Inlet,
    5269              :                                                  NodeInputManager::CompFluidStream::Primary,
    5270              :                                                  ObjectIsNotParent);
    5271           24 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    5272           12 :                                                   Alphas(4),
    5273              :                                                   ErrorsFound,
    5274              :                                                   DataLoopNode::ConnectionObjectType::CoilCoolingDXVariableRefrigerantFlowFluidTemperatureControl,
    5275           12 :                                                   Alphas(1),
    5276              :                                                   DataLoopNode::NodeFluidType::Air,
    5277              :                                                   DataLoopNode::ConnectionType::Outlet,
    5278              :                                                   NodeInputManager::CompFluidStream::Primary,
    5279              :                                                   ObjectIsNotParent);
    5280           12 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    5281              : 
    5282           12 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    5283           12 :         thisDXCoil.RatedSHR(1) = Numbers(2);
    5284           12 :         thisDXCoil.SH = Numbers(3);
    5285              :         // @@ DXCoil( DXCoilNum ).RateBFVRFIUEvap = 0.0592; there will be a new field for this, which will be handled in a separate issue to
    5286              :         // update VRF-HP idd. It is not handled here to avoid transition issues for VRF-HP.
    5287              : 
    5288           12 :         int indexSHCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
    5289              :         // Verify curve name and type
    5290           12 :         if (indexSHCurve == 0) {
    5291            0 :             if (lAlphaBlanks(5)) {
    5292            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5293            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
    5294              :             } else {
    5295            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5296            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
    5297              :             }
    5298            0 :             ErrorsFound = true;
    5299              :         } else {
    5300              :             {
    5301           12 :                 if (state.dataCurveManager->curves(indexSHCurve)->curveType == Curve::CurveType::Quadratic) {
    5302           12 :                     thisDXCoil.C1Te = state.dataCurveManager->curves(indexSHCurve)->coeff[0];
    5303           12 :                     thisDXCoil.C2Te = state.dataCurveManager->curves(indexSHCurve)->coeff[1];
    5304           12 :                     thisDXCoil.C3Te = state.dataCurveManager->curves(indexSHCurve)->coeff[2];
    5305              : 
    5306              :                 } else {
    5307            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5308            0 :                     ShowContinueError(state,
    5309            0 :                                       format("...illegal {} type for this object = {}",
    5310              :                                              cAlphaFields(5),
    5311            0 :                                              Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexSHCurve)->curveType)]));
    5312            0 :                     ShowContinueError(state, "... Curve type must be Quadratic.");
    5313            0 :                     ErrorsFound = true;
    5314              :                 }
    5315              :             }
    5316              :         }
    5317              : 
    5318           12 :         thisDXCoil.CondensateCollectName = Alphas(6);
    5319           12 :         if (lAlphaBlanks(6)) {
    5320           12 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::Discard;
    5321              :         } else {
    5322            0 :             thisDXCoil.CondensateCollectMode = CondensateCollectAction::ToTank;
    5323            0 :             SetupTankSupplyComponent(state,
    5324              :                                      thisDXCoil.Name,
    5325              :                                      CurrentModuleObject,
    5326              :                                      thisDXCoil.CondensateCollectName,
    5327              :                                      ErrorsFound,
    5328            0 :                                      thisDXCoil.CondensateTankID,
    5329            0 :                                      thisDXCoil.CondensateTankSupplyARRID);
    5330              :         }
    5331              :     }
    5332              : 
    5333          134 :     if (ErrorsFound) {
    5334            0 :         ShowFatalError(state,
    5335            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    5336              :     }
    5337              : 
    5338              :     // Loop over the VRF Heating Coils for VRF FluidTCtrl Model_zrp 2015
    5339          134 :     CurrentModuleObject = HVAC::cAllCoilTypes(HVAC::CoilVRF_FluidTCtrl_Heating);
    5340          145 :     for (DXCoilIndex = 1; DXCoilIndex <= state.dataDXCoils->NumVRFHeatingFluidTCtrlCoils; ++DXCoilIndex) {
    5341              : 
    5342           11 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    5343              :                                                                  CurrentModuleObject,
    5344              :                                                                  DXCoilIndex,
    5345              :                                                                  Alphas,
    5346              :                                                                  NumAlphas,
    5347              :                                                                  Numbers,
    5348              :                                                                  NumNumbers,
    5349              :                                                                  IOStatus,
    5350              :                                                                  lNumericBlanks,
    5351              :                                                                  lAlphaBlanks,
    5352              :                                                                  cAlphaFields,
    5353              :                                                                  cNumericFields);
    5354              : 
    5355           11 :         ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    5356           11 :         ++DXCoilNum;
    5357              : 
    5358              :         // allocate single performance mode for numeric field strings used for sizing routine
    5359           11 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode.allocate(1);
    5360           11 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames.allocate(MaxNumbers);
    5361           11 :         state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames = cNumericFields;
    5362              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
    5363           11 :         VerifyUniqueCoilName(state, CurrentModuleObject, Alphas(1), ErrorsFound, CurrentModuleObject + " Name");
    5364              : 
    5365           11 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    5366           11 :         thisDXCoil.Name = Alphas(1);
    5367           11 :         thisDXCoil.DXCoilType = CurrentModuleObject;
    5368           11 :         thisDXCoil.DXCoilType_Num = HVAC::CoilVRF_FluidTCtrl_Heating;
    5369           11 :         if (lAlphaBlanks(2)) {
    5370            2 :             thisDXCoil.availSched = Sched::GetScheduleAlwaysOn(state);
    5371            9 :         } else if ((thisDXCoil.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    5372            0 :             ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    5373            0 :             ErrorsFound = true;
    5374              :         }
    5375              : 
    5376           11 :         thisDXCoil.AirInNode = GetOnlySingleNode(state,
    5377           11 :                                                  Alphas(3),
    5378              :                                                  ErrorsFound,
    5379              :                                                  DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
    5380           11 :                                                  Alphas(1),
    5381              :                                                  DataLoopNode::NodeFluidType::Air,
    5382              :                                                  DataLoopNode::ConnectionType::Inlet,
    5383              :                                                  NodeInputManager::CompFluidStream::Primary,
    5384              :                                                  ObjectIsNotParent);
    5385           22 :         thisDXCoil.AirOutNode = GetOnlySingleNode(state,
    5386           11 :                                                   Alphas(4),
    5387              :                                                   ErrorsFound,
    5388              :                                                   DataLoopNode::ConnectionObjectType::CoilHeatingDXVariableRefrigerantFlowFluidTemperatureControl,
    5389           11 :                                                   Alphas(1),
    5390              :                                                   DataLoopNode::NodeFluidType::Air,
    5391              :                                                   DataLoopNode::ConnectionType::Outlet,
    5392              :                                                   NodeInputManager::CompFluidStream::Primary,
    5393              :                                                   ObjectIsNotParent);
    5394           11 :         TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    5395              : 
    5396           11 :         thisDXCoil.RatedTotCap(1) = Numbers(1);
    5397           11 :         thisDXCoil.SC = Numbers(2);
    5398              :         //@@ DXCoil( DXCoilNum ).RateBFVRFIUCond = 0.136;
    5399              : 
    5400           11 :         int indexSCCurve = GetCurveIndex(state, Alphas(5)); // convert curve name to index number
    5401              :         // Verify curve name and type
    5402           11 :         if (indexSCCurve == 0) {
    5403            0 :             if (lAlphaBlanks(5)) {
    5404            0 :                 ShowSevereError(state, format("{}{}=\"{}\", missing", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5405            0 :                 ShowContinueError(state, format("...required {} is blank.", cAlphaFields(5)));
    5406              :             } else {
    5407            0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5408            0 :                 ShowContinueError(state, format("...not found {}=\"{}\".", cAlphaFields(5), Alphas(5)));
    5409              :             }
    5410            0 :             ErrorsFound = true;
    5411              :         } else {
    5412              :             {
    5413           11 :                 if (state.dataCurveManager->curves(indexSCCurve)->curveType == Curve::CurveType::Quadratic) {
    5414           11 :                     thisDXCoil.C1Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[0];
    5415           11 :                     thisDXCoil.C2Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[1];
    5416           11 :                     thisDXCoil.C3Tc = state.dataCurveManager->curves(indexSCCurve)->coeff[2];
    5417              : 
    5418              :                 } else {
    5419            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, thisDXCoil.Name));
    5420            0 :                     ShowContinueError(state,
    5421            0 :                                       format("...illegal {} type for this object = {}",
    5422              :                                              cAlphaFields(5),
    5423            0 :                                              Curve::objectNames[static_cast<int>(state.dataCurveManager->curves(indexSCCurve)->curveType)]));
    5424            0 :                     ShowContinueError(state, "... Curve type must be Quadratic.");
    5425            0 :                     ErrorsFound = true;
    5426              :                 }
    5427              :             }
    5428              :         }
    5429              :     }
    5430              : 
    5431          134 :     if (ErrorsFound) {
    5432            0 :         ShowFatalError(state,
    5433            0 :                        format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", RoutineName, CurrentModuleObject));
    5434              :     }
    5435              : 
    5436          349 :     for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDXCoils; ++DXCoilNum) {
    5437              : 
    5438          215 :         auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    5439              : 
    5440          215 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    5441              :             // Setup Report Variables for Cooling Equipment
    5442              :             // CurrentModuleObject='Coil:Cooling:DX:SingleSpeed/Coil:Cooling:DX:TwoStageWithHumidityControlMode'
    5443          128 :             SetupOutputVariable(state,
    5444              :                                 "Cooling Coil Total Cooling Rate",
    5445              :                                 Constant::Units::W,
    5446           64 :                                 thisDXCoil.TotalCoolingEnergyRate,
    5447              :                                 OutputProcessor::TimeStepType::System,
    5448              :                                 OutputProcessor::StoreType::Average,
    5449           64 :                                 thisDXCoil.Name);
    5450          128 :             SetupOutputVariable(state,
    5451              :                                 "Cooling Coil Total Cooling Energy",
    5452              :                                 Constant::Units::J,
    5453           64 :                                 thisDXCoil.TotalCoolingEnergy,
    5454              :                                 OutputProcessor::TimeStepType::System,
    5455              :                                 OutputProcessor::StoreType::Sum,
    5456           64 :                                 thisDXCoil.Name,
    5457              :                                 Constant::eResource::EnergyTransfer,
    5458              :                                 OutputProcessor::Group::HVAC,
    5459              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    5460          128 :             SetupOutputVariable(state,
    5461              :                                 "Cooling Coil Sensible Cooling Rate",
    5462              :                                 Constant::Units::W,
    5463           64 :                                 thisDXCoil.SensCoolingEnergyRate,
    5464              :                                 OutputProcessor::TimeStepType::System,
    5465              :                                 OutputProcessor::StoreType::Average,
    5466           64 :                                 thisDXCoil.Name);
    5467          128 :             SetupOutputVariable(state,
    5468              :                                 "Cooling Coil Sensible Cooling Energy",
    5469              :                                 Constant::Units::J,
    5470           64 :                                 thisDXCoil.SensCoolingEnergy,
    5471              :                                 OutputProcessor::TimeStepType::System,
    5472              :                                 OutputProcessor::StoreType::Sum,
    5473           64 :                                 thisDXCoil.Name);
    5474          128 :             SetupOutputVariable(state,
    5475              :                                 "Cooling Coil Latent Cooling Rate",
    5476              :                                 Constant::Units::W,
    5477           64 :                                 thisDXCoil.LatCoolingEnergyRate,
    5478              :                                 OutputProcessor::TimeStepType::System,
    5479              :                                 OutputProcessor::StoreType::Average,
    5480           64 :                                 thisDXCoil.Name);
    5481          128 :             SetupOutputVariable(state,
    5482              :                                 "Cooling Coil Latent Cooling Energy",
    5483              :                                 Constant::Units::J,
    5484           64 :                                 thisDXCoil.LatCoolingEnergy,
    5485              :                                 OutputProcessor::TimeStepType::System,
    5486              :                                 OutputProcessor::StoreType::Sum,
    5487           64 :                                 thisDXCoil.Name);
    5488          128 :             SetupOutputVariable(state,
    5489              :                                 "Cooling Coil Electricity Rate",
    5490              :                                 Constant::Units::W,
    5491           64 :                                 thisDXCoil.ElecCoolingPower,
    5492              :                                 OutputProcessor::TimeStepType::System,
    5493              :                                 OutputProcessor::StoreType::Average,
    5494           64 :                                 thisDXCoil.Name);
    5495          128 :             SetupOutputVariable(state,
    5496              :                                 "Cooling Coil Electricity Energy",
    5497              :                                 Constant::Units::J,
    5498           64 :                                 thisDXCoil.ElecCoolingConsumption,
    5499              :                                 OutputProcessor::TimeStepType::System,
    5500              :                                 OutputProcessor::StoreType::Sum,
    5501           64 :                                 thisDXCoil.Name,
    5502              :                                 Constant::eResource::Electricity,
    5503              :                                 OutputProcessor::Group::HVAC,
    5504              :                                 OutputProcessor::EndUseCat::Cooling);
    5505          128 :             SetupOutputVariable(state,
    5506              :                                 "Cooling Coil Runtime Fraction",
    5507              :                                 Constant::Units::None,
    5508           64 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    5509              :                                 OutputProcessor::TimeStepType::System,
    5510              :                                 OutputProcessor::StoreType::Average,
    5511           64 :                                 thisDXCoil.Name);
    5512           64 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
    5513            0 :                 SetupOutputVariable(state,
    5514              :                                     "Secondary Coil Heat Rejection Rate",
    5515              :                                     Constant::Units::W,
    5516            0 :                                     thisDXCoil.SecCoilSensibleHeatGainRate,
    5517              :                                     OutputProcessor::TimeStepType::System,
    5518              :                                     OutputProcessor::StoreType::Average,
    5519            0 :                                     thisDXCoil.Name);
    5520              :             }
    5521              : 
    5522              :             // do we report these even if no storage tank?
    5523           64 :             if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
    5524            0 :                 SetupOutputVariable(state,
    5525              :                                     "Cooling Coil Condensate Volume Flow Rate",
    5526              :                                     Constant::Units::m3_s,
    5527            0 :                                     thisDXCoil.CondensateVdot,
    5528              :                                     OutputProcessor::TimeStepType::System,
    5529              :                                     OutputProcessor::StoreType::Average,
    5530            0 :                                     thisDXCoil.Name);
    5531            0 :                 SetupOutputVariable(state,
    5532              :                                     "Cooling Coil Condensate Volume",
    5533              :                                     Constant::Units::m3,
    5534            0 :                                     thisDXCoil.CondensateVol,
    5535              :                                     OutputProcessor::TimeStepType::System,
    5536              :                                     OutputProcessor::StoreType::Sum,
    5537            0 :                                     thisDXCoil.Name,
    5538              :                                     Constant::eResource::OnSiteWater,
    5539              :                                     OutputProcessor::Group::HVAC,
    5540              :                                     OutputProcessor::EndUseCat::Condensate);
    5541              :             }
    5542              : 
    5543           64 :             if (thisDXCoil.ReportEvapCondVars) {
    5544           28 :                 SetupOutputVariable(state,
    5545              :                                     "Cooling Coil Condenser Inlet Temperature",
    5546              :                                     Constant::Units::C,
    5547           14 :                                     thisDXCoil.CondInletTemp,
    5548              :                                     OutputProcessor::TimeStepType::System,
    5549              :                                     OutputProcessor::StoreType::Average,
    5550           14 :                                     thisDXCoil.Name);
    5551           28 :                 SetupOutputVariable(state,
    5552              :                                     "Cooling Coil Evaporative Condenser Water Volume",
    5553              :                                     Constant::Units::m3,
    5554           14 :                                     thisDXCoil.EvapWaterConsump,
    5555              :                                     OutputProcessor::TimeStepType::System,
    5556              :                                     OutputProcessor::StoreType::Sum,
    5557           14 :                                     thisDXCoil.Name,
    5558              :                                     Constant::eResource::Water,
    5559              :                                     OutputProcessor::Group::HVAC,
    5560              :                                     OutputProcessor::EndUseCat::Cooling);
    5561           28 :                 SetupOutputVariable(state,
    5562              :                                     "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
    5563              :                                     Constant::Units::m3,
    5564           14 :                                     thisDXCoil.EvapWaterConsump,
    5565              :                                     OutputProcessor::TimeStepType::System,
    5566              :                                     OutputProcessor::StoreType::Sum,
    5567           14 :                                     thisDXCoil.Name,
    5568              :                                     Constant::eResource::MainsWater,
    5569              :                                     OutputProcessor::Group::HVAC,
    5570              :                                     OutputProcessor::EndUseCat::Cooling);
    5571           28 :                 SetupOutputVariable(state,
    5572              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Rate",
    5573              :                                     Constant::Units::W,
    5574           14 :                                     thisDXCoil.EvapCondPumpElecPower,
    5575              :                                     OutputProcessor::TimeStepType::System,
    5576              :                                     OutputProcessor::StoreType::Average,
    5577           14 :                                     thisDXCoil.Name);
    5578           28 :                 SetupOutputVariable(state,
    5579              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Energy",
    5580              :                                     Constant::Units::J,
    5581           14 :                                     thisDXCoil.EvapCondPumpElecConsumption,
    5582              :                                     OutputProcessor::TimeStepType::System,
    5583              :                                     OutputProcessor::StoreType::Sum,
    5584           14 :                                     thisDXCoil.Name,
    5585              :                                     Constant::eResource::Electricity,
    5586              :                                     OutputProcessor::Group::HVAC,
    5587              :                                     OutputProcessor::EndUseCat::Cooling);
    5588           14 :                 if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    5589            6 :                     SetupOutputVariable(state,
    5590              :                                         "Cooling Coil Basin Heater Electricity Rate",
    5591              :                                         Constant::Units::W,
    5592            3 :                                         thisDXCoil.BasinHeaterPower,
    5593              :                                         OutputProcessor::TimeStepType::System,
    5594              :                                         OutputProcessor::StoreType::Average,
    5595            3 :                                         thisDXCoil.Name);
    5596            6 :                     SetupOutputVariable(state,
    5597              :                                         "Cooling Coil Basin Heater Electricity Energy",
    5598              :                                         Constant::Units::J,
    5599            3 :                                         thisDXCoil.BasinHeaterConsumption,
    5600              :                                         OutputProcessor::TimeStepType::System,
    5601              :                                         OutputProcessor::StoreType::Sum,
    5602            3 :                                         thisDXCoil.Name,
    5603              :                                         Constant::eResource::Electricity,
    5604              :                                         OutputProcessor::Group::HVAC,
    5605              :                                         OutputProcessor::EndUseCat::Cooling);
    5606              :                 }
    5607              :             }
    5608              : 
    5609           64 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    5610              :                 // Setup Report Variables for Cooling Equipment
    5611              :                 // CurrentModuleObject='Cooling:DX:TwoStageWithHumidityControlMode'
    5612            4 :                 SetupOutputVariable(state,
    5613              :                                     "Cooling Coil Stage 2 Runtime Fraction",
    5614              :                                     Constant::Units::None,
    5615            2 :                                     thisDXCoil.CoolingCoilStg2RuntimeFrac,
    5616              :                                     OutputProcessor::TimeStepType::System,
    5617              :                                     OutputProcessor::StoreType::Average,
    5618            2 :                                     thisDXCoil.Name);
    5619            2 :                 SetupOutputVariable(state,
    5620              :                                     "Cooling Coil Dehumidification Mode",
    5621              :                                     Constant::Units::None,
    5622            2 :                                     (int &)thisDXCoil.DehumidificationMode,
    5623              :                                     OutputProcessor::TimeStepType::System,
    5624              :                                     OutputProcessor::StoreType::Average,
    5625            2 :                                     thisDXCoil.Name);
    5626              :             }
    5627              : 
    5628              :         }
    5629              : 
    5630          151 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
    5631              :             // Setup Report Variables for Heating Equipment
    5632              :             // CurrentModuleObject='Coil:Heating:DX:SingleSpeed'
    5633           24 :             SetupOutputVariable(state,
    5634              :                                 "Heating Coil Heating Rate",
    5635              :                                 Constant::Units::W,
    5636           12 :                                 thisDXCoil.TotalHeatingEnergyRate,
    5637              :                                 OutputProcessor::TimeStepType::System,
    5638              :                                 OutputProcessor::StoreType::Average,
    5639           12 :                                 thisDXCoil.Name);
    5640           24 :             SetupOutputVariable(state,
    5641              :                                 "Heating Coil Heating Energy",
    5642              :                                 Constant::Units::J,
    5643           12 :                                 thisDXCoil.TotalHeatingEnergy,
    5644              :                                 OutputProcessor::TimeStepType::System,
    5645              :                                 OutputProcessor::StoreType::Sum,
    5646           12 :                                 thisDXCoil.Name,
    5647              :                                 Constant::eResource::EnergyTransfer,
    5648              :                                 OutputProcessor::Group::HVAC,
    5649              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    5650           24 :             SetupOutputVariable(state,
    5651              :                                 "Heating Coil Electricity Rate",
    5652              :                                 Constant::Units::W,
    5653           12 :                                 thisDXCoil.ElecHeatingPower,
    5654              :                                 OutputProcessor::TimeStepType::System,
    5655              :                                 OutputProcessor::StoreType::Average,
    5656           12 :                                 thisDXCoil.Name);
    5657           24 :             SetupOutputVariable(state,
    5658              :                                 "Heating Coil Electricity Energy",
    5659              :                                 Constant::Units::J,
    5660           12 :                                 thisDXCoil.ElecHeatingConsumption,
    5661              :                                 OutputProcessor::TimeStepType::System,
    5662              :                                 OutputProcessor::StoreType::Sum,
    5663           12 :                                 thisDXCoil.Name,
    5664              :                                 Constant::eResource::Electricity,
    5665              :                                 OutputProcessor::Group::HVAC,
    5666              :                                 OutputProcessor::EndUseCat::Heating);
    5667           24 :             SetupOutputVariable(state,
    5668              :                                 "Heating Coil Defrost Electricity Rate",
    5669              :                                 Constant::Units::W,
    5670           12 :                                 thisDXCoil.DefrostPower,
    5671              :                                 OutputProcessor::TimeStepType::System,
    5672              :                                 OutputProcessor::StoreType::Average,
    5673           12 :                                 thisDXCoil.Name);
    5674           24 :             SetupOutputVariable(state,
    5675              :                                 "Heating Coil Defrost Electricity Energy",
    5676              :                                 Constant::Units::J,
    5677           12 :                                 thisDXCoil.DefrostConsumption,
    5678              :                                 OutputProcessor::TimeStepType::System,
    5679              :                                 OutputProcessor::StoreType::Sum,
    5680           12 :                                 thisDXCoil.Name,
    5681              :                                 Constant::eResource::Electricity,
    5682              :                                 OutputProcessor::Group::HVAC,
    5683              :                                 OutputProcessor::EndUseCat::Heating);
    5684           24 :             SetupOutputVariable(state,
    5685              :                                 "Heating Coil Crankcase Heater Electricity Rate",
    5686              :                                 Constant::Units::W,
    5687           12 :                                 thisDXCoil.CrankcaseHeaterPower,
    5688              :                                 OutputProcessor::TimeStepType::System,
    5689              :                                 OutputProcessor::StoreType::Average,
    5690           12 :                                 thisDXCoil.Name);
    5691           24 :             SetupOutputVariable(state,
    5692              :                                 "Heating Coil Crankcase Heater Electricity Energy",
    5693              :                                 Constant::Units::J,
    5694           12 :                                 thisDXCoil.CrankcaseHeaterConsumption,
    5695              :                                 OutputProcessor::TimeStepType::System,
    5696              :                                 OutputProcessor::StoreType::Sum,
    5697           12 :                                 thisDXCoil.Name,
    5698              :                                 Constant::eResource::Electricity,
    5699              :                                 OutputProcessor::Group::HVAC,
    5700              :                                 OutputProcessor::EndUseCat::Heating);
    5701           24 :             SetupOutputVariable(state,
    5702              :                                 "Heating Coil Runtime Fraction",
    5703              :                                 Constant::Units::None,
    5704           12 :                                 thisDXCoil.HeatingCoilRuntimeFraction,
    5705              :                                 OutputProcessor::TimeStepType::System,
    5706              :                                 OutputProcessor::StoreType::Average,
    5707           12 :                                 thisDXCoil.Name);
    5708           12 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
    5709            0 :                 SetupOutputVariable(state,
    5710              :                                     "Secondary Coil Total Heat Removal Rate",
    5711              :                                     Constant::Units::W,
    5712            0 :                                     thisDXCoil.SecCoilTotalHeatRemovalRate,
    5713              :                                     OutputProcessor::TimeStepType::System,
    5714              :                                     OutputProcessor::StoreType::Average,
    5715            0 :                                     thisDXCoil.Name);
    5716            0 :                 SetupOutputVariable(state,
    5717              :                                     "Secondary Coil Sensible Heat Removal Rate",
    5718              :                                     Constant::Units::W,
    5719            0 :                                     thisDXCoil.SecCoilSensibleHeatRemovalRate,
    5720              :                                     OutputProcessor::TimeStepType::System,
    5721              :                                     OutputProcessor::StoreType::Average,
    5722            0 :                                     thisDXCoil.Name);
    5723            0 :                 SetupOutputVariable(state,
    5724              :                                     "Secondary Coil Latent Heat Removal Rate",
    5725              :                                     Constant::Units::W,
    5726            0 :                                     thisDXCoil.SecCoilLatentHeatRemovalRate,
    5727              :                                     OutputProcessor::TimeStepType::System,
    5728              :                                     OutputProcessor::StoreType::Average,
    5729            0 :                                     thisDXCoil.Name);
    5730            0 :                 SetupOutputVariable(state,
    5731              :                                     "Secondary Coil Sensible Heat Ratio",
    5732              :                                     Constant::Units::None,
    5733            0 :                                     thisDXCoil.SecCoilSHR,
    5734              :                                     OutputProcessor::TimeStepType::System,
    5735              :                                     OutputProcessor::StoreType::Average,
    5736            0 :                                     thisDXCoil.Name);
    5737            0 :                 SetupOutputVariable(state,
    5738              :                                     "Secondary Coil Compressor Part Load Ratio",
    5739              :                                     Constant::Units::None,
    5740            0 :                                     thisDXCoil.CompressorPartLoadRatio,
    5741              :                                     OutputProcessor::TimeStepType::System,
    5742              :                                     OutputProcessor::StoreType::Average,
    5743            0 :                                     thisDXCoil.Name);
    5744              :             }
    5745           12 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    5746            0 :                 SetupEMSActuator(state,
    5747              :                                  thisDXCoil.DXCoilType,
    5748              :                                  thisDXCoil.Name,
    5749              :                                  "Frost Heating Capacity Multiplier",
    5750              :                                  "[]",
    5751            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
    5752            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
    5753              : 
    5754            0 :                 SetupEMSActuator(state,
    5755              :                                  thisDXCoil.DXCoilType,
    5756              :                                  thisDXCoil.Name,
    5757              :                                  "Frost Heating Input Power Multiplier",
    5758              :                                  "[]",
    5759            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
    5760            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
    5761              :             }
    5762              :         }
    5763              : 
    5764          139 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    5765              :             // Setup Report Variables for Cooling Equipment
    5766              :             // CurrentModuleObject='Coil:Cooling:DX:TwoSpeed'
    5767           24 :             SetupOutputVariable(state,
    5768              :                                 "Cooling Coil Total Cooling Rate",
    5769              :                                 Constant::Units::W,
    5770           12 :                                 thisDXCoil.TotalCoolingEnergyRate,
    5771              :                                 OutputProcessor::TimeStepType::System,
    5772              :                                 OutputProcessor::StoreType::Average,
    5773           12 :                                 thisDXCoil.Name);
    5774           24 :             SetupOutputVariable(state,
    5775              :                                 "Cooling Coil Total Cooling Energy",
    5776              :                                 Constant::Units::J,
    5777           12 :                                 thisDXCoil.TotalCoolingEnergy,
    5778              :                                 OutputProcessor::TimeStepType::System,
    5779              :                                 OutputProcessor::StoreType::Sum,
    5780           12 :                                 thisDXCoil.Name,
    5781              :                                 Constant::eResource::EnergyTransfer,
    5782              :                                 OutputProcessor::Group::HVAC,
    5783              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    5784           24 :             SetupOutputVariable(state,
    5785              :                                 "Cooling Coil Sensible Cooling Rate",
    5786              :                                 Constant::Units::W,
    5787           12 :                                 thisDXCoil.SensCoolingEnergyRate,
    5788              :                                 OutputProcessor::TimeStepType::System,
    5789              :                                 OutputProcessor::StoreType::Average,
    5790           12 :                                 thisDXCoil.Name);
    5791           24 :             SetupOutputVariable(state,
    5792              :                                 "Cooling Coil Sensible Cooling Energy",
    5793              :                                 Constant::Units::J,
    5794           12 :                                 thisDXCoil.SensCoolingEnergy,
    5795              :                                 OutputProcessor::TimeStepType::System,
    5796              :                                 OutputProcessor::StoreType::Sum,
    5797           12 :                                 thisDXCoil.Name);
    5798           24 :             SetupOutputVariable(state,
    5799              :                                 "Cooling Coil Latent Cooling Rate",
    5800              :                                 Constant::Units::W,
    5801           12 :                                 thisDXCoil.LatCoolingEnergyRate,
    5802              :                                 OutputProcessor::TimeStepType::System,
    5803              :                                 OutputProcessor::StoreType::Average,
    5804           12 :                                 thisDXCoil.Name);
    5805           24 :             SetupOutputVariable(state,
    5806              :                                 "Cooling Coil Latent Cooling Energy",
    5807              :                                 Constant::Units::J,
    5808           12 :                                 thisDXCoil.LatCoolingEnergy,
    5809              :                                 OutputProcessor::TimeStepType::System,
    5810              :                                 OutputProcessor::StoreType::Sum,
    5811           12 :                                 thisDXCoil.Name);
    5812           24 :             SetupOutputVariable(state,
    5813              :                                 "Cooling Coil Electricity Rate",
    5814              :                                 Constant::Units::W,
    5815           12 :                                 thisDXCoil.ElecCoolingPower,
    5816              :                                 OutputProcessor::TimeStepType::System,
    5817              :                                 OutputProcessor::StoreType::Average,
    5818           12 :                                 thisDXCoil.Name);
    5819           24 :             SetupOutputVariable(state,
    5820              :                                 "Cooling Coil Electricity Energy",
    5821              :                                 Constant::Units::J,
    5822           12 :                                 thisDXCoil.ElecCoolingConsumption,
    5823              :                                 OutputProcessor::TimeStepType::System,
    5824              :                                 OutputProcessor::StoreType::Sum,
    5825           12 :                                 thisDXCoil.Name,
    5826              :                                 Constant::eResource::Electricity,
    5827              :                                 OutputProcessor::Group::HVAC,
    5828              :                                 OutputProcessor::EndUseCat::Cooling);
    5829           24 :             SetupOutputVariable(state,
    5830              :                                 "Cooling Coil Runtime Fraction",
    5831              :                                 Constant::Units::None,
    5832           12 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    5833              :                                 OutputProcessor::TimeStepType::System,
    5834              :                                 OutputProcessor::StoreType::Average,
    5835           12 :                                 thisDXCoil.Name);
    5836           12 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
    5837            0 :                 SetupOutputVariable(state,
    5838              :                                     "Secondary Coil Heat Rejection Rate",
    5839              :                                     Constant::Units::W,
    5840            0 :                                     thisDXCoil.SecCoilSensibleHeatGainRate,
    5841              :                                     OutputProcessor::TimeStepType::System,
    5842              :                                     OutputProcessor::StoreType::Average,
    5843            0 :                                     thisDXCoil.Name);
    5844              :             }
    5845              : 
    5846           12 :             if (thisDXCoil.ReportEvapCondVars) {
    5847            4 :                 SetupOutputVariable(state,
    5848              :                                     "Cooling Coil Condenser Inlet Temperature",
    5849              :                                     Constant::Units::C,
    5850            2 :                                     thisDXCoil.CondInletTemp,
    5851              :                                     OutputProcessor::TimeStepType::System,
    5852              :                                     OutputProcessor::StoreType::Average,
    5853            2 :                                     thisDXCoil.Name);
    5854            4 :                 SetupOutputVariable(state,
    5855              :                                     "Cooling Coil Evaporative Condenser Water Volume",
    5856              :                                     Constant::Units::m3,
    5857            2 :                                     thisDXCoil.EvapWaterConsump,
    5858              :                                     OutputProcessor::TimeStepType::System,
    5859              :                                     OutputProcessor::StoreType::Sum,
    5860            2 :                                     thisDXCoil.Name,
    5861              :                                     Constant::eResource::Water,
    5862              :                                     OutputProcessor::Group::HVAC,
    5863              :                                     OutputProcessor::EndUseCat::Cooling);
    5864            4 :                 SetupOutputVariable(state,
    5865              :                                     "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
    5866              :                                     Constant::Units::m3,
    5867            2 :                                     thisDXCoil.EvapWaterConsump,
    5868              :                                     OutputProcessor::TimeStepType::System,
    5869              :                                     OutputProcessor::StoreType::Sum,
    5870            2 :                                     thisDXCoil.Name,
    5871              :                                     Constant::eResource::MainsWater,
    5872              :                                     OutputProcessor::Group::HVAC,
    5873              :                                     OutputProcessor::EndUseCat::Cooling);
    5874            4 :                 SetupOutputVariable(state,
    5875              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Rate",
    5876              :                                     Constant::Units::W,
    5877            2 :                                     thisDXCoil.EvapCondPumpElecPower,
    5878              :                                     OutputProcessor::TimeStepType::System,
    5879              :                                     OutputProcessor::StoreType::Average,
    5880            2 :                                     thisDXCoil.Name);
    5881            4 :                 SetupOutputVariable(state,
    5882              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Energy",
    5883              :                                     Constant::Units::J,
    5884            2 :                                     thisDXCoil.EvapCondPumpElecConsumption,
    5885              :                                     OutputProcessor::TimeStepType::System,
    5886              :                                     OutputProcessor::StoreType::Sum,
    5887            2 :                                     thisDXCoil.Name,
    5888              :                                     Constant::eResource::Electricity,
    5889              :                                     OutputProcessor::Group::HVAC,
    5890              :                                     OutputProcessor::EndUseCat::Cooling);
    5891            2 :                 if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    5892            2 :                     SetupOutputVariable(state,
    5893              :                                         "Cooling Coil Basin Heater Electricity Rate",
    5894              :                                         Constant::Units::W,
    5895            1 :                                         thisDXCoil.BasinHeaterPower,
    5896              :                                         OutputProcessor::TimeStepType::System,
    5897              :                                         OutputProcessor::StoreType::Average,
    5898            1 :                                         thisDXCoil.Name);
    5899            2 :                     SetupOutputVariable(state,
    5900              :                                         "Cooling Coil Basin Heater Electricity Energy",
    5901              :                                         Constant::Units::J,
    5902            1 :                                         thisDXCoil.BasinHeaterConsumption,
    5903              :                                         OutputProcessor::TimeStepType::System,
    5904              :                                         OutputProcessor::StoreType::Sum,
    5905            1 :                                         thisDXCoil.Name,
    5906              :                                         Constant::eResource::Electricity,
    5907              :                                         OutputProcessor::Group::HVAC,
    5908              :                                         OutputProcessor::EndUseCat::Cooling);
    5909              :                 }
    5910              :             }
    5911              : 
    5912              :         }
    5913              : 
    5914          127 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    5915          118 :                  thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    5916              :             // Setup Report Variables for Cooling Equipment
    5917              :             // CurrentModuleObject='Coil:WaterHeating:AirToWaterHeatPump:Pumped'
    5918              :             // or 'Coil:WaterHeating:AirToWaterHeatPump:Wrapped'
    5919           32 :             SetupOutputVariable(state,
    5920              :                                 "Cooling Coil Total Cooling Rate",
    5921              :                                 Constant::Units::W,
    5922           16 :                                 thisDXCoil.TotalCoolingEnergyRate,
    5923              :                                 OutputProcessor::TimeStepType::System,
    5924              :                                 OutputProcessor::StoreType::Average,
    5925           16 :                                 thisDXCoil.Name);
    5926              : 
    5927           16 :             if (thisDXCoil.IsDXCoilInZone) {
    5928           32 :                 SetupOutputVariable(state,
    5929              :                                     "Cooling Coil Total Cooling Energy",
    5930              :                                     Constant::Units::J,
    5931           16 :                                     thisDXCoil.TotalCoolingEnergy,
    5932              :                                     OutputProcessor::TimeStepType::System,
    5933              :                                     OutputProcessor::StoreType::Sum,
    5934           16 :                                     thisDXCoil.Name,
    5935              :                                     Constant::eResource::EnergyTransfer,
    5936              :                                     OutputProcessor::Group::HVAC,
    5937              :                                     OutputProcessor::EndUseCat::CoolingCoils);
    5938              :             } else {
    5939            0 :                 SetupOutputVariable(state,
    5940              :                                     "Cooling Coil Total Cooling Energy",
    5941              :                                     Constant::Units::J,
    5942            0 :                                     thisDXCoil.TotalCoolingEnergy,
    5943              :                                     OutputProcessor::TimeStepType::System,
    5944              :                                     OutputProcessor::StoreType::Sum,
    5945            0 :                                     thisDXCoil.Name);
    5946              :             }
    5947              : 
    5948           32 :             SetupOutputVariable(state,
    5949              :                                 "Cooling Coil Sensible Cooling Rate",
    5950              :                                 Constant::Units::W,
    5951           16 :                                 thisDXCoil.SensCoolingEnergyRate,
    5952              :                                 OutputProcessor::TimeStepType::System,
    5953              :                                 OutputProcessor::StoreType::Average,
    5954           16 :                                 thisDXCoil.Name);
    5955           32 :             SetupOutputVariable(state,
    5956              :                                 "Cooling Coil Sensible Cooling Energy",
    5957              :                                 Constant::Units::J,
    5958           16 :                                 thisDXCoil.SensCoolingEnergy,
    5959              :                                 OutputProcessor::TimeStepType::System,
    5960              :                                 OutputProcessor::StoreType::Sum,
    5961           16 :                                 thisDXCoil.Name);
    5962           32 :             SetupOutputVariable(state,
    5963              :                                 "Cooling Coil Latent Cooling Rate",
    5964              :                                 Constant::Units::W,
    5965           16 :                                 thisDXCoil.LatCoolingEnergyRate,
    5966              :                                 OutputProcessor::TimeStepType::System,
    5967              :                                 OutputProcessor::StoreType::Average,
    5968           16 :                                 thisDXCoil.Name);
    5969           32 :             SetupOutputVariable(state,
    5970              :                                 "Cooling Coil Latent Cooling Energy",
    5971              :                                 Constant::Units::J,
    5972           16 :                                 thisDXCoil.LatCoolingEnergy,
    5973              :                                 OutputProcessor::TimeStepType::System,
    5974              :                                 OutputProcessor::StoreType::Sum,
    5975           16 :                                 thisDXCoil.Name);
    5976           32 :             SetupOutputVariable(state,
    5977              :                                 "Cooling Coil Runtime Fraction",
    5978              :                                 Constant::Units::None,
    5979           16 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    5980              :                                 OutputProcessor::TimeStepType::System,
    5981              :                                 OutputProcessor::StoreType::Average,
    5982           16 :                                 thisDXCoil.Name);
    5983              : 
    5984           16 :             if (thisDXCoil.ReportCoolingCoilCrankcasePower) {
    5985           32 :                 SetupOutputVariable(state,
    5986              :                                     "Cooling Coil Crankcase Heater Electricity Rate",
    5987              :                                     Constant::Units::W,
    5988           16 :                                     thisDXCoil.CrankcaseHeaterPower,
    5989              :                                     OutputProcessor::TimeStepType::System,
    5990              :                                     OutputProcessor::StoreType::Average,
    5991           16 :                                     thisDXCoil.Name);
    5992           32 :                 SetupOutputVariable(state,
    5993              :                                     "Cooling Coil Crankcase Heater Electricity Energy",
    5994              :                                     Constant::Units::J,
    5995           16 :                                     thisDXCoil.CrankcaseHeaterConsumption,
    5996              :                                     OutputProcessor::TimeStepType::System,
    5997              :                                     OutputProcessor::StoreType::Sum,
    5998           16 :                                     thisDXCoil.Name,
    5999              :                                     Constant::eResource::Electricity,
    6000              :                                     OutputProcessor::Group::Plant,
    6001              :                                     OutputProcessor::EndUseCat::WaterSystem); // DHW
    6002              :             }
    6003              : 
    6004              :             // new report variables for a HP water heater DX coil
    6005           32 :             SetupOutputVariable(state,
    6006              :                                 "Cooling Coil Total Water Heating Rate",
    6007              :                                 Constant::Units::W,
    6008           16 :                                 thisDXCoil.TotalHeatingEnergyRate,
    6009              :                                 OutputProcessor::TimeStepType::System,
    6010              :                                 OutputProcessor::StoreType::Average,
    6011           16 :                                 thisDXCoil.Name);
    6012           32 :             SetupOutputVariable(state,
    6013              :                                 "Cooling Coil Total Water Heating Energy",
    6014              :                                 Constant::Units::J,
    6015           16 :                                 thisDXCoil.TotalHeatingEnergy,
    6016              :                                 OutputProcessor::TimeStepType::System,
    6017              :                                 OutputProcessor::StoreType::Sum,
    6018           16 :                                 thisDXCoil.Name); //, &
    6019              :             //                           ResourceTypeKey='ENERGYTRANSFER',EndUseKey='HEATING',GroupKey='Plant')
    6020           32 :             SetupOutputVariable(state,
    6021              :                                 "Cooling Coil Water Heating Electricity Rate",
    6022              :                                 Constant::Units::W,
    6023           16 :                                 thisDXCoil.ElecWaterHeatingPower,
    6024              :                                 OutputProcessor::TimeStepType::System,
    6025              :                                 OutputProcessor::StoreType::Average,
    6026           16 :                                 thisDXCoil.Name);
    6027           32 :             SetupOutputVariable(state,
    6028              :                                 "Cooling Coil Water Heating Electricity Energy",
    6029              :                                 Constant::Units::J,
    6030           16 :                                 thisDXCoil.ElecWaterHeatingConsumption,
    6031              :                                 OutputProcessor::TimeStepType::System,
    6032              :                                 OutputProcessor::StoreType::Sum,
    6033           16 :                                 thisDXCoil.Name,
    6034              :                                 Constant::eResource::Electricity,
    6035              :                                 OutputProcessor::Group::Plant,
    6036              :                                 OutputProcessor::EndUseCat::WaterSystem); // DHW
    6037              :         }
    6038              : 
    6039          111 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
    6040              :             // Setup Report Variables for Cooling Equipment:
    6041              :             // CurrentModuleObject='Coil:Cooling:DX:MultiSpeed'
    6042           54 :             SetupOutputVariable(state,
    6043              :                                 "Cooling Coil Total Cooling Rate",
    6044              :                                 Constant::Units::W,
    6045           27 :                                 thisDXCoil.TotalCoolingEnergyRate,
    6046              :                                 OutputProcessor::TimeStepType::System,
    6047              :                                 OutputProcessor::StoreType::Average,
    6048           27 :                                 thisDXCoil.Name);
    6049           54 :             SetupOutputVariable(state,
    6050              :                                 "Cooling Coil Total Cooling Energy",
    6051              :                                 Constant::Units::J,
    6052           27 :                                 thisDXCoil.TotalCoolingEnergy,
    6053              :                                 OutputProcessor::TimeStepType::System,
    6054              :                                 OutputProcessor::StoreType::Sum,
    6055           27 :                                 thisDXCoil.Name,
    6056              :                                 Constant::eResource::EnergyTransfer,
    6057              :                                 OutputProcessor::Group::HVAC,
    6058              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    6059           54 :             SetupOutputVariable(state,
    6060              :                                 "Cooling Coil Sensible Cooling Rate",
    6061              :                                 Constant::Units::W,
    6062           27 :                                 thisDXCoil.SensCoolingEnergyRate,
    6063              :                                 OutputProcessor::TimeStepType::System,
    6064              :                                 OutputProcessor::StoreType::Average,
    6065           27 :                                 thisDXCoil.Name);
    6066           54 :             SetupOutputVariable(state,
    6067              :                                 "Cooling Coil Sensible Cooling Energy",
    6068              :                                 Constant::Units::J,
    6069           27 :                                 thisDXCoil.SensCoolingEnergy,
    6070              :                                 OutputProcessor::TimeStepType::System,
    6071              :                                 OutputProcessor::StoreType::Sum,
    6072           27 :                                 thisDXCoil.Name);
    6073           54 :             SetupOutputVariable(state,
    6074              :                                 "Cooling Coil Latent Cooling Rate",
    6075              :                                 Constant::Units::W,
    6076           27 :                                 thisDXCoil.LatCoolingEnergyRate,
    6077              :                                 OutputProcessor::TimeStepType::System,
    6078              :                                 OutputProcessor::StoreType::Average,
    6079           27 :                                 thisDXCoil.Name);
    6080           54 :             SetupOutputVariable(state,
    6081              :                                 "Cooling Coil Latent Cooling Energy",
    6082              :                                 Constant::Units::J,
    6083           27 :                                 thisDXCoil.LatCoolingEnergy,
    6084              :                                 OutputProcessor::TimeStepType::System,
    6085              :                                 OutputProcessor::StoreType::Sum,
    6086           27 :                                 thisDXCoil.Name);
    6087           54 :             SetupOutputVariable(state,
    6088              :                                 "Cooling Coil Electricity Rate",
    6089              :                                 Constant::Units::W,
    6090           27 :                                 thisDXCoil.ElecCoolingPower,
    6091              :                                 OutputProcessor::TimeStepType::System,
    6092              :                                 OutputProcessor::StoreType::Average,
    6093           27 :                                 thisDXCoil.Name);
    6094           54 :             SetupOutputVariable(state,
    6095              :                                 "Cooling Coil Electricity Energy",
    6096              :                                 Constant::Units::J,
    6097           27 :                                 thisDXCoil.ElecCoolingConsumption,
    6098              :                                 OutputProcessor::TimeStepType::System,
    6099              :                                 OutputProcessor::StoreType::Sum,
    6100           27 :                                 thisDXCoil.Name,
    6101              :                                 Constant::eResource::Electricity,
    6102              :                                 OutputProcessor::Group::HVAC,
    6103              :                                 OutputProcessor::EndUseCat::Cooling);
    6104              : 
    6105           27 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
    6106            4 :                 std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
    6107           12 :                 SetupOutputVariable(state,
    6108            8 :                                     format("Cooling Coil {} Rate", sFuelType),
    6109              :                                     Constant::Units::W,
    6110            4 :                                     thisDXCoil.FuelUsed,
    6111              :                                     OutputProcessor::TimeStepType::System,
    6112              :                                     OutputProcessor::StoreType::Average,
    6113            4 :                                     thisDXCoil.Name);
    6114           12 :                 SetupOutputVariable(state,
    6115            8 :                                     format("Cooling Coil {} Energy", sFuelType),
    6116              :                                     Constant::Units::J,
    6117            4 :                                     thisDXCoil.FuelConsumed,
    6118              :                                     OutputProcessor::TimeStepType::System,
    6119              :                                     OutputProcessor::StoreType::Sum,
    6120            4 :                                     thisDXCoil.Name,
    6121            4 :                                     Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
    6122              :                                     OutputProcessor::Group::HVAC,
    6123              :                                     OutputProcessor::EndUseCat::Cooling);
    6124              :             }
    6125              : 
    6126           54 :             SetupOutputVariable(state,
    6127              :                                 "Cooling Coil Runtime Fraction",
    6128              :                                 Constant::Units::None,
    6129           27 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    6130              :                                 OutputProcessor::TimeStepType::System,
    6131              :                                 OutputProcessor::StoreType::Average,
    6132           27 :                                 thisDXCoil.Name);
    6133              : 
    6134           27 :             if (thisDXCoil.ReportEvapCondVars) {
    6135            0 :                 SetupOutputVariable(state,
    6136              :                                     "Cooling Coil Condenser Inlet Temperature",
    6137              :                                     Constant::Units::C,
    6138            0 :                                     thisDXCoil.CondInletTemp,
    6139              :                                     OutputProcessor::TimeStepType::System,
    6140              :                                     OutputProcessor::StoreType::Average,
    6141            0 :                                     thisDXCoil.Name);
    6142            0 :                 SetupOutputVariable(state,
    6143              :                                     "Cooling Coil Evaporative Condenser Water Volume",
    6144              :                                     Constant::Units::m3,
    6145            0 :                                     thisDXCoil.EvapWaterConsump,
    6146              :                                     OutputProcessor::TimeStepType::System,
    6147              :                                     OutputProcessor::StoreType::Sum,
    6148            0 :                                     thisDXCoil.Name,
    6149              :                                     Constant::eResource::Water,
    6150              :                                     OutputProcessor::Group::HVAC,
    6151              :                                     OutputProcessor::EndUseCat::Cooling);
    6152            0 :                 SetupOutputVariable(state,
    6153              :                                     "Cooling Coil Evaporative Condenser Mains Supply Water Volume",
    6154              :                                     Constant::Units::m3,
    6155            0 :                                     thisDXCoil.EvapWaterConsump,
    6156              :                                     OutputProcessor::TimeStepType::System,
    6157              :                                     OutputProcessor::StoreType::Sum,
    6158            0 :                                     thisDXCoil.Name,
    6159              :                                     Constant::eResource::MainsWater,
    6160              :                                     OutputProcessor::Group::HVAC,
    6161              :                                     OutputProcessor::EndUseCat::Cooling);
    6162            0 :                 SetupOutputVariable(state,
    6163              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Rate",
    6164              :                                     Constant::Units::W,
    6165            0 :                                     thisDXCoil.EvapCondPumpElecPower,
    6166              :                                     OutputProcessor::TimeStepType::System,
    6167              :                                     OutputProcessor::StoreType::Average,
    6168            0 :                                     thisDXCoil.Name);
    6169            0 :                 SetupOutputVariable(state,
    6170              :                                     "Cooling Coil Evaporative Condenser Pump Electricity Energy",
    6171              :                                     Constant::Units::J,
    6172            0 :                                     thisDXCoil.EvapCondPumpElecConsumption,
    6173              :                                     OutputProcessor::TimeStepType::System,
    6174              :                                     OutputProcessor::StoreType::Sum,
    6175            0 :                                     thisDXCoil.Name,
    6176              :                                     Constant::eResource::Electricity,
    6177              :                                     OutputProcessor::Group::HVAC,
    6178              :                                     OutputProcessor::EndUseCat::Cooling);
    6179            0 :                 if (thisDXCoil.BasinHeaterPowerFTempDiff > 0.0) {
    6180            0 :                     SetupOutputVariable(state,
    6181              :                                         "Cooling Coil Basin Heater Electricity Rate",
    6182              :                                         Constant::Units::W,
    6183            0 :                                         thisDXCoil.BasinHeaterPower,
    6184              :                                         OutputProcessor::TimeStepType::System,
    6185              :                                         OutputProcessor::StoreType::Average,
    6186            0 :                                         thisDXCoil.Name);
    6187            0 :                     SetupOutputVariable(state,
    6188              :                                         "Cooling Coil Basin Heater Electricity Energy",
    6189              :                                         Constant::Units::J,
    6190            0 :                                         thisDXCoil.BasinHeaterConsumption,
    6191              :                                         OutputProcessor::TimeStepType::System,
    6192              :                                         OutputProcessor::StoreType::Sum,
    6193            0 :                                         thisDXCoil.Name,
    6194              :                                         Constant::eResource::Electricity,
    6195              :                                         OutputProcessor::Group::HVAC,
    6196              :                                         OutputProcessor::EndUseCat::Cooling);
    6197              :                 }
    6198              :             }
    6199           27 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
    6200            0 :                 SetupOutputVariable(state,
    6201              :                                     "Secondary Coil Heat Rejection Rate",
    6202              :                                     Constant::Units::W,
    6203            0 :                                     thisDXCoil.SecCoilSensibleHeatGainRate,
    6204              :                                     OutputProcessor::TimeStepType::System,
    6205              :                                     OutputProcessor::StoreType::Average,
    6206            0 :                                     thisDXCoil.Name);
    6207              :             }
    6208              : 
    6209              :         }
    6210              : 
    6211           84 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    6212              :             // Setup Report Variables for Heating Equipment:
    6213              :             // CurrentModuleObject='Coil:Heating:DX:MultiSpeed'
    6214           28 :             SetupOutputVariable(state,
    6215              :                                 "Heating Coil Heating Rate",
    6216              :                                 Constant::Units::W,
    6217           14 :                                 thisDXCoil.TotalHeatingEnergyRate,
    6218              :                                 OutputProcessor::TimeStepType::System,
    6219              :                                 OutputProcessor::StoreType::Average,
    6220           14 :                                 thisDXCoil.Name);
    6221           28 :             SetupOutputVariable(state,
    6222              :                                 "Heating Coil Heating Energy",
    6223              :                                 Constant::Units::J,
    6224           14 :                                 thisDXCoil.TotalHeatingEnergy,
    6225              :                                 OutputProcessor::TimeStepType::System,
    6226              :                                 OutputProcessor::StoreType::Sum,
    6227           14 :                                 thisDXCoil.Name,
    6228              :                                 Constant::eResource::EnergyTransfer,
    6229              :                                 OutputProcessor::Group::HVAC,
    6230              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    6231           28 :             SetupOutputVariable(state,
    6232              :                                 "Heating Coil Electricity Rate",
    6233              :                                 Constant::Units::W,
    6234           14 :                                 thisDXCoil.ElecHeatingPower,
    6235              :                                 OutputProcessor::TimeStepType::System,
    6236              :                                 OutputProcessor::StoreType::Average,
    6237           14 :                                 thisDXCoil.Name);
    6238           28 :             SetupOutputVariable(state,
    6239              :                                 "Heating Coil Electricity Energy",
    6240              :                                 Constant::Units::J,
    6241           14 :                                 thisDXCoil.ElecHeatingConsumption,
    6242              :                                 OutputProcessor::TimeStepType::System,
    6243              :                                 OutputProcessor::StoreType::Sum,
    6244           14 :                                 thisDXCoil.Name,
    6245              :                                 Constant::eResource::Electricity,
    6246              :                                 OutputProcessor::Group::HVAC,
    6247              :                                 OutputProcessor::EndUseCat::Heating);
    6248              : 
    6249           14 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
    6250            3 :                 std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
    6251            9 :                 SetupOutputVariable(state,
    6252            6 :                                     format("Heating Coil {} Rate", sFuelType),
    6253              :                                     Constant::Units::W,
    6254            3 :                                     thisDXCoil.FuelUsed,
    6255              :                                     OutputProcessor::TimeStepType::System,
    6256              :                                     OutputProcessor::StoreType::Average,
    6257            3 :                                     thisDXCoil.Name);
    6258            9 :                 SetupOutputVariable(state,
    6259            6 :                                     format("Heating Coil {} Energy", sFuelType),
    6260              :                                     Constant::Units::J,
    6261            3 :                                     thisDXCoil.FuelConsumed,
    6262              :                                     OutputProcessor::TimeStepType::System,
    6263              :                                     OutputProcessor::StoreType::Sum,
    6264            3 :                                     thisDXCoil.Name,
    6265            3 :                                     Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
    6266              :                                     OutputProcessor::Group::HVAC,
    6267              :                                     OutputProcessor::EndUseCat::HeatingCoils);
    6268              :             }
    6269              : 
    6270           14 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity && thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
    6271            2 :                 std::string_view sFuelType = Constant::eFuelNames[static_cast<int>(thisDXCoil.FuelType)];
    6272            6 :                 SetupOutputVariable(state,
    6273            4 :                                     format("Heating Coil Defrost {} Rate", sFuelType),
    6274              :                                     Constant::Units::W,
    6275            2 :                                     thisDXCoil.DefrostPower,
    6276              :                                     OutputProcessor::TimeStepType::System,
    6277              :                                     OutputProcessor::StoreType::Average,
    6278            2 :                                     thisDXCoil.Name);
    6279            6 :                 SetupOutputVariable(state,
    6280            4 :                                     format("Heating Coil Defrost {} Energy", sFuelType),
    6281              :                                     Constant::Units::J,
    6282            2 :                                     thisDXCoil.DefrostConsumption,
    6283              :                                     OutputProcessor::TimeStepType::System,
    6284              :                                     OutputProcessor::StoreType::Sum,
    6285            2 :                                     thisDXCoil.Name,
    6286            2 :                                     Constant::eFuel2eResource[(int)thisDXCoil.FuelType],
    6287              :                                     OutputProcessor::Group::HVAC,
    6288              :                                     OutputProcessor::EndUseCat::Heating);
    6289            2 :             } else {
    6290           24 :                 SetupOutputVariable(state,
    6291              :                                     "Heating Coil Defrost Electricity Rate",
    6292              :                                     Constant::Units::W,
    6293           12 :                                     thisDXCoil.DefrostPower,
    6294              :                                     OutputProcessor::TimeStepType::System,
    6295              :                                     OutputProcessor::StoreType::Average,
    6296           12 :                                     thisDXCoil.Name);
    6297           24 :                 SetupOutputVariable(state,
    6298              :                                     "Heating Coil Defrost Electricity Energy",
    6299              :                                     Constant::Units::J,
    6300           12 :                                     thisDXCoil.DefrostConsumption,
    6301              :                                     OutputProcessor::TimeStepType::System,
    6302              :                                     OutputProcessor::StoreType::Sum,
    6303           12 :                                     thisDXCoil.Name,
    6304              :                                     Constant::eResource::Electricity,
    6305              :                                     OutputProcessor::Group::HVAC,
    6306              :                                     OutputProcessor::EndUseCat::Heating);
    6307              :             }
    6308              : 
    6309           28 :             SetupOutputVariable(state,
    6310              :                                 "Heating Coil Crankcase Heater Electricity Rate",
    6311              :                                 Constant::Units::W,
    6312           14 :                                 thisDXCoil.CrankcaseHeaterPower,
    6313              :                                 OutputProcessor::TimeStepType::System,
    6314              :                                 OutputProcessor::StoreType::Average,
    6315           14 :                                 thisDXCoil.Name);
    6316           28 :             SetupOutputVariable(state,
    6317              :                                 "Heating Coil Crankcase Heater Electricity Energy",
    6318              :                                 Constant::Units::J,
    6319           14 :                                 thisDXCoil.CrankcaseHeaterConsumption,
    6320              :                                 OutputProcessor::TimeStepType::System,
    6321              :                                 OutputProcessor::StoreType::Sum,
    6322           14 :                                 thisDXCoil.Name,
    6323              :                                 Constant::eResource::Electricity,
    6324              :                                 OutputProcessor::Group::HVAC,
    6325              :                                 OutputProcessor::EndUseCat::Heating);
    6326           28 :             SetupOutputVariable(state,
    6327              :                                 "Heating Coil Runtime Fraction",
    6328              :                                 Constant::Units::None,
    6329           14 :                                 thisDXCoil.HeatingCoilRuntimeFraction,
    6330              :                                 OutputProcessor::TimeStepType::System,
    6331              :                                 OutputProcessor::StoreType::Average,
    6332           14 :                                 thisDXCoil.Name);
    6333              : 
    6334           14 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
    6335            0 :                 SetupOutputVariable(state,
    6336              :                                     "Secondary Coil Total Heat Removal Rate",
    6337              :                                     Constant::Units::W,
    6338            0 :                                     thisDXCoil.SecCoilTotalHeatRemovalRate,
    6339              :                                     OutputProcessor::TimeStepType::System,
    6340              :                                     OutputProcessor::StoreType::Average,
    6341            0 :                                     thisDXCoil.Name);
    6342            0 :                 SetupOutputVariable(state,
    6343              :                                     "Secondary Coil Sensible Heat Removal Rate",
    6344              :                                     Constant::Units::W,
    6345            0 :                                     thisDXCoil.SecCoilSensibleHeatRemovalRate,
    6346              :                                     OutputProcessor::TimeStepType::System,
    6347              :                                     OutputProcessor::StoreType::Average,
    6348            0 :                                     thisDXCoil.Name);
    6349            0 :                 SetupOutputVariable(state,
    6350              :                                     "Secondary Coil Latent Heat Removal Rate",
    6351              :                                     Constant::Units::W,
    6352            0 :                                     thisDXCoil.SecCoilLatentHeatRemovalRate,
    6353              :                                     OutputProcessor::TimeStepType::System,
    6354              :                                     OutputProcessor::StoreType::Average,
    6355            0 :                                     thisDXCoil.Name);
    6356            0 :                 SetupOutputVariable(state,
    6357              :                                     "Secondary Coil Sensible Heat Ratio",
    6358              :                                     Constant::Units::None,
    6359            0 :                                     thisDXCoil.SecCoilSHR,
    6360              :                                     OutputProcessor::TimeStepType::System,
    6361              :                                     OutputProcessor::StoreType::Average,
    6362            0 :                                     thisDXCoil.Name);
    6363              :             }
    6364              : 
    6365           14 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    6366            0 :                 SetupEMSActuator(state,
    6367              :                                  thisDXCoil.DXCoilType,
    6368              :                                  thisDXCoil.Name,
    6369              :                                  "Frost Heating Capacity Multiplier",
    6370              :                                  "[]",
    6371            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
    6372            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
    6373              : 
    6374            0 :                 SetupEMSActuator(state,
    6375              :                                  thisDXCoil.DXCoilType,
    6376              :                                  thisDXCoil.Name,
    6377              :                                  "Frost Heating Input Power Multiplier",
    6378              :                                  "[]",
    6379            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
    6380            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
    6381              :             }
    6382              :         }
    6383              : 
    6384              :         // VRF cooling coil report variables
    6385           70 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
    6386              :             // Setup Report Variables for Cooling Equipment:
    6387              :             // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow
    6388           48 :             SetupOutputVariable(state,
    6389              :                                 "Cooling Coil Total Cooling Rate",
    6390              :                                 Constant::Units::W,
    6391           24 :                                 thisDXCoil.TotalCoolingEnergyRate,
    6392              :                                 OutputProcessor::TimeStepType::System,
    6393              :                                 OutputProcessor::StoreType::Average,
    6394           24 :                                 thisDXCoil.Name);
    6395           48 :             SetupOutputVariable(state,
    6396              :                                 "Cooling Coil Total Cooling Energy",
    6397              :                                 Constant::Units::J,
    6398           24 :                                 thisDXCoil.TotalCoolingEnergy,
    6399              :                                 OutputProcessor::TimeStepType::System,
    6400              :                                 OutputProcessor::StoreType::Sum,
    6401           24 :                                 thisDXCoil.Name,
    6402              :                                 Constant::eResource::EnergyTransfer,
    6403              :                                 OutputProcessor::Group::HVAC,
    6404              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    6405           48 :             SetupOutputVariable(state,
    6406              :                                 "Cooling Coil Sensible Cooling Rate",
    6407              :                                 Constant::Units::W,
    6408           24 :                                 thisDXCoil.SensCoolingEnergyRate,
    6409              :                                 OutputProcessor::TimeStepType::System,
    6410              :                                 OutputProcessor::StoreType::Average,
    6411           24 :                                 thisDXCoil.Name);
    6412           48 :             SetupOutputVariable(state,
    6413              :                                 "Cooling Coil Sensible Cooling Energy",
    6414              :                                 Constant::Units::J,
    6415           24 :                                 thisDXCoil.SensCoolingEnergy,
    6416              :                                 OutputProcessor::TimeStepType::System,
    6417              :                                 OutputProcessor::StoreType::Sum,
    6418           24 :                                 thisDXCoil.Name);
    6419           48 :             SetupOutputVariable(state,
    6420              :                                 "Cooling Coil Latent Cooling Rate",
    6421              :                                 Constant::Units::W,
    6422           24 :                                 thisDXCoil.LatCoolingEnergyRate,
    6423              :                                 OutputProcessor::TimeStepType::System,
    6424              :                                 OutputProcessor::StoreType::Average,
    6425           24 :                                 thisDXCoil.Name);
    6426           48 :             SetupOutputVariable(state,
    6427              :                                 "Cooling Coil Latent Cooling Energy",
    6428              :                                 Constant::Units::J,
    6429           24 :                                 thisDXCoil.LatCoolingEnergy,
    6430              :                                 OutputProcessor::TimeStepType::System,
    6431              :                                 OutputProcessor::StoreType::Sum,
    6432           24 :                                 thisDXCoil.Name);
    6433           48 :             SetupOutputVariable(state,
    6434              :                                 "Cooling Coil Runtime Fraction",
    6435              :                                 Constant::Units::None,
    6436           24 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    6437              :                                 OutputProcessor::TimeStepType::System,
    6438              :                                 OutputProcessor::StoreType::Average,
    6439           24 :                                 thisDXCoil.Name);
    6440           24 :             if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
    6441            0 :                 SetupOutputVariable(state,
    6442              :                                     "Cooling Coil Condensate Volume Flow Rate",
    6443              :                                     Constant::Units::m3_s,
    6444            0 :                                     thisDXCoil.CondensateVdot,
    6445              :                                     OutputProcessor::TimeStepType::System,
    6446              :                                     OutputProcessor::StoreType::Average,
    6447            0 :                                     thisDXCoil.Name);
    6448            0 :                 SetupOutputVariable(state,
    6449              :                                     "Cooling Coil Condensate Volume",
    6450              :                                     Constant::Units::m3,
    6451            0 :                                     thisDXCoil.CondensateVol,
    6452              :                                     OutputProcessor::TimeStepType::System,
    6453              :                                     OutputProcessor::StoreType::Sum,
    6454            0 :                                     thisDXCoil.Name,
    6455              :                                     Constant::eResource::OnSiteWater,
    6456              :                                     OutputProcessor::Group::HVAC,
    6457              :                                     OutputProcessor::EndUseCat::Condensate);
    6458              :             }
    6459              :         }
    6460              : 
    6461              :         // VRF heating coil report variables
    6462           46 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
    6463              :             // Setup Report Variables for Heating Equipment:
    6464              :             // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow
    6465           46 :             SetupOutputVariable(state,
    6466              :                                 "Heating Coil Heating Rate",
    6467              :                                 Constant::Units::W,
    6468           23 :                                 thisDXCoil.TotalHeatingEnergyRate,
    6469              :                                 OutputProcessor::TimeStepType::System,
    6470              :                                 OutputProcessor::StoreType::Average,
    6471           23 :                                 thisDXCoil.Name);
    6472           46 :             SetupOutputVariable(state,
    6473              :                                 "Heating Coil Heating Energy",
    6474              :                                 Constant::Units::J,
    6475           23 :                                 thisDXCoil.TotalHeatingEnergy,
    6476              :                                 OutputProcessor::TimeStepType::System,
    6477              :                                 OutputProcessor::StoreType::Sum,
    6478           23 :                                 thisDXCoil.Name,
    6479              :                                 Constant::eResource::EnergyTransfer,
    6480              :                                 OutputProcessor::Group::HVAC,
    6481              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    6482           46 :             SetupOutputVariable(state,
    6483              :                                 "Heating Coil Runtime Fraction",
    6484              :                                 Constant::Units::None,
    6485           23 :                                 thisDXCoil.HeatingCoilRuntimeFraction,
    6486              :                                 OutputProcessor::TimeStepType::System,
    6487              :                                 OutputProcessor::StoreType::Average,
    6488           23 :                                 thisDXCoil.Name);
    6489              : 
    6490           23 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    6491            0 :                 SetupEMSActuator(state,
    6492              :                                  thisDXCoil.DXCoilType,
    6493              :                                  thisDXCoil.Name,
    6494              :                                  "Frost Heating Capacity Multiplier",
    6495              :                                  "[]",
    6496            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn,
    6497            0 :                                  thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue);
    6498              : 
    6499            0 :                 SetupEMSActuator(state,
    6500              :                                  thisDXCoil.DXCoilType,
    6501              :                                  thisDXCoil.Name,
    6502              :                                  "Frost Heating Input Power Multiplier",
    6503              :                                  "[]",
    6504            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn,
    6505            0 :                                  thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue);
    6506              :             }
    6507              :         }
    6508              : 
    6509              :         // VRF cooling coil for FluidTCtrl, report variables
    6510           23 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    6511              :             // Setup Report Variables for Cooling Equipment:
    6512              :             // CurrentModuleObject='Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl
    6513           24 :             SetupOutputVariable(state,
    6514              :                                 "Cooling Coil Total Cooling Rate",
    6515              :                                 Constant::Units::W,
    6516           12 :                                 thisDXCoil.TotalCoolingEnergyRate,
    6517              :                                 OutputProcessor::TimeStepType::System,
    6518              :                                 OutputProcessor::StoreType::Average,
    6519           12 :                                 thisDXCoil.Name);
    6520           24 :             SetupOutputVariable(state,
    6521              :                                 "Cooling Coil Total Cooling Energy",
    6522              :                                 Constant::Units::J,
    6523           12 :                                 thisDXCoil.TotalCoolingEnergy,
    6524              :                                 OutputProcessor::TimeStepType::System,
    6525              :                                 OutputProcessor::StoreType::Sum,
    6526           12 :                                 thisDXCoil.Name,
    6527              :                                 Constant::eResource::EnergyTransfer,
    6528              :                                 OutputProcessor::Group::HVAC,
    6529              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    6530           24 :             SetupOutputVariable(state,
    6531              :                                 "Cooling Coil Sensible Cooling Rate",
    6532              :                                 Constant::Units::W,
    6533           12 :                                 thisDXCoil.SensCoolingEnergyRate,
    6534              :                                 OutputProcessor::TimeStepType::System,
    6535              :                                 OutputProcessor::StoreType::Average,
    6536           12 :                                 thisDXCoil.Name);
    6537           24 :             SetupOutputVariable(state,
    6538              :                                 "Cooling Coil Sensible Cooling Energy",
    6539              :                                 Constant::Units::J,
    6540           12 :                                 thisDXCoil.SensCoolingEnergy,
    6541              :                                 OutputProcessor::TimeStepType::System,
    6542              :                                 OutputProcessor::StoreType::Sum,
    6543           12 :                                 thisDXCoil.Name);
    6544           24 :             SetupOutputVariable(state,
    6545              :                                 "Cooling Coil Latent Cooling Rate",
    6546              :                                 Constant::Units::W,
    6547           12 :                                 thisDXCoil.LatCoolingEnergyRate,
    6548              :                                 OutputProcessor::TimeStepType::System,
    6549              :                                 OutputProcessor::StoreType::Average,
    6550           12 :                                 thisDXCoil.Name);
    6551           24 :             SetupOutputVariable(state,
    6552              :                                 "Cooling Coil Latent Cooling Energy",
    6553              :                                 Constant::Units::J,
    6554           12 :                                 thisDXCoil.LatCoolingEnergy,
    6555              :                                 OutputProcessor::TimeStepType::System,
    6556              :                                 OutputProcessor::StoreType::Sum,
    6557           12 :                                 thisDXCoil.Name);
    6558           24 :             SetupOutputVariable(state,
    6559              :                                 "Cooling Coil Runtime Fraction",
    6560              :                                 Constant::Units::None,
    6561           12 :                                 thisDXCoil.CoolingCoilRuntimeFraction,
    6562              :                                 OutputProcessor::TimeStepType::System,
    6563              :                                 OutputProcessor::StoreType::Average,
    6564           12 :                                 thisDXCoil.Name);
    6565              :             // Followings for VRF_FluidTCtrl Only
    6566           24 :             SetupOutputVariable(state,
    6567              :                                 "Cooling Coil VRF Evaporating Temperature",
    6568              :                                 Constant::Units::C,
    6569           12 :                                 thisDXCoil.EvaporatingTemp,
    6570              :                                 OutputProcessor::TimeStepType::System,
    6571              :                                 OutputProcessor::StoreType::Average,
    6572           12 :                                 thisDXCoil.Name);
    6573           24 :             SetupOutputVariable(state,
    6574              :                                 "Cooling Coil VRF Super Heating Degrees",
    6575              :                                 Constant::Units::C,
    6576           12 :                                 thisDXCoil.ActualSH,
    6577              :                                 OutputProcessor::TimeStepType::System,
    6578              :                                 OutputProcessor::StoreType::Average,
    6579           12 :                                 thisDXCoil.Name);
    6580              : 
    6581           12 :             if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
    6582            0 :                 SetupOutputVariable(state,
    6583              :                                     "Cooling Coil Condensate Volume Flow Rate",
    6584              :                                     Constant::Units::m3_s,
    6585            0 :                                     thisDXCoil.CondensateVdot,
    6586              :                                     OutputProcessor::TimeStepType::System,
    6587              :                                     OutputProcessor::StoreType::Average,
    6588            0 :                                     thisDXCoil.Name);
    6589            0 :                 SetupOutputVariable(state,
    6590              :                                     "Cooling Coil Condensate Volume",
    6591              :                                     Constant::Units::m3,
    6592            0 :                                     thisDXCoil.CondensateVol,
    6593              :                                     OutputProcessor::TimeStepType::System,
    6594              :                                     OutputProcessor::StoreType::Sum,
    6595            0 :                                     thisDXCoil.Name,
    6596              :                                     Constant::eResource::OnSiteWater,
    6597              :                                     OutputProcessor::Group::HVAC,
    6598              :                                     OutputProcessor::EndUseCat::Condensate);
    6599              :             }
    6600              :         }
    6601              : 
    6602              :         // VRF heating coil for FluidTCtrl, report variables
    6603           11 :         else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    6604              :             // Setup Report Variables for Heating Equipment:
    6605              :             // CurrentModuleObject='Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl
    6606           22 :             SetupOutputVariable(state,
    6607              :                                 "Heating Coil Heating Rate",
    6608              :                                 Constant::Units::W,
    6609           11 :                                 thisDXCoil.TotalHeatingEnergyRate,
    6610              :                                 OutputProcessor::TimeStepType::System,
    6611              :                                 OutputProcessor::StoreType::Average,
    6612           11 :                                 thisDXCoil.Name);
    6613           22 :             SetupOutputVariable(state,
    6614              :                                 "Heating Coil Heating Energy",
    6615              :                                 Constant::Units::J,
    6616           11 :                                 thisDXCoil.TotalHeatingEnergy,
    6617              :                                 OutputProcessor::TimeStepType::System,
    6618              :                                 OutputProcessor::StoreType::Sum,
    6619           11 :                                 thisDXCoil.Name,
    6620              :                                 Constant::eResource::EnergyTransfer,
    6621              :                                 OutputProcessor::Group::HVAC,
    6622              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    6623           22 :             SetupOutputVariable(state,
    6624              :                                 "Heating Coil Runtime Fraction",
    6625              :                                 Constant::Units::None,
    6626           11 :                                 thisDXCoil.HeatingCoilRuntimeFraction,
    6627              :                                 OutputProcessor::TimeStepType::System,
    6628              :                                 OutputProcessor::StoreType::Average,
    6629           11 :                                 thisDXCoil.Name);
    6630              :             // Followings for VRF_FluidTCtrl Only
    6631           22 :             SetupOutputVariable(state,
    6632              :                                 "Heating Coil VRF Condensing Temperature",
    6633              :                                 Constant::Units::C,
    6634           11 :                                 thisDXCoil.CondensingTemp,
    6635              :                                 OutputProcessor::TimeStepType::System,
    6636              :                                 OutputProcessor::StoreType::Average,
    6637           11 :                                 thisDXCoil.Name);
    6638           22 :             SetupOutputVariable(state,
    6639              :                                 "Heating Coil VRF Subcooling Degrees",
    6640              :                                 Constant::Units::C,
    6641           11 :                                 thisDXCoil.ActualSC,
    6642              :                                 OutputProcessor::TimeStepType::System,
    6643              :                                 OutputProcessor::StoreType::Average,
    6644           11 :                                 thisDXCoil.Name);
    6645              :         }
    6646              :     }
    6647              : 
    6648          134 :     if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    6649              :         // setup EMS sizing actuators for single speed DX
    6650            0 :         for (DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDoe2DXCoils; ++DXCoilNum) {
    6651              : 
    6652            0 :             auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    6653              : 
    6654            0 :             SetupEMSActuator(state,
    6655              :                              "Coil:Cooling:DX:SingleSpeed",
    6656              :                              thisDXCoil.Name,
    6657              :                              "Autosized Rated Air Flow Rate",
    6658              :                              "[m3/s]",
    6659              :                              thisDXCoil.RatedAirVolFlowRateEMSOverrideON(1),
    6660            0 :                              thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(1));
    6661              : 
    6662            0 :             SetupEMSActuator(state,
    6663              :                              "Coil:Cooling:DX:SingleSpeed",
    6664              :                              thisDXCoil.Name,
    6665              :                              "Autosized Rated Sensible Heat Ratio",
    6666              :                              "[W/W]",
    6667              :                              thisDXCoil.RatedSHREMSOverrideOn(1),
    6668            0 :                              thisDXCoil.RatedSHREMSOverrideValue(1));
    6669              : 
    6670            0 :             SetupEMSActuator(state,
    6671              :                              "Coil:Cooling:DX:SingleSpeed",
    6672              :                              thisDXCoil.Name,
    6673              :                              "Autosized Rated Total Cooling Capacity",
    6674              :                              "[W]",
    6675              :                              thisDXCoil.RatedTotCapEMSOverrideOn(1),
    6676            0 :                              thisDXCoil.RatedTotCapEMSOverrideValue(1));
    6677              :         }
    6678              :     }
    6679          134 :     Alphas.deallocate();
    6680          134 :     cAlphaFields.deallocate();
    6681          134 :     cNumericFields.deallocate();
    6682          134 :     Numbers.deallocate();
    6683          134 :     lAlphaBlanks.deallocate();
    6684          134 :     lNumericBlanks.deallocate();
    6685              : 
    6686          134 :     Alphas2.deallocate();
    6687          134 :     cAlphaFields2.deallocate();
    6688          134 :     cNumericFields2.deallocate();
    6689          134 :     Numbers2.deallocate();
    6690          134 :     lAlphaBlanks2.deallocate();
    6691          134 :     lNumericBlanks2.deallocate();
    6692              :     bool anyEMSRan;
    6693          134 :     ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyEMSRan, ObjexxFCL::Optional_int_const());
    6694          149 : }
    6695              : 
    6696       539063 : void InitDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current DX coil unit being simulated
    6697              : {
    6698              : 
    6699              :     // SUBROUTINE INFORMATION:
    6700              :     //       AUTHOR         Fred Buhl
    6701              :     //       DATE WRITTEN   May 2000
    6702              :     //                      Feb 2005, M. J. Witte, GARD Analytics, Inc. Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
    6703              :     //                      Jul 2005, R. Raustad, FSEC. Add new coil type COIL:DX:HEATPUMPWATERHEATER
    6704              :     //                      Jun 2007, L. Gu, FSEC. Add new coil type COIL:DX:MULTISPEED:COOLING and HEATING
    6705              :     //                      Aug 2015, R. Zhang, LBNL. Add new coil types for VRF_FluidTCtrl
    6706              : 
    6707              :     // PURPOSE OF THIS SUBROUTINE:
    6708              :     // This subroutine is for initializations of DX Coil Components.
    6709              : 
    6710              :     // METHODOLOGY EMPLOYED:
    6711              :     // Uses the status flags to trigger initializations.
    6712              : 
    6713              :     // SUBROUTINE PARAMETER DEFINITIONS:
    6714       539063 :     constexpr Real64 SmallDifferenceTest(0.00000001);
    6715              :     static constexpr std::string_view RoutineName("InitDXCoil");
    6716              : 
    6717              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6718              :     Real64 RatedHeatPumpIndoorAirTemp; // Indoor dry-bulb temperature to heat pump evaporator at rated conditions [C]
    6719              :     Real64 RatedHeatPumpIndoorHumRat;  // Inlet humidity ratio to heat pump evaporator at rated conditions [kgWater/kgDryAir]
    6720              :     Real64 RatedVolFlowPerRatedTotCap; // Rated Air Volume Flow Rate divided by Rated Total Capacity [m3/s-W)
    6721              :     Real64 HPInletAirHumRat;           // Rated inlet air humidity ratio for heat pump water heater [kgWater/kgDryAir]
    6722       539063 :     bool ErrorsFound(false);           // TRUE when errors found
    6723              :     int CapacityStageNum;              // Loop index for 1,Number of capacity stages
    6724              :     int DehumidModeNum;                // Loop index for 1,Number of enhanced dehumidification modes
    6725              :     int Mode;                          // Performance mode for MultiMode DX coil; Always 1 for other coil types
    6726              :     int DXCoilNumTemp;                 // Counter for crankcase heater report variable DO loop
    6727              :     int AirInletNode;                  // Air inlet node number
    6728              :     int SpeedNum;                      // Speed number for multispeed coils
    6729              : 
    6730       539063 :     if (state.dataDXCoils->MyOneTimeFlag) {
    6731              :         // initialize the environment and sizing flags
    6732           68 :         state.dataDXCoils->MyEnvrnFlag.dimension(state.dataDXCoils->NumDXCoils, true);
    6733           68 :         state.dataDXCoils->MySizeFlag.dimension(state.dataDXCoils->NumDXCoils, true);
    6734           68 :         state.dataDXCoils->MyOneTimeFlag = false;
    6735              :     }
    6736              : 
    6737       539063 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    6738              : 
    6739              :     // if "ISHundredPercentDOASDXCoil" =.TRUE., then set coil as 100% DOAS dx coil
    6740       539063 :     state.dataHVACGlobal->DXCT = (thisDXCoil.ISHundredPercentDOASDXCoil) ? HVAC::DXCoilType::DOAS : HVAC::DXCoilType::Regular;
    6741              : 
    6742      1617030 :     if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    6743       539224 :          thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
    6744          161 :         state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
    6745              : 
    6746            4 :         SizeDXCoil(state, DXCoilNum);
    6747              : 
    6748            4 :         RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(1) / thisDXCoil.RatedTotCap2;
    6749            8 :         if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    6750            4 :             ((RatedVolFlowPerRatedTotCap - HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    6751            0 :             ShowWarningError(state,
    6752            0 :                              format("{} \"{}\": Rated air volume flow rate per watt of rated total water heating capacity is out of range",
    6753            0 :                                     thisDXCoil.DXCoilType,
    6754            0 :                                     thisDXCoil.Name));
    6755            0 :             ShowContinueError(state,
    6756            0 :                               format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    6757              :                                      "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
    6758            0 :                                      HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    6759              :                                      RatedVolFlowPerRatedTotCap,
    6760            0 :                                      HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    6761              :         }
    6762              :         HPInletAirHumRat =
    6763            4 :             PsyWFnTdbTwbPb(state, thisDXCoil.RatedInletDBTemp, thisDXCoil.RatedInletWBTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
    6764            4 :         state.dataHVACGlobal->HPWHInletDBTemp = thisDXCoil.RatedInletDBTemp;
    6765            4 :         state.dataHVACGlobal->HPWHInletWBTemp = thisDXCoil.RatedInletWBTemp;
    6766            8 :         thisDXCoil.RatedAirMassFlowRate(1) =
    6767            4 :             thisDXCoil.RatedAirVolFlowRate(1) *
    6768            4 :             PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, thisDXCoil.RatedInletDBTemp, HPInletAirHumRat, RoutineName);
    6769              :         //   get rated coil bypass factor excluding fan heat
    6770              : 
    6771              :         //   call CalcHPWHDXCoil to determine DXCoil%RatedTotCap(1) for rated CBF calculation below
    6772            4 :         CalcHPWHDXCoil(state, DXCoilNum, 1.0);
    6773            4 :         if (state.dataDXCoils->MySizeFlag(DXCoilNum)) {
    6774            4 :             SizeDXCoil(state, DXCoilNum);
    6775            4 :             state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
    6776              :         }
    6777              : 
    6778            4 :         thisDXCoil.RatedCBF(1) = CalcCBF(state,
    6779            4 :                                          thisDXCoil.DXCoilType,
    6780            4 :                                          thisDXCoil.Name,
    6781              :                                          thisDXCoil.RatedInletDBTemp,
    6782              :                                          HPInletAirHumRat,
    6783            4 :                                          thisDXCoil.RatedTotCap(1),
    6784            4 :                                          thisDXCoil.RatedAirVolFlowRate(1),
    6785            4 :                                          thisDXCoil.RatedSHR(1),
    6786              :                                          true);
    6787            4 :         state.dataDXCoils->MyEnvrnFlag(DXCoilNum) = false;
    6788              :     }
    6789              : 
    6790       539513 :     if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) &&
    6791          450 :         state.dataDXCoils->MyEnvrnFlag(DXCoilNum)) {
    6792           15 :         if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
    6793            4 :             if (thisDXCoil.MSHPHeatRecActive) {
    6794            5 :                 for (SpeedNum = 1; SpeedNum <= thisDXCoil.NumOfSpeeds; ++SpeedNum) {
    6795            4 :                     if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
    6796            0 :                         ShowWarningError(
    6797              :                             state,
    6798            0 :                             format("GetDXCoils:{}. The value of Waste Heat Function of Temperature Curve is assumed to be 1. Simulation continues. ",
    6799            0 :                                    thisDXCoil.Name));
    6800            0 :                         break;
    6801              :                     }
    6802              :                 }
    6803              :             }
    6804              :         }
    6805           15 :         state.dataDXCoils->MyEnvrnFlag(DXCoilNum) = false;
    6806              :     }
    6807              : 
    6808              :     // Find the companion upstream coil (DX cooling coil) that is used with DX heating coils (HP AC units only)
    6809       539063 :     if (thisDXCoil.FindCompanionUpStreamCoil) {
    6810          135 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    6811           40 :             thisDXCoil.CompanionUpstreamDXCoil = GetHPCoolingCoilIndex(state, thisDXCoil.DXCoilType, thisDXCoil.Name, DXCoilNum);
    6812           40 :             if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
    6813            9 :                 state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).ReportCoolingCoilCrankcasePower = false;
    6814            9 :                 thisDXCoil.FindCompanionUpStreamCoil = false;
    6815              :                 //       Copy condenser node number from DX cooling coil when used with a companion DX heating coil
    6816           45 :                 for (Mode = 1; Mode <= MaxModes; ++Mode) {
    6817           36 :                     thisDXCoil.CondenserInletNodeNum(Mode) =
    6818           36 :                         state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CondenserInletNodeNum(Mode);
    6819              :                 }
    6820              :             }
    6821              :         } else {
    6822           95 :             thisDXCoil.FindCompanionUpStreamCoil = false;
    6823              :         }
    6824              :     } // IF(DXCoil(DXCoilNum)%FindCompanionUpStreamCoil)THEN
    6825              : 
    6826              :     // CR7308 - Wait for zone and air loop equipment to be simulated, then print out report variables
    6827       539063 :     if (state.dataDXCoils->CrankcaseHeaterReportVarFlag) {
    6828         1258 :         if (state.dataAirLoop->AirLoopInputsFilled) {
    6829              :             //     Set report variables for DX cooling coils that will have a crankcase heater (all DX coils not used in a HP AC unit)
    6830           90 :             for (DXCoilNumTemp = 1; DXCoilNumTemp <= state.dataDXCoils->NumDXCoils; ++DXCoilNumTemp) {
    6831           60 :                 if ((state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) ||
    6832          103 :                     (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) ||
    6833           43 :                     (state.dataDXCoils->DXCoil(DXCoilNumTemp).DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling)) {
    6834           18 :                     if (state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower) {
    6835           32 :                         SetupOutputVariable(state,
    6836              :                                             "Cooling Coil Crankcase Heater Electricity Rate",
    6837              :                                             Constant::Units::W,
    6838           16 :                                             state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterPower,
    6839              :                                             OutputProcessor::TimeStepType::System,
    6840              :                                             OutputProcessor::StoreType::Average,
    6841           16 :                                             state.dataDXCoils->DXCoil(DXCoilNumTemp).Name);
    6842           32 :                         SetupOutputVariable(state,
    6843              :                                             "Cooling Coil Crankcase Heater Electricity Energy",
    6844              :                                             Constant::Units::J,
    6845           16 :                                             state.dataDXCoils->DXCoil(DXCoilNumTemp).CrankcaseHeaterConsumption,
    6846              :                                             OutputProcessor::TimeStepType::System,
    6847              :                                             OutputProcessor::StoreType::Sum,
    6848           16 :                                             state.dataDXCoils->DXCoil(DXCoilNumTemp).Name,
    6849              :                                             Constant::eResource::Electricity,
    6850              :                                             OutputProcessor::Group::HVAC,
    6851              :                                             OutputProcessor::EndUseCat::Cooling);
    6852           16 :                         state.dataDXCoils->DXCoil(DXCoilNumTemp).ReportCoolingCoilCrankcasePower = false;
    6853              :                     }
    6854              :                 }
    6855              :             }
    6856           30 :             state.dataDXCoils->CrankcaseHeaterReportVarFlag = false;
    6857              :         } //(AirLoopInputsFilled)THEN
    6858              :     } //(CrankcaseHeaterReportVarFlag)THEN
    6859              : 
    6860       539063 :     if (!state.dataGlobal->SysSizingCalc && state.dataDXCoils->MySizeFlag(DXCoilNum)) {
    6861              :         // for each coil, do the sizing once.
    6862           69 :         SizeDXCoil(state, DXCoilNum);
    6863           69 :         state.dataDXCoils->MySizeFlag(DXCoilNum) = false;
    6864              : 
    6865           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
    6866           35 :             thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    6867              : 
    6868           47 :             Mode = 1;
    6869              :             // Check for zero capacity or zero max flow rate
    6870           47 :             if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
    6871            0 :                 ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
    6872            0 :                 ErrorsFound = true;
    6873              :             }
    6874           47 :             if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
    6875            0 :                 ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
    6876            0 :                 ErrorsFound = true;
    6877              :             }
    6878           47 :             if (ErrorsFound) {
    6879            0 :                 ShowFatalError(state, "Preceding condition causes termination.");
    6880              :             }
    6881              : 
    6882              :             // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    6883           47 :             if (thisDXCoil.DXCoilType_Num !=
    6884              :                 HVAC::CoilVRF_FluidTCtrl_Cooling) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
    6885           41 :                 RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
    6886           82 :                 if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    6887           41 :                     ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    6888            2 :                     ShowWarningError(state,
    6889            2 :                                      format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range.",
    6890            1 :                                             thisDXCoil.DXCoilType,
    6891            1 :                                             thisDXCoil.Name));
    6892            2 :                     ShowContinueError(state,
    6893            2 :                                       format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    6894              :                                              "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
    6895            1 :                                              HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    6896              :                                              RatedVolFlowPerRatedTotCap,
    6897            1 :                                              HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    6898              :                 }
    6899              :             }
    6900              : 
    6901           94 :             thisDXCoil.RatedAirMassFlowRate(Mode) =
    6902           47 :                 thisDXCoil.RatedAirVolFlowRate(Mode) *
    6903           47 :                 PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
    6904              :             // get high speed rated coil bypass factor
    6905           47 :             thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
    6906           47 :                                                 thisDXCoil.DXCoilType,
    6907           47 :                                                 thisDXCoil.Name,
    6908              :                                                 RatedInletAirTemp,
    6909              :                                                 RatedInletAirHumRat,
    6910           47 :                                                 thisDXCoil.RatedTotCap(Mode),
    6911           47 :                                                 thisDXCoil.RatedAirVolFlowRate(Mode),
    6912           47 :                                                 thisDXCoil.RatedSHR(Mode));
    6913              : 
    6914              :             // call coil model with everything set at rating point
    6915           47 :             thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
    6916           47 :             thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
    6917           47 :             thisDXCoil.InletAirTemp = RatedInletAirTemp;
    6918              :             Real64 tempInletAirHumRat =
    6919           47 :                 Psychrometrics::PsyWFnTdbTwbPb(state, RatedInletAirTemp, RatedInletWetBulbTemp, DataEnvironment::StdPressureSeaLevel, RoutineName);
    6920              :             // DXCoil( DXCoilNum ).InletAirHumRat = RatedInletAirHumRat; // this seems inconsistent with dry bulb and wetbulb, filed NREL issue
    6921              :             // #5934  Real64 tempInletAirWetBulb = Psychrometrics::PsyTwbFnTdbWPb( RatedInletAirTemp, RatedInletAirHumRat,
    6922              :             // DataEnvironment::StdPressureSeaLevel );
    6923           47 :             thisDXCoil.InletAirHumRat = tempInletAirHumRat;
    6924           47 :             thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTemp, tempInletAirHumRat);
    6925              : 
    6926              :             // store environment data fill back in after rating point calc is over
    6927           47 :             Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
    6928           47 :             Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
    6929           47 :             Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
    6930           47 :             Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
    6931           47 :             Real64 ratedOutdoorAirWetBulb = 23.9; // from I/O ref. more precise value?
    6932           47 :             state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTemp;
    6933           47 :             state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
    6934           47 :             state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
    6935           94 :             state.dataEnvrn->OutHumRat =
    6936           47 :                 Psychrometrics::PsyWFnTdbTwbPb(state, RatedOutdoorAirTemp, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
    6937           47 :             if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
    6938           14 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTemp;
    6939           14 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
    6940           14 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
    6941              :             }
    6942              : 
    6943              :             // calculate coil model at rating point
    6944           47 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
    6945           31 :                 CalcDoe2DXCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, _, 1.0);
    6946           16 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    6947            3 :                 CalcMultiSpeedDXCoil(state, DXCoilNum, 1.0, 1.0);
    6948           13 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
    6949            7 :                 CalcVRFCoolingCoil(state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _, _);
    6950            6 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    6951            6 :                 CalcVRFCoolingCoil_FluidTCtrl(
    6952              :                     state, DXCoilNum, HVAC::CompressorOp::On, false, 1.0, HVAC::FanOp::Cycling, 1.0, _, _, Constant::MaxCap);
    6953              :             }
    6954              : 
    6955              :             // coil outlets
    6956           47 :             Real64 RatedOutletWetBulb(0.0);
    6957           47 :             RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
    6958              :                 state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
    6959              : 
    6960           47 :             state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
    6961              :                 state,
    6962           47 :                 thisDXCoil.Name,
    6963           47 :                 thisDXCoil.DXCoilType,
    6964              :                 thisDXCoil.TotalCoolingEnergyRate, // this is the report variable
    6965              :                 thisDXCoil.SensCoolingEnergyRate,  // this is the report variable
    6966              :                 thisDXCoil.InletAirMassFlowRate,
    6967              :                 thisDXCoil.InletAirTemp,
    6968              :                 thisDXCoil.InletAirHumRat,
    6969              :                 RatedInletWetBulbTemp,
    6970              :                 thisDXCoil.OutletAirTemp,
    6971              :                 thisDXCoil.OutletAirHumRat,
    6972              :                 RatedOutletWetBulb,
    6973              :                 RatedOutdoorAirTemp,
    6974              :                 ratedOutdoorAirWetBulb,
    6975           47 :                 thisDXCoil.RatedCBF(Mode),
    6976              :                 -999.0); // coil effectiveness not define for DX
    6977              : 
    6978              :             // now replace the outdoor air conditions set above for one time rating point calc
    6979           47 :             state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
    6980           47 :             state.dataEnvrn->OutHumRat = holdOutHumRat;
    6981           47 :             state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
    6982           47 :             state.dataEnvrn->OutBaroPress = holdOutBaroPress;
    6983              :         }
    6984              : 
    6985           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    6986            0 :             for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
    6987            0 :                 for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
    6988            0 :                     Mode = DehumidModeNum * 2 + CapacityStageNum;
    6989              :                     // Check for zero capacity or zero max flow rate
    6990            0 :                     if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
    6991            0 :                         ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
    6992            0 :                         ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
    6993            0 :                         ErrorsFound = true;
    6994              :                     }
    6995            0 :                     if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
    6996            0 :                         ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
    6997            0 :                         ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
    6998            0 :                         ErrorsFound = true;
    6999              :                     }
    7000            0 :                     if (ErrorsFound) {
    7001            0 :                         ShowFatalError(state, "Preceding condition causes termination.");
    7002              :                     }
    7003              :                     // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    7004            0 :                     RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
    7005            0 :                     if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    7006            0 :                         ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    7007            0 :                         ShowWarningError(
    7008              :                             state,
    7009            0 :                             format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range.",
    7010            0 :                                    thisDXCoil.DXCoilType,
    7011            0 :                                    thisDXCoil.Name));
    7012            0 :                         ShowContinueError(state,
    7013            0 :                                           format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    7014              :                                                  "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
    7015            0 :                                                  HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    7016              :                                                  RatedVolFlowPerRatedTotCap,
    7017            0 :                                                  HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    7018            0 :                         ShowContinueError(state, format("for CoilPerformance:DX:Cooling mode: {}", thisDXCoil.CoilPerformanceName(Mode)));
    7019              :                     }
    7020            0 :                     thisDXCoil.RatedAirMassFlowRate(Mode) =
    7021            0 :                         thisDXCoil.RatedAirVolFlowRate(Mode) *
    7022            0 :                         PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
    7023              :                     // get rated coil bypass factor
    7024            0 :                     thisDXCoil.RatedCBF(Mode) = CalcCBF(state,
    7025            0 :                                                         thisDXCoil.CoilPerformanceType(Mode),
    7026            0 :                                                         thisDXCoil.CoilPerformanceName(Mode),
    7027              :                                                         RatedInletAirTemp,
    7028              :                                                         RatedInletAirHumRat,
    7029            0 :                                                         thisDXCoil.RatedTotCap(Mode),
    7030            0 :                                                         thisDXCoil.RatedAirVolFlowRate(Mode),
    7031            0 :                                                         thisDXCoil.RatedSHR(Mode));
    7032              :                 } // End capacity stages loop
    7033              :             } // End dehumidification modes loop
    7034              :         }
    7035              : 
    7036           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
    7037           58 :             thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    7038              : 
    7039           17 :             Mode = 1;
    7040           17 :             if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
    7041            0 :                 ShowSevereError(state, format("Sizing: {} {} has zero rated total capacity", thisDXCoil.DXCoilType, thisDXCoil.Name));
    7042            0 :                 ErrorsFound = true;
    7043              :             }
    7044           17 :             if (thisDXCoil.RatedAirVolFlowRate(Mode) <= 0.0) {
    7045            0 :                 ShowSevereError(state, format("Sizing: {} {} has zero rated air flow rate", thisDXCoil.DXCoilType, thisDXCoil.Name));
    7046            0 :                 ErrorsFound = true;
    7047              :             }
    7048           17 :             if (ErrorsFound) {
    7049            0 :                 ShowFatalError(state, "Preceding condition causes termination.");
    7050              :             }
    7051           17 :             RatedHeatPumpIndoorAirTemp = 21.11;  // 21.11C or 70F
    7052           17 :             RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
    7053           34 :             thisDXCoil.RatedAirMassFlowRate(Mode) =
    7054           17 :                 thisDXCoil.RatedAirVolFlowRate(Mode) *
    7055           17 :                 PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
    7056              : 
    7057              :             // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    7058           17 :             if (thisDXCoil.DXCoilType_Num !=
    7059              :                 HVAC::CoilVRF_FluidTCtrl_Heating) { // the VolFlowPerRatedTotCap check is not applicable for VRF-FluidTCtrl coil
    7060           11 :                 RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate(Mode) / thisDXCoil.RatedTotCap(Mode);
    7061           22 :                 if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    7062           11 :                     ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    7063            2 :                     ShowWarningError(state,
    7064            2 :                                      format("Sizing: {} {}: Rated air volume flow rate per watt of rated total heating capacity is out of range.",
    7065            1 :                                             thisDXCoil.DXCoilType,
    7066            1 :                                             thisDXCoil.Name));
    7067            2 :                     ShowContinueError(state,
    7068            2 :                                       format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    7069              :                                              "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
    7070            1 :                                              HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    7071              :                                              RatedVolFlowPerRatedTotCap,
    7072            1 :                                              HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    7073              :                 }
    7074              :             }
    7075              : 
    7076              :             // call coil model with everything set at rating point
    7077           17 :             thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(Mode);
    7078           17 :             thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(Mode);
    7079              : 
    7080           17 :             thisDXCoil.InletAirTemp = RatedInletAirTempHeat;
    7081           17 :             Real64 tempInletAirHumRat = Psychrometrics::PsyWFnTdbTwbPb(
    7082              :                 state, RatedInletAirTempHeat, RatedInletWetBulbTempHeat, DataEnvironment::StdPressureSeaLevel, RoutineName);
    7083           17 :             thisDXCoil.InletAirHumRat = tempInletAirHumRat;
    7084           17 :             thisDXCoil.InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(RatedInletAirTempHeat, tempInletAirHumRat);
    7085              : 
    7086              :             // store environment data fill back in after rating point calc is over
    7087           17 :             Real64 holdOutDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
    7088           17 :             Real64 holdOutHumRat = state.dataEnvrn->OutHumRat;
    7089           17 :             Real64 holdOutWetBulb = state.dataEnvrn->OutWetBulbTemp;
    7090           17 :             Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
    7091              : 
    7092           17 :             state.dataEnvrn->OutDryBulbTemp = RatedOutdoorAirTempHeat;
    7093              : 
    7094           17 :             Real64 ratedOutdoorAirWetBulb = 6.11; // from I/O ref. more precise value?
    7095           17 :             state.dataEnvrn->OutWetBulbTemp = ratedOutdoorAirWetBulb;
    7096           17 :             state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
    7097           17 :             state.dataEnvrn->OutHumRat = Psychrometrics::PsyWFnTdbTwbPb(
    7098              :                 state, RatedOutdoorAirTempHeat, ratedOutdoorAirWetBulb, DataEnvironment::StdPressureSeaLevel, RoutineName);
    7099              : 
    7100           17 :             if (thisDXCoil.CondenserInletNodeNum(1) > 0) { // set condenser inlet node values
    7101            6 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = RatedOutdoorAirTempHeat;
    7102            6 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat = state.dataEnvrn->OutHumRat;
    7103            6 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb = ratedOutdoorAirWetBulb;
    7104              :             }
    7105              : 
    7106              :             // calculate coil model at rating point
    7107           17 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
    7108            4 :                 CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, 1.0);
    7109           13 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
    7110            7 :                 CalcDXHeatingCoil(state, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
    7111            6 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    7112            6 :                 CalcVRFHeatingCoil_FluidTCtrl(state, HVAC::CompressorOp::On, DXCoilNum, 1.0, HVAC::FanOp::Cycling, _, _);
    7113              :             }
    7114              :             // coil outlets
    7115           17 :             Real64 RatedOutletWetBulb(0.0);
    7116           17 :             RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(
    7117              :                 state, thisDXCoil.OutletAirTemp, thisDXCoil.OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
    7118              : 
    7119           17 :             state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
    7120              :                 state,
    7121           17 :                 thisDXCoil.Name,
    7122           17 :                 thisDXCoil.DXCoilType,
    7123              :                 thisDXCoil.TotalHeatingEnergyRate, // this is the report variable
    7124              :                 thisDXCoil.TotalHeatingEnergyRate, // this is the report variable
    7125              :                 thisDXCoil.InletAirMassFlowRate,
    7126              :                 thisDXCoil.InletAirTemp,
    7127              :                 thisDXCoil.InletAirHumRat,
    7128              :                 RatedInletWetBulbTempHeat,
    7129              :                 thisDXCoil.OutletAirTemp,
    7130              :                 thisDXCoil.OutletAirHumRat,
    7131              :                 RatedOutletWetBulb,
    7132              :                 RatedOutdoorAirTempHeat,
    7133              :                 ratedOutdoorAirWetBulb,
    7134           17 :                 thisDXCoil.RatedCBF(Mode),
    7135              :                 -999.0); // coil effectiveness not define for DX
    7136              : 
    7137              :             // now replace the outdoor air conditions set above for one time rating point calc
    7138           17 :             state.dataEnvrn->OutDryBulbTemp = holdOutDryBulbTemp;
    7139           17 :             state.dataEnvrn->OutHumRat = holdOutHumRat;
    7140           17 :             state.dataEnvrn->OutWetBulbTemp = holdOutWetBulb;
    7141           17 :             state.dataEnvrn->OutBaroPress = holdOutBaroPress;
    7142              :         }
    7143              : 
    7144           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7145              :             // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    7146            3 :             RatedVolFlowPerRatedTotCap = thisDXCoil.RatedAirVolFlowRate2 / thisDXCoil.RatedTotCap2;
    7147            6 :             if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    7148            3 :                 ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    7149            0 :                 ShowWarningError(state,
    7150            0 :                                  format("Coil:Cooling:DX:TwoSpeed \"{}\": At low speed rated air volume flow rate per watt of rated total cooling "
    7151              :                                         "capacity is out of range.",
    7152            0 :                                         thisDXCoil.Name));
    7153            0 :                 ShowContinueError(state,
    7154            0 :                                   format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    7155              :                                          "Watt=[{:.3T}]. See Input-Output Reference Manual for valid range.",
    7156            0 :                                          HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    7157              :                                          RatedVolFlowPerRatedTotCap,
    7158            0 :                                          HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    7159              :             }
    7160              : 
    7161            3 :             thisDXCoil.RatedAirMassFlowRate2 =
    7162            6 :                 thisDXCoil.RatedAirVolFlowRate2 *
    7163            3 :                 PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
    7164              :             // get low speed rated coil bypass factor
    7165            6 :             thisDXCoil.RatedCBF2 = CalcCBF(state,
    7166            3 :                                            thisDXCoil.DXCoilType,
    7167            3 :                                            thisDXCoil.Name,
    7168              :                                            RatedInletAirTemp,
    7169              :                                            RatedInletAirHumRat,
    7170              :                                            thisDXCoil.RatedTotCap2,
    7171              :                                            thisDXCoil.RatedAirVolFlowRate2,
    7172              :                                            thisDXCoil.RatedSHR2);
    7173              : 
    7174              :             // call for standard ratings for two-speed DX coil
    7175            3 :             if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air) {
    7176            2 :                 CalcTwoSpeedDXCoilStandardRating(state, DXCoilNum);
    7177              :             }
    7178              :         }
    7179              : 
    7180              :         // Multispeed Cooling
    7181           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
    7182           16 :             for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    7183              :                 // Check for zero capacity or zero max flow rate
    7184           11 :                 if (thisDXCoil.MSRatedTotCap(Mode) <= 0.0) {
    7185            0 :                     ShowSevereError(state,
    7186            0 :                                     format("Sizing: {} {} has zero rated total capacity at speed {}", thisDXCoil.DXCoilType, thisDXCoil.Name, Mode));
    7187            0 :                     ErrorsFound = true;
    7188              :                 }
    7189           11 :                 if (thisDXCoil.MSRatedAirVolFlowRate(Mode) <= 0.0) {
    7190            0 :                     ShowSevereError(state,
    7191            0 :                                     format("Sizing: {} {} has zero rated air flow rate at speed {}", thisDXCoil.DXCoilType, thisDXCoil.Name, Mode));
    7192            0 :                     ErrorsFound = true;
    7193              :                 }
    7194           11 :                 if (ErrorsFound) {
    7195            0 :                     ShowFatalError(state, "Preceding condition causes termination.");
    7196              :                 }
    7197              :                 // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    7198           11 :                 RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
    7199           22 :                 if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    7200           11 :                     ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    7201            0 :                     ShowWarningError(
    7202              :                         state,
    7203            0 :                         format("Sizing: {} \"{}\": Rated air volume flow rate per watt of rated total cooling capacity is out of range at speed {}",
    7204            0 :                                thisDXCoil.DXCoilType,
    7205            0 :                                thisDXCoil.Name,
    7206              :                                Mode));
    7207            0 :                     ShowContinueError(state,
    7208            0 :                                       format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    7209              :                                              "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
    7210            0 :                                              HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    7211              :                                              RatedVolFlowPerRatedTotCap,
    7212            0 :                                              HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    7213              :                 }
    7214           22 :                 thisDXCoil.MSRatedAirMassFlowRate(Mode) =
    7215           11 :                     thisDXCoil.MSRatedAirVolFlowRate(Mode) *
    7216           11 :                     PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedInletAirTemp, RatedInletAirHumRat, RoutineName);
    7217              :                 // get high speed rated coil bypass factor
    7218           11 :                 thisDXCoil.MSRatedCBF(Mode) = CalcCBF(state,
    7219           11 :                                                       thisDXCoil.DXCoilType,
    7220           11 :                                                       thisDXCoil.Name,
    7221              :                                                       RatedInletAirTemp,
    7222              :                                                       RatedInletAirHumRat,
    7223           11 :                                                       thisDXCoil.MSRatedTotCap(Mode),
    7224           11 :                                                       thisDXCoil.MSRatedAirVolFlowRate(Mode),
    7225           11 :                                                       thisDXCoil.MSRatedSHR(Mode));
    7226              :             }
    7227              :         }
    7228              : 
    7229              :         // Multispeed Heating
    7230           69 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    7231            0 :             RatedHeatPumpIndoorAirTemp = 21.11;  // 21.11C or 70F
    7232            0 :             RatedHeatPumpIndoorHumRat = 0.00881; // Humidity ratio corresponding to 70F dry bulb/60F wet bulb
    7233            0 :             for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    7234              : 
    7235            0 :                 thisDXCoil.MSRatedAirMassFlowRate(Mode) =
    7236            0 :                     thisDXCoil.MSRatedAirVolFlowRate(Mode) *
    7237            0 :                     PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, RatedHeatPumpIndoorAirTemp, RatedHeatPumpIndoorHumRat, RoutineName);
    7238              :                 // Check for valid range of (Rated Air Volume Flow Rate / Rated Total Capacity)
    7239            0 :                 RatedVolFlowPerRatedTotCap = thisDXCoil.MSRatedAirVolFlowRate(Mode) / thisDXCoil.MSRatedTotCap(Mode);
    7240            0 :                 if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - RatedVolFlowPerRatedTotCap) > SmallDifferenceTest) ||
    7241            0 :                     ((RatedVolFlowPerRatedTotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
    7242            0 :                     ShowWarningError(state,
    7243            0 :                                      format("Coil:Heating:DX:MultiSpeed {}: Rated air volume flow rate per watt of rated total heating capacity "
    7244              :                                             "is out of range at speed {}",
    7245            0 :                                             thisDXCoil.Name,
    7246              :                                             Mode));
    7247            0 :                     ShowContinueError(state,
    7248            0 :                                       format("Min Rated Vol Flow Per Watt=[{:.3T}], Rated Vol Flow Per Watt=[{:.3T}], Max Rated Vol Flow Per "
    7249              :                                              "Watt=[{:.3T}]. See Input Output Reference Manual for valid range.",
    7250            0 :                                              HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    7251              :                                              RatedVolFlowPerRatedTotCap,
    7252            0 :                                              HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    7253              :                 }
    7254              :             }
    7255              :         }
    7256              : 
    7257              :         // store fan info for coil
    7258           69 :         state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
    7259           69 :             state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType, thisDXCoil.SupplyFanIndex);
    7260              :     }
    7261              : 
    7262       539063 :     AirInletNode = thisDXCoil.AirInNode;
    7263              : 
    7264              :     // Each iteration, load the coil data structure with the inlet conditions
    7265              : 
    7266       539063 :     thisDXCoil.InletAirMassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
    7267       539063 :     thisDXCoil.InletAirMassFlowRateMax =
    7268       539063 :         max(state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax, state.dataLoopNodes->Node(AirInletNode).MassFlowRate);
    7269       539063 :     thisDXCoil.InletAirTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
    7270       539063 :     thisDXCoil.InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
    7271       539063 :     thisDXCoil.InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
    7272              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    7273              :     //  DXCoil(DXCoilNum)%InletAirPressure        = Node(AirInletNode)%Press
    7274              : 
    7275       539063 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    7276       128165 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
    7277            0 :             thisDXCoil.EvapInletWetBulb = PsyTwbFnTdbWPb(state,
    7278            0 :                                                          state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).ZT,
    7279            0 :                                                          state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr).airHumRat,
    7280            0 :                                                          state.dataEnvrn->OutBaroPress,
    7281              :                                                          RoutineName);
    7282              :         }
    7283              :     }
    7284              : 
    7285       539063 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    7286          161 :         thisDXCoil.TotalHeatingEnergyRate = 0.0;
    7287          161 :         thisDXCoil.ElecWaterHeatingPower = 0.0;
    7288              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    7289              :         //  DXCoil(DXCoilNum)%InletAirPressure         = StdBaroPress
    7290              : 
    7291              :         //   HPWH's that use an inlet air temperature schedule also need to have a valid barometric pressure
    7292              :         //   The DX Coil used in HPWH's does not know if it is using a scheduled inlet temperature so check the node pressure
    7293          161 :         if (thisDXCoil.CondenserInletNodeNum(1) > 0) {
    7294          161 :             if (state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press == 0.0) {
    7295            2 :                 state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press = state.dataEnvrn->StdBaroPress;
    7296              :             }
    7297              :         }
    7298              :     }
    7299       539063 :     thisDXCoil.BasinHeaterPower = 0.0;
    7300              : 
    7301       539063 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
    7302            0 :         thisDXCoil.CompressorPartLoadRatio = 0.0;
    7303            0 :         thisDXCoil.SecCoilSensibleHeatGainRate = 0.0;
    7304            0 :         thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
    7305            0 :         thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
    7306            0 :         thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
    7307              :     }
    7308       539063 : }
    7309              : 
    7310           96 : void SizeDXCoil(EnergyPlusData &state, int const DXCoilNum)
    7311              : {
    7312              : 
    7313              :     // SUBROUTINE INFORMATION:
    7314              :     //       AUTHOR         Fred Buhl
    7315              :     //       DATE WRITTEN   January 2002
    7316              :     //                      Feb 2005, M. J. Witte, GARD Analytics, Inc. Add new coil type COIL:DX:MultiMode:CoolingEmpirical.
    7317              :     //                      Jul 2005, R. Raustad, FSEC. Add new coil type COIL:DX:HEATPUMPWATERHEATER
    7318              :     //                      Jun 2007, L. Gu, FSEC. Add new coil type COIL:DX:MULTISPEED:COOLING and HEATING
    7319              :     //                      Jan 2011, B. Griffith, NREL. add EMS overrides for autosized fields
    7320              :     //                      Aug 2013, D. Kang. add component sizing table entries
    7321              :     //                      May 2014, R. Raustad, FSEC. moved sizing calculations to common routine
    7322              :     //                      Aug 2015, R. Zhang, LBNL. Add new coil types for VRF_FluidTCtrl
    7323              :     //       RE-ENGINEERED  na
    7324              : 
    7325              :     // PURPOSE OF THIS SUBROUTINE:
    7326              :     // This subroutine is for sizing DX Coil components for which nominal capacity and air flow rate
    7327              :     // have not been specified in the input.
    7328              : 
    7329              :     // METHODOLOGY EMPLOYED:
    7330              :     // Obtains cooling capacities and air flow rates from the zone or system sizing arrays.
    7331              : 
    7332              :     // Using/Aliasing
    7333              :     using namespace DataSizing;
    7334              :     using Curve::CurveValue;
    7335              : 
    7336              :     using namespace OutputReportPredefined;
    7337              :     using StandardRatings::CalcDXCoilStandardRating;
    7338              : 
    7339              :     // SUBROUTINE PARAMETER DEFINITIONS:
    7340              :     static constexpr std::string_view RoutineName("SizeDXCoil");
    7341              : 
    7342              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    7343              :     Real64 CoilInTemp;       // DX coil inlet temperature
    7344              :     int CapacityStageNum;    // Loop index for 1,Number of capacity stages
    7345              :     int DehumidModeNum;      // Loop index for 1,Number of enhanced dehumidification modes
    7346              :     int Mode;                // Operating mode for MultiMode DX coil; Always 1 for other coil types
    7347              :     int NumOfSpeedCompanion; // Number of speed for a companion cooling coil (Multispeed HO heating coil only
    7348           96 :     std::string equipName;
    7349              :     Real64 DefrostCapacityDes;             // Design defrost heater capacity for reporting
    7350              :     Real64 DefrostCapacityUser;            // Hard-sized defrost heater capacity for reporting
    7351              :     Real64 MSRatedAirVolFlowRateDes;       // Design multispeed rated air volume flow rate for reporting
    7352              :     Real64 MSRatedTotCapDesAtMaxSpeed;     // Design multispeed rated total capacity for reporting (at maximum speed)
    7353              :     Real64 MSRatedSHRDes;                  // Design multispeed rated SHR for reporting
    7354              :     Real64 MSEvapCondAirFlowDes;           // Design evaporative condenser air flow for reporting
    7355              :     Real64 MSEvapCondAirFlowUser;          // Hard-sized evaporative condenser air flow for reporting
    7356              :     Real64 MSEvapCondPumpElecNomPowerDes;  // Design evaporative condenser pump rated power consumption for reporting
    7357              :     Real64 MSEvapCondPumpElecNomPowerUser; // Hard-sized evaporative condenser pump rated power consumption for reporting
    7358              :     bool HardSizeNoDesRun;                 // Indicator to a hard-sized field with no design sizing data
    7359              :     bool IsAutoSize;                       // Indicator to autosize for reporting
    7360              :     bool SizingDesRunThisAirSys;           // true if a particular air system had a Sizing:System object and system sizing done
    7361              :     bool SizingDesRunThisZone;             // true if a particular zone had a Sizing:Zone object and zone sizing was done
    7362           96 :     std::string CompName;                  // component name
    7363           96 :     std::string CompType;                  // component type
    7364           96 :     std::string SizingString;              // input field sizing description (e.g., Nominal Capacity)
    7365           96 :     bool bPRINT = true;                    // TRUE if sizing is reported to output (eio)
    7366              :     Real64 TempSize;                       // autosized value of coil input field
    7367           96 :     int FieldNum = 2;                      // IDD numeric field number where input field description is found
    7368              :     bool PrintFlag;                        // TRUE when sizing information is reported in the eio file
    7369              :     bool SizeSecDXCoil;                    // if true do sizing calculation for secondary coil
    7370              :     Real64 SecCoilAirFlowDes;              // Design secondary DX coil air flow for reporting
    7371              :     Real64 SecCoilAirFlowUser;             // Hard-sized secondary DX coil air flow for reporting
    7372              : 
    7373              :     // Initiate all reporting variables
    7374           96 :     if (state.dataSize->SysSizingRunDone || state.dataSize->ZoneSizingRunDone) {
    7375           72 :         HardSizeNoDesRun = false;
    7376              :     } else {
    7377           24 :         HardSizeNoDesRun = true;
    7378              :     }
    7379              : 
    7380           96 :     if (state.dataSize->CurSysNum > 0) {
    7381           38 :         CheckThisAirSystemForSizing(state, state.dataSize->CurSysNum, SizingDesRunThisAirSys);
    7382              :     } else {
    7383           58 :         SizingDesRunThisAirSys = false;
    7384              :     }
    7385           96 :     if (state.dataSize->CurZoneEqNum > 0) {
    7386           43 :         CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
    7387              :     } else {
    7388           53 :         SizingDesRunThisZone = false;
    7389              :     }
    7390              : 
    7391           96 :     IsAutoSize = false;
    7392           96 :     SizeSecDXCoil = false;
    7393           96 :     MSRatedTotCapDesAtMaxSpeed = 0.0;
    7394           96 :     DefrostCapacityDes = 0.0;
    7395           96 :     DefrostCapacityUser = 0.0;
    7396           96 :     MSRatedAirVolFlowRateDes = 0.0;
    7397           96 :     MSRatedSHRDes = 0.0;
    7398           96 :     MSEvapCondAirFlowDes = 0.0;
    7399           96 :     MSEvapCondAirFlowUser = 0.0;
    7400           96 :     MSEvapCondPumpElecNomPowerDes = 0.0;
    7401           96 :     MSEvapCondPumpElecNomPowerUser = 0.0;
    7402           96 :     SecCoilAirFlowDes = 0.0;
    7403           96 :     SecCoilAirFlowUser = 0.0;
    7404              : 
    7405              :     // Sizer classes
    7406           96 :     CoolingSHRSizer sizerCoolingSHR;
    7407           96 :     bool ErrorsFound = false;
    7408              : 
    7409           96 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    7410              : 
    7411              :     // NOTE: we are sizing COIL:DX:HeatingEmpirical on the COOLING load. Thus the cooling and
    7412              :     // and heating capacities of a DX heat pump system will be identical. In real life the AHRI
    7413              :     // heating and cooling capacities are close but not identical.
    7414          192 :     for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum) {
    7415          192 :         for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum) {
    7416           96 :             Mode = DehumidModeNum * 2 + CapacityStageNum;
    7417           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    7418           90 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    7419            8 :                 if (thisDXCoil.RatedAirVolFlowRate(1) == Constant::AutoCalculate) {
    7420              :                     // report autocalculated sizing
    7421            3 :                     PrintFlag = true;
    7422            3 :                     CompName = thisDXCoil.Name;
    7423            3 :                     CompType = thisDXCoil.DXCoilType;
    7424              :                     // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00005035
    7425            3 :                     state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
    7426            3 :                     state.dataSize->DataFractionUsedForSizing = 0.00005035;
    7427            3 :                     TempSize = AutoSize;
    7428            3 :                     AutoCalculateSizer sizerHPRatedAirVolFlow;
    7429            3 :                     std::string stringOverride = "Rated Evaporator Air Flow Rate [m3/s]";
    7430            3 :                     if (state.dataGlobal->isEpJSON) {
    7431            0 :                         stringOverride = "rated_evaporator_air_flow_rate [m3/s]";
    7432              :                     }
    7433            3 :                     sizerHPRatedAirVolFlow.overrideSizingString(stringOverride);
    7434            3 :                     sizerHPRatedAirVolFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7435            3 :                     thisDXCoil.RatedAirVolFlowRate(1) = sizerHPRatedAirVolFlow.size(state, TempSize, ErrorsFound);
    7436            3 :                     PrintFlag = false;
    7437            3 :                 }
    7438              : 
    7439            8 :                 if (thisDXCoil.RatedHPWHCondWaterFlow == Constant::AutoCalculate) {
    7440              :                     // report autocalculated sizing
    7441            3 :                     PrintFlag = true;
    7442            3 :                     CompName = thisDXCoil.Name;
    7443            3 :                     CompType = thisDXCoil.DXCoilType;
    7444              :                     // DXCoil( DXCoilNum ).RatedAirVolFlowRate( 1 ) = DXCoil( DXCoilNum ).RatedTotCap2 * 0.00000004487
    7445            3 :                     state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap2;
    7446            3 :                     state.dataSize->DataFractionUsedForSizing = 0.00000004487;
    7447            3 :                     TempSize = AutoSize;
    7448            3 :                     AutoCalculateSizer sizerHPWHCondWaterFlow;
    7449            3 :                     std::string stringOverride = "Rated Condenser Water Flow Rate [m3/s]";
    7450            3 :                     if (state.dataGlobal->isEpJSON) {
    7451            0 :                         stringOverride = "rated_condenser_water_flow_rate [m3/s]";
    7452              :                     }
    7453            3 :                     sizerHPWHCondWaterFlow.overrideSizingString(stringOverride);
    7454            3 :                     sizerHPWHCondWaterFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7455            3 :                     thisDXCoil.RatedHPWHCondWaterFlow = sizerHPWHCondWaterFlow.size(state, TempSize, ErrorsFound);
    7456            3 :                     PrintFlag = false;
    7457            3 :                 }
    7458            8 :             } else {
    7459           88 :                 PrintFlag = true;
    7460           88 :                 FieldNum = 0;
    7461           88 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    7462            0 :                     CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
    7463            0 :                     FieldNum = 4;
    7464            0 :                     state.dataSize->DataBypassFrac = thisDXCoil.BypassedFlowFrac(Mode);
    7465           88 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
    7466            5 :                     CompName = thisDXCoil.Name;
    7467            5 :                     FieldNum = 3;
    7468              :                     // doesn't look like this is needed for air flow sizing, only for heating capacity sizing
    7469           10 :                     state.dataSize->DataCoolCoilCap =
    7470            5 :                         state.dataSize->DXCoolCap; // pass global variable used only for heat pumps (i.e., DX cooling and heating coils)
    7471            5 :                     if ((thisDXCoil.IsSecondaryDXCoilInZone) &&
    7472            0 :                         (thisDXCoil.CondenserType(1) ==
    7473              :                          DataHeatBalance::RefrigCondenserType::Air)) { // secondary DX coil in secondary zone is specified
    7474            0 :                         SizeSecDXCoil = true;
    7475              :                     }
    7476           83 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating) {
    7477            7 :                     CompName = thisDXCoil.Name;
    7478            7 :                     FieldNum = 2;
    7479           76 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling) {
    7480            7 :                     CompName = thisDXCoil.Name;
    7481            7 :                     FieldNum = 3;
    7482           69 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    7483            6 :                     CompName = thisDXCoil.Name;
    7484           63 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    7485            6 :                     CompName = thisDXCoil.Name;
    7486           57 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
    7487           10 :                     thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
    7488           10 :                     CompName = thisDXCoil.Name;
    7489           10 :                     PrintFlag = false;
    7490           47 :                 } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    7491            7 :                     thisDXCoil.RatedAirVolFlowRate(Mode) = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
    7492            7 :                     CompName = thisDXCoil.Name;
    7493            7 :                     PrintFlag = false;
    7494              :                 } else {
    7495           40 :                     CompName = thisDXCoil.Name;
    7496           40 :                     FieldNum = 4;
    7497              :                 }
    7498              : 
    7499           88 :                 TempSize = thisDXCoil.RatedAirVolFlowRate(Mode);
    7500           88 :                 if (FieldNum > 0) {
    7501           59 :                     SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
    7502              :                 } else {
    7503           29 :                     SizingString = "Rated Air Flow Rate [m3/s]";
    7504              :                 }
    7505           88 :                 CompType = thisDXCoil.DXCoilType;
    7506           88 :                 state.dataSize->DataIsDXCoil = true;
    7507           88 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
    7508           88 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
    7509           88 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating ||
    7510           75 :                     thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
    7511           25 :                     bool errorsFound = false;
    7512           25 :                     HeatingAirFlowSizer sizingHeatingAirFlow;
    7513           25 :                     sizingHeatingAirFlow.overrideSizingString(SizingString);
    7514              :                     // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    7515           25 :                     sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7516           25 :                     thisDXCoil.RatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
    7517           25 :                 } else {
    7518           63 :                     bool errorsFound = false;
    7519           63 :                     CoolingAirFlowSizer sizingCoolingAirFlow;
    7520           63 :                     sizingCoolingAirFlow.overrideSizingString(SizingString);
    7521              :                     // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    7522           63 :                     sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7523           63 :                     thisDXCoil.RatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    7524           63 :                 }
    7525           88 :                 state.dataSize->DataIsDXCoil = false;
    7526           88 :                 state.dataSize->DataEMSOverrideON = false;
    7527           88 :                 state.dataSize->DataEMSOverride = 0.0;
    7528           88 :                 state.dataSize->DataBypassFrac = 0.0;
    7529              :             }
    7530              : 
    7531           96 :             state.dataSize->DataFlowUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
    7532              :             // get autosized air flow for capacity calc's if capacity is not autosized
    7533              :             // *** RAR this if block is a last minute addition to correct capacity reporting when not autosized and a sizing run is done. Test
    7534              :             // suite was not run with this code included. *** The question here is if the autosized air flow rate or the user specified air flow
    7535              :             // rate should be used to calculate capacity removing this for now until more is known
    7536              :             //                if ( DXCoil( DXCoilNum ).RatedTotCap( Mode ) != AutoSize && ( ( SysSizingRunDone && CurSysNum > 0 ) ||
    7537              :             //(  ZoneSizingRunDone && CurZoneEqNum > 0 ) ) ) {                     if ( DXCoil( DXCoilNum ).DXCoilType_Num ==
    7538              :             // HVAC::CoilDX_CoolingTwoStageWHumControl ) {                         SizingMethod = CoolingAirflowSizing;
    7539              :             //                        DataBypassFrac = DXCoil ( DXCoilNum ).BypassedFlowFrac ( Mode );
    7540              :             //                    } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical ) {
    7541              :             //                        SizingMethod = HeatingAirflowSizing;
    7542              :             ////                        DataCoolCoilCap = DXCoolCap; // pass global variable used only for heat pumps (i.e.,
    7543              :             /// DX  cooling  and  heating coils)
    7544              :             //                    } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilVRF_Heating ) {
    7545              :             //                        SizingMethod = HeatingAirflowSizing;
    7546              :             //                    } else if ( DXCoil( DXCoilNum ).DXCoilType_Num == HVAC::CoilVRF_Cooling ) {
    7547              :             //                        SizingMethod = CoolingAirflowSizing;
    7548              :             //                    } else {
    7549              :             //                        SizingMethod = CoolingAirflowSizing;
    7550              :             //                    }
    7551              :             //                    CompName = DXCoil( DXCoilNum ).Name;
    7552              :             //                    TempSize = AutoSize;
    7553              :             //                    SizingString.clear(); // don't care
    7554              :             //                    CompType = DXCoil( DXCoilNum ).DXCoilType;
    7555              :             //                    DataIsDXCoil = true;
    7556              :             //                    DataEMSOverrideON = DXCoil ( DXCoilNum ).RatedAirVolFlowRateEMSOverrideON ( Mode );
    7557              :             //                    DataEMSOverride = DXCoil( DXCoilNum ).RatedAirVolFlowRateEMSOverrideValue( Mode );
    7558              :             //                  CoolingAirFlowSizer sizingCoolingAirFlow;
    7559              :             //                  sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    7560              :             //                  sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    7561              :             //                  DataAirFlowUsedForSizing = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    7562              :             //                    DataIsDXCoil = false; // don't need this and next 2, they are just overwritten below. Delete
    7563              :             // on  next  pass so testing will show problems if any.                     DataEMSOverrideON = false;
    7564              :             //                    DataEMSOverride = 0.0;
    7565              :             //                    DataBypassFrac = 0.0;
    7566              :             //                }
    7567           96 :             PrintFlag = true;
    7568           96 :             state.dataSize->DataTotCapCurveIndex = thisDXCoil.CCapFTemp(Mode);
    7569           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    7570            0 :                 CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
    7571            0 :                 FieldNum = 1;
    7572            0 :                 TempSize = thisDXCoil.RatedTotCap(Mode);
    7573            0 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7574           96 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating ||
    7575           84 :                        thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    7576           18 :                 CompName = thisDXCoil.Name;
    7577           18 :                 FieldNum = 1;
    7578           18 :                 TempSize = thisDXCoil.RatedTotCap(Mode);
    7579           18 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7580           18 :                 state.dataSize->DataCoolCoilCap = state.dataSize->DXCoolCap;
    7581           78 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    7582           72 :                        thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    7583            8 :                 CompName = thisDXCoil.Name;
    7584            8 :                 FieldNum = 1;
    7585            8 :                 TempSize = thisDXCoil.RatedTotCap(Mode);
    7586            8 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7587            8 :                 PrintFlag = false;
    7588            8 :                 state.dataLoopNodes->Node(thisDXCoil.WaterInNode).Temp =
    7589            8 :                     thisDXCoil.RatedInletWaterTemp; // set the rated water inlet node for HPWHs for use in CalcHPWHDXCoil
    7590           70 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    7591            6 :                 CompName = thisDXCoil.Name;
    7592            6 :                 FieldNum = 1;
    7593            6 :                 TempSize = thisDXCoil.RatedTotCap(Mode);
    7594            6 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7595            6 :                 if (state.dataSize->CurZoneEqNum > 0) {
    7596            6 :                     CoilInTemp =
    7597            6 :                         state.dataSize->ZoneSizingRunDone ? state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp : 26;
    7598              :                 } else {
    7599            0 :                     if (state.dataSize->CurOASysNum > 0) {
    7600            0 :                         CoilInTemp =
    7601            0 :                             state.dataSize->SysSizingRunDone ? state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).OutTempAtCoolPeak : 32;
    7602              :                     } else {
    7603            0 :                         CoilInTemp =
    7604            0 :                             state.dataSize->SysSizingRunDone ? state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).MixTempAtCoolPeak : 26;
    7605              :                     }
    7606              :                 }
    7607            6 :                 CalcVRFCoilCapModFac(state, 0, _, CompName, CoilInTemp, _, _, _, state.dataSize->DataTotCapCurveValue);
    7608           64 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
    7609           10 :                 CompName = thisDXCoil.Name;
    7610           10 :                 FieldNum = 7 + (thisDXCoil.NumOfSpeeds - 1) * 13;
    7611           10 :                 state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
    7612           10 :                 TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
    7613           10 :                 PrintFlag = false;
    7614           10 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7615           54 :             } else if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    7616            7 :                 CompName = thisDXCoil.Name;
    7617            7 :                 FieldNum = 10 + (thisDXCoil.NumOfSpeeds - 1) * 6;
    7618            7 :                 state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(thisDXCoil.NumOfSpeeds);
    7619            7 :                 TempSize = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
    7620            7 :                 PrintFlag = false;
    7621            7 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7622              :             } else {
    7623           47 :                 CompName = thisDXCoil.Name;
    7624           47 :                 FieldNum = 1;
    7625           47 :                 TempSize = thisDXCoil.RatedTotCap(Mode);
    7626           47 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [W]";
    7627              :             }
    7628           96 :             CompType = thisDXCoil.DXCoilType;
    7629           96 :             state.dataSize->DataIsDXCoil = true;
    7630           96 :             state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    7631           96 :             state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    7632           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical ||
    7633           84 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Heating || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Heating) {
    7634           25 :                 HeatingCapacitySizer sizerHeatingCapacity;
    7635           25 :                 sizerHeatingCapacity.overrideSizingString(SizingString);
    7636           25 :                 sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7637           25 :                 thisDXCoil.RatedTotCap(Mode) = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    7638           25 :             } else {
    7639           71 :                 CoolingCapacitySizer sizerCoolingCapacity;
    7640           71 :                 sizerCoolingCapacity.overrideSizingString(SizingString);
    7641           71 :                 sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7642           71 :                 thisDXCoil.RatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    7643           71 :             }
    7644           96 :             state.dataSize->DataIsDXCoil = false;
    7645           96 :             state.dataSize->DataFlowUsedForSizing = 0.0;
    7646           96 :             state.dataSize->DataCoolCoilCap = 0.0;
    7647           96 :             state.dataSize->DataTotCapCurveIndex = 0;
    7648           96 :             state.dataSize->DataEMSOverrideON = false;
    7649           96 :             state.dataSize->DataEMSOverride = 0.0;
    7650           96 :             state.dataSize->DataConstantUsedForSizing = 0.0;
    7651           96 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    7652           96 :             state.dataSize->DataTotCapCurveValue = 0.0;
    7653              : 
    7654              :             // Cooling coil capacity
    7655           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
    7656           56 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
    7657           49 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    7658           53 :                 state.dataSize->DXCoolCap = thisDXCoil.RatedTotCap(Mode);
    7659              :             }
    7660              : 
    7661              :             // Sizing DX cooling coil SHR
    7662           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
    7663           56 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl || thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_Cooling ||
    7664           49 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilVRF_FluidTCtrl_Cooling) {
    7665              : 
    7666           53 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    7667            0 :                     CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
    7668              :                 } else {
    7669           53 :                     CompName = thisDXCoil.Name;
    7670              :                 }
    7671           53 :                 CompType = thisDXCoil.DXCoilType;
    7672           53 :                 TempSize = thisDXCoil.RatedSHR(Mode);
    7673           53 :                 state.dataSize->DataDXSpeedNum = Mode;
    7674           53 :                 state.dataSize->DataFlowUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
    7675           53 :                 state.dataSize->DataCapacityUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7676           53 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
    7677           53 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
    7678           53 :                 bool ErrorsFound = false;
    7679           53 :                 sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7680           53 :                 thisDXCoil.RatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
    7681           53 :                 state.dataSize->DataDXSpeedNum = 0;
    7682           53 :                 state.dataSize->DataFlowUsedForSizing = 0.0;
    7683           53 :                 state.dataSize->DataCapacityUsedForSizing = 0.0;
    7684           53 :                 state.dataSize->DataEMSOverrideON = false;
    7685           53 :                 state.dataSize->DataEMSOverride = 0.0;
    7686              : 
    7687              :             } // End of Rated SHR
    7688              : 
    7689              :             // Sizing evaporator condenser air flow
    7690           98 :             if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow(Mode) != 0.0 &&
    7691            2 :                 (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
    7692            0 :                  thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    7693              : 
    7694            2 :                 AutoCalculateSizer sizerEvapCondAirFlow;
    7695            2 :                 std::string stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
    7696            2 :                 if (state.dataGlobal->isEpJSON) {
    7697            0 :                     stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
    7698              :                 }
    7699            2 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    7700            0 :                     CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
    7701              :                 } else {
    7702            2 :                     CompName = thisDXCoil.Name;
    7703            2 :                     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7704            1 :                         stringOverride = "High Speed Evaporative Condenser Air Flow Rate [m3/s]";
    7705            1 :                         if (state.dataGlobal->isEpJSON) {
    7706            0 :                             stringOverride = "high_speed_evaporative_condenser_air_flow_rate [m3/s]";
    7707              :                         }
    7708              :                     } else {
    7709            1 :                         stringOverride = "Evaporative Condenser Air Flow Rate [m3/s]";
    7710            1 :                         if (state.dataGlobal->isEpJSON) {
    7711            0 :                             stringOverride = "evaporative_condenser_air_flow_rate [m3/s]";
    7712              :                         }
    7713              :                     }
    7714              :                 }
    7715            2 :                 CompType = thisDXCoil.DXCoilType;
    7716              :                 // Auto-size condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
    7717            2 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7718            2 :                 state.dataSize->DataFractionUsedForSizing = 0.000114;
    7719            2 :                 TempSize = thisDXCoil.EvapCondAirFlow(Mode);
    7720            2 :                 sizerEvapCondAirFlow.overrideSizingString(stringOverride);
    7721            2 :                 sizerEvapCondAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7722            2 :                 thisDXCoil.EvapCondAirFlow(Mode) = sizerEvapCondAirFlow.size(state, TempSize, ErrorsFound);
    7723            2 :             }
    7724              : 
    7725           96 :             if (SizeSecDXCoil) { // autosize secondary coil air flow rate for AirCooled condenser type
    7726            0 :                 IsAutoSize = false;
    7727            0 :                 if (thisDXCoil.SecCoilAirFlow == AutoSize) {
    7728            0 :                     IsAutoSize = true;
    7729              :                 }
    7730              :                 // Autosize Primary Coil Air Flow * Secondary Coil Scaling Factor
    7731            0 :                 SecCoilAirFlowDes = thisDXCoil.RatedAirVolFlowRate(1) * thisDXCoil.SecCoilAirFlowScalingFactor;
    7732            0 :                 if (IsAutoSize) {
    7733            0 :                     thisDXCoil.SecCoilAirFlow = SecCoilAirFlowDes;
    7734            0 :                     BaseSizer::reportSizerOutput(
    7735              :                         state, thisDXCoil.DXCoilType, thisDXCoil.Name, "Design Size Secondary Coil Air Flow Rate [m3/s]", SecCoilAirFlowDes);
    7736              :                 } else {
    7737            0 :                     if (thisDXCoil.SecCoilAirFlow > 0.0 && SecCoilAirFlowDes > 0.0 && !HardSizeNoDesRun) {
    7738            0 :                         SecCoilAirFlowUser = thisDXCoil.SecCoilAirFlow;
    7739            0 :                         BaseSizer::reportSizerOutput(state,
    7740              :                                                      thisDXCoil.DXCoilType,
    7741              :                                                      thisDXCoil.Name,
    7742              :                                                      "Design Size Secondary Coil Air Flow Rate [m3/s]",
    7743              :                                                      SecCoilAirFlowDes,
    7744              :                                                      "User-Specified Secondary Coil Air Flow Rate [m3/s]",
    7745              :                                                      SecCoilAirFlowUser);
    7746            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    7747            0 :                             if ((std::abs(SecCoilAirFlowDes - SecCoilAirFlowUser) / SecCoilAirFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
    7748            0 :                                 ShowMessage(
    7749              :                                     state,
    7750            0 :                                     format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
    7751            0 :                                 ShowContinueError(state, format("User-Specified Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowUser));
    7752            0 :                                 ShowContinueError(
    7753            0 :                                     state, format("differs from Design Size Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowDes));
    7754            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    7755            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    7756              :                             }
    7757              :                         }
    7758              :                     }
    7759              :                 }
    7760              :             }
    7761              : 
    7762              :             // Sizing evaporative condenser air flow 2
    7763           96 :             PrintFlag = true;
    7764           97 :             if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondAirFlow2 != 0.0 &&
    7765            1 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7766            1 :                 CompName = thisDXCoil.Name;
    7767            1 :                 FieldNum = 15; // Low Speed Evaporative Condenser Air Flow Rate
    7768            1 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum) + " [m3/s]";
    7769            1 :                 CompType = thisDXCoil.DXCoilType;
    7770              :                 // Autosize low speed condenser air flow to 1/3 Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
    7771            1 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7772            1 :                 state.dataSize->DataFractionUsedForSizing = 0.000114 * 0.3333;
    7773            1 :                 TempSize = thisDXCoil.EvapCondAirFlow2;
    7774            1 :                 AutoCalculateSizer sizerEvapCondAirFlow2;
    7775            1 :                 std::string stringOverride = "Low Speed Evaporative Condenser Air Flow Rate [m3/s]";
    7776            1 :                 if (state.dataGlobal->isEpJSON) {
    7777            0 :                     stringOverride = "low_speed_evaporative_condenser_air_flow_rate [m3/s]";
    7778              :                 }
    7779            1 :                 sizerEvapCondAirFlow2.overrideSizingString(stringOverride);
    7780            1 :                 sizerEvapCondAirFlow2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7781            1 :                 thisDXCoil.EvapCondAirFlow2 = sizerEvapCondAirFlow2.size(state, TempSize, ErrorsFound);
    7782            1 :             }
    7783              : 
    7784              :             // Sizing evaporative condenser pump electric nominal power
    7785          108 :             if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower(Mode) != 0.0 &&
    7786           12 :                 (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
    7787            0 :                  thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    7788              : 
    7789           12 :                 AutoCalculateSizer sizerEvapCondPumpPower;
    7790           12 :                 std::string stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
    7791           12 :                 if (state.dataGlobal->isEpJSON) {
    7792            0 :                     stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
    7793              :                 }
    7794           12 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
    7795            0 :                     CompName = thisDXCoil.Name + ":" + thisDXCoil.CoilPerformanceName(Mode);
    7796              :                 } else {
    7797           12 :                     CompName = thisDXCoil.Name;
    7798           12 :                     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7799            1 :                         stringOverride = "High Speed Evaporative Condenser Pump Rated Power Consumption [W]";
    7800            1 :                         if (state.dataGlobal->isEpJSON) {
    7801            0 :                             stringOverride = "high_speed_evaporative_condenser_pump_rated_power_consumption [W]";
    7802              :                         }
    7803              :                     } else {
    7804           11 :                         stringOverride = "Evaporative Condenser Pump Rated Power Consumption [W]";
    7805           11 :                         if (state.dataGlobal->isEpJSON) {
    7806            0 :                             stringOverride = "evaporative_condenser_pump_rated_power_consumption [W]";
    7807              :                         }
    7808              :                     }
    7809              :                 }
    7810           12 :                 CompType = thisDXCoil.DXCoilType;
    7811              :                 // Autosize high speed evap condenser pump power to Total Capacity * 0.004266 w/w (15 w/ton)
    7812           12 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7813           12 :                 state.dataSize->DataFractionUsedForSizing = 0.004266;
    7814           12 :                 TempSize = thisDXCoil.EvapCondPumpElecNomPower(Mode);
    7815           12 :                 sizerEvapCondPumpPower.overrideSizingString(stringOverride);
    7816           12 :                 sizerEvapCondPumpPower.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7817           12 :                 thisDXCoil.EvapCondPumpElecNomPower(Mode) = sizerEvapCondPumpPower.size(state, TempSize, ErrorsFound);
    7818           12 :             }
    7819              : 
    7820              :             // Sizing low speed evaporative condenser pump electric nominal power
    7821           97 :             if (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap && thisDXCoil.EvapCondPumpElecNomPower2 != 0.0 &&
    7822            1 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7823            1 :                 CompName = thisDXCoil.Name;
    7824            1 :                 CompType = thisDXCoil.DXCoilType;
    7825              :                 // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
    7826            1 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7827            1 :                 state.dataSize->DataFractionUsedForSizing = 0.004266 * 0.3333;
    7828            1 :                 TempSize = thisDXCoil.EvapCondPumpElecNomPower2;
    7829            1 :                 AutoCalculateSizer sizerEvapCondPumpPower2;
    7830            1 :                 std::string stringOverride = "Low Speed Evaporative Condenser Pump Rated Power Consumption [W]";
    7831            1 :                 if (state.dataGlobal->isEpJSON) {
    7832            0 :                     stringOverride = "low_speed_evaporative_condenser_pump_rated_power_consumption [W]";
    7833              :                 }
    7834            1 :                 sizerEvapCondPumpPower2.overrideSizingString(stringOverride);
    7835            1 :                 sizerEvapCondPumpPower2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7836            1 :                 thisDXCoil.EvapCondPumpElecNomPower2 = sizerEvapCondPumpPower2.size(state, TempSize, ErrorsFound);
    7837            1 :             }
    7838              : 
    7839              :             //                // Sizing rated low speed air flow rate
    7840           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7841            4 :                 CompName = thisDXCoil.Name;
    7842            4 :                 CompType = thisDXCoil.DXCoilType;
    7843              :                 // Autosize low speed air flow rate to 1/3 high speed air flow rate
    7844            4 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedAirVolFlowRate(Mode);
    7845            4 :                 state.dataSize->DataFractionUsedForSizing = 0.3333;
    7846            4 :                 TempSize = thisDXCoil.RatedAirVolFlowRate2;
    7847            4 :                 AutoCalculateSizer sizerLowSpdAirFlow;
    7848            4 :                 std::string stringOverride = "Low Speed Rated Air Flow Rate [m3/s]";
    7849            4 :                 if (state.dataGlobal->isEpJSON) {
    7850            0 :                     stringOverride = "low_speed_rated_air_flow_rate [m3/s]";
    7851              :                 }
    7852            4 :                 sizerLowSpdAirFlow.overrideSizingString(stringOverride);
    7853            4 :                 sizerLowSpdAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7854            4 :                 thisDXCoil.RatedAirVolFlowRate2 = sizerLowSpdAirFlow.size(state, TempSize, ErrorsFound);
    7855            4 :             }
    7856              : 
    7857              :             //                // Sizing rated low speed total cooling capacity
    7858           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7859            4 :                 CompName = thisDXCoil.Name;
    7860            4 :                 CompType = thisDXCoil.DXCoilType;
    7861              :                 // Autosize low speed capacity to 1/3 high speed capacity
    7862            4 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(Mode);
    7863            4 :                 state.dataSize->DataFractionUsedForSizing = 0.3333;
    7864            4 :                 TempSize = thisDXCoil.RatedTotCap2;
    7865            4 :                 AutoCalculateSizer sizerLowSpdCap;
    7866            4 :                 std::string stringOverride = "Low Speed Gross Rated Total Cooling Capacity [W]";
    7867            4 :                 if (state.dataGlobal->isEpJSON) {
    7868            0 :                     stringOverride = "low_speed_gross_rated_total_cooling_capacity [W]";
    7869              :                 }
    7870            4 :                 sizerLowSpdCap.overrideSizingString(stringOverride);
    7871            4 :                 sizerLowSpdCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7872            4 :                 thisDXCoil.RatedTotCap2 = sizerLowSpdCap.size(state, TempSize, ErrorsFound);
    7873            4 :             }
    7874              : 
    7875           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7876            4 :                 if (thisDXCoil.EvapCondAirFlow2 > thisDXCoil.EvapCondAirFlow(Mode)) {
    7877            0 :                     ShowSevereError(
    7878              :                         state,
    7879            0 :                         format("SizeDXCoil: {} {}, Evaporative Condenser low speed air flow must be less than or equal to high speed air flow.",
    7880            0 :                                thisDXCoil.DXCoilType,
    7881            0 :                                thisDXCoil.Name));
    7882            0 :                     ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.EvapCondAirFlow2, thisDXCoil.EvapCondAirFlow(Mode)));
    7883            0 :                     ShowFatalError(state, "Preceding conditions cause termination.");
    7884              :                 }
    7885              : 
    7886            4 :                 if (thisDXCoil.EvapCondPumpElecNomPower2 > thisDXCoil.EvapCondPumpElecNomPower(Mode)) {
    7887            0 :                     ShowSevereError(
    7888              :                         state,
    7889            0 :                         format("SizeDXCoil: {} {}, Evaporative Condenser low speed pump power must be less than or equal to high speed pump power.",
    7890            0 :                                thisDXCoil.DXCoilType,
    7891            0 :                                thisDXCoil.Name));
    7892            0 :                     ShowContinueError(
    7893            0 :                         state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.EvapCondPumpElecNomPower2, thisDXCoil.EvapCondPumpElecNomPower(Mode)));
    7894            0 :                     ShowFatalError(state, "Preceding conditions cause termination.");
    7895              :                 }
    7896              : 
    7897            4 :                 if (thisDXCoil.RatedTotCap2 > thisDXCoil.RatedTotCap(Mode)) {
    7898            0 :                     ShowSevereError(state,
    7899            0 :                                     format("SizeDXCoil: {} {}, Rated Total Cooling Capacity, Low Speed must be less than or equal to Rated Total "
    7900              :                                            "Cooling Capacity, High Speed.",
    7901            0 :                                            thisDXCoil.DXCoilType,
    7902            0 :                                            thisDXCoil.Name));
    7903            0 :                     ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.RatedTotCap2, thisDXCoil.RatedTotCap(Mode)));
    7904            0 :                     ShowFatalError(state, "Preceding conditions cause termination.");
    7905              :                 }
    7906              : 
    7907            4 :                 if (thisDXCoil.RatedAirVolFlowRate2 > thisDXCoil.RatedAirVolFlowRate(Mode)) {
    7908            0 :                     ShowFatalError(state,
    7909            0 :                                    format("SizeDXCoil: {} {}, Rated Air Volume Flow Rate, low speed must be less than or equal to Rated Air Volume "
    7910              :                                           "Flow Rate, high speed.",
    7911            0 :                                           thisDXCoil.DXCoilType,
    7912            0 :                                           thisDXCoil.Name));
    7913            0 :                     ShowContinueError(state,
    7914            0 :                                       format("Instead, {:.2R} > {:.2R}", thisDXCoil.RatedAirVolFlowRate2, thisDXCoil.RatedAirVolFlowRate(Mode)));
    7915            0 :                     ShowFatalError(state, "Preceding conditions cause termination.");
    7916              :                 }
    7917              :             }
    7918              : 
    7919              :             //                // Sizing rated low speed SHR2
    7920           96 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
    7921            4 :                 CompName = thisDXCoil.Name;
    7922            4 :                 FieldNum = 7;
    7923            4 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(Mode).FieldNames(FieldNum);
    7924            4 :                 CompType = thisDXCoil.DXCoilType;
    7925              :                 // Autosize low speed SHR to be the same as high speed SHR
    7926            4 :                 state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedSHR(Mode);
    7927            4 :                 state.dataSize->DataFractionUsedForSizing = 1.0;
    7928            4 :                 state.dataSize->DataDXSpeedNum = 2; // refers to low speed in sizer
    7929            4 :                 bool ErrorsFound = false;
    7930            4 :                 TempSize = thisDXCoil.RatedSHR2;
    7931            4 :                 sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7932            4 :                 thisDXCoil.RatedSHR2 = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
    7933            4 :                 state.dataSize->DataConstantUsedForSizing = 0.0;
    7934            4 :                 state.dataSize->DataFractionUsedForSizing = 0.0;
    7935            4 :                 state.dataSize->DataDXSpeedNum = 0;
    7936              :             }
    7937              : 
    7938              :             //                // Sizing resistive defrost heater capacity
    7939           96 :             if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating &&
    7940           83 :                 thisDXCoil.DXCoilType_Num != HVAC::CoilDX_MultiSpeedHeating) {
    7941              :                 // IF (DXCoil(DXCoilNum)%DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating .OR. &
    7942              :                 //    DXCoil(DXCoilNum)%DXCoilType_Num == Coil_HeatingAirToAirVariableSpeed) THEN
    7943           76 :                 if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
    7944            3 :                     CompName = thisDXCoil.Name;
    7945            3 :                     CompType = thisDXCoil.DXCoilType;
    7946              :                     // Autosize low speed capacity to 1/3 high speed capacity
    7947            3 :                     state.dataSize->DataConstantUsedForSizing = state.dataSize->DXCoolCap;
    7948            3 :                     state.dataSize->DataFractionUsedForSizing = 1.0;
    7949            3 :                     TempSize = thisDXCoil.DefrostCapacity;
    7950            3 :                     AutoCalculateSizer sizerResDefCap;
    7951            3 :                     std::string stringOverride = "Resistive Defrost Heater Capacity [W]";
    7952            3 :                     if (state.dataGlobal->isEpJSON) {
    7953            0 :                         stringOverride = "resistive_defrost_heater_capacity [W]";
    7954              :                     }
    7955            3 :                     sizerResDefCap.overrideSizingString(stringOverride);
    7956            3 :                     sizerResDefCap.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7957            3 :                     thisDXCoil.DefrostCapacity = sizerResDefCap.size(state, TempSize, ErrorsFound);
    7958            3 :                 } else {
    7959           73 :                     thisDXCoil.DefrostCapacity = 0.0;
    7960              :                 }
    7961              :             }
    7962              : 
    7963              :         } // End capacity stages loop
    7964              :     } // End dehumidification modes loop
    7965              : 
    7966              :     // Autosizing for multispeed cooling coil
    7967           96 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
    7968              :         // flow rate autosize
    7969           31 :         for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    7970              :             // Sizing multispeed air volume flow rate
    7971           21 :             IsAutoSize = false;
    7972           21 :             if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
    7973           15 :                 IsAutoSize = true;
    7974              :             }
    7975           21 :             state.dataSize->DataIsDXCoil = true;
    7976           21 :             CompName = thisDXCoil.Name;
    7977           21 :             CompType = thisDXCoil.DXCoilType;
    7978           21 :             if (Mode == thisDXCoil.NumOfSpeeds) {
    7979           10 :                 FieldNum = 10 + (Mode - 1) * 14;
    7980           10 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
    7981           10 :                 TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    7982           10 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
    7983           10 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
    7984           10 :                 bool errorsFound = false;
    7985           10 :                 CoolingAirFlowSizer sizingCoolingAirFlow;
    7986           10 :                 sizingCoolingAirFlow.overrideSizingString(SizingString);
    7987              :                 // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    7988           10 :                 sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    7989           10 :                 TempSize = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    7990           10 :                 thisDXCoil.MSRatedAirVolFlowRate(Mode) = TempSize;
    7991           10 :                 state.dataSize->DataEMSOverrideON = false;
    7992           10 :                 state.dataSize->DataEMSOverride = 0.0;
    7993           10 :                 if (!IsAutoSize && !HardSizeNoDesRun) {
    7994            1 :                     TempSize = AutoSize;
    7995            1 :                     bPRINT = false;
    7996            1 :                     sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    7997            1 :                     MSRatedAirVolFlowRateDes = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    7998            1 :                     bPRINT = true;
    7999              :                 }
    8000           10 :                 if (IsAutoSize) {
    8001            7 :                     MSRatedAirVolFlowRateDes = TempSize;
    8002              :                 }
    8003           10 :             } else {
    8004           11 :                 FieldNum = 10 + (Mode - 1) * 14;
    8005           11 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
    8006           11 :                 if (IsAutoSize || !HardSizeNoDesRun) {
    8007              :                     // Autosize low speed flow to fraction of the highest speed flow
    8008            9 :                     state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
    8009            9 :                     if (!IsAutoSize && !HardSizeNoDesRun) {
    8010            1 :                         state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
    8011              :                     }
    8012            9 :                     state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
    8013              :                 }
    8014           11 :                 TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    8015           11 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
    8016           11 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
    8017           11 :                 bool errorsFound = false;
    8018           11 :                 CoolingAirFlowSizer sizingCoolingAirFlow;
    8019           11 :                 sizingCoolingAirFlow.overrideSizingString(SizingString);
    8020           11 :                 sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    8021           11 :                 thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    8022           11 :             }
    8023           21 :             state.dataSize->DataEMSOverride = 0.0;
    8024           21 :             state.dataSize->DataEMSOverrideON = false;
    8025           21 :             state.dataSize->DataIsDXCoil = false;
    8026           21 :             state.dataSize->DataTotCapCurveIndex = 0;
    8027           21 :             state.dataSize->DataConstantUsedForSizing = 0.0;
    8028           21 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    8029              :         }
    8030              : 
    8031              :         // Ensure flow rate at lower speed must be lower or equal to the flow rate at higher speed. Otherwise, a severe error is issued.
    8032           21 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    8033           11 :             if (thisDXCoil.MSRatedAirVolFlowRate(Mode) > thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)) {
    8034            0 :                 ShowWarningError(state,
    8035            0 :                                  format("SizeDXCoil: {} {}, Speed {} Rated Air Flow Rate must be less than or equal to Speed {} Rated Air Flow Rate.",
    8036            0 :                                         thisDXCoil.DXCoilType,
    8037            0 :                                         thisDXCoil.Name,
    8038              :                                         Mode,
    8039            0 :                                         Mode + 1));
    8040            0 :                 ShowContinueError(
    8041            0 :                     state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedAirVolFlowRate(Mode), thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)));
    8042            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    8043              :             }
    8044              :         }
    8045              : 
    8046              :         // Sizing multispeed rated total cooling capacity
    8047           31 :         for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    8048           21 :             IsAutoSize = false;
    8049           21 :             if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
    8050           15 :                 IsAutoSize = true;
    8051              :             }
    8052           21 :             CompName = thisDXCoil.Name;
    8053           21 :             CompType = thisDXCoil.DXCoilType;
    8054           21 :             state.dataSize->DataIsDXCoil = true;
    8055           21 :             state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
    8056           21 :             if (Mode == thisDXCoil.NumOfSpeeds) {
    8057           10 :                 PrintFlag = true;
    8058           10 :                 state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    8059           10 :                 FieldNum = 7 + (Mode - 1) * 14;
    8060           10 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
    8061           10 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    8062           10 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    8063           10 :                 MSRatedTotCapDesAtMaxSpeed = thisDXCoil.MSRatedTotCap(Mode);
    8064           10 :                 if (!HardSizeNoDesRun) {
    8065            8 :                     PrintFlag = false;
    8066            8 :                     TempSize = DataSizing::AutoSize;
    8067              :                     // Auto-size capacity at the highest speed
    8068            8 :                     CoolingCapacitySizer sizerCoolingCapacity;
    8069            8 :                     sizerCoolingCapacity.overrideSizingString(SizingString);
    8070            8 :                     sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8071            8 :                     TempSize = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    8072            8 :                     state.dataSize->DataConstantUsedForSizing = TempSize;
    8073            8 :                     state.dataSize->DataFractionUsedForSizing = 1.0;
    8074            8 :                     MSRatedTotCapDesAtMaxSpeed = TempSize;
    8075            8 :                     thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
    8076            8 :                     PrintFlag = true;
    8077            8 :                 }
    8078           10 :                 TempSize = thisDXCoil.MSRatedTotCap(Mode);
    8079           10 :                 CoolingCapacitySizer sizerCoolingCapacity2;
    8080           10 :                 sizerCoolingCapacity2.overrideSizingString(SizingString);
    8081           10 :                 sizerCoolingCapacity2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8082           10 :                 TempSize = sizerCoolingCapacity2.size(state, TempSize, ErrorsFound);
    8083           10 :                 thisDXCoil.MSRatedTotCap(Mode) = TempSize;
    8084           10 :                 if (IsAutoSize) {
    8085            7 :                     MSRatedTotCapDesAtMaxSpeed = TempSize;
    8086            7 :                     thisDXCoil.MSRatedTotCapDes(Mode) = TempSize;
    8087              :                 }
    8088           10 :             } else {
    8089              :                 // cooling capacity at lower speeds
    8090           11 :                 PrintFlag = true;
    8091           11 :                 FieldNum = 7 + (Mode - 1) * 14;
    8092           11 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
    8093           11 :                 if (IsAutoSize || !HardSizeNoDesRun) {
    8094              :                     // autosize low speed capacity to fraction of the highest speed capacity
    8095            9 :                     if (!HardSizeNoDesRun) {
    8096            9 :                         state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
    8097              :                     } else {
    8098            0 :                         state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
    8099              :                     }
    8100            9 :                     state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
    8101            9 :                     thisDXCoil.MSRatedTotCapDes(Mode) = state.dataSize->DataConstantUsedForSizing * state.dataSize->DataFractionUsedForSizing;
    8102              :                 }
    8103           11 :                 TempSize = thisDXCoil.MSRatedTotCap(Mode);
    8104           11 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    8105           11 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    8106           11 :                 CoolingCapacitySizer sizerCoolingCapacity;
    8107           11 :                 sizerCoolingCapacity.overrideSizingString(SizingString);
    8108           11 :                 sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8109           11 :                 thisDXCoil.MSRatedTotCap(Mode) = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    8110           11 :             }
    8111           21 :             state.dataSize->DataEMSOverride = 0.0;
    8112           21 :             state.dataSize->DataEMSOverrideON = false;
    8113           21 :             state.dataSize->DataIsDXCoil = false;
    8114           21 :             state.dataSize->DataCoolCoilCap = 0.0;
    8115           21 :             state.dataSize->DataTotCapCurveIndex = 0;
    8116           21 :             state.dataSize->DataConstantUsedForSizing = 0.0;
    8117           21 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    8118              :         }
    8119              : 
    8120              :         // Ensure capacity at lower speed must be lower or equal to the capacity at higher speed.
    8121           21 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    8122           11 :             if (thisDXCoil.MSRatedTotCap(Mode) > thisDXCoil.MSRatedTotCap(Mode + 1)) {
    8123            0 :                 ShowWarningError(state,
    8124            0 :                                  format("SizeDXCoil: {} {}, Speed {} Rated Total Cooling Capacity must be less than or equal to Speed {} Rated "
    8125              :                                         "Total Cooling Capacity.",
    8126            0 :                                         thisDXCoil.DXCoilType,
    8127            0 :                                         thisDXCoil.Name,
    8128              :                                         Mode,
    8129            0 :                                         Mode + 1));
    8130            0 :                 ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedTotCap(Mode), thisDXCoil.MSRatedTotCap(Mode + 1)));
    8131            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    8132              :             }
    8133              :         }
    8134              : 
    8135              :         // Rated SHR
    8136           31 :         for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    8137           21 :             IsAutoSize = false;
    8138           21 :             if (thisDXCoil.MSRatedSHR(Mode) == AutoSize) {
    8139           15 :                 IsAutoSize = true;
    8140              :             }
    8141           21 :             if (Mode == thisDXCoil.NumOfSpeeds) {
    8142           10 :                 CompType = thisDXCoil.DXCoilType;
    8143           10 :                 CompName = thisDXCoil.Name;
    8144           10 :                 TempSize = thisDXCoil.MSRatedSHR(Mode);
    8145           10 :                 state.dataSize->DataFlowUsedForSizing = MSRatedAirVolFlowRateDes;
    8146           10 :                 state.dataSize->DataCapacityUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
    8147           10 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedSHREMSOverrideOn(Mode);
    8148           10 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedSHREMSOverrideValue(Mode);
    8149           10 :                 bool ErrorsFound = false;
    8150           10 :                 state.dataSize->DataDXSpeedNum = Mode;
    8151           10 :                 sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8152           10 :                 thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
    8153              :                 // added for rated sensible cooling capacity estimate for html reporting, issue #7381
    8154           10 :                 thisDXCoil.RatedSHR(1) = thisDXCoil.MSRatedSHR(Mode);
    8155              :                 // design SHR value at the maximum speed calculated above was supposed to be used for all speeds
    8156              :                 // Now user specified SHR value is used when the SHR field is not autosized and design day run is
    8157              :                 // set to yes unless the code below is commented out
    8158           10 :                 MSRatedSHRDes = thisDXCoil.MSRatedSHR(Mode);
    8159              :             } else {
    8160           11 :                 TempSize = thisDXCoil.MSRatedSHR(Mode);
    8161           11 :                 bool ErrorsFound = false;
    8162           11 :                 state.dataSize->DataDXSpeedNum = Mode;
    8163           11 :                 state.dataSize->DataFractionUsedForSizing = MSRatedSHRDes;
    8164           11 :                 state.dataSize->DataConstantUsedForSizing = 1.0;
    8165           11 :                 sizerCoolingSHR.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8166           11 :                 thisDXCoil.MSRatedSHR(Mode) = sizerCoolingSHR.size(state, TempSize, ErrorsFound);
    8167              :             }
    8168              :         }
    8169           10 :         state.dataSize->DataFlowUsedForSizing = 0.0;
    8170           10 :         state.dataSize->DataCapacityUsedForSizing = 0.0;
    8171           10 :         state.dataSize->DataEMSOverrideON = false;
    8172           10 :         state.dataSize->DataEMSOverride = 0.0;
    8173           10 :         state.dataSize->DataDXSpeedNum = 0;
    8174           10 :         state.dataSize->DataFractionUsedForSizing = 0.0;
    8175           10 :         state.dataSize->DataConstantUsedForSizing = 0.0;
    8176              : 
    8177              :         // Rated Evaporative condenser airflow rates
    8178           31 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    8179           21 :             IsAutoSize = false;
    8180           21 :             if (thisDXCoil.MSEvapCondAirFlow(Mode) == AutoSize) {
    8181           16 :                 IsAutoSize = true;
    8182              :             }
    8183           21 :             if (IsAutoSize || !HardSizeNoDesRun) {
    8184              :                 // Autosize condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
    8185           21 :                 MSEvapCondAirFlowDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.000114;
    8186              :             } else {
    8187              :                 // this is done to duplicate any existing calc method
    8188            0 :                 MSEvapCondAirFlowDes = thisDXCoil.MSRatedTotCap(Mode) * 0.000114;
    8189              :             }
    8190           21 :             if (IsAutoSize) {
    8191           16 :                 thisDXCoil.MSEvapCondAirFlow(Mode) = MSEvapCondAirFlowDes;
    8192           48 :                 BaseSizer::reportSizerOutput(state,
    8193              :                                              thisDXCoil.DXCoilType,
    8194              :                                              thisDXCoil.Name,
    8195           32 :                                              format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
    8196              :                                              MSEvapCondAirFlowDes);
    8197              :             } else {
    8198            5 :                 if (thisDXCoil.MSEvapCondAirFlow(Mode) > 0.0 && MSEvapCondAirFlowDes > 0.0 && !HardSizeNoDesRun) {
    8199            2 :                     MSEvapCondAirFlowUser = thisDXCoil.MSEvapCondAirFlow(Mode);
    8200            6 :                     BaseSizer::reportSizerOutput(state,
    8201              :                                                  thisDXCoil.DXCoilType,
    8202              :                                                  thisDXCoil.Name,
    8203            4 :                                                  format("Design Size Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
    8204              :                                                  MSEvapCondAirFlowDes,
    8205            4 :                                                  format("User-Specified Speed {} Evaporative Condenser Air Flow Rate [m3/s]", Mode),
    8206              :                                                  MSEvapCondAirFlowUser);
    8207            2 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    8208            0 :                         if ((std::abs(MSEvapCondAirFlowDes - MSEvapCondAirFlowUser) / MSEvapCondAirFlowUser) >
    8209            0 :                             state.dataSize->AutoVsHardSizingThreshold) {
    8210            0 :                             ShowMessage(
    8211            0 :                                 state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
    8212            0 :                             ShowContinueError(state,
    8213            0 :                                               format("User-Specified Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", MSEvapCondAirFlowUser));
    8214            0 :                             ShowContinueError(
    8215            0 :                                 state, format("differs from Design Size Evaporative Condenser Air Flow Rate of {:.5R} [m3/s]", MSEvapCondAirFlowDes));
    8216            0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    8217            0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    8218              :                         }
    8219              :                     }
    8220              :                 }
    8221              :             }
    8222              :         }
    8223              : 
    8224              :         // Ensure evaporative condenser airflow rate at lower speed must be lower or equal to one at higher speed.
    8225           21 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    8226           11 :             if (thisDXCoil.MSEvapCondAirFlow(Mode) > thisDXCoil.MSEvapCondAirFlow(Mode + 1)) {
    8227            0 :                 ShowWarningError(state,
    8228            0 :                                  format("SizeDXCoil: {} {}, Speed {} Evaporative Condenser Air Flow Rate must be less than or equal to Speed {} "
    8229              :                                         "Evaporative Condenser Air Flow Rate.",
    8230            0 :                                         thisDXCoil.DXCoilType,
    8231            0 :                                         thisDXCoil.Name,
    8232              :                                         Mode,
    8233            0 :                                         Mode + 1));
    8234            0 :                 ShowContinueError(state,
    8235            0 :                                   format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSEvapCondAirFlow(Mode), thisDXCoil.MSEvapCondAirFlow(Mode + 1)));
    8236            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    8237              :             }
    8238              :         }
    8239              : 
    8240              :         // Sizing multispeed rated evaporative condenser pump power
    8241           31 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    8242           21 :             IsAutoSize = false;
    8243           21 :             if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) == AutoSize) {
    8244           16 :                 IsAutoSize = true;
    8245              :             }
    8246              : 
    8247           21 :             if (IsAutoSize || !HardSizeNoDesRun) {
    8248              :                 // Autosize low speed evap condenser pump power to 1/3 Total Capacity * 0.004266 w/w (15 w/ton)
    8249           21 :                 MSEvapCondPumpElecNomPowerDes = ((float)Mode / thisDXCoil.NumOfSpeeds) * MSRatedTotCapDesAtMaxSpeed * 0.004266;
    8250              :             } else {
    8251              :                 // this is done to duplicate any existing calc method
    8252            0 :                 MSEvapCondPumpElecNomPowerDes = thisDXCoil.MSRatedTotCap(Mode) * 0.004266;
    8253              :             }
    8254              :             // Design Size data is always available
    8255           21 :             if (IsAutoSize) {
    8256           16 :                 thisDXCoil.MSEvapCondPumpElecNomPower(Mode) = MSEvapCondPumpElecNomPowerDes;
    8257           48 :                 BaseSizer::reportSizerOutput(state,
    8258              :                                              thisDXCoil.DXCoilType,
    8259              :                                              thisDXCoil.Name,
    8260           32 :                                              format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
    8261              :                                              MSEvapCondPumpElecNomPowerDes);
    8262              :             } else {
    8263            5 :                 if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) > 0.0 && MSEvapCondPumpElecNomPowerDes > 0.0 && !HardSizeNoDesRun) {
    8264            2 :                     MSEvapCondPumpElecNomPowerUser = thisDXCoil.MSEvapCondPumpElecNomPower(Mode);
    8265            6 :                     BaseSizer::reportSizerOutput(state,
    8266              :                                                  thisDXCoil.DXCoilType,
    8267              :                                                  thisDXCoil.Name,
    8268            4 :                                                  format("Design Size Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
    8269              :                                                  MSEvapCondPumpElecNomPowerDes,
    8270            4 :                                                  format("User-Specified Speed {} Rated Evaporative Condenser Pump Power Consumption [W]", Mode),
    8271              :                                                  MSEvapCondPumpElecNomPowerUser);
    8272            2 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    8273            0 :                         if ((std::abs(MSEvapCondPumpElecNomPowerDes - MSEvapCondPumpElecNomPowerUser) / MSEvapCondPumpElecNomPowerUser) >
    8274            0 :                             state.dataSize->AutoVsHardSizingThreshold) {
    8275            0 :                             ShowMessage(
    8276            0 :                                 state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
    8277            0 :                             ShowContinueError(state,
    8278            0 :                                               format("User-Specified Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
    8279              :                                                      MSEvapCondPumpElecNomPowerUser));
    8280            0 :                             ShowContinueError(state,
    8281            0 :                                               format("differs from Design Size Evaporative Condenser Pump Rated Power Consumption of {:.2R} [W]",
    8282              :                                                      MSEvapCondPumpElecNomPowerDes));
    8283            0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    8284            0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    8285              :                         }
    8286              :                     }
    8287              :                 }
    8288              :             }
    8289              :         }
    8290              : 
    8291              :         // Ensure evaporative condenser pump power at lower speed must be lower or equal to one at higher speed.
    8292           21 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    8293           11 :             if (thisDXCoil.MSEvapCondPumpElecNomPower(Mode) > thisDXCoil.MSEvapCondPumpElecNomPower(Mode + 1)) {
    8294            0 :                 ShowWarningError(state,
    8295            0 :                                  format("SizeDXCoil: {} {}, Speed {} Rated Evaporative Condenser Pump Power Consumption must be less than or "
    8296              :                                         "equal to Speed {} Rated Evaporative Condenser Pump Power Consumption.",
    8297            0 :                                         thisDXCoil.DXCoilType,
    8298            0 :                                         thisDXCoil.Name,
    8299              :                                         Mode,
    8300            0 :                                         Mode + 1));
    8301            0 :                 ShowContinueError(
    8302              :                     state,
    8303            0 :                     format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSEvapCondPumpElecNomPower(Mode), thisDXCoil.MSEvapCondPumpElecNomPower(Mode + 1)));
    8304            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    8305              :             }
    8306              :         }
    8307              :     }
    8308              : 
    8309              :     // Autosizing for multispeed heating coil
    8310           96 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    8311              :         // flow rate autosize
    8312           23 :         for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    8313           16 :             IsAutoSize = false;
    8314           16 :             if (thisDXCoil.MSRatedAirVolFlowRate(Mode) == AutoSize) {
    8315           12 :                 IsAutoSize = true;
    8316              :             }
    8317           16 :             state.dataSize->DataIsDXCoil = true;
    8318           16 :             CompName = thisDXCoil.Name;
    8319           16 :             CompType = thisDXCoil.DXCoilType;
    8320              :             // Sizing rated air flow rate
    8321           16 :             if (Mode == thisDXCoil.NumOfSpeeds) {
    8322            7 :                 FieldNum = 12 + (Mode - 1) * 6;
    8323            7 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
    8324            7 :                 TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    8325            7 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedAirVolFlowRateEMSOverrideON(Mode);
    8326            7 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedAirVolFlowRateEMSOverrideValue(Mode);
    8327            7 :                 bool errorsFound = false;
    8328            7 :                 HeatingAirFlowSizer sizingHeatingAirFlow;
    8329            7 :                 sizingHeatingAirFlow.overrideSizingString(SizingString);
    8330              :                 // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    8331            7 :                 sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    8332            7 :                 thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
    8333            7 :                 if (!IsAutoSize && !HardSizeNoDesRun) {
    8334            0 :                     TempSize = AutoSize;
    8335            0 :                     bPRINT = false;
    8336            0 :                     errorsFound = false;
    8337            0 :                     HeatingAirFlowSizer sizingHeatingAirFlow2;
    8338            0 :                     sizingHeatingAirFlow2.overrideSizingString(SizingString);
    8339              :                     // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    8340            0 :                     sizingHeatingAirFlow2.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    8341            0 :                     MSRatedAirVolFlowRateDes = sizingHeatingAirFlow2.size(state, TempSize, errorsFound);
    8342            0 :                     bPRINT = true;
    8343            0 :                 }
    8344            7 :             } else {
    8345            9 :                 FieldNum = 12 + (Mode - 1) * 6;
    8346            9 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [m3/s]";
    8347            9 :                 if (IsAutoSize || !HardSizeNoDesRun) {
    8348              :                     // Auto-size low speed flow to fraction of the highest speed capacity
    8349            7 :                     state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(thisDXCoil.NumOfSpeeds);
    8350            7 :                     if (!IsAutoSize && !HardSizeNoDesRun) {
    8351            0 :                         state.dataSize->DataConstantUsedForSizing = MSRatedAirVolFlowRateDes;
    8352              :                     }
    8353            7 :                     state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
    8354              :                 }
    8355            9 :                 TempSize = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    8356            9 :                 bool errorsFound = false;
    8357            9 :                 HeatingAirFlowSizer sizingHeatingAirFlow;
    8358            9 :                 sizingHeatingAirFlow.overrideSizingString(SizingString);
    8359              :                 // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    8360            9 :                 sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    8361            9 :                 thisDXCoil.MSRatedAirVolFlowRate(Mode) = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
    8362            9 :             }
    8363           16 :             state.dataSize->DataEMSOverride = 0.0;
    8364           16 :             state.dataSize->DataEMSOverrideON = false;
    8365           16 :             state.dataSize->DataIsDXCoil = false;
    8366           16 :             state.dataSize->DataTotCapCurveIndex = 0;
    8367           16 :             state.dataSize->DataConstantUsedForSizing = 0.0;
    8368           16 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    8369              :         }
    8370              : 
    8371              :         // Ensure flow rate at lower speed must be lower or equal to the flow rate at higher speed. Otherwise, a severe error is issued.
    8372           16 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    8373            9 :             if (thisDXCoil.MSRatedAirVolFlowRate(Mode) > thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)) {
    8374            0 :                 ShowWarningError(state,
    8375            0 :                                  format("SizeDXCoil: {} {}, Speed {} Rated Air Flow Rate must be less than or equal to Speed {} Rated Air Flow Rate.",
    8376            0 :                                         thisDXCoil.DXCoilType,
    8377            0 :                                         thisDXCoil.Name,
    8378              :                                         Mode,
    8379            0 :                                         Mode + 1));
    8380            0 :                 ShowContinueError(
    8381            0 :                     state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedAirVolFlowRate(Mode), thisDXCoil.MSRatedAirVolFlowRate(Mode + 1)));
    8382            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    8383              :             }
    8384              :         }
    8385              :         // Rated Secondary Coil Airflow Rates for AirCooled condenser type
    8386            7 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
    8387            0 :             for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    8388            0 :                 IsAutoSize = false;
    8389            0 :                 if (thisDXCoil.MSSecCoilAirFlow(Mode) == AutoSize) {
    8390            0 :                     IsAutoSize = true;
    8391              :                 }
    8392              :                 // Autosize Primary Coil air flow * Secondary Coil Scaling Factor
    8393            0 :                 SecCoilAirFlowDes = thisDXCoil.MSRatedAirVolFlowRate(Mode) * thisDXCoil.MSSecCoilAirFlowScalingFactor(Mode);
    8394            0 :                 if (IsAutoSize) {
    8395            0 :                     thisDXCoil.MSSecCoilAirFlow(Mode) = SecCoilAirFlowDes;
    8396            0 :                     BaseSizer::reportSizerOutput(state,
    8397              :                                                  thisDXCoil.DXCoilType,
    8398              :                                                  thisDXCoil.Name,
    8399            0 :                                                  format("Design Size Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
    8400              :                                                  SecCoilAirFlowDes);
    8401              :                 } else {
    8402            0 :                     if (thisDXCoil.MSSecCoilAirFlow(Mode) > 0.0 && SecCoilAirFlowDes > 0.0 && !HardSizeNoDesRun) {
    8403            0 :                         SecCoilAirFlowUser = thisDXCoil.MSSecCoilAirFlow(Mode);
    8404            0 :                         BaseSizer::reportSizerOutput(state,
    8405              :                                                      thisDXCoil.DXCoilType,
    8406              :                                                      thisDXCoil.Name,
    8407            0 :                                                      format("Design Size Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
    8408              :                                                      SecCoilAirFlowDes,
    8409            0 :                                                      format("User-Specified Speed {} Secondary Coil Air Flow Rate [m3/s]", Mode),
    8410              :                                                      SecCoilAirFlowUser);
    8411            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    8412            0 :                             if ((std::abs(SecCoilAirFlowDes - SecCoilAirFlowUser) / SecCoilAirFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
    8413            0 :                                 ShowMessage(
    8414              :                                     state,
    8415            0 :                                     format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
    8416            0 :                                 ShowContinueError(state, format("User-Specified Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowUser));
    8417            0 :                                 ShowContinueError(
    8418            0 :                                     state, format("differs from Design Size Secondary Coil Air Flow Rate of {:.5R} [m3/s]", SecCoilAirFlowDes));
    8419            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    8420            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    8421              :                             }
    8422              :                         }
    8423              :                     }
    8424              :                 }
    8425              :             }
    8426              :         }
    8427              : 
    8428              :         // Sizing rated total heating capacity
    8429           23 :         for (Mode = thisDXCoil.NumOfSpeeds; Mode >= 1; --Mode) {
    8430           16 :             IsAutoSize = false;
    8431           16 :             if (thisDXCoil.MSRatedTotCap(Mode) == AutoSize) {
    8432           12 :                 IsAutoSize = true;
    8433              :             }
    8434           16 :             state.dataSize->DataIsDXCoil = true;
    8435           16 :             CompName = thisDXCoil.Name;
    8436           16 :             CompType = thisDXCoil.DXCoilType;
    8437           16 :             if (Mode == thisDXCoil.NumOfSpeeds) {
    8438            7 :                 state.dataSize->DataFlowUsedForSizing = thisDXCoil.MSRatedAirVolFlowRate(Mode);
    8439            7 :                 FieldNum = 10 + (Mode - 1) * 6;
    8440            7 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
    8441            7 :                 state.dataSize->DataTotCapCurveIndex = thisDXCoil.MSCCapFTemp(Mode);
    8442            7 :                 if (IsAutoSize || !HardSizeNoDesRun) {
    8443              :                     // Heating capacity is assumed to be equal to the cooling capacity
    8444            5 :                     PrintFlag = false;
    8445            5 :                     state.dataSize->DataFractionUsedForSizing = 1.0;
    8446            5 :                     if (thisDXCoil.CompanionUpstreamDXCoil > 0) {
    8447            1 :                         NumOfSpeedCompanion = state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).NumOfSpeeds;
    8448            1 :                         state.dataSize->DataConstantUsedForSizing =
    8449            1 :                             state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).MSRatedTotCapDes(NumOfSpeedCompanion);
    8450              :                     } else {
    8451            4 :                         state.dataSize->DataConstantUsedForSizing = thisDXCoil.RatedTotCap(1); // sized above
    8452              :                     }
    8453            5 :                     TempSize = DataSizing::AutoSize;
    8454            5 :                     state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    8455            5 :                     state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    8456            5 :                     HeatingCapacitySizer sizerHeatingCapacity;
    8457            5 :                     sizerHeatingCapacity.overrideSizingString(SizingString);
    8458            5 :                     sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8459            5 :                     MSRatedTotCapDesAtMaxSpeed = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    8460            5 :                     state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
    8461            5 :                     state.dataSize->DataFractionUsedForSizing = 1.0;
    8462            5 :                 }
    8463            7 :                 PrintFlag = true;
    8464            7 :                 TempSize = thisDXCoil.MSRatedTotCap(Mode);
    8465            7 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    8466            7 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    8467            7 :                 HeatingCapacitySizer sizerHeatingCapacity;
    8468            7 :                 sizerHeatingCapacity.overrideSizingString(SizingString);
    8469            7 :                 sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8470            7 :                 TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    8471            7 :                 thisDXCoil.MSRatedTotCap(Mode) = TempSize;
    8472            7 :                 if (IsAutoSize) {
    8473            5 :                     MSRatedTotCapDesAtMaxSpeed = TempSize;
    8474              :                 }
    8475            7 :             } else {
    8476            9 :                 PrintFlag = true;
    8477            9 :                 FieldNum = 10 + (Mode - 1) * 6;
    8478            9 :                 SizingString = state.dataDXCoils->DXCoilNumericFields(DXCoilNum).PerfMode(1).FieldNames(FieldNum) + " [W]";
    8479            9 :                 if (IsAutoSize || !HardSizeNoDesRun) {
    8480              :                     // autosize low speed capacity to fraction of the highest speed capacity
    8481            7 :                     if (!HardSizeNoDesRun) {
    8482            7 :                         state.dataSize->DataConstantUsedForSizing = MSRatedTotCapDesAtMaxSpeed;
    8483              :                     } else {
    8484            0 :                         state.dataSize->DataConstantUsedForSizing = thisDXCoil.MSRatedTotCap(thisDXCoil.NumOfSpeeds);
    8485              :                     }
    8486            7 :                     state.dataSize->DataFractionUsedForSizing = (float)Mode / thisDXCoil.NumOfSpeeds;
    8487              :                 }
    8488            9 :                 TempSize = thisDXCoil.MSRatedTotCap(Mode);
    8489            9 :                 state.dataSize->DataEMSOverrideON = thisDXCoil.RatedTotCapEMSOverrideOn(Mode);
    8490            9 :                 state.dataSize->DataEMSOverride = thisDXCoil.RatedTotCapEMSOverrideValue(Mode);
    8491            9 :                 HeatingCapacitySizer sizerHeatingCapacity;
    8492            9 :                 sizerHeatingCapacity.overrideSizingString(SizingString);
    8493            9 :                 sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    8494            9 :                 TempSize = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    8495            9 :                 thisDXCoil.MSRatedTotCap(Mode) = TempSize;
    8496            9 :             }
    8497           16 :             PrintFlag = false;
    8498           16 :             state.dataSize->DataEMSOverrideON = false;
    8499           16 :             state.dataSize->DataEMSOverride = 0.0;
    8500           16 :             state.dataSize->DataIsDXCoil = false;
    8501           16 :             state.dataSize->DataFlowUsedForSizing = 0.0;
    8502           16 :             state.dataSize->DataCoolCoilCap = 0.0;
    8503           16 :             state.dataSize->DataTotCapCurveIndex = 0;
    8504           16 :             state.dataSize->DataConstantUsedForSizing = 0.0;
    8505           16 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    8506              :         }
    8507              :         // Ensure capacity at lower speed must be lower or equal to the capacity at higher speed.
    8508           16 :         for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds - 1; ++Mode) {
    8509            9 :             if (thisDXCoil.MSRatedTotCap(Mode) > thisDXCoil.MSRatedTotCap(Mode + 1)) {
    8510            0 :                 ShowWarningError(state,
    8511            0 :                                  format("SizeDXCoil: {} {}, Speed {} Rated Total Heating Capacity must be less than or equal to Speed {} Rated "
    8512              :                                         "Total Heating Capacity.",
    8513            0 :                                         thisDXCoil.DXCoilType,
    8514            0 :                                         thisDXCoil.Name,
    8515              :                                         Mode,
    8516            0 :                                         Mode + 1));
    8517            0 :                 ShowContinueError(state, format("Instead, {:.2R} > {:.2R}", thisDXCoil.MSRatedTotCap(Mode), thisDXCoil.MSRatedTotCap(Mode + 1)));
    8518            0 :                 ShowFatalError(state, "Preceding conditions cause termination.");
    8519              :             }
    8520              :         }
    8521              : 
    8522              :         // Resistive Defrost Heater Capacity = capacity at the first stage
    8523              :         // Sizing defrost heater capacity
    8524            7 :         IsAutoSize = false;
    8525            7 :         if (thisDXCoil.DefrostCapacity == AutoSize) {
    8526            6 :             IsAutoSize = true;
    8527              :         }
    8528            7 :         if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::Resistive) {
    8529            2 :             DefrostCapacityDes = thisDXCoil.MSRatedTotCap(1);
    8530              :         } else {
    8531            5 :             DefrostCapacityDes = 0.0;
    8532              :         }
    8533            7 :         if (IsAutoSize) {
    8534            6 :             thisDXCoil.DefrostCapacity = DefrostCapacityDes;
    8535            6 :             BaseSizer::reportSizerOutput(
    8536              :                 state, thisDXCoil.DXCoilType, thisDXCoil.Name, "Design Size Resistive Defrost Heater Capacity", DefrostCapacityDes);
    8537              :         } else {
    8538            1 :             if (thisDXCoil.DefrostCapacity > 0.0 && DefrostCapacityDes > 0.0 && !HardSizeNoDesRun) {
    8539            0 :                 DefrostCapacityUser = thisDXCoil.DefrostCapacity;
    8540            0 :                 BaseSizer::reportSizerOutput(state,
    8541              :                                              thisDXCoil.DXCoilType,
    8542              :                                              thisDXCoil.Name,
    8543              :                                              "Design Size Resistive Defrost Heater Capacity",
    8544              :                                              DefrostCapacityDes,
    8545              :                                              "User-Specified Resistive Defrost Heater Capacity",
    8546              :                                              DefrostCapacityUser);
    8547            0 :                 if (state.dataGlobal->DisplayExtraWarnings) {
    8548            0 :                     if ((std::abs(DefrostCapacityDes - DefrostCapacityUser) / DefrostCapacityUser) > state.dataSize->AutoVsHardSizingThreshold) {
    8549            0 :                         ShowWarningMessage(
    8550            0 :                             state, format("SizeDxCoil: Potential issue with equipment sizing for {} {}", thisDXCoil.DXCoilType, thisDXCoil.Name));
    8551            0 :                         ShowContinueError(state, format("User-Specified Resistive Defrost Heater Capacity of {:.2R}[W]", DefrostCapacityUser));
    8552            0 :                         ShowContinueError(state,
    8553            0 :                                           format("differs from Design Size Resistive Defrost Heater Capacity of {:.2R}[W]", DefrostCapacityDes));
    8554            0 :                         ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    8555            0 :                         ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    8556              :                     }
    8557              :                 }
    8558              :             }
    8559              :         }
    8560              :     }
    8561              : 
    8562              :     // Call routine that computes AHRI certified rating for single-speed DX Coils
    8563          228 :     if ((thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed &&
    8564           36 :          (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
    8565          192 :           thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) ||
    8566           60 :         thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
    8567           82 :         CalcDXCoilStandardRating(state,
    8568           41 :                                  thisDXCoil.Name,
    8569           41 :                                  thisDXCoil.DXCoilType,
    8570              :                                  thisDXCoil.DXCoilType_Num,
    8571              :                                  1,
    8572           41 :                                  thisDXCoil.RatedTotCap(1),
    8573           41 :                                  thisDXCoil.RatedCOP(1),
    8574           41 :                                  thisDXCoil.CCapFFlow(1),
    8575           41 :                                  thisDXCoil.CCapFTemp(1),
    8576           41 :                                  thisDXCoil.EIRFFlow(1),
    8577           41 :                                  thisDXCoil.EIRFTemp(1),
    8578           41 :                                  thisDXCoil.PLFFPLR(1),
    8579           41 :                                  thisDXCoil.RatedAirVolFlowRate(1),
    8580           41 :                                  thisDXCoil.FanPowerPerEvapAirFlowRate(1),
    8581           41 :                                  thisDXCoil.FanPowerPerEvapAirFlowRate_2023(1),
    8582           41 :                                  thisDXCoil.CondenserType,
    8583           41 :                                  thisDXCoil.RegionNum,
    8584           41 :                                  thisDXCoil.MinOATCompressor,
    8585           41 :                                  thisDXCoil.OATempCompressorOn,
    8586           41 :                                  thisDXCoil.OATempCompressorOnOffBlank,
    8587           41 :                                  thisDXCoil.DefrostControl,
    8588           41 :                                  thisDXCoil.ASHRAE127StdRprt);
    8589              :     }
    8590              :     // Call routine that computes AHRI certified rating for multi-speed DX cooling Coils
    8591           96 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
    8592           68 :         CalcDXCoilStandardRating(state,
    8593           17 :                                  thisDXCoil.Name,
    8594           17 :                                  thisDXCoil.DXCoilType,
    8595              :                                  thisDXCoil.DXCoilType_Num,
    8596              :                                  thisDXCoil.NumOfSpeeds,
    8597              :                                  thisDXCoil.MSRatedTotCap,
    8598              :                                  thisDXCoil.MSRatedCOP,
    8599              :                                  thisDXCoil.MSCCapFFlow,
    8600              :                                  thisDXCoil.MSCCapFTemp,
    8601              :                                  thisDXCoil.MSEIRFFlow,
    8602              :                                  thisDXCoil.MSEIRFTemp,
    8603              :                                  thisDXCoil.MSPLFFPLR,
    8604              :                                  thisDXCoil.MSRatedAirVolFlowRate,
    8605              :                                  thisDXCoil.MSFanPowerPerEvapAirFlowRate,
    8606              :                                  thisDXCoil.MSFanPowerPerEvapAirFlowRate_2023,
    8607           17 :                                  thisDXCoil.CondenserType,
    8608           17 :                                  thisDXCoil.RegionNum,
    8609           17 :                                  thisDXCoil.MinOATCompressor,
    8610           17 :                                  thisDXCoil.OATempCompressorOn,
    8611           17 :                                  thisDXCoil.OATempCompressorOnOffBlank,
    8612           17 :                                  thisDXCoil.DefrostControl,
    8613           34 :                                  ObjexxFCL::Optional_bool_const());
    8614              :     }
    8615              : 
    8616           98 :     if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed && (thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Air ||
    8617            2 :                                                                       thisDXCoil.CondenserType(1) == DataHeatBalance::RefrigCondenserType::Evap)) {
    8618            8 :         StandardRatings::CalcTwoSpeedDXCoilRating(state,
    8619            4 :                                                   thisDXCoil.Name,
    8620            4 :                                                   thisDXCoil.DXCoilType,
    8621              :                                                   thisDXCoil.DXCoilType_Num,
    8622              :                                                   thisDXCoil.RatedTotCap,
    8623              :                                                   thisDXCoil.RatedTotCap2,
    8624              :                                                   thisDXCoil.RatedCOP,
    8625              :                                                   thisDXCoil.RatedCOP2,
    8626              :                                                   thisDXCoil.CCapFFlow, // High Speed
    8627              :                                                   thisDXCoil.CCapFTemp,
    8628              :                                                   thisDXCoil.CCapFTemp2,
    8629              :                                                   thisDXCoil.EIRFFlow, // High Speed
    8630              :                                                   thisDXCoil.EIRFTemp,
    8631              :                                                   thisDXCoil.EIRFTemp2,
    8632              :                                                   thisDXCoil.RatedAirVolFlowRate,
    8633              :                                                   thisDXCoil.RatedAirVolFlowRate2,
    8634              :                                                   thisDXCoil.FanPowerPerEvapAirFlowRate_2023,
    8635              :                                                   thisDXCoil.FanPowerPerEvapAirFlowRate_2023_LowSpeed,
    8636            4 :                                                   thisDXCoil.CondenserType,
    8637            4 :                                                   thisDXCoil.PLFFPLR(1));
    8638              :     }
    8639              : 
    8640              :     // create predefined report entries
    8641           96 :     equipName = thisDXCoil.Name;
    8642              :     // put tables for cooling and heating separate
    8643           96 :     switch (thisDXCoil.DXCoilType_Num) {
    8644           50 :     case HVAC::CoilDX_CoolingSingleSpeed:
    8645              :     case HVAC::CoilDX_CoolingTwoSpeed:
    8646              :     case HVAC::CoilDX_CoolingTwoStageWHumControl:
    8647              :     case HVAC::CoilDX_MultiSpeedCooling: {
    8648           50 :         PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilType, equipName, thisDXCoil.DXCoilType);
    8649           50 :         if (thisDXCoil.NumOfSpeeds == 0) {
    8650           40 :             if (thisDXCoil.NumCapacityStages == 1) {
    8651           40 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(1));
    8652           80 :                 PreDefTableEntry(
    8653           40 :                     state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
    8654           80 :                 PreDefTableEntry(state,
    8655           40 :                                  state.dataOutRptPredefined->pdchCoolCoilLatCap,
    8656              :                                  equipName,
    8657           40 :                                  thisDXCoil.RatedTotCap(1) - thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1));
    8658           40 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(1));
    8659           40 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(1));
    8660              :             } else {
    8661            0 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.RatedTotCap(2));
    8662            0 :                 PreDefTableEntry(
    8663            0 :                     state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
    8664            0 :                 PreDefTableEntry(state,
    8665            0 :                                  state.dataOutRptPredefined->pdchCoolCoilLatCap,
    8666              :                                  equipName,
    8667            0 :                                  thisDXCoil.RatedTotCap(2) - thisDXCoil.RatedTotCap(2) * thisDXCoil.RatedSHR(2));
    8668            0 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.RatedSHR(2));
    8669            0 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.RatedCOP(2));
    8670              :             }
    8671              :         } else {
    8672           31 :             for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    8673           21 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
    8674           42 :                 PreDefTableEntry(
    8675           21 :                     state, state.dataOutRptPredefined->pdchCoolCoilSensCap, equipName, thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
    8676           42 :                 PreDefTableEntry(state,
    8677           21 :                                  state.dataOutRptPredefined->pdchCoolCoilLatCap,
    8678              :                                  equipName,
    8679           21 :                                  thisDXCoil.MSRatedTotCap(Mode) - thisDXCoil.MSRatedTotCap(Mode) * thisDXCoil.MSRatedSHR(Mode));
    8680           21 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, equipName, thisDXCoil.MSRatedSHR(Mode));
    8681           21 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
    8682              :             }
    8683              :         }
    8684          100 :         addFootNoteSubTable(state,
    8685           50 :                             state.dataOutRptPredefined->pdstCoolCoil,
    8686              :                             "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
    8687           50 :     } break;
    8688           20 :     case HVAC::CoilDX_HeatingEmpirical:
    8689              :     case HVAC::CoilDX_MultiSpeedHeating:
    8690              :     case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
    8691              :     case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
    8692           20 :         PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, equipName, thisDXCoil.DXCoilType);
    8693           20 :         if (thisDXCoil.NumOfSpeeds == 0) {
    8694           13 :             if (thisDXCoil.NumCapacityStages == 1) {
    8695           13 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.RatedTotCap(1));
    8696           13 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.RatedCOP(1));
    8697              :             } else {
    8698            0 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.RatedTotCap(2));
    8699            0 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.RatedCOP(2));
    8700              :             }
    8701              :         } else {
    8702           23 :             for (Mode = 1; Mode <= thisDXCoil.NumOfSpeeds; ++Mode) {
    8703           16 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, equipName, thisDXCoil.MSRatedTotCap(Mode));
    8704           16 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, equipName, thisDXCoil.MSRatedCOP(Mode));
    8705              :             }
    8706              :         }
    8707           40 :         addFootNoteSubTable(state,
    8708           20 :                             state.dataOutRptPredefined->pdstHeatCoil,
    8709              :                             "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
    8710              : 
    8711              :         // std 229 existing table DX Heating coil new reporting variables
    8712           40 :         OutputReportPredefined::PreDefTableEntry(
    8713           20 :             state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp, equipName, thisDXCoil.MinOATCompressor);
    8714           40 :         OutputReportPredefined::PreDefTableEntry(state,
    8715           20 :                                                  state.dataOutRptPredefined->pdchDXHeatCoilAirloopName,
    8716              :                                                  equipName,
    8717           60 :                                                  thisDXCoil.AirLoopNum > 0 ? state.dataAirSystemsData->PrimaryAirSystems(thisDXCoil.AirLoopNum).Name
    8718              :                                                                            : "N/A");
    8719              :         // std 229 existing table DX Heating coil 2023 AHRI new reporting variables
    8720           40 :         OutputReportPredefined::PreDefTableEntry(
    8721           20 :             state, state.dataOutRptPredefined->pdchDXHeatCoilMinOADBTforCompOp_2023, equipName, thisDXCoil.MinOATCompressor);
    8722           40 :         OutputReportPredefined::PreDefTableEntry(state,
    8723           20 :                                                  state.dataOutRptPredefined->pdchDXHeatCoilAirloopName_2023,
    8724              :                                                  equipName,
    8725           60 :                                                  thisDXCoil.AirLoopNum > 0 ? state.dataAirSystemsData->PrimaryAirSystems(thisDXCoil.AirLoopNum).Name
    8726              :                                                                            : "N/A");
    8727           20 :     } break;
    8728           26 :     default:
    8729           26 :         break;
    8730              :     }
    8731           96 : }
    8732              : 
    8733          178 : void CalcHPWHDXCoil(EnergyPlusData &state,
    8734              :                     int const DXCoilNum,       // the number of the DX coil to be simulated
    8735              :                     Real64 const PartLoadRatio // sensible water heating load / full load sensible water heating capacity
    8736              : )
    8737              : {
    8738              : 
    8739              :     // SUBROUTINE INFORMATION:
    8740              :     //       AUTHOR         Richard Raustad
    8741              :     //       DATE WRITTEN   May 2005
    8742              : 
    8743              :     // PURPOSE OF THIS SUBROUTINE:
    8744              :     // Calculates the gross cooling capacity of a heat pump water heater evaporator and
    8745              :     // heating capacity of the condenser coil given the rated heating capacity and COP.
    8746              : 
    8747              :     // METHODOLOGY EMPLOYED:
    8748              :     // The routine requires the user to enter the total heating capacity and COP for the
    8749              :     // heat pump water heater along with logicals defining if fan and condenser pump are included.
    8750              :     // Since manufacturer's can rate their HPWH equipment with or without including condenser
    8751              :     // pump heat, this information is required to accurately determine the condenser's leaving
    8752              :     // water temperature. In addition, knowledge of the fan heat is required to back into
    8753              :     // a compressor COP.
    8754              : 
    8755              :     // Using/Aliasing
    8756              :     using Curve::CurveValue;
    8757              : 
    8758              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    8759              :     Real64 RatedHeatingCapacity;     // Water heating rated capacity with or without condenser water pump heat (W)
    8760              :     Real64 RatedHeatingCOP;          // Water heating rated COP with or without evap fan and cond water pump heat (W/W)
    8761              :     Real64 OperatingHeatingCapacity; // Water heating operating capacity including the impact of capacity and COP curves (W)
    8762              :     Real64 OperatingHeatingCOP;      // Water heating operating COP including the impact of capacity and COP curves (W/W)
    8763              :     Real64 OperatingHeatingPower;    // Water heating operating Power (W)
    8764              :     Real64 CompressorPower;          // Power consumed by compressor only (W)
    8765              : 
    8766              :     Real64 TotalTankHeatingCapacity; // Water heating capacity corrected for condenser water pump heat (W)
    8767              :     Real64 TankHeatingCOP;           // Water heating COP corrected for fan and condenser water pump power (W/W)
    8768              :     // (these previous 2 variables also include the impact of capacity and COP curves)
    8769              :     Real64 EvapCoolingCapacity;   // Air cooling capacity corrected for evap fan and cond water pump heat (W)
    8770              :     Real64 InletWaterTemp;        // Condenser water inlet temperature (C)
    8771              :     Real64 OutletWaterTemp;       // Condenser water outlet temperature (C)
    8772              :     Real64 EvapInletMassFlowRate; // Evaporator air inlet mass flow rate (m3/s)
    8773              :     Real64 CondInletMassFlowRate; // Condenser water inlet mass flow rate (m3/s)
    8774              :     Real64 CpWater;               // Specific heat of condenser inlet water (J/Kg/k)
    8775              :     Real64 InletAirTemp;          // HPWH inlet air temperature (dry-bulb or wet-bulb) (C)
    8776              :     Real64 HeatCapFTemp;          // Output of HPWH Heating Capacity as a Function of Temperature curve
    8777              :     Real64 HeatCapFAirFlow;       // Output of HPWH Heating Capacity as a Function of Air Flow Rate Ratio curve
    8778              :     Real64 HeatCapFWaterFlow;     // Output of HPWH Heating Capacity as a Function of Water Flow Rate Ratio curve
    8779              :     Real64 HeatCOPFTemp;          // Output of HPWH COP as a Function of Temperature curve
    8780              :     Real64 HeatCOPFAirFlow;       // Output of HPWH COP as a Function of Air Flow Rate Ratio curve
    8781              :     Real64 HeatCOPFWaterFlow;     // Output of HPWH COP as a Function of Water Flow Rate Ratio curve
    8782              :     Real64 AirFlowRateRatio;      // Ratio of evaporator inlet air mass flow rate to rated mass flow rate
    8783              :     Real64 WaterFlowRateRatio;    // Ratio of evaporator inlet water mass flow rate to rated mass flow rate
    8784              :     Real64 PartLoadFraction;      // Output of Part Load Fraction as a Function of Part Load Ratio curve
    8785              :     Real64 PumpHeatToWater;       // Amount of pump heat attributed to heating water
    8786              :     Real64 HPRTF;                 // Heat pump run time fraction
    8787              : 
    8788              :     // References to Coil and Node struct
    8789          178 :     DXCoilData &Coil = state.dataDXCoils->DXCoil(DXCoilNum);
    8790          178 :     NodeData &AirInletNode = state.dataLoopNodes->Node(Coil.AirInNode);
    8791          178 :     NodeData &WaterInletNode = state.dataLoopNodes->Node(Coil.WaterInNode);
    8792          178 :     NodeData &WaterOutletNode = state.dataLoopNodes->Node(Coil.WaterOutNode);
    8793              : 
    8794              :     // If heat pump water heater is OFF, set outlet to inlet and RETURN
    8795              :     // Also set the heating energy rate to zero
    8796          178 :     if (PartLoadRatio == 0.0) {
    8797            8 :         WaterOutletNode = WaterInletNode;
    8798            8 :         Coil.TotalHeatingEnergyRate = 0.0;
    8799            8 :         return;
    8800              :     } else {
    8801          170 :         RatedHeatingCapacity = Coil.RatedTotCap2;
    8802          170 :         RatedHeatingCOP = Coil.RatedCOP(1);
    8803          170 :         InletWaterTemp = WaterInletNode.Temp;
    8804          170 :         CondInletMassFlowRate = WaterInletNode.MassFlowRate / PartLoadRatio;
    8805          170 :         EvapInletMassFlowRate = AirInletNode.MassFlowRate / PartLoadRatio;
    8806          170 :         CpWater = CPHW(InletWaterTemp);
    8807          170 :         CompressorPower = 0.0;
    8808          170 :         OperatingHeatingPower = 0.0;
    8809          170 :         TankHeatingCOP = 0.0;
    8810              :     }
    8811              : 
    8812              :     // determine inlet air temperature type for curve objects
    8813          170 :     if (Coil.InletAirTemperatureType == HVAC::OATType::WetBulb) {
    8814          170 :         InletAirTemp = state.dataHVACGlobal->HPWHInletWBTemp;
    8815              :     } else {
    8816            0 :         InletAirTemp = state.dataHVACGlobal->HPWHInletDBTemp;
    8817              :     }
    8818              : 
    8819              :     // get output of Heating Capacity and Heating COP curves (curves default to 1 if user has not specified curve name)
    8820          170 :     if (Coil.HCapFTemp > 0) {
    8821          170 :         if (state.dataCurveManager->curves(Coil.HCapFTemp)->numDims == 1) {
    8822            0 :             HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp);
    8823              :         } else {
    8824          170 :             HeatCapFTemp = CurveValue(state, Coil.HCapFTemp, InletAirTemp, InletWaterTemp);
    8825              :         }
    8826              :         //   Warn user if curve output goes negative
    8827          170 :         if (HeatCapFTemp < 0.0) {
    8828            0 :             if (Coil.HCapFTempErrorIndex == 0) {
    8829            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8830            0 :                 ShowContinueError(
    8831            0 :                     state, format(" HPWH Heating Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", HeatCapFTemp));
    8832            0 :                 if (state.dataCurveManager->curves(Coil.HCapFTemp)->numDims == 2) {
    8833            0 :                     ShowContinueError(
    8834              :                         state,
    8835            0 :                         format(" Negative value occurs using an inlet air temperature of {:.1T} and an inlet water temperature of {:.1T}.",
    8836              :                                InletAirTemp,
    8837              :                                InletWaterTemp));
    8838              :                 } else {
    8839            0 :                     ShowContinueError(state, format(" Negative value occurs using an inlet air temperature of {:.1T}.", InletAirTemp));
    8840              :                 }
    8841            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8842              :             }
    8843            0 :             ShowRecurringWarningErrorAtEnd(
    8844              :                 state,
    8845            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8846              :                     "\": HPWH Heating Capacity Modifier curve (function of temperature) output is negative warning continues...",
    8847            0 :                 Coil.HCapFTempErrorIndex,
    8848              :                 HeatCapFTemp,
    8849              :                 HeatCapFTemp,
    8850              :                 _,
    8851              :                 "[C]",
    8852              :                 "[C]");
    8853            0 :             HeatCapFTemp = 0.0;
    8854              :         }
    8855              :     } else {
    8856            0 :         HeatCapFTemp = 1.0;
    8857              :     }
    8858              : 
    8859          170 :     if (Coil.HCOPFTemp > 0) {
    8860          170 :         if (state.dataCurveManager->curves(Coil.HCOPFTemp)->numDims == 1) {
    8861            0 :             HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp);
    8862              :         } else {
    8863          170 :             HeatCOPFTemp = CurveValue(state, Coil.HCOPFTemp, InletAirTemp, InletWaterTemp);
    8864              :         }
    8865              :         //   Warn user if curve output goes negative
    8866          170 :         if (HeatCOPFTemp < 0.0) {
    8867            0 :             if (Coil.HCOPFTempErrorIndex == 0) {
    8868            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8869            0 :                 ShowContinueError(state,
    8870            0 :                                   format(" HPWH Heating COP Modifier curve (function of temperature) output is negative ({:.3T}).", HeatCOPFTemp));
    8871            0 :                 if (state.dataCurveManager->curves(Coil.HCOPFTemp)->numDims == 2) {
    8872            0 :                     ShowContinueError(
    8873              :                         state,
    8874            0 :                         format(" Negative value occurs using an inlet air temperature of {:.1T} and an inlet water temperature of {:.1T}.",
    8875              :                                InletAirTemp,
    8876              :                                InletWaterTemp));
    8877              :                 } else {
    8878            0 :                     ShowContinueError(state, format(" Negative value occurs using an inlet air temperature of {:.1T}.", InletAirTemp));
    8879              :                 }
    8880            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8881              :             }
    8882            0 :             ShowRecurringWarningErrorAtEnd(
    8883              :                 state,
    8884            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8885              :                     "\": HPWH Heating COP Modifier curve (function of temperature) output is negative warning continues...",
    8886            0 :                 Coil.HCOPFTempErrorIndex,
    8887              :                 HeatCOPFTemp,
    8888              :                 HeatCOPFTemp,
    8889              :                 _,
    8890              :                 "[C]",
    8891              :                 "[C]");
    8892            0 :             HeatCOPFTemp = 0.0;
    8893              :         }
    8894              :     } else {
    8895            0 :         HeatCOPFTemp = 1.0;
    8896              :     }
    8897              : 
    8898          170 :     if (Coil.HCapFAirFlow > 0) {
    8899            0 :         AirFlowRateRatio = EvapInletMassFlowRate / (Coil.RatedAirMassFlowRate(1));
    8900            0 :         HeatCapFAirFlow = CurveValue(state, Coil.HCapFAirFlow, AirFlowRateRatio);
    8901              :         //   Warn user if curve output goes negative
    8902            0 :         if (HeatCapFAirFlow < 0.0) {
    8903            0 :             if (Coil.HCapFAirFlowErrorIndex == 0) {
    8904            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8905            0 :                 ShowContinueError(
    8906              :                     state,
    8907            0 :                     format(" HPWH Heating Capacity Modifier curve (function of air flow fraction) output is negative ({:.3T}).", HeatCapFAirFlow));
    8908            0 :                 ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirFlowRateRatio));
    8909            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8910              :             }
    8911            0 :             ShowRecurringWarningErrorAtEnd(
    8912              :                 state,
    8913            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8914              :                     "\": HPWH Heating Capacity Modifier curve (function of air flow fraction) output is negative warning continues...",
    8915            0 :                 Coil.HCapFAirFlowErrorIndex,
    8916              :                 HeatCapFAirFlow,
    8917              :                 HeatCapFAirFlow);
    8918            0 :             HeatCapFAirFlow = 0.0;
    8919              :         }
    8920              :     } else {
    8921          170 :         HeatCapFAirFlow = 1.0;
    8922              :     }
    8923              : 
    8924          170 :     if (Coil.HCOPFAirFlow > 0) {
    8925            0 :         AirFlowRateRatio = EvapInletMassFlowRate / (Coil.RatedAirMassFlowRate(1));
    8926            0 :         HeatCOPFAirFlow = CurveValue(state, Coil.HCOPFAirFlow, AirFlowRateRatio);
    8927              :         //   Warn user if curve output goes negative
    8928            0 :         if (HeatCOPFAirFlow < 0.0) {
    8929            0 :             if (Coil.HCOPFAirFlowErrorIndex == 0) {
    8930            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8931            0 :                 ShowContinueError(
    8932            0 :                     state, format(" HPWH Heating COP Modifier curve (function of air flow fraction) output is negative ({:.3T}).", HeatCOPFAirFlow));
    8933            0 :                 ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirFlowRateRatio));
    8934            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8935              :             }
    8936            0 :             ShowRecurringWarningErrorAtEnd(
    8937              :                 state,
    8938            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8939              :                     "\": HPWH Heating COP Modifier curve (function of air flow fraction) output is negative warning continues...",
    8940            0 :                 Coil.HCOPFAirFlowErrorIndex,
    8941              :                 HeatCOPFAirFlow,
    8942              :                 HeatCOPFAirFlow);
    8943            0 :             HeatCOPFAirFlow = 0.0;
    8944              :         }
    8945              :     } else {
    8946          170 :         HeatCOPFAirFlow = 1.0;
    8947              :     }
    8948              : 
    8949          170 :     if (Coil.HCapFWaterFlow > 0) {
    8950            0 :         WaterFlowRateRatio = CondInletMassFlowRate / (Coil.RatedHPWHCondWaterFlow * RhoH2O(InletWaterTemp));
    8951            0 :         HeatCapFWaterFlow = CurveValue(state, Coil.HCapFWaterFlow, WaterFlowRateRatio);
    8952              :         //   Warn user if curve output goes negative
    8953            0 :         if (HeatCapFWaterFlow < 0.0) {
    8954            0 :             if (Coil.HCapFWaterFlowErrorIndex == 0) {
    8955            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8956            0 :                 ShowContinueError(state,
    8957            0 :                                   format(" HPWH Heating Capacity Modifier curve (function of water flow fraction) output is negative ({:.3T}).",
    8958              :                                          HeatCapFWaterFlow));
    8959            0 :                 ShowContinueError(state, format(" Negative value occurs using a water flow fraction of {:.3T}.", WaterFlowRateRatio));
    8960            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8961              :             }
    8962            0 :             ShowRecurringWarningErrorAtEnd(
    8963              :                 state,
    8964            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8965              :                     "\": HPWH Heating Capacity Modifier curve (function of water flow fraction) output is negative warning continues...",
    8966            0 :                 Coil.HCapFWaterFlowErrorIndex,
    8967              :                 HeatCapFWaterFlow,
    8968              :                 HeatCapFWaterFlow);
    8969            0 :             HeatCapFWaterFlow = 0.0;
    8970              :         }
    8971              :     } else {
    8972          170 :         HeatCapFWaterFlow = 1.0;
    8973              :     }
    8974              : 
    8975          170 :     if (Coil.HCOPFWaterFlow > 0) {
    8976            0 :         WaterFlowRateRatio = CondInletMassFlowRate / (Coil.RatedHPWHCondWaterFlow * RhoH2O(InletWaterTemp));
    8977            0 :         HeatCOPFWaterFlow = CurveValue(state, Coil.HCOPFWaterFlow, WaterFlowRateRatio);
    8978              :         //   Warn user if curve output goes negative
    8979            0 :         if (HeatCOPFWaterFlow < 0.0) {
    8980            0 :             if (Coil.HCOPFWaterFlowErrorIndex == 0) {
    8981            0 :                 ShowWarningMessage(state, format("{} \"{}\":", Coil.DXCoilType, Coil.Name));
    8982            0 :                 ShowContinueError(
    8983              :                     state,
    8984            0 :                     format(" HPWH Heating COP Modifier curve (function of water flow fraction) output is negative ({:.3T}).", HeatCOPFWaterFlow));
    8985            0 :                 ShowContinueError(state, format(" Negative value occurs using a water flow fraction of {:.3T}.", WaterFlowRateRatio));
    8986            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    8987              :             }
    8988            0 :             ShowRecurringWarningErrorAtEnd(
    8989              :                 state,
    8990            0 :                 Coil.DXCoilType + " \"" + Coil.Name +
    8991              :                     "\": HPWH Heating COP Modifier curve (function of water flow fraction) output is negative warning continues...",
    8992            0 :                 Coil.HCOPFWaterFlowErrorIndex,
    8993              :                 HeatCOPFWaterFlow,
    8994              :                 HeatCOPFWaterFlow);
    8995            0 :             HeatCOPFWaterFlow = 0.0;
    8996              :         }
    8997              :     } else {
    8998          170 :         HeatCOPFWaterFlow = 1.0;
    8999              :     }
    9000              : 
    9001              :     // adjust Heating Capacity and COP for off-design conditions
    9002          170 :     OperatingHeatingCapacity = RatedHeatingCapacity * HeatCapFTemp * HeatCapFAirFlow * HeatCapFWaterFlow;
    9003          170 :     OperatingHeatingCOP = RatedHeatingCOP * HeatCOPFTemp * HeatCOPFAirFlow * HeatCOPFWaterFlow;
    9004              : 
    9005          170 :     if (OperatingHeatingCOP > 0.0) {
    9006          170 :         OperatingHeatingPower = OperatingHeatingCapacity / OperatingHeatingCOP;
    9007              :     }
    9008              : 
    9009          170 :     PumpHeatToWater = Coil.HPWHCondPumpElecNomPower * Coil.HPWHCondPumpFracToWater;
    9010          170 :     TankHeatingCOP = OperatingHeatingCOP;
    9011              : 
    9012              :     // account for pump heat if not included in total water heating capacity
    9013          170 :     if (Coil.CondPumpHeatInCapacity) {
    9014            0 :         TotalTankHeatingCapacity = OperatingHeatingCapacity;
    9015              :     } else {
    9016          170 :         TotalTankHeatingCapacity = OperatingHeatingCapacity + PumpHeatToWater;
    9017              :     }
    9018              : 
    9019              :     // find part load fraction to calculate RTF
    9020          170 :     if (Coil.PLFFPLR(1) > 0) {
    9021          162 :         PartLoadFraction = max(0.7, CurveValue(state, Coil.PLFFPLR(1), PartLoadRatio));
    9022              :     } else {
    9023            8 :         PartLoadFraction = 1.0;
    9024              :     }
    9025              : 
    9026          170 :     HPRTF = min(1.0, (PartLoadRatio / PartLoadFraction));
    9027              : 
    9028          170 :     Real64 locFanElecPower = state.dataFans->fans(Coil.SupplyFanIndex)->totalPower;
    9029              : 
    9030              :     // calculate evaporator total cooling capacity
    9031          170 :     if (HPRTF > 0.0) {
    9032          170 :         if (Coil.FanPowerIncludedInCOP) {
    9033            8 :             if (Coil.CondPumpPowerInCOP) {
    9034              :                 //       make sure fan power is full load fan power
    9035            0 :                 CompressorPower = OperatingHeatingPower - locFanElecPower / HPRTF - Coil.HPWHCondPumpElecNomPower;
    9036            0 :                 if (OperatingHeatingPower > 0.0) {
    9037            0 :                     TankHeatingCOP = TotalTankHeatingCapacity / OperatingHeatingPower;
    9038              :                 }
    9039              :             } else {
    9040            8 :                 CompressorPower = OperatingHeatingPower - locFanElecPower / HPRTF;
    9041            8 :                 if ((OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower) > 0.0) {
    9042            8 :                     TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + Coil.HPWHCondPumpElecNomPower);
    9043              :                 }
    9044              :             }
    9045              :         } else {
    9046          162 :             if (Coil.CondPumpPowerInCOP) {
    9047              :                 //       make sure fan power is full load fan power
    9048            0 :                 CompressorPower = OperatingHeatingPower - Coil.HPWHCondPumpElecNomPower;
    9049            0 :                 if ((OperatingHeatingPower + locFanElecPower / HPRTF) > 0.0) {
    9050            0 :                     TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + locFanElecPower / HPRTF);
    9051              :                 }
    9052              :             } else {
    9053          162 :                 CompressorPower = OperatingHeatingPower;
    9054          162 :                 if ((OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower) > 0.0) {
    9055          162 :                     TankHeatingCOP = TotalTankHeatingCapacity / (OperatingHeatingPower + locFanElecPower / HPRTF + Coil.HPWHCondPumpElecNomPower);
    9056              :                 }
    9057              :             }
    9058              :         }
    9059              :     }
    9060              : 
    9061          170 :     if (Coil.CondPumpHeatInCapacity) {
    9062            0 :         EvapCoolingCapacity = TotalTankHeatingCapacity - PumpHeatToWater - CompressorPower;
    9063              :     } else {
    9064          170 :         EvapCoolingCapacity = TotalTankHeatingCapacity - CompressorPower;
    9065              :     }
    9066              : 
    9067              :     // set evaporator total cooling capacity prior to CalcDOE2DXCoil subroutine
    9068          170 :     Coil.RatedTotCap(1) = EvapCoolingCapacity;
    9069              : 
    9070              :     // determine condenser water inlet/outlet condition at full capacity
    9071          170 :     if (CondInletMassFlowRate == 0.0) {
    9072            8 :         OutletWaterTemp = InletWaterTemp;
    9073              :     } else {
    9074          162 :         OutletWaterTemp = InletWaterTemp + TotalTankHeatingCapacity / (CpWater * CondInletMassFlowRate);
    9075              :     }
    9076              : 
    9077          170 :     WaterOutletNode.Temp = OutletWaterTemp;
    9078              : 
    9079          170 :     WaterOutletNode.MassFlowRate = WaterInletNode.MassFlowRate;
    9080              : 
    9081              :     // send heating capacity and COP to water heater module for standards rating calculation
    9082              :     // total heating capacity including condenser pump
    9083          170 :     state.dataDXCoils->HPWHHeatingCapacity = TotalTankHeatingCapacity;
    9084              :     // total heating COP including compressor, fan, and condenser pump
    9085          170 :     state.dataDXCoils->HPWHHeatingCOP = TankHeatingCOP;
    9086              : 
    9087              :     // send DX coil total cooling capacity to HPWH for reporting
    9088          170 :     state.dataHVACGlobal->DXCoilTotalCapacity = EvapCoolingCapacity;
    9089              : 
    9090          170 :     Coil.TotalHeatingEnergyRate = TotalTankHeatingCapacity * PartLoadRatio;
    9091              : 
    9092              :     // calculate total compressor plus condenser pump power, fan power reported in fan module
    9093          170 :     Coil.ElecWaterHeatingPower = (CompressorPower + Coil.HPWHCondPumpElecNomPower) * HPRTF;
    9094              : }
    9095              : 
    9096       331312 : void CalcDoe2DXCoil(EnergyPlusData &state,
    9097              :                     int const DXCoilNum,                                 // the number of the DX coil to be simulated
    9098              :                     HVAC::CompressorOp const compressorOp,               // compressor operation; 1=on, 0=off
    9099              :                     bool const FirstHVACIteration,                       // true if this is the first iteration of HVAC
    9100              :                     Real64 const PartLoadRatio,                          // sensible cooling load / full load sensible cooling capacity
    9101              :                     HVAC::FanOp const fanOp,                             // Allows parent object to control fan operation
    9102              :                     ObjexxFCL::Optional_int_const PerfMode,              // Performance mode for MultiMode DX coil; Always 1 for other coil types
    9103              :                     ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
    9104              :                     ObjexxFCL::Optional<Real64 const> CoolingHeatingPLR  // used for cycling fan RH control
    9105              : )
    9106              : {
    9107              : 
    9108              :     // SUBROUTINE INFORMATION:
    9109              :     //       AUTHOR         Fred Buhl
    9110              :     //       DATE WRITTEN   May 2000
    9111              :     //       MODIFIED       Shirey, Feb/October 2001, Feb/Mar 2004
    9112              :     //                      Feb 2005 M. J. Witte, GARD Analytics, Inc.
    9113              :     //                        Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
    9114              :     //                      April 2010 Chandan Sharma, FSEC, Added basin heater
    9115              :     //       RE-ENGINEERED  Don Shirey, Aug/Sept 2000
    9116              : 
    9117              :     // PURPOSE OF THIS SUBROUTINE:
    9118              :     // Calculates the air-side performance and electrical energy use of a direct-
    9119              :     // expansion, air-cooled cooling unit.
    9120              : 
    9121              :     // METHODOLOGY EMPLOYED:
    9122              :     // This routine simulates the performance of air-cooled DX cooling equipment.
    9123              :     // The routine requires the user to enter the total cooling capacity, sensible heat ratio,
    9124              :     // and COP for the unit at ARI 210/240 rating conditions (26.67C [80F] dry-bulb, 19.44C [67F]
    9125              :     // wet-bulb air entering the cooling coil, 35C [95F] dry-bulb air entering the outdoor
    9126              :     // condenser. Since different manufacturer's rate their equipment at different air flow rates,
    9127              :     // the supply air flow rate corresponding to the rated capacities and rated COP must also be
    9128              :     // entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information entered by
    9129              :     // the user should NOT include the thermal or electrical impacts of the supply air fan, as
    9130              :     // this is addressed by another module.
    9131              : 
    9132              :     // With the rated performance data entered by the user, the model employs some of the
    9133              :     // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
    9134              :     // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
    9135              :     // does NOT employ the exact same methodology to calculate performance as DOE-2, although
    9136              :     // some of the DOE-2 curve fits are employed by this model.
    9137              : 
    9138              :     // The model checks for coil dryout conditions, and adjusts the calculated performance
    9139              :     // appropriately.
    9140              : 
    9141              :     // REFERENCES:
    9142              :     // ASHRAE HVAC 2 Toolkit page 4-81.
    9143              :     // Henderson, H.I. Jr., K. Rengarajan and D.B. Shirey, III. 1992.The impact of comfort
    9144              :     // control on air conditioner energy use in humid climates. ASHRAE Transactions 98(2):
    9145              :     // 104-113.
    9146              :     // Henderson, H.I. Jr., Danny Parker and Y.J. Huang. 2000.Improving DOE-2's RESYS routine:
    9147              :     // User Defined Functions to Provide More Accurate Part Load Energy Use and Humidity
    9148              :     // Predictions. Proceedings of ACEEE Conference.
    9149              : 
    9150              :     // Using/Aliasing
    9151              :     using Curve::CurveValue;
    9152       331312 :     Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
    9153       331312 :     Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
    9154              :     using General::CreateSysTimeIntervalString;
    9155              : 
    9156              :     // SUBROUTINE PARAMETER DEFINITIONS:
    9157              :     static constexpr std::string_view RoutineName("CalcDoe2DXCoil: ");
    9158              :     static constexpr std::string_view calcDoe2DXCoil("CalcDoe2DXCoil");
    9159              : 
    9160              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    9161              :     Real64 AirMassFlow;       // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
    9162              :     Real64 AirMassFlowRatio;  // Ratio of actual air mass flow to rated air mass flow (adjusted for bypass if any)
    9163              :     Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
    9164              :     // (average flow if cycling fan, full flow if constant fan)
    9165              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
    9166              :     Real64 BypassFlowFraction;    // Fraction of total flow which is bypassed around the cooling coil
    9167              :     Real64 TotCap;                // gross total cooling capacity at off-rated conditions [W]
    9168              :     Real64 TotCapTempModFac;      // Total capacity modifier (function of entering wetbulb, outside drybulb)
    9169              :     Real64 TotCapFlowModFac;      // Total capacity modifier (function of actual supply air flow vs rated flow)
    9170              :     Real64 InletAirWetBulbC;      // wetbulb temperature of inlet air [C]
    9171              :     Real64 InletAirDryBulbTemp;   // inlet air dry bulb temperature [C]
    9172              :     Real64 InletAirEnthalpy;      // inlet air enthalpy [J/kg]
    9173              :     Real64 InletAirHumRat;        // inlet air humidity ratio [kg/kg]
    9174              :     Real64 InletAirHumRatTemp;    // inlet air humidity ratio used in ADP/BF loop [kg/kg]
    9175              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9176              :     // REAL(r64) :: InletAirPressure      ! inlet air pressure [Pa]
    9177              :     Real64 RatedCBF;             // coil bypass factor at rated conditions
    9178              :     Real64 SHR;                  // Sensible Heat Ratio (sensible/total) of the cooling coil
    9179              :     Real64 CBF;                  // coil bypass factor at off rated conditions
    9180              :     Real64 A0;                   // NTU * air mass flow rate, used in CBF calculation
    9181              :     Real64 hDelta;               // Change in air enthalpy across the cooling coil [J/kg]
    9182              :     Real64 hADP;                 // Apparatus dew point enthalpy [J/kg]
    9183              :     Real64 hTinwADP;             // Enthalpy at inlet dry-bulb and wADP [J/kg]
    9184              :     Real64 hTinwout;             // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
    9185              :     Real64 tADP;                 // Apparatus dew point temperature [C]
    9186              :     Real64 wADP;                 // Apparatus dew point humidity ratio [kg/kg]
    9187              :     Real64 FullLoadOutAirEnth;   // outlet full load enthalpy [J/kg]
    9188              :     Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
    9189              :     Real64 FullLoadOutAirTemp;   // outlet air temperature at full load [C]
    9190              :     Real64 EIRTempModFac;        // EIR modifier (function of entering wetbulb, outside drybulb)
    9191              :     Real64 EIRFlowModFac;        // EIR modifier (function of actual supply air flow vs rated flow)
    9192              :     Real64 EIR;                  // EIR at part load and off rated conditions
    9193              :     Real64 PLF;                  // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
    9194              :     Real64 QLatActual;           // operating latent capacity of DX coil
    9195              :     Real64 QLatRated;            // Rated latent capacity of DX coil
    9196              :     Real64 SHRUnadjusted;        // SHR prior to latent degradation effective SHR calculation
    9197              :     int Counter;                 // Counter for dry evaporator iterations
    9198              :     int MaxIter;                 // Maximum number of iterations for dry evaporator calculations
    9199              :     Real64 RF;                   // Relaxation factor for dry evaporator iterations
    9200              :     Real64 Tolerance;            // Error tolerance for dry evaporator iterations
    9201              :     Real64 werror;               // Deviation of humidity ratio in dry evaporator iteration loop
    9202              :     Real64 CondInletTemp;        // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
    9203              :     // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
    9204              :     Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
    9205              :     // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
    9206              :     Real64 CondAirMassFlow;       // Condenser air mass flow rate [kg/s]
    9207              :     Real64 RhoAir;                // Density of air [kg/m3]
    9208              :     Real64 RhoWater;              // Density of water [kg/m3]
    9209              :     Real64 CrankcaseHeatingPower; // power due to crankcase heater
    9210       331312 :     Real64 CompAmbTemp(0.0);      // Ambient temperature at compressor
    9211              :     Real64 AirFlowRatio;          // ratio of compressor on airflow to average timestep airflow
    9212              :     // used when constant fan mode yields different air flow rates when compressor is ON and OFF
    9213              :     // (e.g. Packaged Terminal Heat Pump)
    9214              :     Real64 OutdoorDryBulb;  // Outdoor dry-bulb temperature at condenser (C)
    9215              :     Real64 OutdoorWetBulb;  // Outdoor wet-bulb temperature at condenser (C)
    9216              :     Real64 OutdoorHumRat;   // Outdoor humidity ratio at condenser (kg/kg)
    9217              :     Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
    9218              : 
    9219              :     int Mode;                    // Performance mode for Multimode DX coil; Always 1 for other coil types
    9220              :     Real64 OutletAirTemp;        // Supply air temperature (average value if constant fan, full output if cycling fan)
    9221              :     Real64 OutletAirHumRat;      // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
    9222              :     Real64 OutletAirEnthalpy;    // Supply air enthalpy (average value if constant fan, full output if cycling fan)
    9223              :     Real64 ADiff;                // Used for exponential
    9224              :     Real64 DXcoolToHeatPLRRatio; // ratio of cooling PLR to heating PLR, used for cycling fan RH control
    9225              :     Real64 HeatRTF;              // heating coil part-load ratio, used for cycling fan RH control
    9226              :     Real64 HeatingCoilPLF;       // heating coil PLF (function of PLR), used for cycling fan RH control
    9227              : 
    9228              :     // If Performance mode not present, then set to 1.  Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
    9229       331312 :     if (present(PerfMode)) {
    9230            0 :         Mode = PerfMode;
    9231              :     } else {
    9232       331312 :         Mode = 1;
    9233              :     }
    9234              : 
    9235              :     // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
    9236              :     // during cooling and when no cooling is required (constant fan, fan speed changes)
    9237       331312 :     if (present(OnOffAirFlowRatio)) {
    9238       247143 :         AirFlowRatio = OnOffAirFlowRatio;
    9239              :     } else {
    9240        84169 :         AirFlowRatio = 1.0;
    9241              :     }
    9242              : 
    9243              :     // If CoolingHeatingPLR not present, then set to 1. Used for cycling fan systems where
    9244              :     // heating PLR is greater than cooling PLR, otherwise CoolingHeatingPLR = 1.
    9245       331312 :     if (present(CoolingHeatingPLR)) {
    9246        59945 :         DXcoolToHeatPLRRatio = CoolingHeatingPLR;
    9247              :     } else {
    9248       271367 :         DXcoolToHeatPLRRatio = 1.0;
    9249              :     }
    9250              : 
    9251       331312 :     MaxIter = 30;
    9252       331312 :     RF = 0.4;
    9253       331312 :     Counter = 0;
    9254       331312 :     Tolerance = 0.01;
    9255       331312 :     CondInletTemp = 0.0;
    9256       331312 :     CondInletHumRat = 0.0;
    9257              : 
    9258       331312 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
    9259              : 
    9260       331312 :     BypassFlowFraction = thisDXCoil.BypassedFlowFrac(Mode);
    9261       331312 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate * (1.0 - BypassFlowFraction);
    9262       331312 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
    9263       331312 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
    9264       331312 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
    9265              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9266              :     // InletAirPressure    = DXCoil(DXCoilNum)%InletAirPressure
    9267       331312 :     state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
    9268       331312 :     thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
    9269       331312 :     thisDXCoil.PartLoadRatio = 0.0;
    9270       331312 :     thisDXCoil.BasinHeaterPower = 0.0;
    9271              : 
    9272       331312 :     if (thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::WaterHeater) {
    9273       331149 :         if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
    9274       117452 :             OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
    9275              :             // If node is not connected to anything, pressure = default, use weather data
    9276       117452 :             if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
    9277            0 :                 OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
    9278            0 :                 OutdoorHumRat = state.dataEnvrn->OutHumRat;
    9279            0 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress;
    9280            0 :                 OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
    9281              :             } else {
    9282       117452 :                 OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
    9283       117452 :                 OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
    9284              :                 // this should use Node%WetBulbTemp or a PSYC function, not OAWB
    9285       117452 :                 OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
    9286              :             }
    9287              :         } else {
    9288       213697 :             OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
    9289       213697 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
    9290       213697 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
    9291       213697 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
    9292              :         }
    9293       331149 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
    9294            0 :             auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
    9295            0 :             OutdoorDryBulb = secZoneHB.ZT;
    9296            0 :             OutdoorHumRat = secZoneHB.airHumRat;
    9297            0 :             OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
    9298            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
    9299              :         }
    9300              :     } else {
    9301          163 :         if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
    9302          163 :             OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
    9303              :             // If node is not connected to anything, pressure = default, use weather data
    9304          163 :             if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
    9305          163 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress; // node not connected
    9306              :             }
    9307              :         } else {
    9308            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
    9309              :         }
    9310              :     }
    9311              : 
    9312       331312 :     if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
    9313       263297 :         CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
    9314       263297 :         CompAmbTemp = OutdoorDryBulb;
    9315       263297 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
    9316            0 :             auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
    9317            0 :             CondInletTemp = secZoneHB.ZT;
    9318            0 :             CompAmbTemp = CondInletTemp; // assumes compressor is in same location as secondary coil
    9319            0 :             OutdoorDryBulb = CondInletTemp;
    9320            0 :             OutdoorHumRat = secZoneHB.airHumRat;
    9321            0 :             OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
    9322            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
    9323              :         }
    9324        68015 :     } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
    9325        67852 :         RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
    9326        67852 :         CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
    9327              :         // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
    9328        67852 :         CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
    9329        67852 :         CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
    9330        67852 :         CompAmbTemp = OutdoorDryBulb;
    9331          163 :     } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::WaterHeater) {
    9332          163 :         CompAmbTemp = state.dataHVACGlobal->HPWHCrankcaseDBTemp;   // Temperature at HP water heater compressor
    9333          163 :         CondInletTemp = state.dataHVACGlobal->HPWHCrankcaseDBTemp; // Temperature at HP water heater compressor
    9334              :     }
    9335              : 
    9336              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
    9337              :     // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
    9338       331312 :     if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
    9339        82507 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
    9340        82507 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
    9341            3 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
    9342              :         }
    9343              :     } else {
    9344       248805 :         CrankcaseHeatingPower = 0.0;
    9345              :     }
    9346              : 
    9347              :     // calculate end time of current time step to determine if error messages should be printed
    9348       331312 :     state.dataDXCoils->CurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
    9349              : 
    9350              :     //   Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
    9351              :     //   Wait for next time step to print warnings. If simulation iterates, print out
    9352              :     //   the warning for the last iteration only. Must wait for next time step to accomplish this.
    9353              :     //   If a warning occurs and the simulation down shifts, the warning is not valid.
    9354              : 
    9355       331312 :     if (thisDXCoil.PrintLowAmbMessage) { // .AND. &
    9356          240 :         if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
    9357            0 :             if (thisDXCoil.LowAmbErrIndex == 0) {
    9358            0 :                 ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowAmbBuffer1));
    9359            0 :                 ShowContinueError(state, thisDXCoil.LowAmbBuffer2);
    9360            0 :                 ShowContinueError(state, "... Operation at low ambient temperatures may require special performance curves.");
    9361              :             }
    9362            0 :             if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
    9363            0 :                 ShowRecurringWarningErrorAtEnd(state,
    9364            0 :                                                std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9365              :                                                    "\" - Low condenser dry-bulb temperature error continues...",
    9366            0 :                                                thisDXCoil.LowAmbErrIndex,
    9367            0 :                                                thisDXCoil.LowTempLast,
    9368            0 :                                                thisDXCoil.LowTempLast,
    9369              :                                                _,
    9370              :                                                "[C]",
    9371              :                                                "[C]");
    9372              :             } else {
    9373            0 :                 ShowRecurringWarningErrorAtEnd(state,
    9374            0 :                                                std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9375              :                                                    "\" - Low condenser wet-bulb temperature error continues...",
    9376            0 :                                                thisDXCoil.LowAmbErrIndex,
    9377            0 :                                                thisDXCoil.LowTempLast,
    9378            0 :                                                thisDXCoil.LowTempLast,
    9379              :                                                _,
    9380              :                                                "[C]",
    9381              :                                                "[C]");
    9382              :             }
    9383              :         }
    9384              :     }
    9385              : 
    9386       331312 :     if (thisDXCoil.PrintLowOutTempMessage) {
    9387         1017 :         if (state.dataDXCoils->CurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
    9388          376 :             if (thisDXCoil.LowOutletTempIndex == 0) {
    9389            4 :                 ShowWarningMessage(state, format("{}{}", RoutineName, thisDXCoil.LowOutTempBuffer1));
    9390            4 :                 ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
    9391            8 :                 ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
    9392            8 :                 ShowContinueError(state,
    9393            8 :                                   format("   1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
    9394            4 :                                          thisDXCoil.FullLoadInletAirTempLast));
    9395            8 :                 ShowContinueError(state, "   2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
    9396           12 :                 ShowContinueError(state,
    9397              :                                   "   3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
    9398              :             }
    9399         3008 :             ShowRecurringWarningErrorAtEnd(state,
    9400         1128 :                                            std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9401              :                                                "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
    9402              :                                                "Outlet air temperature statistics follow:",
    9403          376 :                                            thisDXCoil.LowOutletTempIndex,
    9404          376 :                                            thisDXCoil.FullLoadOutAirTempLast,
    9405          376 :                                            thisDXCoil.FullLoadOutAirTempLast);
    9406              :         }
    9407              :     }
    9408              : 
    9409              :     // save last system time step and last end time of current time step (used to determine if warning is valid)
    9410       331312 :     thisDXCoil.TimeStepSysLast = TimeStepSys;
    9411       331312 :     thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CurrentEndTime;
    9412       331312 :     thisDXCoil.PrintLowAmbMessage = false;
    9413       331312 :     thisDXCoil.PrintLowOutTempMessage = false;
    9414              : 
    9415       269753 :     if ((AirMassFlow > 0.0) &&
    9416       269908 :         (thisDXCoil.availSched->getCurrentVal() > 0.0 || thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9417            3 :          thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
    9418       771102 :         (PartLoadRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On) &&
    9419       170037 :         CompAmbTemp > thisDXCoil.MinOATCompressor) { // criteria for coil operation
    9420       170031 :         if (fanOp == HVAC::FanOp::Cycling) {
    9421        57669 :             AirMassFlow /= (PartLoadRatio / DXcoolToHeatPLRRatio);
    9422       112362 :         } else if (fanOp == HVAC::FanOp::Continuous && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_CoolingTwoSpeed) {
    9423       112362 :             AirMassFlow *= AirFlowRatio;
    9424              :         } else {
    9425            0 :             AirMassFlow = thisDXCoil.RatedAirMassFlowRate(Mode);
    9426              :         }
    9427              : 
    9428              :         // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton)
    9429              : 
    9430              :         // for some reason there are diff's when using coil inlet air pressure
    9431              :         // these lines (more to follow) are commented out for the time being
    9432              : 
    9433       170031 :         InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
    9434       170031 :         AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
    9435              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9436              :         //  InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
    9437              :         //  AirVolumeFlowRate = AirMassFlow/ PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
    9438       170031 :         if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
    9439            0 :             ShowFatalError(
    9440            0 :                 state, format("{}{}=\"{}\" - Rated total cooling capacity is zero or less.", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9441              :         }
    9442       170031 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9443       169884 :             thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9444          147 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap2;
    9445              :         } else {
    9446       169884 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
    9447              :         }
    9448        81326 :         if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag && thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterPumped &&
    9449       263161 :             thisDXCoil.DXCoilType_Num != HVAC::CoilDX_HeatPumpWaterHeaterWrapped &&
    9450        11804 :             ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
    9451        10710 :              (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
    9452         1095 :             if (thisDXCoil.ErrIndex1 == 0) {
    9453            8 :                 ShowWarningMessage(
    9454              :                     state,
    9455            8 :                     format("{}{}=\"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
    9456              :                            RoutineName,
    9457            4 :                            thisDXCoil.DXCoilType,
    9458            4 :                            thisDXCoil.Name,
    9459              :                            VolFlowperRatedTotCap));
    9460            8 :                 ShowContinueErrorTimeStamp(state, "");
    9461            8 :                 ShowContinueError(state,
    9462            8 :                                   format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
    9463            4 :                                          HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    9464            4 :                                          HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    9465            8 :                 ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components,");
    9466           12 :                 ShowContinueError(state, "or variable air volume [VAV] system using incorrect coil type.");
    9467              :             }
    9468         8760 :             ShowRecurringWarningErrorAtEnd(
    9469              :                 state,
    9470         3285 :                 std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9471              :                     "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
    9472         1095 :                 thisDXCoil.ErrIndex1,
    9473              :                 VolFlowperRatedTotCap,
    9474              :                 VolFlowperRatedTotCap);
    9475       168936 :         } else if (!state.dataGlobal->WarmupFlag &&
    9476        22954 :                    (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9477       191890 :                     thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) &&
    9478           49 :                    ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
    9479           49 :                     (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
    9480            0 :             if (thisDXCoil.ErrIndex1 == 0) {
    9481            0 :                 ShowWarningMessage(
    9482              :                     state,
    9483            0 :                     format("{}{}=\"{}\" - Air volume flow rate per watt of rated total water heating capacity is out of range at {:.2R} m3/s/W.",
    9484              :                            RoutineName,
    9485            0 :                            thisDXCoil.DXCoilType,
    9486            0 :                            thisDXCoil.Name,
    9487              :                            VolFlowperRatedTotCap));
    9488            0 :                 ShowContinueErrorTimeStamp(state, "");
    9489            0 :                 ShowContinueError(state,
    9490            0 :                                   format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
    9491            0 :                                          HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
    9492            0 :                                          HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
    9493            0 :                 ShowContinueError(state,
    9494              :                                   "Possible causes may be that the parent object is calling for an actual supply air flow rate that is much "
    9495              :                                   "higher or lower than the DX coil rated supply air flow rate.");
    9496              :             }
    9497            0 :             ShowRecurringWarningErrorAtEnd(
    9498              :                 state,
    9499            0 :                 std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9500              :                     "\" - Air volume flow rate per watt of rated total water heating capacity is out of range error continues...",
    9501            0 :                 thisDXCoil.ErrIndex1,
    9502              :                 VolFlowperRatedTotCap,
    9503              :                 VolFlowperRatedTotCap);
    9504              :         }
    9505              :         //    Adjust coil bypass factor for actual air flow rate. Use relation CBF = exp(-NTU) where
    9506              :         //    NTU = A0/(m*cp). Relationship models the cooling coil as a heat exchanger with Cmin/Cmax = 0.
    9507              : 
    9508       170031 :         RatedCBF = thisDXCoil.RatedCBF(Mode);
    9509       170031 :         if (RatedCBF > 0.0) {
    9510       170031 :             A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
    9511              :         } else {
    9512            0 :             A0 = 0.0;
    9513              :         }
    9514       170031 :         ADiff = -A0 / AirMassFlow;
    9515       170031 :         if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
    9516       166270 :             CBF = std::exp(ADiff);
    9517              :         } else {
    9518         3761 :             CBF = 0.0;
    9519              :         }
    9520              : 
    9521              :         //   check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
    9522       170031 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
    9523       127084 :             if (OutdoorDryBulb < 0.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for air-cooled electric chiller
    9524            0 :                 thisDXCoil.PrintLowAmbMessage = true;
    9525            0 :                 thisDXCoil.LowTempLast = OutdoorDryBulb;
    9526            0 :                 if (thisDXCoil.LowAmbErrIndex == 0) {
    9527              :                     thisDXCoil.LowAmbBuffer1 =
    9528            0 :                         format("{} \"{}\" - Air-cooled condenser inlet dry-bulb temperature below 0 C. Outdoor dry-bulb temperature = {:.2R}",
    9529            0 :                                thisDXCoil.DXCoilType,
    9530            0 :                                thisDXCoil.Name,
    9531            0 :                                OutdoorDryBulb);
    9532            0 :                     thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
    9533            0 :                                                CreateSysTimeIntervalString(state);
    9534              :                 }
    9535              :             }
    9536        42947 :         } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
    9537        42800 :             if (OutdoorWetBulb < 10.0 && !state.dataGlobal->WarmupFlag) { // Same threshold as for evap-cooled electric chiller
    9538          240 :                 thisDXCoil.PrintLowAmbMessage = true;
    9539          240 :                 thisDXCoil.LowTempLast = OutdoorWetBulb;
    9540          240 :                 if (thisDXCoil.LowAmbErrIndex == 0) {
    9541              :                     thisDXCoil.LowAmbBuffer1 =
    9542          480 :                         format("{} \"{}\" - Evap-cooled condenser inlet wet-bulb temperature below 10 C. Outdoor wet-bulb temperature = {:.2R}",
    9543          240 :                                thisDXCoil.DXCoilType,
    9544          240 :                                thisDXCoil.Name,
    9545          240 :                                OutdoorWetBulb);
    9546          480 :                     thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
    9547          720 :                                                CreateSysTimeIntervalString(state);
    9548              :                 }
    9549              :             }
    9550              :         }
    9551              : 
    9552              :         //  Get total capacity modifying factor (function of temperature) for off-rated conditions
    9553              :         //  InletAirHumRat may be modified in this ADP/BF loop, use temporary variable for calculations
    9554       170031 :         InletAirHumRatTemp = InletAirHumRat;
    9555       170031 :         AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
    9556              :         while (true) {
    9557       199692 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9558       199545 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9559              :                 // Coil:DX:HeatPumpWaterHeater does not have total cooling capacity as a function of temp or flow curve
    9560          147 :                 TotCapTempModFac = 1.0;
    9561          147 :                 TotCapFlowModFac = 1.0;
    9562              :             } else {
    9563       199545 :                 if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
    9564       199504 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
    9565              :                 } else {
    9566           41 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), CondInletTemp);
    9567              :                 }
    9568              : 
    9569              :                 //    Warn user if curve output goes negative
    9570       199545 :                 if (TotCapTempModFac < 0.0) {
    9571            0 :                     if (thisDXCoil.CCapFTempErrorIndex == 0) {
    9572            0 :                         ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9573            0 :                         ShowContinueError(state,
    9574            0 :                                           format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).",
    9575              :                                                  TotCapTempModFac));
    9576            0 :                         if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
    9577            0 :                             ShowContinueError(state,
    9578            0 :                                               format(" Negative value occurs using a condenser inlet air temperature of {:.1T} and an inlet air "
    9579              :                                                      "wet-bulb temperature of {:.1T}.",
    9580              :                                                      CondInletTemp,
    9581              :                                                      InletAirWetBulbC));
    9582              :                         } else {
    9583            0 :                             ShowContinueError(state,
    9584            0 :                                               format(" Negative value occurs using a condenser inlet air temperature of {:.1T}.", CondInletTemp));
    9585              :                         }
    9586            0 :                         if (Mode > 1) {
    9587            0 :                             ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
    9588              :                         }
    9589            0 :                         ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    9590              :                     }
    9591            0 :                     ShowRecurringWarningErrorAtEnd(
    9592              :                         state,
    9593            0 :                         std::string{RoutineName} + thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
    9594              :                             "\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
    9595            0 :                         thisDXCoil.CCapFTempErrorIndex,
    9596              :                         TotCapTempModFac,
    9597              :                         TotCapTempModFac);
    9598            0 :                     TotCapTempModFac = 0.0;
    9599              :                 }
    9600              : 
    9601              :                 //    Get total capacity modifying factor (function of mass flow) for off-rated conditions
    9602       199545 :                 TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
    9603              :                 //    Warn user if curve output goes negative
    9604       199545 :                 if (TotCapFlowModFac < 0.0) {
    9605            0 :                     if (thisDXCoil.CCapFFlowErrorIndex == 0) {
    9606            0 :                         ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9607            0 :                         ShowContinueError(state,
    9608            0 :                                           format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).",
    9609              :                                                  TotCapFlowModFac));
    9610            0 :                         ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
    9611            0 :                         ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    9612            0 :                         if (Mode > 1) {
    9613            0 :                             ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
    9614              :                         }
    9615              :                     }
    9616            0 :                     ShowRecurringWarningErrorAtEnd(
    9617              :                         state,
    9618            0 :                         std::string{RoutineName} + thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
    9619              :                             "\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
    9620            0 :                         thisDXCoil.CCapFFlowErrorIndex,
    9621              :                         TotCapFlowModFac,
    9622              :                         TotCapFlowModFac);
    9623            0 :                     TotCapFlowModFac = 0.0;
    9624              :                 }
    9625              :             }
    9626       199692 :             TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
    9627              :             // if user specified SHR modifier curves are available calculate the SHR as follows:
    9628       199692 :             if (thisDXCoil.UserSHRCurveExists) {
    9629            0 :                 SHR = CalcSHRUserDefinedCurves(state,
    9630              :                                                InletAirDryBulbTemp,
    9631              :                                                InletAirWetBulbC,
    9632              :                                                AirMassFlowRatio,
    9633            0 :                                                thisDXCoil.SHRFTemp(Mode),
    9634            0 :                                                thisDXCoil.SHRFFlow(Mode),
    9635            0 :                                                thisDXCoil.RatedSHR(Mode));
    9636            0 :                 hDelta = TotCap / AirMassFlow;
    9637            0 :                 break;
    9638              :             } else {
    9639              :                 // Calculate apparatus dew point conditions using TotCap and CBF
    9640       199692 :                 hDelta = TotCap / AirMassFlow;
    9641       199692 :                 hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
    9642       199692 :                 tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, calcDoe2DXCoil);
    9643              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9644              :                 //  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
    9645       199692 :                 wADP = PsyWFnTdbH(state, tADP, hADP, calcDoe2DXCoil);
    9646       199692 :                 hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
    9647       199692 :                 if ((InletAirEnthalpy - hADP) > 1.e-10) {
    9648       199692 :                     SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
    9649              :                 } else {
    9650            0 :                     SHR = 1.0;
    9651              :                 }
    9652              :                 // Check for dry evaporator conditions (win < wadp)
    9653       199692 :                 if (wADP > InletAirHumRatTemp || (Counter >= 1 && Counter < MaxIter)) {
    9654        34640 :                     if (InletAirHumRatTemp == 0.0) {
    9655            9 :                         InletAirHumRatTemp = 0.00001;
    9656              :                     }
    9657        34640 :                     werror = (InletAirHumRatTemp - wADP) / InletAirHumRatTemp;
    9658              :                     // Increase InletAirHumRatTemp at constant InletAirTemp to find coil dry-out point. Then use the
    9659              :                     // capacity at the dry-out point to determine exiting conditions from coil. This is required
    9660              :                     // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
    9661        34640 :                     InletAirHumRatTemp = RF * wADP + (1.0 - RF) * InletAirHumRatTemp;
    9662        34640 :                     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRatTemp, OutdoorPressure);
    9663              :                     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment
    9664              :                     //  line InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRatTemp,InletAirPressure)
    9665        34640 :                     ++Counter;
    9666        34640 :                     if (std::abs(werror) > Tolerance) {
    9667        29661 :                         continue; // Recalculate with modified inlet conditions
    9668              :                     }
    9669         4979 :                     break;
    9670              :                 } else {
    9671              :                     break;
    9672              :                 }
    9673              :             }
    9674              :         } // end of DO iteration loop
    9675              : 
    9676       170031 :         if (thisDXCoil.PLFFPLR(Mode) > 0) {
    9677       170031 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PartLoadRatio); // Calculate part-load factor
    9678              :         } else {
    9679            0 :             PLF = 1.0;
    9680              :         }
    9681              : 
    9682       170031 :         if (PLF < 0.7) {
    9683            0 :             if (thisDXCoil.ErrIndex2 == 0) {
    9684            0 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9685            0 :                     thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9686            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\", PLF curve value", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9687            0 :                     ShowContinueError(state, format("The PLF curve value = {:.3T} for part-load ratio = {:.3T}", PLF, PartLoadRatio));
    9688            0 :                     ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
    9689            0 :                     ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
    9690              :                 } else {
    9691            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\", PLF curve value", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9692            0 :                     ShowContinueError(state, format("The PLF curve value = {:.3T} for part-load ratio = {:.3T}", PLF, PartLoadRatio));
    9693            0 :                     ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
    9694            0 :                     ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
    9695              :                 }
    9696              :             }
    9697            0 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9698            0 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9699            0 :                 ShowRecurringWarningErrorAtEnd(
    9700            0 :                     state, thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
    9701              :             } else {
    9702            0 :                 ShowRecurringWarningErrorAtEnd(
    9703            0 :                     state, thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
    9704              :             }
    9705            0 :             PLF = 0.7;
    9706              :         }
    9707              : 
    9708       170031 :         thisDXCoil.PartLoadRatio = PartLoadRatio;
    9709       170031 :         thisDXCoil.CoolingCoilRuntimeFraction = PartLoadRatio / PLF;
    9710       170031 :         if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
    9711            0 :             if (thisDXCoil.ErrIndex3 == 0) {
    9712            0 :                 if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9713            0 :                     thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9714            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\", runtime fraction", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9715            0 :                     ShowWarningMessage(state, format("The runtime fraction exceeded 1.0. [{:.4R}].", thisDXCoil.CoolingCoilRuntimeFraction));
    9716            0 :                     ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
    9717            0 :                     ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
    9718            0 :                     ShowContinueErrorTimeStamp(state, "");
    9719              :                 } else {
    9720            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\", runtime fraction", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9721            0 :                     ShowWarningMessage(state, format("The runtime fraction exceeded 1.0. [{:.4R}].", thisDXCoil.CoolingCoilRuntimeFraction));
    9722            0 :                     ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
    9723            0 :                     ShowContinueError(state, format("Check the IO reference manual for PLF curve guidance [{}].", thisDXCoil.DXCoilType));
    9724            0 :                     ShowContinueErrorTimeStamp(state, "");
    9725              :                 }
    9726              :             }
    9727            0 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9728            0 :                 thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9729            0 :                 ShowRecurringWarningErrorAtEnd(state,
    9730            0 :                                                thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " runtime fraction > 1.0 warning continues...",
    9731            0 :                                                thisDXCoil.ErrIndex3,
    9732            0 :                                                thisDXCoil.CoolingCoilRuntimeFraction,
    9733            0 :                                                thisDXCoil.CoolingCoilRuntimeFraction);
    9734              :             } else {
    9735            0 :                 ShowRecurringWarningErrorAtEnd(state,
    9736            0 :                                                thisDXCoil.Name + ", " + thisDXCoil.DXCoilType + " runtime fraction > 1.0 warning continues...",
    9737            0 :                                                thisDXCoil.ErrIndex3,
    9738            0 :                                                thisDXCoil.CoolingCoilRuntimeFraction,
    9739            0 :                                                thisDXCoil.CoolingCoilRuntimeFraction);
    9740              :             }
    9741            0 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
    9742       170031 :         } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
    9743         5482 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
    9744              :         }
    9745              : 
    9746              :         // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
    9747       170031 :         if (fanOp == HVAC::FanOp::Cycling) {
    9748        57669 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
    9749              :         }
    9750              : 
    9751              :         //  Calculate full load output conditions
    9752       170031 :         if (thisDXCoil.UserSHRCurveExists) {
    9753            0 :             FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
    9754            0 :             if (SHR < 1.0) {
    9755            0 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9756            0 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9757            0 :                 if (FullLoadOutAirHumRat <= 0.0) {
    9758            0 :                     FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
    9759              :                 }
    9760              :             } else {
    9761            0 :                 SHR = 1.0;
    9762            0 :                 FullLoadOutAirHumRat = InletAirHumRat;
    9763              :             }
    9764              :         } else {
    9765       170031 :             if (SHR > 1.0 || Counter > 0) {
    9766         4979 :                 SHR = 1.0;
    9767              :             }
    9768       170031 :             FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
    9769       170031 :             hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9770       170031 :             if (SHR < 1.0) {
    9771       165052 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9772              :             } else {
    9773         4979 :                 FullLoadOutAirHumRat = InletAirHumRat;
    9774              :             }
    9775              :         }
    9776       170031 :         FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
    9777              : 
    9778              :         // Check for saturation error and modify temperature at constant enthalpy
    9779       170031 :         if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
    9780        17527 :             FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
    9781              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9782              :             //   IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
    9783              :             //    FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
    9784        17527 :             FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
    9785              :         }
    9786              : 
    9787              :         // Store actual outlet conditions when DX coil is ON for use in heat recovery module
    9788       170031 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
    9789       170031 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
    9790              : 
    9791              :         // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
    9792       170031 :         if (FullLoadOutAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
    9793         1018 :             thisDXCoil.PrintLowOutTempMessage = true;
    9794         1018 :             thisDXCoil.FullLoadOutAirTempLast = FullLoadOutAirTemp;
    9795         1018 :             if (thisDXCoil.LowOutletTempIndex == 0) {
    9796            8 :                 thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
    9797           16 :                 thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
    9798              :                                                       "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
    9799            8 :                                                       thisDXCoil.DXCoilType,
    9800            8 :                                                       thisDXCoil.Name,
    9801            8 :                                                       FullLoadOutAirTemp);
    9802           16 :                 thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
    9803           24 :                                                CreateSysTimeIntervalString(state);
    9804              :             }
    9805              :         }
    9806              : 
    9807              :         //  If constant fan with cycling compressor, call function to determine "effective SHR"
    9808              :         //  which includes the part-load degradation on latent capacity
    9809       170031 :         if (fanOp == HVAC::FanOp::Continuous) {
    9810       112362 :             QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode));
    9811       112362 :             QLatActual = TotCap * (1.0 - SHR);
    9812       112362 :             SHRUnadjusted = SHR;
    9813       112362 :             SHR = CalcEffectiveSHR(
    9814              :                 state, DXCoilNum, SHR, thisDXCoil.CoolingCoilRuntimeFraction, QLatRated, QLatActual, InletAirDryBulbTemp, InletAirWetBulbC, Mode);
    9815              :             // For multimode coil, if stage-2 operation (modes 2 or 4), adjust Stage1&2 SHR to account for
    9816              :             // Stage 1 operating at full load, so there is no degradation for that portion
    9817              :             // Use the stage 1 bypass fraction to allocate
    9818       112362 :             if (Mode == 2 || Mode == 4) {
    9819            0 :                 SHR = SHRUnadjusted * (1.0 - thisDXCoil.BypassedFlowFrac(Mode - 1)) + SHR * thisDXCoil.BypassedFlowFrac(Mode - 1);
    9820              :             }
    9821              : 
    9822              :             //  Calculate full load output conditions
    9823       112362 :             if (thisDXCoil.UserSHRCurveExists) {
    9824            0 :                 FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
    9825            0 :                 if (SHR < 1.0) {
    9826            0 :                     hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9827            0 :                     FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9828            0 :                     if (FullLoadOutAirHumRat <= 0.0) {
    9829            0 :                         FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
    9830              :                     }
    9831              :                 } else {
    9832            0 :                     SHR = 1.0;
    9833            0 :                     FullLoadOutAirHumRat = InletAirHumRat;
    9834              :                 }
    9835              :             } else {
    9836       112362 :                 if (SHR > 1.0 || Counter > 0) {
    9837         4899 :                     SHR = 1.0;
    9838              :                 }
    9839       112362 :                 FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
    9840       112362 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9841       112362 :                 if (SHR < 1.0) {
    9842       102175 :                     FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9843              :                 } else {
    9844        10187 :                     FullLoadOutAirHumRat = InletAirHumRat;
    9845              :                 }
    9846              :             }
    9847       112362 :             FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
    9848              : 
    9849              :             // apply latent degradation model to cycling fan when RH control is desired and heating coil operates
    9850              :             // longer than the cooling coil. DXcoolToHeatPLRRatio = Cooling coil PLR / Heating coil PLR.
    9851        57669 :         } else if (fanOp == HVAC::FanOp::Cycling) {
    9852        57669 :             if (DXcoolToHeatPLRRatio < 1.0) {
    9853            0 :                 QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode));
    9854            0 :                 QLatActual = TotCap * (1.0 - SHR);
    9855            0 :                 HeatRTF = PartLoadRatio / DXcoolToHeatPLRRatio;
    9856            0 :                 if (thisDXCoil.HeatingCoilPLFCurvePTR > 0) {
    9857            0 :                     HeatingCoilPLF = CurveValue(state, thisDXCoil.HeatingCoilPLFCurvePTR, HeatRTF);
    9858            0 :                     if (HeatingCoilPLF > 0) {
    9859            0 :                         HeatRTF /= HeatingCoilPLF;
    9860              :                     }
    9861              :                 }
    9862            0 :                 SHRUnadjusted = SHR;
    9863            0 :                 SHR = CalcEffectiveSHR(state,
    9864              :                                        DXCoilNum,
    9865              :                                        SHR,
    9866              :                                        thisDXCoil.CoolingCoilRuntimeFraction,
    9867              :                                        QLatRated,
    9868              :                                        QLatActual,
    9869              :                                        InletAirDryBulbTemp,
    9870              :                                        InletAirWetBulbC,
    9871              :                                        Mode,
    9872              :                                        HeatRTF);
    9873              :                 //   Calculate full load output conditions
    9874            0 :                 if (thisDXCoil.UserSHRCurveExists) {
    9875            0 :                     FullLoadOutAirEnth = InletAirEnthalpy - hDelta;
    9876            0 :                     if (SHR < 1.0) {
    9877            0 :                         hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9878            0 :                         FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9879            0 :                         if (FullLoadOutAirHumRat <= 0.0) {
    9880            0 :                             FullLoadOutAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
    9881              :                         }
    9882              :                     } else {
    9883            0 :                         SHR = 1.0;
    9884            0 :                         FullLoadOutAirHumRat = InletAirHumRat;
    9885              :                     }
    9886              :                 } else {
    9887            0 :                     if (SHR > 1.0 || Counter > 0) {
    9888            0 :                         SHR = 1.0;
    9889              :                     }
    9890            0 :                     FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
    9891            0 :                     hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
    9892            0 :                     if (SHR < 1.0) {
    9893            0 :                         FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
    9894              :                     } else {
    9895            0 :                         FullLoadOutAirHumRat = InletAirHumRat;
    9896              :                     }
    9897              :                 }
    9898            0 :                 FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
    9899              :             }
    9900              :         }
    9901              : 
    9902              :         //  Calculate actual outlet conditions for the input part load ratio
    9903              :         //  Actual outlet conditions are "average" for time step
    9904              : 
    9905              :         // For multimode coil, if stage-2 operation (modes 2 or 4), return "full load" outlet conditions
    9906       170031 :         if (((fanOp == HVAC::FanOp::Continuous) && (Mode == 1)) || (Mode == 3)) {
    9907              :             // Continuous fan, cycling compressor
    9908       112362 :             OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
    9909       112362 :             OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
    9910       112362 :             OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
    9911              :         } else {
    9912              :             // Default to cycling fan, cycling compressor
    9913              :             // Also return this result for stage 2 operation of multimode coil
    9914              :             // Cycling fan typically provides full outlet conditions. When RH control is used, account for additional
    9915              :             // heating run time by using cooling/heating ratio the same as constant fan (otherwise PLRRatio = 1).
    9916        57669 :             OutletAirEnthalpy = FullLoadOutAirEnth * DXcoolToHeatPLRRatio + InletAirEnthalpy * (1.0 - DXcoolToHeatPLRRatio);
    9917        57669 :             OutletAirHumRat = FullLoadOutAirHumRat * DXcoolToHeatPLRRatio + InletAirHumRat * (1.0 - DXcoolToHeatPLRRatio);
    9918        57669 :             OutletAirTemp = FullLoadOutAirTemp * DXcoolToHeatPLRRatio + InletAirDryBulbTemp * (1.0 - DXcoolToHeatPLRRatio);
    9919              :         }
    9920              : 
    9921              :         // Check for saturation error and modify temperature at constant enthalpy
    9922       170031 :         if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, calcDoe2DXCoil)) {
    9923        10242 :             OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
    9924              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9925              :             //   IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
    9926              :             //    OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
    9927        10242 :             OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
    9928              :         }
    9929              : 
    9930              :         // Mix with air that was bypassed around coil, if any
    9931       170031 :         if (BypassFlowFraction > 0.0) {
    9932            0 :             OutletAirEnthalpy = (1.0 - BypassFlowFraction) * OutletAirEnthalpy + BypassFlowFraction * InletAirEnthalpy;
    9933            0 :             OutletAirHumRat = (1.0 - BypassFlowFraction) * OutletAirHumRat + BypassFlowFraction * InletAirHumRat;
    9934            0 :             OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
    9935              :             // Check for saturation error and modify temperature at constant enthalpy
    9936            0 :             if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) {
    9937            0 :                 OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
    9938              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
    9939              :                 //     IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
    9940              :                 //       OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
    9941            0 :                 OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
    9942              :             }
    9943              :         }
    9944              : 
    9945              :         // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
    9946       170031 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterPumped ||
    9947       169884 :             thisDXCoil.DXCoilType_Num == HVAC::CoilDX_HeatPumpWaterHeaterWrapped) {
    9948              :             //   Coil:DX:HeatPumpWaterHeater does not have EIR temp or flow curves
    9949          147 :             EIRTempModFac = 1.0;
    9950          147 :             EIRFlowModFac = 1.0;
    9951              :         } else {
    9952       169884 :             EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
    9953              : 
    9954              :             //   Warn user if curve output goes negative
    9955       169884 :             if (EIRTempModFac < 0.0) {
    9956            0 :                 if (thisDXCoil.EIRFTempErrorIndex == 0) {
    9957            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9958            0 :                     ShowContinueError(
    9959            0 :                         state, format(" Energy Input Ratio Modifier curve (function of temperature) output is negative ({:.3T}).", EIRTempModFac));
    9960            0 :                     if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 2) {
    9961            0 :                         ShowContinueError(state,
    9962            0 :                                           format(" Negative value occurs using a condenser inlet air temperature of {:.1T} and an inlet air "
    9963              :                                                  "wet-bulb temperature of {:.1T}.",
    9964              :                                                  CondInletTemp,
    9965              :                                                  InletAirWetBulbC));
    9966              :                     } else {
    9967            0 :                         ShowContinueError(state, format(" Negative value occurs using a condenser inlet air temperature of {:.1T}.", CondInletTemp));
    9968              :                     }
    9969            0 :                     if (Mode > 1) {
    9970            0 :                         ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
    9971              :                     }
    9972            0 :                     ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    9973              :                 }
    9974            0 :                 ShowRecurringWarningErrorAtEnd(
    9975              :                     state,
    9976            0 :                     std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
    9977              :                         "\": Energy Input Ratio Modifier curve (function of temperature) output is negative warning continues...",
    9978            0 :                     thisDXCoil.EIRFTempErrorIndex,
    9979              :                     EIRTempModFac,
    9980              :                     EIRTempModFac);
    9981            0 :                 EIRTempModFac = 0.0;
    9982              :             }
    9983              : 
    9984       169884 :             EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
    9985              : 
    9986              :             //   Warn user if curve output goes negative
    9987       169884 :             if (EIRFlowModFac < 0.0) {
    9988            0 :                 if (thisDXCoil.EIRFFlowErrorIndex == 0) {
    9989            0 :                     ShowWarningMessage(state, format("{}{}=\"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
    9990            0 :                     ShowContinueError(
    9991            0 :                         state, format(" Energy Input Ratio Modifier curve (function of flow fraction) output is negative ({:.3T}).", EIRFlowModFac));
    9992            0 :                     ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
    9993            0 :                     ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    9994            0 :                     if (Mode > 1) {
    9995            0 :                         ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
    9996              :                     }
    9997              :                 }
    9998            0 :                 ShowRecurringWarningErrorAtEnd(
    9999              :                     state,
   10000            0 :                     std::string{RoutineName} + thisDXCoil.DXCoilType + "=\"" + thisDXCoil.Name +
   10001              :                         "\": Energy Input Ratio Modifier curve (function of flow fraction) output is negative warning continues...",
   10002            0 :                     thisDXCoil.EIRFFlowErrorIndex,
   10003              :                     EIRFlowModFac,
   10004              :                     EIRFlowModFac);
   10005            0 :                 EIRFlowModFac = 0.0;
   10006              :             }
   10007              :         }
   10008              : 
   10009       170031 :         EIR = thisDXCoil.RatedEIR(Mode) * EIRFlowModFac * EIRTempModFac;
   10010              : 
   10011              :         // For multimode coil, if stage-2 operation (Modes 2 or 4), return "full load" power adjusted for PLF
   10012       170031 :         if (Mode == 1 || Mode == 3) {
   10013       170031 :             thisDXCoil.ElecCoolingPower = TotCap * EIR * thisDXCoil.CoolingCoilRuntimeFraction;
   10014              :         } else {
   10015            0 :             thisDXCoil.ElecCoolingPower = TotCap * EIR * thisDXCoil.CoolingCoilRuntimeFraction / PartLoadRatio;
   10016              :         }
   10017              : 
   10018              :         // Reset AirMassFlow to inlet node air mass flow for final total, sensible and latent calculations
   10019              :         // since AirMassFlow might have been modified above (in this subroutine):
   10020              :         //     IF (FanOpMode .EQ. FanOp::Cycling) AirMassFlow = AirMassFlow / PartLoadRatio
   10021              :         // For multimode coil, this should be full flow including bypassed fraction
   10022       170031 :         AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   10023       170031 :         CalcComponentSensibleLatentOutput(AirMassFlow,
   10024              :                                           InletAirDryBulbTemp,
   10025              :                                           InletAirHumRat,
   10026              :                                           OutletAirTemp,
   10027              :                                           OutletAirHumRat,
   10028       170031 :                                           thisDXCoil.SensCoolingEnergyRate,
   10029       170031 :                                           thisDXCoil.LatCoolingEnergyRate,
   10030       170031 :                                           thisDXCoil.TotalCoolingEnergyRate);
   10031              : 
   10032              :         // Set DataHeatGlobal heat reclaim variable for use by heat reclaim coil (part load ratio is accounted for)
   10033              :         // Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
   10034       170031 :         state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
   10035              : 
   10036              :         // Calculate crankcase heater power using the runtime fraction for this DX cooling coil only if there is no companion DX coil.
   10037              :         // Else use the largest runtime fraction of this DX cooling coil and the companion DX heating coil.
   10038       170031 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   10039       170031 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   10040              :         } else {
   10041            0 :             thisDXCoil.CrankcaseHeaterPower =
   10042            0 :                 CrankcaseHeatingPower * (1.0 - max(thisDXCoil.CoolingCoilRuntimeFraction,
   10043            0 :                                                    state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction));
   10044              :         }
   10045              : 
   10046       170031 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   10047              :             //******************
   10048              :             //             WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
   10049              :             //             H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
   10050              :             //                                /RhoWater [kgWater/m3]
   10051              :             //******************
   10052        42800 :             RhoWater = RhoH2O(OutdoorDryBulb);
   10053        42800 :             thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater * thisDXCoil.CoolingCoilRuntimeFraction;
   10054        42800 :             thisDXCoil.EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode) * thisDXCoil.CoolingCoilRuntimeFraction;
   10055              :             // Calculate basin heater power
   10056        42800 :             CalcBasinHeaterPower(state,
   10057              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
   10058              :                                  thisDXCoil.basinHeaterSched,
   10059              :                                  thisDXCoil.BasinHeaterSetPointTemp,
   10060        42800 :                                  thisDXCoil.BasinHeaterPower);
   10061        42800 :             if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
   10062        42800 :                 thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   10063              :             }
   10064              :         }
   10065              : 
   10066       170031 :         thisDXCoil.OutletAirTemp = OutletAirTemp;
   10067       170031 :         thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   10068       170031 :         thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   10069              : 
   10070              :     } else {
   10071              : 
   10072              :         // DX coil is off; just pass through conditions
   10073       161281 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   10074       161281 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   10075       161281 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   10076              : 
   10077       161281 :         thisDXCoil.ElecCoolingPower = 0.0;
   10078       161281 :         thisDXCoil.TotalCoolingEnergyRate = 0.0;
   10079       161281 :         thisDXCoil.SensCoolingEnergyRate = 0.0;
   10080       161281 :         thisDXCoil.LatCoolingEnergyRate = 0.0;
   10081       161281 :         thisDXCoil.EvapCondPumpElecPower = 0.0;
   10082       161281 :         thisDXCoil.EvapWaterConsumpRate = 0.0;
   10083              : 
   10084              :         // Reset globals when DX coil is OFF for use in heat recovery module
   10085       161281 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
   10086       161281 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
   10087              : 
   10088              :         // Calculate crankcase heater power using the runtime fraction for this DX cooling coil (here DXCoolingCoilRTF=0) if
   10089              :         // there is no companion DX coil, or the runtime fraction of the companion DX heating coil (here DXHeatingCoilRTF>=0).
   10090       161281 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   10091       161281 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
   10092              :         } else {
   10093            0 :             thisDXCoil.CrankcaseHeaterPower =
   10094            0 :                 CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction);
   10095              :         }
   10096              : 
   10097              :         // Calculate basin heater power
   10098       161281 :         if (thisDXCoil.DXCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
   10099            1 :             if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
   10100            0 :                 CalcBasinHeaterPower(state,
   10101              :                                      thisDXCoil.BasinHeaterPowerFTempDiff,
   10102              :                                      thisDXCoil.basinHeaterSched,
   10103              :                                      thisDXCoil.BasinHeaterSetPointTemp,
   10104            0 :                                      thisDXCoil.BasinHeaterPower);
   10105              :             }
   10106              :         } else {
   10107       161280 :             if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   10108        25052 :                 CalcBasinHeaterPower(state,
   10109              :                                      thisDXCoil.BasinHeaterPowerFTempDiff,
   10110              :                                      thisDXCoil.basinHeaterSched,
   10111              :                                      thisDXCoil.BasinHeaterSetPointTemp,
   10112        25052 :                                      thisDXCoil.BasinHeaterPower);
   10113              :             }
   10114              :         }
   10115              : 
   10116              :     } // end of on/off if - else
   10117              : 
   10118              :     // set water system demand request (if needed)
   10119       331312 :     if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
   10120            0 :         state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
   10121            0 :             thisDXCoil.EvapWaterConsumpRate;
   10122              :     }
   10123              : 
   10124       331312 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   10125       331312 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   10126       331312 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
   10127       331312 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   10128       331312 :     thisDXCoil.CondInletTemp = CondInletTemp;
   10129              : 
   10130              :     // set outlet node conditions
   10131       331312 :     int airOutletNode = thisDXCoil.AirOutNode;
   10132       331312 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   10133       331312 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   10134              : 
   10135              :     // calc secondary coil if specified
   10136       331312 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   10137            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   10138              :     }
   10139       331312 : }
   10140              : 
   10141        49499 : void CalcVRFCoolingCoil(EnergyPlusData &state,
   10142              :                         int const DXCoilNum,                                 // the number of the DX coil to be simulated
   10143              :                         HVAC::CompressorOp const compressorOp,               // compressor operation; 1=on, 0=off
   10144              :                         bool const FirstHVACIteration,                       // true if this is the first iteration of HVAC
   10145              :                         Real64 const PartLoadRatio,                          // sensible cooling load / full load sensible cooling capacity
   10146              :                         HVAC::FanOp const fanOp,                             // Allows parent object to control fan operation
   10147              :                         Real64 const CompCycRatio,                           // cycling ratio of VRF condenser
   10148              :                         ObjexxFCL::Optional_int_const PerfMode,              // Performance mode for MultiMode DX coil; Always 1 for other coil types
   10149              :                         ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
   10150              :                         ObjexxFCL::Optional<Real64 const> MaxCoolCap         // maximum capacity of DX coil
   10151              : )
   10152              : {
   10153              : 
   10154              :     // SUBROUTINE INFORMATION:
   10155              :     //       AUTHOR         Richard Raustad
   10156              :     //       DATE WRITTEN   August 2010
   10157              : 
   10158              :     // PURPOSE OF THIS SUBROUTINE:
   10159              :     // Calculates the air-side performance of a direct-expansion, air-cooled
   10160              :     // VRF terminal unit cooling coil.
   10161              :     // A new subroutine was created in case this DX coil model is significantly
   10162              :     // different from the existing CalcDoe2DXCoil subroutine. The VRF heating coil
   10163              :     // uses the existing DX heating coil subroutine (CalcDXHeatingCoil).
   10164              : 
   10165              :     // METHODOLOGY EMPLOYED:
   10166              :     // This routine simulates the performance of a variable refrigerant flow cooling coil.
   10167              :     // The routine requires the user to enter the total cooling capacity and sensible heat ratio.
   10168              :     // Since different manufacturer's rate their equipment at different air flow rates,
   10169              :     // the supply air flow rate corresponding to the rated capacities must also be
   10170              :     // entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information entered by
   10171              :     // the user should NOT include the thermal or electrical impacts of the supply air fan, as
   10172              :     // this is addressed by another module.
   10173              : 
   10174              :     // With the rated performance data entered by the user, the model employs some of the
   10175              :     // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
   10176              :     // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
   10177              :     // does NOT employ the exact same methodology to calculate performance as DOE-2.
   10178              :     // This VRF cooling coil model adjusts the rated total cooling capacity by the CAPFT
   10179              :     // and CAP function of flow curve/model currently used by the existing DX coil model.
   10180              :     // The part-load ratio is then applied to the total operating capacity to find the capacity
   10181              :     // required to meet the load. This VRF model then uses the ADP/bypass method to find the
   10182              :     // SHR and resulting outlet conditions given that total capacity (or delta H).
   10183              : 
   10184              :     // The model checks for coil dryout conditions, and adjusts the calculated performance
   10185              :     // appropriately.
   10186              : 
   10187              :     // Using/Aliasing
   10188              :     using Curve::CurveValue;
   10189        49499 :     Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
   10190        49499 :     Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
   10191              :     using General::CreateSysTimeIntervalString;
   10192              : 
   10193              :     // SUBROUTINE ARGUMENT DEFINITIONS:
   10194              :     //  REAL(r64), INTENT(IN), OPTIONAL :: CoolingHeatingPLR   ! used for cycling fan RH control
   10195              : 
   10196              :     // SUBROUTINE PARAMETER DEFINITIONS:
   10197              :     static constexpr std::string_view RoutineName("CalcVRFCoolingCoil");
   10198              : 
   10199              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   10200              :     Real64 AirMassFlow;       // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
   10201              :     Real64 AirMassFlowRatio;  // Ratio of actual air mass flow to rated air mass flow (adjusted for bypass if any)
   10202              :     Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
   10203              :     // (average flow if cycling fan, full flow if constant fan)
   10204              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
   10205              :     Real64 TotCap;                // gross total cooling capacity at off-rated conditions [W]
   10206              :     Real64 TotCapTempModFac;      // Total capacity modifier (function of entering wetbulb, outside drybulb)
   10207              :     Real64 TotCapFlowModFac;      // Total capacity modifier (function of actual supply air flow vs rated flow)
   10208              :     Real64 InletAirWetBulbC;      // wetbulb temperature of inlet air [C]
   10209              :     Real64 InletAirDryBulbTemp;   // inlet air dry bulb temperature [C]
   10210              :     Real64 InletAirEnthalpy;      // inlet air enthalpy [J/kg]
   10211              :     Real64 InletAirHumRat;        // inlet air humidity ratio [kg/kg]
   10212              :     Real64 InletAirHumRatTemp;    // inlet air humidity ratio used in ADP/BF loop [kg/kg]
   10213              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10214              :     // REAL(r64) :: InletAirPressure      ! inlet air pressure [Pa]
   10215              :     Real64 RatedCBF;             // coil bypass factor at rated conditions
   10216              :     Real64 SHR;                  // Sensible Heat Ratio (sensible/total) of the cooling coil
   10217              :     Real64 CBF;                  // coil bypass factor at off rated conditions
   10218              :     Real64 A0;                   // NTU * air mass flow rate, used in CBF calculation
   10219              :     Real64 hDelta;               // Change in air enthalpy across the cooling coil [J/kg]
   10220              :     Real64 hADP;                 // Apparatus dew point enthalpy [J/kg]
   10221              :     Real64 hTinwADP;             // Enthalpy at inlet dry-bulb and wADP [J/kg]
   10222              :     Real64 hTinwout;             // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
   10223              :     Real64 tADP;                 // Apparatus dew point temperature [C]
   10224              :     Real64 wADP;                 // Apparatus dew point humidity ratio [kg/kg]
   10225              :     Real64 FullLoadOutAirEnth;   // outlet full load enthalpy [J/kg]
   10226              :     Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
   10227              :     Real64 FullLoadOutAirTemp;   // outlet air temperature at full load [C]
   10228              :     Real64 PLF;                  // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
   10229              :     Real64 QLatActual;           // operating latent capacity of DX coil
   10230              :     Real64 QLatRated;            // Rated latent capacity of DX coil
   10231              :     Real64 SHRUnadjusted;        // SHR prior to latent degradation effective SHR calculation
   10232              :     int Counter;                 // Counter for dry evaporator iterations
   10233              :     int MaxIter;                 // Maximum number of iterations for dry evaporator calculations
   10234              :     Real64 RF;                   // Relaxation factor for dry evaporator iterations
   10235              :     Real64 Tolerance;            // Error tolerance for dry evaporator iterations
   10236              :     Real64 werror;               // Deviation of humidity ratio in dry evaporator iteration loop
   10237              :     Real64 CondInletTemp;        // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
   10238              :     // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
   10239              :     Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
   10240              :     // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
   10241              :     Real64 CondAirMassFlow;       // Condenser air mass flow rate [kg/s]
   10242              :     Real64 RhoAir;                // Density of air [kg/m3]
   10243              :     Real64 CrankcaseHeatingPower; // power due to crankcase heater
   10244        49499 :     Real64 CompAmbTemp(0.0);      // Ambient temperature at compressor
   10245              :     Real64 AirFlowRatio;          // ratio of compressor on airflow to average timestep airflow
   10246              :     // used when constant fan mode yields different air flow rates when compressor is ON and OFF
   10247              :     // (e.g. Packaged Terminal Heat Pump)
   10248              :     Real64 OutdoorDryBulb;  // Outdoor dry-bulb temperature at condenser (C)
   10249              :     Real64 OutdoorWetBulb;  // Outdoor wet-bulb temperature at condenser (C)
   10250              :     Real64 OutdoorHumRat;   // Outdoor humidity ratio at condenser (kg/kg)
   10251              :     Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
   10252              : 
   10253              :     int Mode;                 // Performance mode for Multimode DX coil; Always 1 for other coil types
   10254              :     Real64 OutletAirTemp;     // Supply air temperature (average value if constant fan, full output if cycling fan)
   10255              :     Real64 OutletAirHumRat;   // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
   10256              :     Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
   10257              :     Real64 ADiff;             // Used for exponential
   10258              : 
   10259              :     // If Performance mode not present, then set to 1.  Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
   10260        49499 :     if (present(PerfMode)) {
   10261            0 :         Mode = PerfMode;
   10262              :     } else {
   10263        49499 :         Mode = 1;
   10264              :     }
   10265              : 
   10266              :     // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
   10267              :     // during cooling and when no cooling is required (constant fan, fan speed changes)
   10268        49499 :     if (present(OnOffAirFlowRatio)) {
   10269        49492 :         AirFlowRatio = OnOffAirFlowRatio;
   10270              :     } else {
   10271            7 :         AirFlowRatio = 1.0;
   10272              :     }
   10273              : 
   10274        49499 :     MaxIter = 30;
   10275        49499 :     RF = 0.4;
   10276        49499 :     Counter = 0;
   10277        49499 :     Tolerance = 0.01;
   10278        49499 :     CondInletTemp = 0.0;
   10279        49499 :     CondInletHumRat = 0.0;
   10280              : 
   10281        49499 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   10282              : 
   10283        49499 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   10284        49499 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   10285        49499 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   10286        49499 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   10287              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10288              :     // InletAirPressure    = DXCoil(DXCoilNum)%InletAirPressure
   10289        49499 :     state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
   10290        49499 :     thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
   10291        49499 :     thisDXCoil.PartLoadRatio = 0.0;
   10292        49499 :     thisDXCoil.BasinHeaterPower = 0.0;
   10293              : 
   10294        49499 :     if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
   10295        49438 :         OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
   10296        49438 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
   10297           32 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10298           32 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10299           32 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10300              :         } else {
   10301        49406 :             OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
   10302              :             // If node is not connected to anything, pressure = default, use weather data
   10303        49406 :             if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   10304           94 :                 OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   10305           94 :                 OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10306           94 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10307           94 :                 OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10308              :             } else {
   10309        49312 :                 OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
   10310              :                 // this should use Node%WetBulbTemp or a PSYC function, not OAWB
   10311        49312 :                 OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
   10312              :             }
   10313              :         }
   10314              :     } else {
   10315           61 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   10316           61 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10317           61 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10318           61 :         OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10319              :     }
   10320              : 
   10321        49499 :     if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   10322            0 :         RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
   10323            0 :         CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
   10324              :         // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   10325            0 :         CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
   10326            0 :         CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
   10327            0 :         CompAmbTemp = OutdoorDryBulb;
   10328              :     } else {                            // for air or water-cooled, inlet temp is stored in OutdoorDryBulb temp
   10329        49499 :         CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
   10330        49499 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
   10331           32 :             CompAmbTemp = state.dataEnvrn->OutDryBulbTemp; // for crankcase heater use actual outdoor temp for water-cooled
   10332              :         } else {
   10333        49467 :             CompAmbTemp = OutdoorDryBulb;
   10334              :         }
   10335              :     }
   10336              : 
   10337              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
   10338              :     // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
   10339        49499 :     if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
   10340           71 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   10341           71 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   10342            0 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
   10343              :         }
   10344              :     } else {
   10345        49428 :         CrankcaseHeatingPower = 0.0;
   10346              :     }
   10347              : 
   10348              :     // calculate end time of current time step to determine if error messages should be printed
   10349        49499 :     state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
   10350              : 
   10351              :     //   Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
   10352              :     //   Wait for next time step to print warnings. If simulation iterates, print out
   10353              :     //   the warning for the last iteration only. Must wait for next time step to accomplish this.
   10354              :     //   If a warning occurs and the simulation down shifts, the warning is not valid.
   10355        49499 :     if (thisDXCoil.PrintLowAmbMessage) { // .AND. &
   10356            0 :         if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
   10357            0 :             if (thisDXCoil.LowAmbErrIndex == 0) {
   10358            0 :                 ShowWarningMessage(state, thisDXCoil.LowAmbBuffer1);
   10359            0 :                 ShowContinueError(state, thisDXCoil.LowAmbBuffer2);
   10360            0 :                 ShowContinueError(state, "... Operation at low inlet temperatures may require special performance curves.");
   10361              :             }
   10362            0 :             ShowRecurringWarningErrorAtEnd(state,
   10363            0 :                                            thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10364              :                                                "\" - Low condenser inlet temperature error continues...",
   10365            0 :                                            thisDXCoil.LowAmbErrIndex,
   10366            0 :                                            thisDXCoil.LowTempLast,
   10367            0 :                                            thisDXCoil.LowTempLast,
   10368              :                                            _,
   10369              :                                            "[C]",
   10370              :                                            "[C]");
   10371              :         }
   10372              :     }
   10373              : 
   10374        49499 :     if (thisDXCoil.PrintHighAmbMessage) { // .AND. &
   10375           60 :         if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
   10376            0 :             if (thisDXCoil.HighAmbErrIndex == 0) {
   10377            0 :                 ShowWarningMessage(state, thisDXCoil.HighAmbBuffer1);
   10378            0 :                 ShowContinueError(state, thisDXCoil.HighAmbBuffer2);
   10379            0 :                 ShowContinueError(state, "... Operation at high inlet temperatures may require special performance curves.");
   10380              :             }
   10381            0 :             ShowRecurringWarningErrorAtEnd(state,
   10382            0 :                                            thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10383              :                                                "\" - High condenser inlet temperature error continues...",
   10384            0 :                                            thisDXCoil.HighAmbErrIndex,
   10385            0 :                                            thisDXCoil.HighTempLast,
   10386            0 :                                            thisDXCoil.HighTempLast,
   10387              :                                            _,
   10388              :                                            "[C]",
   10389              :                                            "[C]");
   10390              :         }
   10391              :     }
   10392              : 
   10393        49499 :     if (thisDXCoil.PrintLowOutTempMessage) {
   10394            0 :         if (state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime > thisDXCoil.CurrentEndTimeLast && TimeStepSys >= thisDXCoil.TimeStepSysLast) {
   10395            0 :             if (thisDXCoil.LowOutletTempIndex == 0) {
   10396            0 :                 ShowWarningMessage(state, thisDXCoil.LowOutTempBuffer1);
   10397            0 :                 ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
   10398            0 :                 ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
   10399            0 :                 ShowContinueError(state,
   10400            0 :                                   format("   1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
   10401            0 :                                          thisDXCoil.FullLoadInletAirTempLast));
   10402            0 :                 ShowContinueError(state, "   2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
   10403            0 :                 ShowContinueError(state,
   10404              :                                   "   3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
   10405              :             }
   10406            0 :             ShowRecurringWarningErrorAtEnd(state,
   10407            0 :                                            thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10408              :                                                "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
   10409              :                                                "Outlet air temperature statistics follow:",
   10410            0 :                                            thisDXCoil.LowOutletTempIndex,
   10411            0 :                                            thisDXCoil.FullLoadOutAirTempLast,
   10412            0 :                                            thisDXCoil.FullLoadOutAirTempLast);
   10413              :         }
   10414              :     }
   10415              : 
   10416              :     // save last system time step and last end time of current time step (used to determine if warning is valid)
   10417        49499 :     thisDXCoil.TimeStepSysLast = TimeStepSys;
   10418        49499 :     thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoilCurrentEndTime;
   10419        49499 :     thisDXCoil.PrintLowAmbMessage = false;
   10420        49499 :     thisDXCoil.PrintLowOutTempMessage = false;
   10421              : 
   10422        49499 :     if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
   10423              :         (compressorOp == HVAC::CompressorOp::On)) { // for cycling fan, reset mass flow to full on rate
   10424        21285 :         if (fanOp == HVAC::FanOp::Cycling) {
   10425           43 :             AirMassFlow /= PartLoadRatio;
   10426        21242 :         } else if (fanOp == HVAC::FanOp::Continuous) {
   10427        21242 :             AirMassFlow *= AirFlowRatio;
   10428              :         } else {
   10429            0 :             AirMassFlow = thisDXCoil.RatedAirMassFlowRate(Mode);
   10430              :         }
   10431              : 
   10432              :         // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton)
   10433              : 
   10434              :         // for some reason there are diff's when using coil inlet air pressure
   10435              :         // these lines (more to follow) are commented out for the time being
   10436              : 
   10437        21285 :         InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   10438        21285 :         AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
   10439        21285 :         VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
   10440              : 
   10441        21285 :         if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
   10442            0 :             ShowFatalError(state, format("{} \"{}\" - Rated total cooling capacity is zero or less.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   10443              :         }
   10444              : 
   10445        23678 :         if (!FirstHVACIteration && !state.dataGlobal->WarmupFlag &&
   10446         2393 :             ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   10447         2393 :              (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]))) {
   10448            0 :             if (thisDXCoil.ErrIndex1 == 0) {
   10449            0 :                 ShowWarningMessage(
   10450              :                     state,
   10451            0 :                     format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at {:.3R} m3/s/W.",
   10452            0 :                            thisDXCoil.DXCoilType,
   10453            0 :                            thisDXCoil.Name,
   10454              :                            VolFlowperRatedTotCap));
   10455            0 :                 ShowContinueErrorTimeStamp(state, "");
   10456            0 :                 ShowContinueError(state,
   10457            0 :                                   format("...Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
   10458            0 :                                          HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   10459            0 :                                          HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
   10460            0 :                 ShowContinueError(state, "...Possible causes include inconsistent air flow rates in system components,");
   10461            0 :                 ShowContinueError(state, "...or mixing manual inputs with autosize inputs. Also check the following values and calculations.");
   10462            0 :                 ShowContinueError(state, "...Volume Flow Rate per Rated Total Capacity = Volume Flow Rate / Rated Total Capacity");
   10463            0 :                 ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
   10464            0 :                 ShowContinueError(state, "...Data used for calculations:");
   10465            0 :                 ShowContinueError(state, format("...Rated Total Capacity = {:.2R} W.", thisDXCoil.RatedTotCap(Mode)));
   10466            0 :                 ShowContinueError(state, "...Volume Flow Rate = Air Mass Flow Rate / Air Density");
   10467            0 :                 ShowContinueError(state, format("...Volume Flow Rate   = {:.8R} m3/s.", AirVolumeFlowRate));
   10468            0 :                 ShowContinueError(state, format("...Air Mass Flow Rate = {:.8R} kg/s.", AirMassFlow));
   10469            0 :                 ShowContinueError(
   10470              :                     state,
   10471            0 :                     format("...Air Density        = {:.8R} kg/m3.", PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat)));
   10472            0 :                 ShowContinueError(state, "...Data used for air density calculation:");
   10473            0 :                 ShowContinueError(state, format("...Outdoor Air Pressure     = {:.3R} Pa.", OutdoorPressure));
   10474            0 :                 ShowContinueError(state, format("...Inlet Air Dry-Bulb Temp  = {:.3R} C.", InletAirDryBulbTemp));
   10475            0 :                 ShowContinueError(state, format("...Inlet Air Humidity Ratio = {:.8R} kgWater/kgDryAir.", InletAirHumRat));
   10476              :             }
   10477            0 :             ShowRecurringWarningErrorAtEnd(
   10478              :                 state,
   10479            0 :                 thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10480              :                     "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
   10481            0 :                 thisDXCoil.ErrIndex1,
   10482              :                 VolFlowperRatedTotCap,
   10483              :                 VolFlowperRatedTotCap);
   10484              :         }
   10485              :         //    Adjust coil bypass factor for actual air flow rate. Use relation CBF = exp(-NTU) where
   10486              :         //    NTU = A0/(m*cp). Relationship models the cooling coil as a heat exchanger with Cmin/Cmax = 0.
   10487              : 
   10488        21285 :         RatedCBF = thisDXCoil.RatedCBF(Mode);
   10489        21285 :         if (RatedCBF > 0.0) {
   10490        21285 :             A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
   10491              :         } else {
   10492            0 :             A0 = 0.0;
   10493              :         }
   10494        21285 :         ADiff = -A0 / AirMassFlow;
   10495        21285 :         if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
   10496        21285 :             CBF = std::exp(ADiff);
   10497              :         } else {
   10498            0 :             CBF = 0.0;
   10499              :         }
   10500              : 
   10501              :         // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
   10502        21285 :         if (OutdoorDryBulb < thisDXCoil.MinOATCompressor && !state.dataGlobal->WarmupFlag) {
   10503            0 :             thisDXCoil.PrintLowAmbMessage = true;
   10504            0 :             thisDXCoil.LowTempLast = OutdoorDryBulb;
   10505            0 :             if (thisDXCoil.LowAmbErrIndex == 0) {
   10506            0 :                 thisDXCoil.LowAmbBuffer1 = format("{} \"{}\" - Condenser inlet temperature below {:.2R} C. Condenser inlet temperature = {:.2R}",
   10507            0 :                                                   thisDXCoil.DXCoilType,
   10508            0 :                                                   thisDXCoil.Name,
   10509            0 :                                                   thisDXCoil.MinOATCompressor,
   10510            0 :                                                   OutdoorDryBulb);
   10511            0 :                 thisDXCoil.LowAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
   10512            0 :                                            CreateSysTimeIntervalString(state);
   10513              :             }
   10514              :         }
   10515              : 
   10516              :         // check boundary for high ambient temperature and post warnings to individual DX coil buffers to print at end of time step
   10517        21285 :         if (OutdoorDryBulb > thisDXCoil.MaxOATCompressor && !state.dataGlobal->WarmupFlag) {
   10518           27 :             thisDXCoil.PrintHighAmbMessage = true;
   10519           27 :             thisDXCoil.HighTempLast = OutdoorDryBulb;
   10520           27 :             if (thisDXCoil.HighAmbErrIndex == 0) {
   10521           54 :                 thisDXCoil.HighAmbBuffer1 = format("{} \"{}\" - Condenser inlet temperature above {:.2R} C. Condenser temperature = {:.2R}",
   10522           27 :                                                    thisDXCoil.DXCoilType,
   10523           27 :                                                    thisDXCoil.Name,
   10524           27 :                                                    thisDXCoil.MaxOATCompressor,
   10525           27 :                                                    OutdoorDryBulb);
   10526           54 :                 thisDXCoil.HighAmbBuffer2 = " ... Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
   10527           81 :                                             CreateSysTimeIntervalString(state);
   10528              :             }
   10529              :         }
   10530              : 
   10531              :         //  Get total capacity modifying factor (function of temperature) for off-rated conditions
   10532              :         //  InletAirHumRat may be modified in this ADP/BF loop, use temporary variable for calculations
   10533        21285 :         InletAirHumRatTemp = InletAirHumRat;
   10534              : 
   10535        21285 :     Label50:;
   10536        21285 :         switch (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims) {
   10537        21285 :         case 1:
   10538        21285 :             TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC);
   10539        21285 :             break;
   10540            0 :         case 2:
   10541              :         default: // this default allows the simulation to continue, but will issue a warning, should be removed eventually
   10542            0 :             TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirWetBulbC, CondInletTemp);
   10543            0 :             break;
   10544              :         }
   10545              : 
   10546              :         //  Warn user if curve output goes negative
   10547        21285 :         if (TotCapTempModFac < 0.0) {
   10548            0 :             if (thisDXCoil.CCapFTempErrorIndex == 0) {
   10549            0 :                 ShowWarningMessage(state, format("{} \"{}\":", thisDXCoil.DXCoilType, thisDXCoil.Name));
   10550            0 :                 ShowContinueError(
   10551            0 :                     state, format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
   10552            0 :                 ShowContinueError(
   10553              :                     state,
   10554            0 :                     format(" Negative value occurs using a condenser inlet temperature of {:.1T} and an inlet air wet-bulb temperature of {:.1T}.",
   10555              :                            CondInletTemp,
   10556              :                            InletAirWetBulbC));
   10557            0 :                 if (Mode > 1) {
   10558            0 :                     ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
   10559              :                 }
   10560            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
   10561              :             }
   10562            0 :             ShowRecurringWarningErrorAtEnd(
   10563              :                 state,
   10564            0 :                 thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10565              :                     "\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
   10566            0 :                 thisDXCoil.CCapFTempErrorIndex,
   10567              :                 TotCapTempModFac,
   10568              :                 TotCapTempModFac);
   10569            0 :             TotCapTempModFac = 0.0;
   10570              :         }
   10571              : 
   10572              :         //  Get total capacity modifying factor (function of mass flow) for off-rated conditions
   10573        21285 :         AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
   10574        21285 :         TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
   10575              : 
   10576              :         //  Warn user if curve output goes negative
   10577        21285 :         if (TotCapFlowModFac < 0.0) {
   10578            0 :             if (thisDXCoil.CCapFFlowErrorIndex == 0) {
   10579            0 :                 ShowWarningMessage(state, format("{} \"{}\":", thisDXCoil.DXCoilType, thisDXCoil.Name));
   10580            0 :                 ShowContinueError(
   10581              :                     state,
   10582            0 :                     format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).", TotCapFlowModFac));
   10583            0 :                 ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
   10584            0 :                 ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
   10585            0 :                 if (Mode > 1) {
   10586            0 :                     ShowContinueError(state, format(" Negative output results from stage {} compressor operation.", Mode));
   10587              :                 }
   10588              :             }
   10589            0 :             ShowRecurringWarningErrorAtEnd(
   10590              :                 state,
   10591            0 :                 thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   10592              :                     "\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
   10593            0 :                 thisDXCoil.CCapFFlowErrorIndex,
   10594              :                 TotCapFlowModFac,
   10595              :                 TotCapFlowModFac);
   10596            0 :             TotCapFlowModFac = 0.0;
   10597              :         }
   10598              : 
   10599        21285 :         if (present(MaxCoolCap)) {
   10600        21278 :             TotCap = min(MaxCoolCap, thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac);
   10601              :         } else {
   10602            7 :             TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
   10603              :         }
   10604              : 
   10605        21285 :         TotCap *= PartLoadRatio;
   10606              : 
   10607              :         // Calculate apparatus dew point conditions using TotCap and CBF
   10608        21285 :         hDelta = TotCap / AirMassFlow;
   10609              :         // there is an issue here with using CBF to calculate the ADP enthalpy.
   10610              :         // at low loads the bypass factor increases significantly.
   10611        21285 :         hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
   10612        21285 :         tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
   10613              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10614              :         //  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   10615        21285 :         wADP = min(InletAirHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
   10616        21285 :         hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   10617        21285 :         if ((InletAirEnthalpy - hADP) > 1.e-10) {
   10618        18971 :             SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   10619              :         } else {
   10620         2314 :             SHR = 1.0;
   10621              :         }
   10622              :         // Check for dry evaporator conditions (win < wadp)
   10623        21285 :         if (wADP > InletAirHumRatTemp || (Counter >= 1 && Counter < MaxIter)) {
   10624            0 :             if (InletAirHumRatTemp == 0.0) {
   10625            0 :                 InletAirHumRatTemp = 0.00001;
   10626              :             }
   10627            0 :             werror = (InletAirHumRatTemp - wADP) / InletAirHumRatTemp;
   10628              :             // Increase InletAirHumRatTemp at constant InletAirTemp to find coil dry-out point. Then use the
   10629              :             // capacity at the dry-out point to determine exiting conditions from coil. This is required
   10630              :             // since the TotCapTempModFac doesn't work properly with dry-coil conditions.
   10631            0 :             InletAirHumRatTemp = RF * wADP + (1.0 - RF) * InletAirHumRatTemp;
   10632            0 :             InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRatTemp, OutdoorPressure);
   10633              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10634              :             //     InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRatTemp,InletAirPressure)
   10635            0 :             ++Counter;
   10636            0 :             if (std::abs(werror) > Tolerance) {
   10637            0 :                 goto Label50; // Recalculate with modified inlet conditions
   10638              :             }
   10639              :         }
   10640              : 
   10641        21285 :         if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
   10642           26 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
   10643              :         } else {
   10644        21259 :             PLF = 1.0;
   10645              :         }
   10646              : 
   10647        21285 :         if (PLF < 0.7) {
   10648            0 :             if (thisDXCoil.ErrIndex2 == 0) {
   10649            0 :                 ShowWarningMessage(
   10650              :                     state,
   10651            0 :                     format(
   10652            0 :                         "The PLF curve value for the DX cooling coil {} ={:.3R} for part-load ratio ={:.3R}", thisDXCoil.Name, PLF, PartLoadRatio));
   10653            0 :                 ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   10654            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
   10655              :             }
   10656            0 :             ShowRecurringWarningErrorAtEnd(
   10657            0 :                 state, thisDXCoil.Name + ", DX cooling coil PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
   10658            0 :             PLF = 0.7;
   10659              :         }
   10660              : 
   10661        21285 :         thisDXCoil.PartLoadRatio = PartLoadRatio;
   10662        21285 :         thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
   10663        21285 :         if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
   10664            0 :             if (thisDXCoil.ErrIndex3 == 0) {
   10665            0 :                 ShowWarningMessage(state,
   10666            0 :                                    format("The runtime fraction for DX cooling coil {} exceeded 1.0. [{:.4R}].",
   10667            0 :                                           thisDXCoil.Name,
   10668            0 :                                           thisDXCoil.CoolingCoilRuntimeFraction));
   10669            0 :                 ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
   10670            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
   10671            0 :                 ShowContinueErrorTimeStamp(state, "");
   10672              :             }
   10673            0 :             ShowRecurringWarningErrorAtEnd(state,
   10674            0 :                                            thisDXCoil.Name + ", DX cooling coil runtime fraction > 1.0 warning continues...",
   10675            0 :                                            thisDXCoil.ErrIndex3,
   10676            0 :                                            thisDXCoil.CoolingCoilRuntimeFraction,
   10677            0 :                                            thisDXCoil.CoolingCoilRuntimeFraction);
   10678            0 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   10679        21285 :         } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
   10680            0 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   10681              :         }
   10682              : 
   10683              :         // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
   10684        21285 :         if (fanOp == HVAC::FanOp::Cycling) {
   10685           43 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
   10686              :         }
   10687              : 
   10688              :         //  Calculate full load output conditions
   10689              :         //            if ( SHR > 1.0 || Counter > 0 ) SHR = 1.0;
   10690        21285 :         if (SHR > 1.0) {
   10691            0 :             SHR = 1.0;
   10692              :         }
   10693        21285 :         FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
   10694        21285 :         hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   10695        21285 :         if (SHR < 1.0) {
   10696        12378 :             FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   10697              :         } else {
   10698         8907 :             FullLoadOutAirHumRat = InletAirHumRat;
   10699              :         }
   10700        21285 :         FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   10701              : 
   10702              :         // Check for saturation error and modify temperature at constant enthalpy
   10703        21285 :         if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure)) {
   10704            0 :             FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
   10705              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10706              :             //   IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
   10707              :             //    FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
   10708            0 :             FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
   10709              :         }
   10710              : 
   10711              :         // Store actual outlet conditions when DX coil is ON for use in heat recovery module
   10712        21285 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = FullLoadOutAirTemp;
   10713        21285 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = FullLoadOutAirHumRat;
   10714              : 
   10715              :         // Add warning message for cold cooling coil (FullLoadOutAirTemp < 2 C)
   10716        21285 :         if (FullLoadOutAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
   10717            0 :             thisDXCoil.PrintLowOutTempMessage = true;
   10718            0 :             thisDXCoil.FullLoadOutAirTempLast = FullLoadOutAirTemp;
   10719            0 :             if (thisDXCoil.LowOutletTempIndex == 0) {
   10720            0 :                 thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
   10721            0 :                 thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
   10722              :                                                       "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
   10723            0 :                                                       thisDXCoil.DXCoilType,
   10724            0 :                                                       thisDXCoil.Name,
   10725            0 :                                                       FullLoadOutAirTemp);
   10726            0 :                 thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + ' ' +
   10727            0 :                                                CreateSysTimeIntervalString(state);
   10728              :             }
   10729              :         }
   10730              : 
   10731              :         //  If constant fan with cycling compressor, call function to determine "effective SHR"
   10732              :         //  which includes the part-load degradation on latent capacity
   10733        21285 :         if (fanOp == HVAC::FanOp::Continuous && CompCycRatio < 1.0) {
   10734         3662 :             QLatRated = thisDXCoil.RatedTotCap(Mode) * (1.0 - thisDXCoil.RatedSHR(Mode)); // always the same number
   10735         3662 :             QLatActual = TotCap * (1.0 - SHR);
   10736         3662 :             SHRUnadjusted = SHR;
   10737         3662 :             SHR = CalcEffectiveSHR(
   10738              :                 state, DXCoilNum, SHR, thisDXCoil.CoolingCoilRuntimeFraction, QLatRated, QLatActual, InletAirDryBulbTemp, InletAirWetBulbC, Mode);
   10739              : 
   10740              :             //  Calculate full load output conditions
   10741              :             //                if ( SHR > 1.0 || Counter > 0 ) SHR = 1.0;
   10742         3662 :             if (SHR > 1.0) {
   10743            0 :                 SHR = 1.0;
   10744              :             }
   10745         3662 :             FullLoadOutAirEnth = InletAirEnthalpy - TotCap / AirMassFlow;
   10746         3662 :             hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   10747         3662 :             if (SHR < 1.0) {
   10748         3180 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   10749              :             } else {
   10750          482 :                 FullLoadOutAirHumRat = InletAirHumRat;
   10751              :             }
   10752         3662 :             FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   10753              :         }
   10754              : 
   10755              :         //  Calculate actual outlet conditions for the input part load ratio
   10756              :         //  Actual outlet conditions are "average" for time step when compressor cycles
   10757              : 
   10758        21285 :         if (fanOp == HVAC::FanOp::Continuous && CompCycRatio < 1.0) {
   10759              :             // Continuous fan, cycling compressor
   10760              :             // hmmm ... this seems wrong. PLR * AirFlowRatio = 1. So we get FullLoadOutAirEnth all this time. This is OK since above TotCap *=
   10761              :             // PLR.
   10762         3662 :             OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
   10763         3662 :             OutletAirHumRat = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirHumRat + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirHumRat);
   10764         3662 :             OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   10765              :         } else {
   10766              :             // Default to cycling fan, cycling compressor
   10767        17623 :             OutletAirEnthalpy = FullLoadOutAirEnth;
   10768        17623 :             OutletAirHumRat = FullLoadOutAirHumRat;
   10769        17623 :             OutletAirTemp = FullLoadOutAirTemp;
   10770              :         }
   10771              : 
   10772              :         // Check for saturation error and modify temperature at constant enthalpy
   10773        21285 :         if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, RoutineName)) {
   10774          436 :             OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
   10775              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10776              :             //   IF(OutletAirTemp .LT. PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)) THEN
   10777              :             //    OutletAirTemp = PsyTsatFnHPb(OutletAirEnthalpy,InletAirPressure)
   10778          436 :             OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
   10779              :         }
   10780              : 
   10781              :         // Reset AirMassFlow to inlet node air mass flow for final total, sensible and latent calculations
   10782              :         // since AirMassFlow might have been modified above (in this subroutine):
   10783              :         //     IF (FanOpMode .EQ. FanOp::Cycling) AirMassFlow = AirMassFlow / PartLoadRatio
   10784              :         // For multimode coil, this should be full flow including bypassed fraction
   10785        21285 :         AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   10786              : 
   10787              :         // Coil total/sensible/latent cooling rates
   10788        21285 :         CalcComponentSensibleLatentOutput(AirMassFlow,
   10789              :                                           InletAirDryBulbTemp,
   10790              :                                           InletAirHumRat,
   10791              :                                           OutletAirTemp,
   10792              :                                           OutletAirHumRat,
   10793        21285 :                                           thisDXCoil.SensCoolingEnergyRate,
   10794        21285 :                                           thisDXCoil.LatCoolingEnergyRate,
   10795        21285 :                                           thisDXCoil.TotalCoolingEnergyRate);
   10796              : 
   10797        21285 :         thisDXCoil.OutletAirTemp = OutletAirTemp;
   10798        21285 :         thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   10799        21285 :         thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   10800              : 
   10801              :     } else {
   10802              : 
   10803              :         // DX coil is off; just pass through conditions
   10804        28214 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   10805        28214 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   10806        28214 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   10807              : 
   10808        28214 :         thisDXCoil.ElecCoolingPower = 0.0;
   10809        28214 :         thisDXCoil.TotalCoolingEnergyRate = 0.0;
   10810        28214 :         thisDXCoil.SensCoolingEnergyRate = 0.0;
   10811        28214 :         thisDXCoil.LatCoolingEnergyRate = 0.0;
   10812        28214 :         thisDXCoil.EvapCondPumpElecPower = 0.0;
   10813        28214 :         thisDXCoil.EvapWaterConsumpRate = 0.0;
   10814              : 
   10815              :         // Reset globals when DX coil is OFF for use in heat recovery module
   10816        28214 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
   10817        28214 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
   10818              : 
   10819              :     } // end of on/off if - else
   10820              : 
   10821              :     // set water system demand request (if needed)
   10822        49499 :     if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
   10823            0 :         state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
   10824            0 :             thisDXCoil.EvapWaterConsumpRate;
   10825              :     }
   10826              : 
   10827        49499 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   10828        49499 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   10829        49499 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
   10830        49499 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   10831        49499 :     thisDXCoil.CondInletTemp = CondInletTemp;
   10832        49499 :     state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
   10833        49499 :     state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   10834              : 
   10835              :     // set outlet node conditions
   10836        49499 :     int airOutletNode = thisDXCoil.AirOutNode;
   10837        49499 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   10838        49499 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   10839        49499 : }
   10840              : 
   10841       177475 : void CalcDXHeatingCoil(EnergyPlusData &state,
   10842              :                        int const DXCoilNum,                                 // the number of the DX heating coil to be simulated
   10843              :                        Real64 const PartLoadRatio,                          // sensible cooling load / full load sensible cooling capacity
   10844              :                        HVAC::FanOp const fanOp,                             // Allows parent object to control fan mode
   10845              :                        ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
   10846              :                        ObjexxFCL::Optional<Real64 const> MaxHeatCap         // maximum allowed heating capacity
   10847              : )
   10848              : {
   10849              : 
   10850              :     // SUBROUTINE INFORMATION:
   10851              :     //       AUTHOR         Richard Raustad
   10852              :     //       DATE WRITTEN   October 2001
   10853              :     //       MODIFIED       Raustad/Shirey Mar 2004
   10854              :     //                      Kenneth Tang 2004 (Sensitivity of TotCapTempModFac & EIRTempModFac  to indoor dry bulb temp)
   10855              :     //                      Feb 2005 M. J. Witte, GARD Analytics, Inc.
   10856              :     //                        Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
   10857              : 
   10858              :     // PURPOSE OF THIS SUBROUTINE:
   10859              :     // Calculates the air-side heating performance and electrical heating energy
   10860              :     // use of a direct-expansion, air-cooled heat pump unit.
   10861              : 
   10862              :     // METHODOLOGY EMPLOYED:
   10863              :     // This routine simulates the performance of air-cooled DX heating equipment.
   10864              :     // The routine requires the user to enter the total heating capacity
   10865              :     // and COP for the unit at ARI 210/240 rating conditions (21.11C [70F] dry-bulb,
   10866              :     // 15.55C [60F] wet-bulb air entering the heating coil, 8.33C [47F] dry-bulb,
   10867              :     // 6.11C [43F] wet-bulb air entering the outdoor condenser. Since different
   10868              :     // manufacturer's rate their equipment at different air flow rates, the supply
   10869              :     // air flow rate corresponding to the rated capacities and rated COP must also
   10870              :     // be entered (should be between 300 cfm/ton and 450 cfm/ton). The rated information
   10871              :     // entered by the user should NOT include the thermal or electrical impacts of the
   10872              :     // supply air fan, as this is addressed by another module.
   10873              : 
   10874              :     // With the rated performance data entered by the user, the model employs some of the
   10875              :     // DOE-2.1E curve fits to adjust the capacity and efficiency of the unit as a function
   10876              :     // of outdoor air temperatures and supply air flow rate (actual vs rated flow). The
   10877              :     // model does NOT employ the exact same methodology to calculate performance as DOE-2,
   10878              :     // although some of the DOE-2 curve fits are employed by this model.
   10879              : 
   10880              :     // REFERENCES:
   10881              :     // Winkelmann, F.C., Birdsall, B.E., Buhl W.F., Ellington, K.L., Erdem, A.E. 1993.
   10882              :     // DOE-2 Supplement Version 2.1E.  Energy and Environment Division, Lawrence Berkeley
   10883              :     // Laboratory.
   10884              :     // Henderson, H.I. Jr., Y.J. Huang and Danny Parker. 1999. Residential Equipment Part
   10885              :     // Load Curves for Use in DOE-2.  Environmental Energy Technologies Division, Ernest
   10886              :     // Orlando Lawrence Berkeley National Laboratory.
   10887              : 
   10888              :     // Using/Aliasing
   10889              :     using Curve::CurveValue;
   10890              : 
   10891              :     // SUBROUTINE PARAMETER DEFINITIONS:
   10892              :     static constexpr std::string_view RoutineNameFullLoad("CalcDXHeatingCoil:fullload");
   10893              : 
   10894              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   10895              :     Real64 AirMassFlow;           // dry air mass flow rate through coil [kg/s]
   10896              :     Real64 AirMassFlowRatio;      // Ratio of actual air mass flow to rated air mass flow
   10897              :     Real64 AirVolumeFlowRate;     // Air volume flow rate across the cooling coil [m3/s]
   10898              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W]
   10899              :     Real64 TotCap;                // gross total cooling capacity at off-rated conditions [W]
   10900              :     Real64 TotCapAdj;             // adjusted total cooling capacity at off-rated conditions [W]
   10901              :     Real64 TotCapTempModFac;      // Total capacity modifier (function of entering drybulb, outside drybulb) depending
   10902              :     // on the type of curve
   10903              :     Real64 TotCapFlowModFac;    // Total capacity modifier (function of actual supply air flow vs rated flow)
   10904              :     Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
   10905              :     Real64 InletAirWetBulbC;    // wetbulb temperature of inlet air [C]
   10906              :     Real64 InletAirEnthalpy;    // inlet air enthalpy [J/kg]
   10907              :     Real64 InletAirHumRat;      // inlet air humidity ratio [kg/kg]
   10908              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10909              :     // REAL(r64)     :: InletAirPressure            ! inlet air pressure [Pa]
   10910              :     Real64 FullLoadOutAirEnth;   // outlet full load enthalpy [J/kg]
   10911              :     Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
   10912              :     Real64 FullLoadOutAirTemp;   // outlet air temperature at full load [C]
   10913              :     Real64 FullLoadOutAirRH;     // outlet air relative humidity at full load
   10914       177475 :     Real64 EIRTempModFac(0.0);   // EIR modifier (function of entering drybulb, outside drybulb) depending on the
   10915              :     // type of curve
   10916              :     Real64 DefrostEIRTempModFac;      // EIR modifier for defrost (function of entering wetbulb, outside drybulb)
   10917              :     Real64 EIRFlowModFac;             // EIR modifier (function of actual supply air flow vs rated flow)
   10918              :     Real64 EIR;                       // EIR at part load and off rated conditions
   10919              :     Real64 PLF;                       // Part load factor, accounts for thermal lag at compressor startup
   10920              :     Real64 PLRHeating;                // PartLoadRatio in heating
   10921              :     Real64 OutdoorCoilT;              // Outdoor coil temperature (C)
   10922              :     Real64 OutdoorCoildw;             // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
   10923              :     Real64 FractionalDefrostTime;     // Fraction of time step system is in defrost
   10924              :     Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
   10925              :     Real64 InputPowerMultiplier;      // Multiplier for power when system is in defrost
   10926              :     Real64 LoadDueToDefrost;          // Additional load due to defrost
   10927              :     Real64 CrankcaseHeatingPower;     // power due to crankcase heater
   10928              :     Real64 OutdoorDryBulb;            // Outdoor dry-bulb temperature at condenser (C)
   10929              :     Real64 OutdoorWetBulb;            // Outdoor wet-bulb temperature at condenser (C)
   10930              :     Real64 OutdoorHumRat;             // Outdoor humidity ratio at condenser (kg/kg)
   10931              :     Real64 OutdoorPressure;           // Outdoor barometric pressure at condenser (Pa)
   10932       177475 :     constexpr int Mode(1);            // Performance mode for MultiMode DX coil; Always 1 for other coil types
   10933              :     Real64 AirFlowRatio;              // Ratio of compressor on airflow to average timestep airflow
   10934              :     Real64 OutletAirTemp;             // Supply air temperature (average value if constant fan, full output if cycling fan)
   10935              :     Real64 OutletAirHumRat;           // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
   10936              :     Real64 OutletAirEnthalpy;         // Supply air enthalpy (average value if constant fan, full output if cycling fan)
   10937       177475 :     Real64 CompAmbTemp(0.0);          // Ambient temperature at compressor
   10938              : 
   10939       177475 :     if (present(OnOffAirFlowRatio)) {
   10940       177462 :         AirFlowRatio = OnOffAirFlowRatio;
   10941              :     } else {
   10942           13 :         AirFlowRatio = 1.0;
   10943              :     }
   10944              : 
   10945       177475 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   10946              :     // Get condenser outdoor node info from DX Heating Coil
   10947       177475 :     if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
   10948        49438 :         OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
   10949        49438 :         CompAmbTemp = OutdoorDryBulb;
   10950        49438 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
   10951           32 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10952           32 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10953           32 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10954           32 :             CompAmbTemp = state.dataEnvrn->OutDryBulbTemp;
   10955              :         } else {
   10956        49406 :             OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
   10957              :             // If node is not connected to anything, pressure = default, use weather data
   10958        49406 :             if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   10959           94 :                 OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   10960           94 :                 OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10961           94 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10962           94 :                 OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10963              :             } else {
   10964        49312 :                 OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
   10965              :                 // this should use Node%WetBulbTemp or a PSYC function, not OAWB
   10966        49312 :                 OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).OutAirWetBulb;
   10967              :             }
   10968        49406 :             if (thisDXCoil.IsSecondaryDXCoilInZone) {
   10969            0 :                 auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   10970            0 :                 OutdoorDryBulb = secZoneHB.ZT;
   10971            0 :                 OutdoorHumRat = secZoneHB.airHumRat;
   10972            0 :                 OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   10973            0 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10974            0 :                 CompAmbTemp = OutdoorDryBulb;
   10975              :             }
   10976              :         }
   10977       128037 :     } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
   10978            0 :         auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   10979            0 :         OutdoorDryBulb = secZoneHB.ZT;
   10980            0 :         OutdoorHumRat = secZoneHB.airHumRat;
   10981            0 :         OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   10982            0 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10983            0 :         CompAmbTemp = OutdoorDryBulb;
   10984              :     } else {
   10985       128037 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   10986       128037 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   10987       128037 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   10988       128037 :         OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   10989       128037 :         CompAmbTemp = OutdoorDryBulb;
   10990              :     }
   10991              : 
   10992       177475 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   10993       177475 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   10994       177475 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   10995       177475 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   10996              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   10997              :     // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
   10998              :     // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
   10999       177475 :     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   11000       177475 :     PLRHeating = 0.0;
   11001       177475 :     thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
   11002              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
   11003       177475 :     if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
   11004        40005 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   11005        40005 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   11006            2 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
   11007              :         }
   11008              :     } else {
   11009       137470 :         CrankcaseHeatingPower = 0.0;
   11010              :     }
   11011              : 
   11012       220922 :     if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
   11013        43447 :         OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
   11014              :         // for cycling fan, reset mass flow to full on rate
   11015        14022 :         if (fanOp == HVAC::FanOp::Cycling) {
   11016           32 :             AirMassFlow /= PartLoadRatio;
   11017              :         }
   11018        14022 :         if (fanOp == HVAC::FanOp::Continuous) {
   11019        13990 :             AirMassFlow *= AirFlowRatio;
   11020              :         }
   11021              :         // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
   11022        14022 :         AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
   11023              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11024              :         //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   11025        14022 :         VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
   11026              : 
   11027        28044 :         if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   11028        14022 :             (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
   11029            1 :             if (thisDXCoil.ErrIndex1 == 0) {
   11030            2 :                 ShowWarningMessage(
   11031              :                     state,
   11032            2 :                     format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at {:.3R} m3/s/W.",
   11033            1 :                            thisDXCoil.DXCoilType,
   11034            1 :                            thisDXCoil.Name,
   11035              :                            VolFlowperRatedTotCap));
   11036            2 :                 ShowContinueErrorTimeStamp(state, "");
   11037            2 :                 ShowContinueError(state,
   11038            2 :                                   format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}]",
   11039            1 :                                          HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   11040            1 :                                          HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]));
   11041            2 :                 ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   11042            3 :                 ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   11043              :             }
   11044            8 :             ShowRecurringWarningErrorAtEnd(
   11045              :                 state,
   11046            2 :                 thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   11047              :                     "\" - Air volume flow rate per watt of rated total heating capacity is out of range error continues...",
   11048            1 :                 thisDXCoil.ErrIndex1,
   11049              :                 VolFlowperRatedTotCap,
   11050              :                 VolFlowperRatedTotCap);
   11051              :         }
   11052              : 
   11053              :         // Get total capacity modifying factor (function of temperature) for off-rated conditions
   11054              :         // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
   11055              :         // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   11056              :         // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   11057        14022 :         if (state.dataCurveManager->curves(thisDXCoil.CCapFTemp(Mode))->numDims == 2) {
   11058           15 :             switch (thisDXCoil.HeatingPerformanceOATType) {
   11059           15 :             case HVAC::OATType::DryBulb: {
   11060           15 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
   11061           15 :             } break;
   11062            0 :             case HVAC::OATType::WetBulb: {
   11063            0 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp, OutdoorWetBulb);
   11064            0 :             } break;
   11065            0 :             default: {
   11066            0 :                 TotCapTempModFac = 1.0;
   11067            0 :             } break;
   11068              :             }
   11069              :         } else {
   11070        14007 :             switch (thisDXCoil.HeatingPerformanceOATType) {
   11071           14 :             case HVAC::OATType::DryBulb: {
   11072           14 :                 if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
   11073            3 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), OutdoorDryBulb);
   11074              :                 } else {
   11075           11 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
   11076              :                 }
   11077           14 :             } break;
   11078        13993 :             case HVAC::OATType::WetBulb: {
   11079        13993 :                 if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
   11080            0 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), OutdoorWetBulb);
   11081              :                 } else {
   11082        13993 :                     TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(Mode), InletAirDryBulbTemp);
   11083              :                 }
   11084        13993 :             } break;
   11085            0 :             default: {
   11086            0 :                 TotCapTempModFac = 1.0;
   11087            0 :             } break;
   11088              :             }
   11089              :         }
   11090              : 
   11091        14022 :         if (TotCapTempModFac < 0.0) {
   11092            0 :             if (thisDXCoil.CAPFTErrIndex == 0) {
   11093            0 :                 ShowWarningMessage(state,
   11094            0 :                                    format("The TotCapTempModFac curve value for DX heating coil {} ={:.2R}", thisDXCoil.Name, TotCapTempModFac));
   11095            0 :                 ShowContinueError(state,
   11096              :                                   "TotCapTempModFac curve value must be > 0. TotCapTempModFac curve value has been reset to 0.0 and "
   11097              :                                   "simulation is continuing.");
   11098            0 :                 ShowContinueError(state, format("Check the IO reference manual for TotCapTempModFac curve guidance [ {} ].", thisDXCoil.DXCoilType));
   11099            0 :                 ShowContinueErrorTimeStamp(state, "");
   11100              :             }
   11101            0 :             ShowRecurringWarningErrorAtEnd(state,
   11102              :                                            "DX heating coil TotCapTempModFac curve value < 0 warning continues... ",
   11103            0 :                                            thisDXCoil.CAPFTErrIndex,
   11104              :                                            TotCapTempModFac,
   11105              :                                            TotCapTempModFac);
   11106            0 :             TotCapTempModFac = 0.0;
   11107              :         }
   11108              : 
   11109              :         //  Get total capacity modifying factor (function of mass flow) for off-rated conditions
   11110        14022 :         AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
   11111        14022 :         TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(Mode), AirMassFlowRatio);
   11112              : 
   11113              :         // Calculate total heating capacity for off-rated conditions
   11114        14022 :         TotCap = thisDXCoil.RatedTotCap(Mode) * TotCapFlowModFac * TotCapTempModFac;
   11115              : 
   11116              :         // Calculating adjustment factors for defrost
   11117              :         // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
   11118        14022 :         OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
   11119        14022 :         OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
   11120              : 
   11121              :         // Initializing defrost adjustment factors
   11122        14022 :         LoadDueToDefrost = 0.0;
   11123        14022 :         HeatingCapacityMultiplier = 1.0;
   11124        14022 :         FractionalDefrostTime = 0.0;
   11125        14022 :         InputPowerMultiplier = 1.0;
   11126              : 
   11127              :         // Check outdoor temperature to determine of defrost is active
   11128        14022 :         if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost && thisDXCoil.CondenserType(Mode) != DataHeatBalance::RefrigCondenserType::Water) {
   11129              :             // Calculate defrost adjustment factors depending on defrost control type
   11130           37 :             if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
   11131           37 :                 FractionalDefrostTime = thisDXCoil.DefrostTime;
   11132           37 :                 if (FractionalDefrostTime > 0.0) {
   11133           37 :                     if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   11134            1 :                         HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   11135            1 :                         InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   11136              :                     } else {
   11137           36 :                         HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
   11138           36 :                         InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
   11139           36 :                         if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   11140            0 :                             ShowWarningMessage(state,
   11141            0 :                                                format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   11142              :                                                       "actuator must be both provided for DX heating coil {}",
   11143            0 :                                                       thisDXCoil.Name));
   11144            0 :                             ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   11145              :                         }
   11146              :                     }
   11147              :                 }
   11148              :             } else { // else defrost control is on-demand
   11149            0 :                 FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
   11150            0 :                 if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   11151            0 :                     HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   11152            0 :                     InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   11153              :                 } else {
   11154            0 :                     HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
   11155            0 :                     InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
   11156            0 :                     if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   11157            0 :                         ShowWarningMessage(state,
   11158            0 :                                            format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   11159              :                                                   "actuator must be both provided for DX heating coil {}",
   11160            0 :                                                   thisDXCoil.Name));
   11161            0 :                         ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   11162              :                     }
   11163              :                 }
   11164              :             }
   11165              : 
   11166           37 :             if (FractionalDefrostTime > 0.0) {
   11167              :                 // Calculate defrost adjustment factors depending on defrost control strategy
   11168           37 :                 if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
   11169           32 :                     LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.RatedTotCap(Mode) / 1.01667);
   11170           32 :                     DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
   11171           32 :                     thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.RatedTotCap(Mode) / 1.01667) * FractionalDefrostTime;
   11172              :                 } else { // Defrost strategy is resistive
   11173            5 :                     thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
   11174              :                 }
   11175              :             } else { // Defrost is not active because (FractionalDefrostTime .EQ. 0.0)
   11176            0 :                 thisDXCoil.DefrostPower = 0.0;
   11177              :             }
   11178              :         }
   11179              : 
   11180              :         // Modify total heating capacity based on defrost heating capacity multiplier
   11181              :         // MaxHeatCap passed from parent object VRF Condenser and is used to limit capacity of TU's to that available from condenser
   11182        14022 :         if (present(MaxHeatCap)) {
   11183        13997 :             TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
   11184        13997 :             TotCap = min(MaxHeatCap, TotCap);
   11185              :         } else {
   11186           25 :             TotCapAdj = TotCap * HeatingCapacityMultiplier;
   11187              :         }
   11188              : 
   11189              :         // Calculate full load outlet conditions
   11190        14022 :         FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
   11191        14022 :         FullLoadOutAirHumRat = InletAirHumRat;
   11192        14022 :         FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   11193        14022 :         FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
   11194              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11195              :         //  FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
   11196        14022 :         if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
   11197            0 :             FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
   11198              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11199              :             //    FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
   11200            0 :             FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
   11201              :         }
   11202              : 
   11203              :         // Calculate actual outlet conditions for the input part load ratio
   11204              :         // Actual outlet conditions are "average" for time step
   11205        14022 :         if (fanOp == HVAC::FanOp::Continuous) {
   11206              :             // continuous fan, cycling compressor
   11207        13990 :             OutletAirEnthalpy = ((PartLoadRatio * AirFlowRatio) * FullLoadOutAirEnth + (1.0 - (PartLoadRatio * AirFlowRatio)) * InletAirEnthalpy);
   11208        13990 :             OutletAirHumRat = (PartLoadRatio * FullLoadOutAirHumRat + (1.0 - PartLoadRatio) * InletAirHumRat);
   11209        13990 :             OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   11210              :         } else {
   11211              :             // default to cycling fan, cycling compressor
   11212           32 :             OutletAirEnthalpy = FullLoadOutAirEnth;
   11213           32 :             OutletAirHumRat = FullLoadOutAirHumRat;
   11214           32 :             OutletAirTemp = FullLoadOutAirTemp;
   11215              :         }
   11216              :         // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
   11217              :         // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
   11218              :         // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   11219              :         // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   11220        14022 :         if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
   11221           18 :             if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 1) {
   11222            2 :                 EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), OutdoorDryBulb);
   11223              :             } else {
   11224           16 :                 EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
   11225              :             }
   11226           18 :             EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
   11227              :         } else {
   11228        14004 :             EIRTempModFac = 1.0;
   11229        14004 :             EIRFlowModFac = 1.0;
   11230              :         }
   11231              : 
   11232        14022 :         if (EIRTempModFac < 0.0) {
   11233            0 :             if (thisDXCoil.EIRFTErrIndex == 0) {
   11234            0 :                 ShowWarningMessage(state, format("The EIRTempModFac curve value for DX heating coil {} ={:.2R}", thisDXCoil.Name, EIRTempModFac));
   11235            0 :                 ShowContinueError(
   11236              :                     state, "EIRTempModFac curve value must be > 0.  EIRTempModFac curve value has been reset to 0.0 and simulation is continuing.");
   11237            0 :                 ShowContinueError(state, format("Check the IO reference manual for EIRTempModFac curve guidance [ {} ].", thisDXCoil.DXCoilType));
   11238            0 :                 ShowContinueErrorTimeStamp(state, "");
   11239              :             }
   11240            0 :             ShowRecurringWarningErrorAtEnd(state,
   11241              :                                            "DX heating coil EIRTempModFac curve value < 0.0 warning continues... ",
   11242            0 :                                            thisDXCoil.EIRFTErrIndex,
   11243              :                                            EIRTempModFac,
   11244              :                                            EIRTempModFac);
   11245            0 :             EIRTempModFac = 0.0;
   11246              :         }
   11247              : 
   11248        14022 :         EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
   11249              :         // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
   11250        14022 :         if (TotCapAdj > 0.0) {
   11251        14021 :             PLRHeating = min(1.0, (PartLoadRatio + (LoadDueToDefrost * PartLoadRatio) / TotCapAdj));
   11252              :         } else {
   11253            1 :             PLRHeating = 0.0;
   11254              :         }
   11255        14022 :         if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating) {
   11256           18 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PLRHeating); // Calculate part-load factor
   11257              :         } else {
   11258        14004 :             PLF = 1.0;
   11259              :         }
   11260              : 
   11261        14022 :         if (PLF < 0.7) {
   11262            1 :             if (thisDXCoil.PLRErrIndex == 0) {
   11263            2 :                 ShowWarningMessage(
   11264              :                     state,
   11265            2 :                     format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
   11266            2 :                 ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   11267            2 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   11268            3 :                 ShowContinueErrorTimeStamp(state, "");
   11269              :             }
   11270            7 :             ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
   11271            1 :             PLF = 0.7;
   11272              :         }
   11273              : 
   11274        14022 :         thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
   11275        14022 :         if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
   11276            0 :             if (thisDXCoil.ErrIndex4 == 0) {
   11277            0 :                 ShowWarningMessage(state,
   11278            0 :                                    format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
   11279            0 :                                           thisDXCoil.Name,
   11280            0 :                                           thisDXCoil.HeatingCoilRuntimeFraction));
   11281            0 :                 ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
   11282            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   11283            0 :                 ShowContinueErrorTimeStamp(state, "");
   11284              :             }
   11285            0 :             ShowRecurringWarningErrorAtEnd(state,
   11286            0 :                                            thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
   11287            0 :                                            thisDXCoil.ErrIndex4,
   11288            0 :                                            thisDXCoil.HeatingCoilRuntimeFraction,
   11289            0 :                                            thisDXCoil.HeatingCoilRuntimeFraction);
   11290            0 :             thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   11291        14022 :         } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
   11292            0 :             thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   11293              :         }
   11294              :         // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
   11295        14022 :         if (fanOp == HVAC::FanOp::Cycling) {
   11296           32 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
   11297              :         }
   11298        14022 :         thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
   11299              : 
   11300              :         // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
   11301              :         // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
   11302              : 
   11303        14022 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   11304        14017 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
   11305              :         } else {
   11306            5 :             thisDXCoil.CrankcaseHeaterPower =
   11307            5 :                 CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
   11308            5 :                                                    state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
   11309              :         }
   11310              : 
   11311        14022 :         AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   11312        14022 :         thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy);
   11313              :         // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
   11314              :         // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
   11315        14022 :         thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
   11316              : 
   11317        14022 :         thisDXCoil.OutletAirTemp = OutletAirTemp;
   11318        14022 :         thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   11319        14022 :         thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   11320        14022 :         thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
   11321              : 
   11322              :     } else {
   11323              : 
   11324              :         // DX coil is off; just pass through conditions
   11325       163453 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   11326       163453 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   11327       163453 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   11328              : 
   11329       163453 :         thisDXCoil.ElecHeatingPower = 0.0;
   11330       163453 :         thisDXCoil.TotalHeatingEnergyRate = 0.0;
   11331       163453 :         thisDXCoil.DefrostPower = 0.0;
   11332              : 
   11333              :         // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
   11334              :         // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
   11335       163453 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   11336        35512 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
   11337              :         } else {
   11338       127941 :             thisDXCoil.CrankcaseHeaterPower =
   11339       127941 :                 CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
   11340              :         }
   11341       163453 :         thisDXCoil.CompressorPartLoadRatio = 0.0;
   11342              : 
   11343              :     } // end of on/off if - else
   11344              : 
   11345       177475 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   11346       177475 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   11347       177475 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   11348       177475 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
   11349       177475 :     state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
   11350       177475 :     state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
   11351       177475 :     state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
   11352              : 
   11353              :     // set outlet node conditions
   11354       177475 :     int airOutletNode = thisDXCoil.AirOutNode;
   11355       177475 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   11356       177475 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   11357              : 
   11358              :     // calc secondary coil if specified
   11359       177475 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   11360            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   11361              :     }
   11362       177475 : }
   11363              : 
   11364        36791 : void CalcMultiSpeedDXCoil(EnergyPlusData &state,
   11365              :                           int const DXCoilNum,     // the number of the DX heating coil to be simulated
   11366              :                           Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
   11367              :                           Real64 const CycRatio,   // cycling part load ratio
   11368              :                           ObjexxFCL::Optional_bool_const ForceOn)
   11369              : {
   11370              : 
   11371              :     // SUBROUTINE INFORMATION:
   11372              :     //       AUTHOR         Fred Buhl
   11373              :     //       DATE WRITTEN   September 2002
   11374              :     //       MODIFIED       Raustad/Shirey, Feb 2004
   11375              :     //                      Feb 2005 M. J. Witte, GARD Analytics, Inc.
   11376              :     //                        Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
   11377              :     //                      April 2010, Chandan sharma, FSEC, added basin heater
   11378              : 
   11379              :     // PURPOSE OF THIS SUBROUTINE:
   11380              :     // Calculates the air-side performance and electrical energy use of a direct-
   11381              :     // expansion, air-cooled cooling unit with a 2 speed or variable speed compressor.
   11382              : 
   11383              :     // METHODOLOGY EMPLOYED:
   11384              :     // Uses the same methodology as the single speed DX unit model (SUBROUTINE CalcDoe2DXCoil).
   11385              :     // In addition it assumes that the unit performance is obtained by interpolating between
   11386              :     // the performance at high speed and that at low speed. If the output needed is below
   11387              :     // that produced at low speed, the compressor cycles between off and low speed.
   11388              : 
   11389              :     // Using/Aliasing
   11390              :     using Curve::CurveValue;
   11391              : 
   11392              :     // SUBROUTINE ARGUMENT DEFINITIONS:
   11393              :     // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
   11394              : 
   11395              :     // SUBROUTINE PARAMETER DEFINITIONS:
   11396              :     static constexpr std::string_view RoutineNameHighSpeedOutlet("CalcMultiSpeedDXCoil:highspeedoutlet");
   11397              :     static constexpr std::string_view RoutineNameLowSpeedOutlet("CalcMultiSpeedDXCoil:lowspeedoutlet");
   11398              :     static constexpr std::string_view RoutineNameNewDewPointConditions("CalcMultiSpeedDXCoil:newdewpointconditions");
   11399              : 
   11400              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   11401              :     Real64 AirMassFlow;         // dry air mass flow rate through coil [kg/s]
   11402              :     Real64 AirMassFlowRatio;    // Ratio of max air mass flow to rated air mass flow
   11403              :     Real64 InletAirWetBulbC;    // wetbulb temperature of inlet air [C]
   11404              :     Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
   11405              :     Real64 InletAirEnthalpy;    // inlet air enthalpy [J/kg]
   11406              :     Real64 InletAirHumRat;      // inlet air humidity ratio [kg/kg]
   11407              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11408              :     // REAL(r64) :: InletAirPressure    ! inlet air pressure [Pa]
   11409              :     Real64 OutletAirDryBulbTemp;    // outlet air dry bulb temperature [C]
   11410              :     Real64 OutletAirEnthalpy;       // outlet air enthalpy [J/kg]
   11411              :     Real64 OutletAirHumRat;         // outlet air humidity ratio [kg/kg]
   11412              :     Real64 OutletAirDryBulbTempSat; // outlet air dry bulb temp at saturation at the outlet enthalpy [C]
   11413              :     Real64 LSOutletAirDryBulbTemp;  // low speed outlet air dry bulb temperature [C]
   11414              :     Real64 LSOutletAirEnthalpy;     // low speed outlet air enthalpy [J/kg]
   11415              :     Real64 LSOutletAirHumRat;       // low speed outlet air humidity ratio [kg/kg]
   11416              :     Real64 hDelta;                  // Change in air enthalpy across the cooling coil [J/kg]
   11417              :     Real64 hTinwout;                // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
   11418              :     Real64 hADP;                    // Apparatus dew point enthalpy [J/kg]
   11419              :     Real64 tADP;                    // Apparatus dew point temperature [C]
   11420              :     Real64 wADP;                    // Apparatus dew point humidity ratio [kg/kg]
   11421              :     Real64 hTinwADP;                // Enthalpy at inlet dry-bulb and wADP [J/kg]
   11422              :     Real64 RatedCBFHS;              // coil bypass factor at rated conditions (high speed)
   11423              :     Real64 CBFHS;                   // coil bypass factor at max flow (high speed)
   11424              :     Real64 TotCapHS;                // total capacity at high speed [W]
   11425              :     Real64 SHRHS;                   // sensible heat ratio at high speed
   11426              :     Real64 TotCapLS;                // total capacity at low speed [W]
   11427              :     Real64 SHRLS;                   // sensible heat ratio at low speed
   11428              :     Real64 EIRTempModFacHS;         // EIR modifier (function of entering wetbulb, outside drybulb) (high speed)
   11429              :     Real64 EIRFlowModFacHS;         // EIR modifier (function of actual supply air flow vs rated flow) (high speed)
   11430              :     Real64 EIRHS;                   // EIR at off rated conditions (high speed)
   11431              :     Real64 EIRTempModFacLS;         // EIR modifier (function of entering wetbulb, outside drybulb) (low speed)
   11432              :     Real64 EIRLS;                   // EIR at off rated conditions (low speed)
   11433              :     Real64 TotCap;                  // total capacity at current speed [W]
   11434              :     Real64 SHR;                     // sensible heat ratio at current speed
   11435              :     Real64 EIR;                     // EIR at current speed
   11436              :     Real64 AirMassFlowNom;          // speed ratio weighted average of high and low speed air mass flow rates [kg/s]
   11437              :     Real64 CBFNom;                  // coil bypass factor corresponding to AirMassFlowNom and SpeedRatio
   11438              :     Real64 CBF;                     // CBFNom adjusted for actual air mass flow rate
   11439              :     Real64 PLF;                     // Part load factor, accounts for thermal lag at compressor startup, used in
   11440              :     // power calculation
   11441              :     Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
   11442              :     // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
   11443              :     Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
   11444              :     // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
   11445              :     Real64 RhoAir;                // Density of air [kg/m3]
   11446              :     Real64 RhoWater;              // Density of water [kg/m3]
   11447              :     Real64 CondAirMassFlow;       // Condenser air mass flow rate [kg/s]
   11448              :     Real64 EvapCondPumpElecPower; // Evaporative condenser electric pump power [W]
   11449        36791 :     constexpr int Mode(1);        // Performance mode for MultiMode DX coil; Always 1 for other coil types
   11450              :     Real64 OutdoorDryBulb;        // Outdoor dry-bulb temperature at condenser (C)
   11451              :     Real64 OutdoorWetBulb;        // Outdoor wet-bulb temperature at condenser (C)
   11452              :     Real64 OutdoorHumRat;         // Outdoor humidity ratio at condenser (kg/kg)
   11453              :     Real64 OutdoorPressure;       // Outdoor barometric pressure at condenser (Pa)
   11454              :     bool LocalForceOn;
   11455              :     Real64 AirMassFlowRatio2; // Ratio of low speed air mass flow to rated air mass flow
   11456        36791 :     Real64 CompAmbTemp(0.0);  // Ambient temperature at compressor
   11457              : 
   11458        36791 :     if (present(ForceOn)) {
   11459         3306 :         LocalForceOn = true;
   11460              :     } else {
   11461        33485 :         LocalForceOn = false;
   11462              :     }
   11463              : 
   11464        36791 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   11465              : 
   11466        36791 :     if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
   11467            0 :         OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
   11468              :         // If node is not connected to anything, pressure = default, use weather data
   11469            0 :         if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   11470            0 :             OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   11471            0 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   11472            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   11473            0 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   11474              :         } else {
   11475            0 :             OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
   11476            0 :             OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
   11477            0 :             OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure);
   11478              :         }
   11479            0 :         CompAmbTemp = OutdoorDryBulb;
   11480            0 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
   11481            0 :             auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   11482            0 :             OutdoorDryBulb = secZoneHB.ZT;
   11483            0 :             OutdoorHumRat = secZoneHB.airHumRat;
   11484            0 :             OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   11485            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   11486            0 :             CompAmbTemp = OutdoorDryBulb;
   11487              :         }
   11488        36791 :     } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
   11489            0 :         auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   11490            0 :         OutdoorDryBulb = secZoneHB.ZT;
   11491            0 :         OutdoorHumRat = secZoneHB.airHumRat;
   11492            0 :         OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   11493            0 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   11494            0 :         CompAmbTemp = OutdoorDryBulb;
   11495              :     } else {
   11496        36791 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   11497        36791 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   11498        36791 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   11499        36791 :         OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   11500        36791 :         CompAmbTemp = OutdoorDryBulb;
   11501              :     }
   11502              : 
   11503        36791 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   11504        36791 :     AirMassFlowRatio = thisDXCoil.InletAirMassFlowRateMax / thisDXCoil.RatedAirMassFlowRate(Mode);
   11505        36791 :     thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
   11506        36791 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   11507        36791 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   11508        36791 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   11509        36791 :     AirMassFlowRatio2 = 1.0; // DXCoil(DXCoilNum)%RatedAirMassFlowRate2 / DXCoil(DXCoilNum)%RatedAirMassFlowRate(Mode)
   11510              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11511              :     // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
   11512              :     // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
   11513        36791 :     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   11514        36791 :     if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Air) {
   11515        36780 :         CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
   11516           11 :     } else if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   11517              :         // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   11518           11 :         CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
   11519           11 :         CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
   11520              :     }
   11521              : 
   11522        58329 :     if ((AirMassFlow > 0.0 && CompAmbTemp >= thisDXCoil.MinOATCompressor) && ((thisDXCoil.availSched->getCurrentVal() > 0.0) || (LocalForceOn)) &&
   11523        21538 :         (SpeedRatio > 0.0 || CycRatio > 0.0)) {
   11524              : 
   11525        29226 :         RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
   11526        29226 :         if (SpeedRatio > 0.0) {
   11527              :             // Adjust high speed coil bypass factor for actual maximum air flow rate.
   11528        15248 :             RatedCBFHS = thisDXCoil.RatedCBF(Mode);
   11529        15248 :             CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.RatedAirMassFlowRate(Mode), thisDXCoil.InletAirMassFlowRateMax);
   11530              :             // get high speed total capacity and SHR at current conditions
   11531        45744 :             CalcTotCapSHR(state,
   11532              :                           InletAirDryBulbTemp,
   11533              :                           InletAirHumRat,
   11534              :                           InletAirEnthalpy,
   11535              :                           InletAirWetBulbC,
   11536              :                           AirMassFlowRatio,
   11537              :                           thisDXCoil.InletAirMassFlowRateMax,
   11538        15248 :                           thisDXCoil.RatedTotCap(Mode),
   11539              :                           CBFHS,
   11540        15248 :                           thisDXCoil.CCapFTemp(Mode),
   11541        15248 :                           thisDXCoil.CCapFFlow(Mode),
   11542              :                           TotCapHS,
   11543              :                           SHRHS,
   11544              :                           CondInletTemp,
   11545              :                           OutdoorPressure,
   11546        15248 :                           thisDXCoil.capModFacTotal);
   11547              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11548              :             //                       CondInletTemp, Node(DXCoil(DXCoilNum)%AirInNode)%Press)
   11549              :             // get the high speed SHR from user specified SHR modifier curves
   11550        15248 :             if (thisDXCoil.UserSHRCurveExists) {
   11551            0 :                 SHRHS = CalcSHRUserDefinedCurves(state,
   11552              :                                                  InletAirDryBulbTemp,
   11553              :                                                  InletAirWetBulbC,
   11554              :                                                  AirMassFlowRatio,
   11555            0 :                                                  thisDXCoil.SHRFTemp(Mode),
   11556            0 :                                                  thisDXCoil.SHRFFlow(Mode),
   11557            0 :                                                  thisDXCoil.RatedSHR(Mode));
   11558              :             }
   11559              :             // get low speed total capacity and SHR at current conditions
   11560        15248 :             CalcTotCapSHR(state,
   11561              :                           InletAirDryBulbTemp,
   11562              :                           InletAirHumRat,
   11563              :                           InletAirEnthalpy,
   11564              :                           InletAirWetBulbC,
   11565              :                           1.0,
   11566              :                           thisDXCoil.RatedAirMassFlowRate2,
   11567              :                           thisDXCoil.RatedTotCap2,
   11568              :                           thisDXCoil.RatedCBF2,
   11569              :                           thisDXCoil.CCapFTemp2,
   11570        15248 :                           thisDXCoil.CCapFFlow(Mode),
   11571              :                           TotCapLS,
   11572              :                           SHRLS,
   11573              :                           CondInletTemp,
   11574              :                           OutdoorPressure,
   11575        15248 :                           thisDXCoil.capModFacTotal);
   11576              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11577              :             //                       Node(DXCoil(DXCoilNum)%AirInNode)%Press)
   11578              :             // get the low speed SHR from user specified SHR modifier curves
   11579        15248 :             if (thisDXCoil.UserSHRCurveExists) {
   11580            0 :                 SHRLS = CalcSHRUserDefinedCurves(state,
   11581              :                                                  InletAirDryBulbTemp,
   11582              :                                                  InletAirWetBulbC,
   11583              :                                                  AirMassFlowRatio2,
   11584              :                                                  thisDXCoil.SHRFTemp2,
   11585              :                                                  thisDXCoil.SHRFFlow2,
   11586              :                                                  thisDXCoil.RatedSHR2);
   11587              :             }
   11588              :             // get high speed EIR at current conditions
   11589        15248 :             EIRTempModFacHS = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirWetBulbC, CondInletTemp);
   11590        15248 :             EIRFlowModFacHS = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
   11591        15248 :             EIRHS = thisDXCoil.RatedEIR(Mode) * EIRFlowModFacHS * EIRTempModFacHS;
   11592              :             // get low speed EIR at current conditions
   11593              :             //    EIRTempModFacLS = CurveValue(state, DXCoil(DXCoilNum)%EIRFTemp(Mode),InletAirWetBulbC,CondInletTemp)
   11594              :             //    CR7307 changed EIRTempModFacLS calculation to that shown below.
   11595        15248 :             EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
   11596        15248 :             EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
   11597              : 
   11598              :             // get current total capacity, SHR, EIR
   11599        15248 :             if (SpeedRatio >= 1.0) {
   11600         5106 :                 TotCap = TotCapHS;
   11601         5106 :                 SHR = SHRHS;
   11602         5106 :                 EIR = EIRHS;
   11603         5106 :                 CBFNom = CBFHS;
   11604         5106 :                 AirMassFlowNom = thisDXCoil.InletAirMassFlowRateMax;
   11605         5106 :                 CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
   11606         5106 :                 EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower(Mode);
   11607              :             } else {
   11608        10142 :                 TotCap = SpeedRatio * TotCapHS + (1.0 - SpeedRatio) * TotCapLS;
   11609        10142 :                 EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
   11610        10142 :                 CBFNom = SpeedRatio * CBFHS + (1.0 - SpeedRatio) * thisDXCoil.RatedCBF2;
   11611        10142 :                 AirMassFlowNom = SpeedRatio * thisDXCoil.InletAirMassFlowRateMax + (1.0 - SpeedRatio) * thisDXCoil.RatedAirMassFlowRate2;
   11612        10142 :                 CondAirMassFlow = RhoAir * (SpeedRatio * thisDXCoil.EvapCondAirFlow(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondAirFlow2);
   11613        10142 :                 EvapCondPumpElecPower =
   11614        10142 :                     SpeedRatio * thisDXCoil.EvapCondPumpElecNomPower(Mode) + (1.0 - SpeedRatio) * thisDXCoil.EvapCondPumpElecNomPower2;
   11615              :             }
   11616        15248 :             hDelta = TotCap / AirMassFlow;
   11617        15248 :             if (thisDXCoil.UserSHRCurveExists) {
   11618            0 :                 if (SpeedRatio >= 1.0) {
   11619            0 :                     SHR = SHRHS;
   11620              :                 } else {
   11621            0 :                     SHR = min(SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS, 1.0);
   11622              :                 }
   11623            0 :                 OutletAirEnthalpy = InletAirEnthalpy - hDelta;
   11624            0 :                 if (SHR < 1.0) {
   11625            0 :                     hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   11626            0 :                     OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   11627            0 :                     if (OutletAirHumRat <= 0.0) {
   11628            0 :                         OutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
   11629              :                     }
   11630              :                 } else {
   11631            0 :                     SHR = 1.0;
   11632            0 :                     OutletAirHumRat = InletAirHumRat;
   11633              :                 }
   11634            0 :                 OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   11635            0 :                 OutletAirDryBulbTempSat = PsyTdpFnWPb(state, OutletAirHumRat, OutdoorPressure, RoutineNameHighSpeedOutlet);
   11636            0 :                 if (OutletAirDryBulbTempSat > OutletAirDryBulbTemp) {
   11637            0 :                     OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   11638            0 :                     OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineNameHighSpeedOutlet);
   11639              :                 }
   11640              : 
   11641              :             } else {
   11642              :                 // Adjust CBF for off-nominal flow
   11643        15248 :                 CBF = AdjustCBF(CBFNom, AirMassFlowNom, AirMassFlow);
   11644              :                 // Calculate new apparatus dew point conditions
   11645        15248 :                 hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
   11646        15248 :                 tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure);
   11647              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11648              :                 //    tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   11649        15248 :                 wADP = PsyWFnTdbH(state, tADP, hADP);
   11650        15248 :                 hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   11651              :                 // get corresponding SHR
   11652        15248 :                 if ((InletAirEnthalpy - hADP) > 1.e-10) {
   11653        15248 :                     SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   11654              :                 } else {
   11655            0 :                     SHR = 1.0;
   11656              :                 }
   11657              : 
   11658              :                 // cr8918    SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
   11659        15248 :                 OutletAirEnthalpy = InletAirEnthalpy - hDelta;
   11660              :                 // get outlet conditions
   11661        15248 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   11662        15248 :                 OutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   11663              : 
   11664        15248 :                 OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   11665        15248 :                 OutletAirDryBulbTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
   11666        15248 :                 if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   11667           12 :                     OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   11668           12 :                     OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy);
   11669              :                 }
   11670              :             }
   11671              :             // Coil total/sensible/latent cooling rates and electrical power
   11672        15248 :             CalcComponentSensibleLatentOutput(AirMassFlow,
   11673              :                                               InletAirDryBulbTemp,
   11674              :                                               InletAirHumRat,
   11675              :                                               OutletAirDryBulbTemp,
   11676              :                                               OutletAirHumRat,
   11677        15248 :                                               thisDXCoil.SensCoolingEnergyRate,
   11678        15248 :                                               thisDXCoil.LatCoolingEnergyRate,
   11679        15248 :                                               thisDXCoil.TotalCoolingEnergyRate);
   11680        15248 :             thisDXCoil.ElecCoolingPower = TotCap * EIR;
   11681              :             //   Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
   11682        15248 :             state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
   11683        15248 :             thisDXCoil.PartLoadRatio = 1.0;
   11684        15248 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
   11685              : 
   11686        15248 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   11687        15248 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   11688        15248 :             thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
   11689              : 
   11690        13978 :         } else if (CycRatio > 0.0) {
   11691              : 
   11692        13978 :             if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   11693              :                 // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   11694            2 :                 CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect2);
   11695            2 :                 CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
   11696              :             }
   11697              : 
   11698              :             // Adjust low speed coil bypass factor for actual flow rate.
   11699              :             // CBF = AdjustCBF(DXCoil(DXCoilNum)%RatedCBF2,DXCoil(DXCoilNum)%RatedAirMassFlowRate2,AirMassFlow)
   11700              :             // get low speed total capacity and SHR at current conditions
   11701        13978 :             CalcTotCapSHR(state,
   11702              :                           InletAirDryBulbTemp,
   11703              :                           InletAirHumRat,
   11704              :                           InletAirEnthalpy,
   11705              :                           InletAirWetBulbC,
   11706              :                           1.0,
   11707              :                           thisDXCoil.RatedAirMassFlowRate2,
   11708              :                           thisDXCoil.RatedTotCap2,
   11709              :                           thisDXCoil.RatedCBF2,
   11710              :                           thisDXCoil.CCapFTemp2,
   11711        13978 :                           thisDXCoil.CCapFFlow(Mode),
   11712              :                           TotCapLS,
   11713              :                           SHRLS,
   11714              :                           CondInletTemp,
   11715              :                           OutdoorPressure,
   11716        13978 :                           thisDXCoil.capModFacTotal);
   11717              :             // get the low speed SHR from user specified SHR modifier curves
   11718        13978 :             if (thisDXCoil.UserSHRCurveExists) {
   11719            0 :                 SHRLS = CalcSHRUserDefinedCurves(
   11720              :                     state, InletAirDryBulbTemp, InletAirWetBulbC, 1.0, thisDXCoil.SHRFTemp2, thisDXCoil.SHRFFlow2, thisDXCoil.RatedSHR2);
   11721              :             }
   11722              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11723              :             //                       Node(DXCoil(DXCoilNum)%AirInNode)%Press)
   11724        13978 :             hDelta = TotCapLS / AirMassFlow;
   11725        13978 :             if (thisDXCoil.UserSHRCurveExists) {
   11726            0 :                 SHR = SHRLS;
   11727            0 :                 LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
   11728            0 :                 if (SHR < 1.0) {
   11729            0 :                     hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   11730            0 :                     LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   11731            0 :                     if (LSOutletAirHumRat <= 0.0) {
   11732            0 :                         LSOutletAirHumRat = min(DryCoilOutletHumRatioMin, InletAirHumRat);
   11733              :                     }
   11734              :                 } else {
   11735            0 :                     SHR = 1.0;
   11736            0 :                     LSOutletAirHumRat = InletAirHumRat;
   11737              :                 }
   11738            0 :                 LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
   11739            0 :                 OutletAirDryBulbTempSat = PsyTdpFnWPb(state, LSOutletAirHumRat, OutdoorPressure, RoutineNameLowSpeedOutlet);
   11740            0 :                 if (OutletAirDryBulbTempSat > LSOutletAirDryBulbTemp) {
   11741            0 :                     LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   11742            0 :                     LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
   11743              :                 }
   11744              : 
   11745              :             } else {
   11746              :                 // Adjust CBF for off-nominal flow
   11747        13978 :                 CBF = AdjustCBF(thisDXCoil.RatedCBF2, thisDXCoil.RatedAirMassFlowRate2, AirMassFlow);
   11748              :                 // Calculate new apparatus dew point conditions
   11749        13978 :                 hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
   11750        13978 :                 tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineNameNewDewPointConditions);
   11751              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   11752              :                 //    tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   11753        13978 :                 wADP = PsyWFnTdbH(state, tADP, hADP, RoutineNameNewDewPointConditions);
   11754        13978 :                 hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   11755              :                 // get corresponding SHR
   11756        13978 :                 if ((InletAirEnthalpy - hADP) > 1.e-10) {
   11757        13978 :                     SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   11758              :                 } else {
   11759            0 :                     SHR = 1.0;
   11760              :                 }
   11761              :                 // cr8918    SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
   11762              :                 // get low speed outlet conditions
   11763        13978 :                 LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
   11764        13978 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   11765        13978 :                 LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout);
   11766        13978 :                 LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
   11767        13978 :                 OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineNameLowSpeedOutlet);
   11768        13978 :                 if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   11769            6 :                     LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   11770            6 :                     LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineNameLowSpeedOutlet);
   11771              :                 }
   11772              :             }
   11773              :             // outlet conditions are average of inlet and low speed weighted by CycRatio
   11774        13978 :             OutletAirEnthalpy = CycRatio * LSOutletAirEnthalpy + (1.0 - CycRatio) * InletAirEnthalpy;
   11775        13978 :             OutletAirHumRat = CycRatio * LSOutletAirHumRat + (1.0 - CycRatio) * InletAirHumRat;
   11776        13978 :             OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   11777              :             // get low speed EIR at current conditions
   11778              :             //    EIRTempModFacLS = CurveValue(state, DXCoil(DXCoilNum)%EIRFTemp(Mode),InletAirWetBulbC,CondInletTemp)
   11779              :             //    CR7307 changed EIRTempModFacLS calculation to that shown below.
   11780        13978 :             EIRTempModFacLS = CurveValue(state, thisDXCoil.EIRFTemp2, InletAirWetBulbC, CondInletTemp);
   11781        13978 :             EIRLS = thisDXCoil.RatedEIR2 * EIRTempModFacLS;
   11782              :             // get the part load factor that will account for cycling losses
   11783        13978 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CycRatio);
   11784        13978 :             if (PLF < 0.7) {
   11785            0 :                 PLF = 0.7;
   11786              :             }
   11787              :             // calculate the run time fraction
   11788        13978 :             thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
   11789        13978 :             thisDXCoil.PartLoadRatio = CycRatio;
   11790        13978 :             if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
   11791            0 :                 thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   11792              :             }
   11793              :             // get the electrical power consumption
   11794        13978 :             thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
   11795              : 
   11796              :             // Coil total/sensible/latent cooling rates and electrical power
   11797        13978 :             CalcComponentSensibleLatentOutput(AirMassFlow,
   11798              :                                               InletAirDryBulbTemp,
   11799              :                                               InletAirHumRat,
   11800              :                                               OutletAirDryBulbTemp,
   11801              :                                               OutletAirHumRat,
   11802        13978 :                                               thisDXCoil.SensCoolingEnergyRate,
   11803        13978 :                                               thisDXCoil.LatCoolingEnergyRate,
   11804        13978 :                                               thisDXCoil.TotalCoolingEnergyRate);
   11805        13978 :             state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
   11806        13978 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   11807        13978 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   11808        13978 :             thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
   11809        13978 :             CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow2 * thisDXCoil.CoolingCoilRuntimeFraction;
   11810        13978 :             EvapCondPumpElecPower = thisDXCoil.EvapCondPumpElecNomPower2 * thisDXCoil.CoolingCoilRuntimeFraction;
   11811              :         }
   11812              : 
   11813        29226 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   11814              :             //******************
   11815              :             //             WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
   11816              :             //             H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
   11817              :             //                                /RhoWater [kgWater/m3]
   11818              :             //******************
   11819            9 :             RhoWater = RhoH2O(OutdoorDryBulb);
   11820            9 :             thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater;
   11821            9 :             thisDXCoil.EvapCondPumpElecPower = EvapCondPumpElecPower;
   11822              :             // set water system demand request (if needed)
   11823            9 :             if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
   11824              : 
   11825            0 :                 state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
   11826            0 :                     thisDXCoil.EvapWaterConsumpRate;
   11827              :             }
   11828              : 
   11829              :             // Calculate basin heater power
   11830            9 :             CalcBasinHeaterPower(state,
   11831              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
   11832              :                                  thisDXCoil.basinHeaterSched,
   11833              :                                  thisDXCoil.BasinHeaterSetPointTemp,
   11834            9 :                                  thisDXCoil.BasinHeaterPower);
   11835            9 :             thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   11836              :         }
   11837              : 
   11838              :     } else {
   11839              : 
   11840              :         // DX coil is off; just pass through conditions
   11841         7565 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   11842         7565 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   11843         7565 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   11844              : 
   11845         7565 :         thisDXCoil.ElecCoolingPower = 0.0;
   11846         7565 :         thisDXCoil.TotalCoolingEnergyRate = 0.0;
   11847         7565 :         thisDXCoil.SensCoolingEnergyRate = 0.0;
   11848         7565 :         thisDXCoil.LatCoolingEnergyRate = 0.0;
   11849         7565 :         thisDXCoil.EvapCondPumpElecPower = 0.0;
   11850         7565 :         thisDXCoil.EvapWaterConsumpRate = 0.0;
   11851              : 
   11852              :         // Calculate basin heater power
   11853         7565 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   11854            2 :             CalcBasinHeaterPower(state,
   11855              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
   11856              :                                  thisDXCoil.basinHeaterSched,
   11857              :                                  thisDXCoil.BasinHeaterSetPointTemp,
   11858            2 :                                  thisDXCoil.BasinHeaterPower);
   11859              :         }
   11860              :     }
   11861              : 
   11862        36791 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   11863        36791 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   11864        36791 :     thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
   11865              : 
   11866              :     // set outlet node conditions
   11867        36791 :     int airOutletNode = thisDXCoil.AirOutNode;
   11868        36791 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   11869        36791 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   11870              : 
   11871              :     // calc secondary coil if specified
   11872        36791 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   11873            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   11874              :     }
   11875        36791 : }
   11876              : 
   11877            0 : void CalcBasinHeaterPowerForMultiModeDXCoil(EnergyPlusData &state,
   11878              :                                             int const DXCoilNum,             // Index of coil being simulated
   11879              :                                             HVAC::CoilMode const DehumidMode // Dehumidification mode (0=normal, 1=enhanced)
   11880              : )
   11881              : {
   11882              : 
   11883              :     // SUBROUTINE INFORMATION:
   11884              :     //       AUTHOR         Chandan Sharma, FSEC
   11885              :     //       DATE WRITTEN   May 2010
   11886              : 
   11887              :     // PURPOSE OF THIS SUBROUTINE:
   11888              :     // To calculate the basin heater power for multi mode DX cooling coil
   11889              : 
   11890              :     // METHODOLOGY EMPLOYED:
   11891              :     // The methodology employed is as follows:
   11892              :     // 1) If the number of capacity stages is equal to 1 and the CondenserType for stage 1
   11893              :     //    is EvapCooled, then the basin heater power is calculated for (1-runtimefractionstage1) of DX coil
   11894              :     // 2) If the number of capacity stages is greater than 1, then
   11895              :     //    a) If the CondenserType for stage 1 is EvapCooled, then the basin heater power is calculated for
   11896              :     //       (1-runtimefractionofstage1) of DX coil
   11897              :     //    b) Elseif the CondenserType for stage 2 is EvapCooled, then the basin heater power is calculated for
   11898              :     //       (1-runtimefractionofstage2) of DX coil
   11899              : 
   11900              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   11901              :     int PerfMode; // Performance mode for MultiMode DX coil; Always 1 for other coil types
   11902              :     // 1-2=normal mode: 1=stage 1 only, 2=stage 1&2
   11903              :     // 3-4=enhanced dehumidification mode: 3=stage 1 only, 4=stage 1&2
   11904              : 
   11905            0 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   11906              : 
   11907            0 :     if (thisDXCoil.NumCapacityStages == 1) {
   11908            0 :         thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   11909              :     } else {
   11910            0 :         PerfMode = (int)DehumidMode * 2 + 1;
   11911            0 :         if (thisDXCoil.CondenserType(PerfMode) == DataHeatBalance::RefrigCondenserType::Evap) {
   11912            0 :             thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   11913            0 :         } else if (thisDXCoil.CondenserType(PerfMode + 1) == DataHeatBalance::RefrigCondenserType::Evap) {
   11914            0 :             CalcBasinHeaterPower(state,
   11915              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
   11916              :                                  thisDXCoil.basinHeaterSched,
   11917              :                                  thisDXCoil.BasinHeaterSetPointTemp,
   11918            0 :                                  thisDXCoil.BasinHeaterPower);
   11919            0 :             thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilStg2RuntimeFrac);
   11920              :         }
   11921              :     }
   11922            0 : }
   11923              : 
   11924        59001 : Real64 AdjustCBF(Real64 const CBFNom,             // nominal coil bypass factor
   11925              :                  Real64 const AirMassFlowRateNom, // nominal air mass flow rate [kg/s]
   11926              :                  Real64 const AirMassFlowRate     // actual air mass flow rate [kg/s]
   11927              : )
   11928              : {
   11929              : 
   11930              :     // FUNCTION INFORMATION:
   11931              :     //       AUTHOR         Fred Buhl using Don Shirey's code
   11932              :     //       DATE WRITTEN   September 2002
   11933              : 
   11934              :     // PURPOSE OF THIS FUNCTION:
   11935              :     //    Adjust coil bypass factor for actual air flow rate.
   11936              : 
   11937              :     // METHODOLOGY EMPLOYED:
   11938              :     // Uses relation CBF = exp(-NTU) whereNTU = A0/(m*cp). Relationship models the cooling coil
   11939              :     // as a heat exchanger with Cmin/Cmax = 0.
   11940              : 
   11941              :     // Return value
   11942              :     Real64 CBFAdj; // the result - the adjusted coil bypass factor
   11943              : 
   11944              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   11945              :     Real64 A0;    // intermediate variable
   11946              :     Real64 ADiff; // intermediate variable
   11947              : 
   11948        59001 :     if (CBFNom > 0.0) {
   11949        58998 :         A0 = -std::log(CBFNom) * AirMassFlowRateNom;
   11950              :     } else {
   11951            3 :         A0 = 0.0;
   11952              :     }
   11953        59001 :     ADiff = -A0 / AirMassFlowRate;
   11954        59001 :     if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
   11955        58541 :         CBFAdj = std::exp(ADiff);
   11956              :     } else {
   11957          460 :         CBFAdj = 1.0e-6;
   11958              :     }
   11959              : 
   11960        59001 :     return CBFAdj;
   11961              : }
   11962              : 
   11963         3120 : Real64 CalcCBF(EnergyPlusData &state,
   11964              :                std::string const &UnitType,
   11965              :                std::string const &UnitName,
   11966              :                Real64 const InletAirTemp,   // inlet air temperature [C]
   11967              :                Real64 const InletAirHumRat, // inlet air humidity ratio [kg water / kg dry air]
   11968              :                Real64 const TotCap,         // total cooling  capacity [Watts]
   11969              :                Real64 const AirVolFlowRate, // the air volume flow rate at the given capacity [m3/s]
   11970              :                Real64 const SHR,            // sensible heat ratio at the given capacity and flow rate
   11971              :                bool const PrintFlag         // flag used to print warnings if desired
   11972              : )
   11973              : {
   11974              : 
   11975              :     // FUNCTION INFORMATION:
   11976              :     //       AUTHOR         Fred Buhl using Don Shirey's code
   11977              :     //       DATE WRITTEN   September 2002
   11978              : 
   11979              :     // PURPOSE OF THIS FUNCTION:
   11980              :     // Calculate the coil bypass factor for a coil given the total capacity at the entering conditions,
   11981              :     // air mass flow rate at the entering conditions, and the sensible heat ratio (SHR) at the
   11982              :     // entering conditions. Standard barometric pressure is used for this model parameter.
   11983              : 
   11984              :     // METHODOLOGY EMPLOYED:
   11985              :     // calculate SlopeRated (deltahumrat/deltaT) using rated unit information provided by
   11986              :     // user. Then hunt along saturation curve of psychrometric chart until the slope of the line
   11987              :     // between the saturation point and rated inlet air humidity ratio and T is the same as SlopeRated.
   11988              :     // When the slopes are equal, then we have located the apparatus dewpoint of the coil at rated
   11989              :     // conditions. From this information, coil bypass factor is calculated.
   11990              : 
   11991              :     // Using/Aliasing
   11992              : 
   11993              :     // Return value
   11994         3120 :     Real64 CBF(0.0); // the result - the coil bypass factor
   11995              : 
   11996              :     // FUNCTION PARAMETER DEFINITIONS:
   11997              :     static constexpr std::string_view RoutineName("CalcCBF");
   11998         3120 :     constexpr Real64 SmallDifferenceTest(0.00000001);
   11999              : 
   12000              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   12001              :     Real64 InletAirEnthalpy;                // Enthalpy of inlet air to evaporator at given conditions [J/kg]
   12002         3120 :     Real64 DeltaH(0.0);                     // Enthalpy drop across evaporator at given conditions [J/kg]
   12003         3120 :     Real64 DeltaT(0.0);                     // Temperature drop across evaporator at given conditions [C]
   12004         3120 :     Real64 DeltaHumRat(0.0);                // Humidity ratio drop across evaporator at given conditions [kg/kg]
   12005         3120 :     Real64 OutletAirTemp(InletAirTemp);     // Outlet dry-bulb temperature from evaporator at given conditions [C]
   12006         3120 :     Real64 OutletAirTempSat(InletAirTemp);  // Saturation dry-bulb temperature from evaporator at outlet air enthalpy [C]
   12007              :     Real64 OutletAirEnthalpy;               // Enthalpy of outlet air at given conditions [J/kg]
   12008         3120 :     Real64 OutletAirHumRat(InletAirHumRat); // Outlet humidity ratio from evaporator at given conditions [kg/kg]
   12009              :     Real64 OutletAirRH;                     // relative humidity of the outlet air
   12010              :     Real64 Error;                           // Error term used in given coil bypass factor (CBF) calculations
   12011              :     Real64 ErrorLast;                       // Error term, from previous iteration
   12012              :     int Iter;                               // Iteration loop counter in CBF calculations
   12013         3120 :     int IterMax(50);                        // Maximum number of iterations in CBF calculations
   12014              :     Real64 ADPTemp;                         // Apparatus dewpoint temperature used in CBF calculations [C]
   12015              :     Real64 ADPHumRat;                       // Apparatus dewpoint humidity used in CBF calculations [kg/kg]
   12016              :     Real64 ADPEnthalpy;                     // Air enthalpy at apparatus dew point [J/kg]
   12017              :     Real64 DeltaADPTemp;                    // Change in Apparatus Dew Point used in CBF calculations [C]
   12018         3120 :     Real64 SlopeAtConds(0.0);               // Slope (DeltaHumRat/DeltaT) at given conditions
   12019         3120 :     Real64 Slope(0.0);                      // Calculated Slope used while hunting for Tadp
   12020              :     Real64 Tolerance;                       // Convergence tolerance for CBF calculations
   12021              :     Real64 HTinHumRatOut;                   // Air enthalpy at inlet air temp and outlet air humidity ratio [J/kg]
   12022              :     Real64 AirMassFlowRate;                 // the standard air mass flow rate at the given capacity [kg/s]
   12023              :     Real64 adjustedSHR;                     // SHR calculated using adjusted outlet air properties []
   12024         3120 :     bool CBFErrors(false);                  // Set to true if errors in CBF calculation, fatal at end of routine
   12025              : 
   12026         3120 :     if (AirVolFlowRate <= 0.0 || TotCap <= 0.0) { // Coil not running or has no capacity, don't calculate CBF
   12027            5 :         return CBF;
   12028              :     }
   12029              : 
   12030         3115 :     AirMassFlowRate = AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, InletAirTemp, InletAirHumRat, RoutineName);
   12031         3115 :     DeltaH = TotCap / AirMassFlowRate;
   12032         3115 :     InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
   12033         3115 :     HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
   12034         3115 :     OutletAirHumRat = PsyWFnTdbH(state, InletAirTemp, HTinHumRatOut);
   12035         3115 :     DeltaHumRat = InletAirHumRat - OutletAirHumRat;
   12036         3115 :     OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
   12037         3115 :     OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   12038              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12039              :     //  Pressure will have to be pass into this subroutine to fix this one
   12040         3115 :     OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, RoutineName);
   12041         3115 :     if (OutletAirRH >= 1.0 && PrintFlag) {
   12042           16 :         ShowWarningError(state, format("For object = {}, name = \"{}\"", UnitType, UnitName));
   12043           32 :         ShowContinueError(state, "Calculated outlet air relative humidity greater than 1. The combination of");
   12044           32 :         ShowContinueError(state, "rated air volume flow rate, total cooling capacity and sensible heat ratio yields coil exiting");
   12045           32 :         ShowContinueError(state, "air conditions above the saturation curve. Possible fixes are to reduce the rated total cooling");
   12046           32 :         ShowContinueError(state, "capacity, increase the rated air volume flow rate, or reduce the rated sensible heat ratio for this coil.");
   12047           32 :         ShowContinueError(state, "If autosizing, it is recommended that all three of these values be autosized.");
   12048           32 :         ShowContinueError(state, "...Inputs used for calculating cooling coil bypass factor.");
   12049           16 :         ShowContinueError(state, format("...Inlet Air Temperature     = {:.2R} C", InletAirTemp));
   12050           16 :         ShowContinueError(state, format("...Outlet Air Temperature    = {:.2R} C", OutletAirTemp));
   12051           16 :         ShowContinueError(state, format("...Inlet Air Humidity Ratio  = {:.6R} kgWater/kgDryAir", InletAirHumRat));
   12052           16 :         ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
   12053           16 :         ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
   12054           16 :         ShowContinueError(state, format("...Air Mass Flow Rate used in calculation     = {:.6R} kg/s", AirMassFlowRate));
   12055           16 :         ShowContinueError(state, format("...Air Volume Flow Rate used in calculation   = {:.6R} m3/s", AirVolFlowRate));
   12056           16 :         if (TotCap > 0.0) {
   12057           28 :             if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
   12058           12 :                 ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
   12059           12 :                 ShowContinueError(state,
   12060           12 :                                   format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
   12061           12 :                                          AirVolFlowRate / TotCap));
   12062              :             }
   12063              :         }
   12064           32 :         ShowContinueErrorTimeStamp(state, "");
   12065           16 :         OutletAirTempSat = PsyTsatFnHPb(state, OutletAirEnthalpy, DataEnvironment::StdPressureSeaLevel, RoutineName);
   12066           16 :         if (OutletAirTemp < OutletAirTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   12067           16 :             OutletAirTemp = OutletAirTempSat + 0.005;
   12068           16 :             OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy, RoutineName);
   12069           16 :             DeltaHumRat = InletAirHumRat - OutletAirHumRat;
   12070           16 :             HTinHumRatOut = PsyHFnTdbW(InletAirTemp, OutletAirHumRat);
   12071           16 :             adjustedSHR = (HTinHumRatOut - OutletAirEnthalpy) / DeltaH;
   12072           32 :             ShowContinueError(state, "CalcCBF: SHR adjusted to achieve valid outlet air properties and the simulation continues.");
   12073           16 :             ShowContinueError(state, format("CalcCBF: initial SHR = {:.5R}", SHR));
   12074           16 :             ShowContinueError(state, format("CalcCBF: adjusted SHR = {:.5R}", adjustedSHR));
   12075              :         }
   12076              :     }
   12077         3115 :     DeltaT = InletAirTemp - OutletAirTemp;
   12078         3115 :     if (DeltaT <= 0.0) {
   12079            0 :         ShowSevereError(state, format("For object = {}, name = \"{}\"", UnitType, UnitName));
   12080            0 :         ShowContinueError(state, "Calculated coil delta T is less than or equal to 0. The combination of");
   12081            0 :         ShowContinueError(state, "rated air volume flow rate, total cooling capacity and sensible heat ratio yields coil exiting");
   12082            0 :         ShowContinueError(state, "air conditions that are not reasonable. Possible fixes are to adjust the rated total cooling");
   12083            0 :         ShowContinueError(state, "capacity, rated air volume flow rate, or rated sensible heat ratio for this coil.");
   12084            0 :         ShowContinueError(state, "If autosizing, it is recommended that all three of these values be autosized.");
   12085            0 :         ShowContinueError(state, "...Inputs used for calculating cooling coil bypass factor.");
   12086            0 :         ShowContinueError(state, format("...Inlet Air Temperature     = {:.2R} C", InletAirTemp));
   12087            0 :         ShowContinueError(state, format("...Outlet Air Temperature    = {:.2R} C", OutletAirTemp));
   12088            0 :         ShowContinueError(state, format("...Inlet Air Humidity Ratio  = {:.6R} kgWater/kgDryAir", InletAirHumRat));
   12089            0 :         ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
   12090            0 :         ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
   12091            0 :         ShowContinueError(state, format("...Air Mass Flow Rate used in calculation     = {:.6R} kg/s", AirMassFlowRate));
   12092            0 :         ShowContinueError(state, format("...Air Volume Flow Rate used in calculation   = {:.6R} m3/s", AirVolFlowRate));
   12093            0 :         if (TotCap > 0.0) {
   12094            0 :             if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
   12095            0 :                 ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
   12096            0 :                 ShowContinueError(state,
   12097            0 :                                   format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
   12098            0 :                                          AirVolFlowRate / TotCap));
   12099              :             }
   12100              :         }
   12101            0 :         ShowContinueErrorTimeStamp(state, "");
   12102            0 :         ShowFatalError(state, "Check and revise the input data for this coil before rerunning the simulation.");
   12103              :     }
   12104              :     // Calculate slope at given conditions
   12105         3115 :     if (DeltaT > 0.0) {
   12106         3115 :         SlopeAtConds = DeltaHumRat / DeltaT;
   12107              :     }
   12108              : 
   12109              :     //  IF (SlopeAtConds .le. .0000001d0 .or. OutletAirHumRat .le. 0.0d0) THEN
   12110         3115 :     if (SlopeAtConds < 0.0 || OutletAirHumRat <= 0.0) {
   12111              :         //   Invalid conditions, slope can't be less than zero (SHR > 1) or
   12112              :         //   outlet air humidity ratio can't be less than zero.
   12113            0 :         ShowSevereError(state, format("{} \"{}\"", UnitType, UnitName));
   12114            0 :         ShowContinueError(state, "...Invalid slope or outlet air condition when calculating cooling coil bypass factor.");
   12115            0 :         ShowContinueError(state, format("...Slope = {:.8R}", SlopeAtConds));
   12116            0 :         ShowContinueError(state, format("...Inlet Air Temperature     = {:.2R} C", InletAirTemp));
   12117            0 :         ShowContinueError(state, format("...Outlet Air Temperature    = {:.2R} C", OutletAirTemp));
   12118            0 :         ShowContinueError(state, format("...Inlet Air Humidity Ratio  = {:.6R} kgWater/kgDryAir", InletAirHumRat));
   12119            0 :         ShowContinueError(state, format("...Outlet Air Humidity Ratio = {:.6R} kgWater/kgDryAir", OutletAirHumRat));
   12120            0 :         ShowContinueError(state, format("...Total Cooling Capacity used in calculation = {:.2R} W", TotCap));
   12121            0 :         ShowContinueError(state, format("...Air Mass Flow Rate used in calculation     = {:.6R} kg/s", AirMassFlowRate));
   12122            0 :         ShowContinueError(state, format("...Air Volume Flow Rate used in calculation   = {:.6R} m3/s", AirVolFlowRate));
   12123            0 :         if (TotCap > 0.0) {
   12124            0 :             if (((HVAC::MinRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT] - AirVolFlowRate / TotCap) > SmallDifferenceTest) ||
   12125            0 :                 ((AirVolFlowRate / TotCap - HVAC::MaxRatedVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) > SmallDifferenceTest)) {
   12126            0 :                 ShowContinueError(state,
   12127            0 :                                   format("...Air Volume Flow Rate per Watt of Rated Cooling Capacity is also out of bounds at = {:.7R} m3/s/W",
   12128            0 :                                          AirVolFlowRate / TotCap));
   12129              :             }
   12130              :         }
   12131            0 :         ShowContinueErrorTimeStamp(state, "");
   12132            0 :         CBFErrors = true;
   12133            0 :         CBF = 0.0; //? Added: Is this what should be returned
   12134              :     } else {
   12135              : 
   12136              :         //   First guess for Tadp is outlet air dew point
   12137              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12138              :         //  Pressure will have to be pass into this subroutine to fix this one
   12139         3115 :         ADPTemp = PsyTdpFnWPb(state, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel);
   12140              : 
   12141         3115 :         Tolerance = 1.0; // initial conditions for iteration
   12142         3115 :         ErrorLast = 100.0;
   12143         3115 :         Iter = 0;
   12144         3115 :         DeltaADPTemp = 5.0;
   12145        51003 :         while ((Iter <= IterMax) && (Tolerance > 0.001)) {
   12146              :             //     Do for IterMax iterations or until the error gets below .1%
   12147        47888 :             if (Iter > 0) {
   12148        44773 :                 ADPTemp += DeltaADPTemp;
   12149              :             }
   12150        47888 :             ++Iter;
   12151              : 
   12152              :             //     Find new slope using guessed Tadp
   12153              : 
   12154              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12155              :             //  Pressure will have to be pass into this subroutine to fix this one
   12156        47888 :             ADPHumRat = min(OutletAirHumRat, PsyWFnTdpPb(state, ADPTemp, DataEnvironment::StdPressureSeaLevel));
   12157        47888 :             Slope = (InletAirHumRat - ADPHumRat) / max(0.001, (InletAirTemp - ADPTemp));
   12158              : 
   12159              :             //     check for convergence (slopes are equal to within error tolerance)
   12160              : 
   12161        47888 :             Error = (Slope - SlopeAtConds) / SlopeAtConds;
   12162        47888 :             if ((Error > 0.0) && (ErrorLast < 0.0)) {
   12163        11633 :                 DeltaADPTemp = -DeltaADPTemp / 2.0;
   12164        36255 :             } else if ((Error < 0.0) && (ErrorLast > 0.0)) {
   12165        13158 :                 DeltaADPTemp = -DeltaADPTemp / 2.0;
   12166        23097 :             } else if (std::abs(Error) > std::abs(ErrorLast)) {
   12167         2957 :                 DeltaADPTemp = -DeltaADPTemp / 2.0;
   12168              :             }
   12169        47888 :             ErrorLast = Error;
   12170              : 
   12171        47888 :             Tolerance = std::abs(Error);
   12172              :         }
   12173              : 
   12174              :         //   Calculate Bypass Factor from Enthalpies
   12175              : 
   12176         3115 :         InletAirEnthalpy = PsyHFnTdbW(InletAirTemp, InletAirHumRat);
   12177         3115 :         OutletAirEnthalpy = PsyHFnTdbW(OutletAirTemp, OutletAirHumRat);
   12178         3115 :         ADPEnthalpy = PsyHFnTdbW(ADPTemp, ADPHumRat);
   12179         3115 :         CBF = min(1.0, (OutletAirEnthalpy - ADPEnthalpy) / (InletAirEnthalpy - ADPEnthalpy));
   12180         3115 :         if (Iter > IterMax && PrintFlag) {
   12181            0 :             ShowSevereError(state, format("{} \"{}\" -- coil bypass factor calculation did not converge after max iterations.", UnitType, UnitName));
   12182            0 :             ShowContinueError(state, format("The RatedSHR of [{:.3R}], entered by the user or autosized (see *.eio file),", SHR));
   12183            0 :             ShowContinueError(state, "may be causing this. The line defined by the coil rated inlet air conditions");
   12184            0 :             ShowContinueError(state, "(26.7C drybulb and 19.4C wetbulb) and the RatedSHR (i.e., slope of the line) must intersect");
   12185            0 :             ShowContinueError(state, "the saturation curve of the psychrometric chart. If the RatedSHR is too low, then this");
   12186            0 :             ShowContinueError(state, "intersection may not occur and the coil bypass factor calculation will not converge.");
   12187            0 :             ShowContinueError(state, "If autosizing the SHR, recheck the design supply air humidity ratio and design supply air");
   12188            0 :             ShowContinueError(state, "temperature values in the Sizing:System and Sizing:Zone objects. In general, the temperatures");
   12189            0 :             ShowContinueError(state, "and humidity ratios specified in these two objects should be the same for each system");
   12190            0 :             ShowContinueError(state, "and the zones that it serves.");
   12191            0 :             ShowContinueErrorTimeStamp(state, "");
   12192            0 :             CBFErrors = true; // Didn't converge within MaxIter iterations
   12193              :         }
   12194         3115 :         if (CBF < 0.0 && PrintFlag) {
   12195            0 :             ShowSevereError(state, format("{} \"{}\" -- negative coil bypass factor calculated.", UnitType, UnitName));
   12196            0 :             ShowContinueErrorTimeStamp(state, "");
   12197            0 :             CBFErrors = true; // Negative CBF not valid
   12198              :         }
   12199              :     }
   12200              : 
   12201              :     // Show fatal error for specific coil that caused a CBF error
   12202         3115 :     if (CBFErrors) {
   12203            0 :         ShowFatalError(state, format("{} \"{}\" Errors found in calculating coil bypass factors", UnitType, UnitName));
   12204              :     }
   12205              : 
   12206         3115 :     return CBF;
   12207              : }
   12208              : 
   12209           90 : Real64 ValidateADP(EnergyPlusData &state,
   12210              :                    std::string const &UnitType,      // component name
   12211              :                    std::string const &UnitName,      // component type
   12212              :                    Real64 const RatedInletAirTemp,   // coil inlet air temperature [C]
   12213              :                    Real64 const RatedInletAirHumRat, // coil inlet air humidity ratio [kg/kg]
   12214              :                    Real64 const TotCap,              // coil total capacity [W]
   12215              :                    Real64 const AirVolFlowRate,      // coil air volume flow rate [m3/s]
   12216              :                    Real64 const InitialSHR,          // coil sensible heat ratio []
   12217              :                    std::string const &CallingRoutine // function name calling this routine
   12218              : )
   12219              : {
   12220              : 
   12221              :     // FUNCTION INFORMATION:
   12222              :     //    AUTHOR         Richard Raustad, FSEC
   12223              :     //    DATE WRITTEN   December 2015
   12224              : 
   12225              :     // PURPOSE OF THIS FUNCTION:
   12226              :     //    Validates that the calculated bypass factor represents valid SHR based on total capacity and air mass flow rate.
   12227              : 
   12228              :     // METHODOLOGY EMPLOYED:
   12229              :     //    With model parameters autosized by the user, the SHR is selected based on an empirical model.
   12230              :     //    This can sometimes lead to an SHR that does not cross the saturation curve, or one that crosses excessively where
   12231              :     //    the coil outlet air conditions exceed the saturation curve (i.e., RH > 1).
   12232              :     //    This function checks to see if the ADP based on coil delta T and calculated bypass factor and the ADP based
   12233              :     //    on coil delta W and calculated bypass factor land on the saturation curve at the same place within a tolerance.
   12234              :     //    The result is passed back to the sizing routine as the new value for SHR.
   12235              :     //    If the SHR is not autosized, this routine will still adjust the design SHR appropriately, however, the hard-sized SHR will not
   12236              :     //    change.
   12237              : 
   12238              :     // Return value
   12239           90 :     Real64 SHR(0.0); // the result - the adjusted design SHR
   12240              : 
   12241              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   12242           90 :     Real64 CBF_calculated(0.0);    // coil bypass factor based on TotCap, AirFlow, SHR, and BaroPress
   12243           90 :     Real64 InletAirEnthalpy(0.0);  // Enthalpy of inlet air to evaporator at given conditions [J/kg]
   12244           90 :     Real64 DeltaH(0.0);            // Enthalpy drop across evaporator at given conditions [J/kg]
   12245           90 :     Real64 HTinHumRatOut(0.0);     // Air enthalpy at inlet air temp and outlet air humidity ratio [J/kg]
   12246           90 :     Real64 DeltaHumRat(0.0);       // Humidity ratio drop across evaporator at given conditions [kg/kg]
   12247           90 :     Real64 OutletAirTemp(0.0);     // Outlet dry-bulb temperature from evaporator at given conditions [C]
   12248           90 :     Real64 OutletAirEnthalpy(0.0); // Enthalpy of outlet air at given conditions [J/kg]
   12249           90 :     Real64 OutletAirHumRat(0.0);   // Outlet humidity ratio from evaporator at given conditions [kg/kg]
   12250           90 :     Real64 OutletAirRH(0.0);       // relative humidity of the outlet air
   12251           90 :     Real64 CalcADPTemp(0.0);       // actual ADP temperature based on bypass factor [C]
   12252           90 :     Real64 CalcADPHumRat(0.0);     // actual ADP humidity ratio based on bypass factor [kg/kg]
   12253           90 :     Real64 CalcADPTempFnHR(0.0);   // actual ADP temperature as a function of humidity ratio based on bypass factor [C]
   12254           90 :     Real64 ADPerror(0.0);          // difference between ADP function of temperature and humidity ratio [deltaC]
   12255           90 :     Real64 AirMassFlow(0.0);       // air mass flow rate based on standard barometric pressure [kg/s]
   12256           90 :     bool bStillValidating(true);   // while loop flag
   12257           90 :     bool bNoReporting(false);      // don't report specific warnings in calcCBF while iterating on result
   12258           90 :     bool bReversePerturb(false);   // identifies when SHR is being lowered based on outlet air RH
   12259              : 
   12260           90 :     SHR = InitialSHR;
   12261           90 :     AirMassFlow =
   12262           90 :         AirVolFlowRate * PsyRhoAirFnPbTdbW(state, DataEnvironment::StdPressureSeaLevel, RatedInletAirTemp, RatedInletAirHumRat, CallingRoutine);
   12263         3059 :     while (bStillValidating) {
   12264         2969 :         CBF_calculated = max(0.0, CalcCBF(state, UnitType, UnitName, RatedInletAirTemp, RatedInletAirHumRat, TotCap, AirMassFlow, SHR, bNoReporting));
   12265         2969 :         DeltaH = TotCap / AirMassFlow;
   12266         2969 :         InletAirEnthalpy = PsyHFnTdbW(RatedInletAirTemp, RatedInletAirHumRat);
   12267         2969 :         HTinHumRatOut = InletAirEnthalpy - (1.0 - SHR) * DeltaH;
   12268         2969 :         OutletAirHumRat = PsyWFnTdbH(state, RatedInletAirTemp, HTinHumRatOut, CallingRoutine);
   12269         2969 :         DeltaHumRat = RatedInletAirHumRat - OutletAirHumRat;
   12270         2969 :         OutletAirEnthalpy = InletAirEnthalpy - DeltaH;
   12271         2969 :         OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   12272         2969 :         OutletAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
   12273         2969 :         if (CBF_calculated < 1) {
   12274         2969 :             CalcADPTemp = RatedInletAirTemp - ((RatedInletAirTemp - OutletAirTemp) / (1 - CBF_calculated));
   12275         2969 :             CalcADPHumRat = RatedInletAirHumRat - ((DeltaHumRat) / (1 - CBF_calculated));
   12276         2969 :             CalcADPTempFnHR = PsyTdpFnWPb(state, CalcADPHumRat, DataEnvironment::StdPressureSeaLevel, CallingRoutine);
   12277         2969 :             ADPerror = CalcADPTemp - CalcADPTempFnHR;
   12278              :         } else {
   12279            0 :             ADPerror = 0; // might be able to check for RH >= 1 and reduce SHR, need defect file for that since can't create one
   12280              :         }
   12281              : 
   12282         2969 :         if (std::abs(ADPerror) > 0.012) {
   12283         2969 :             if (OutletAirRH >= 1.0) { // if RH > 1, reduce SHR until it crosses the saturation curve
   12284          344 :                 SHR -= 0.001;
   12285          344 :                 bReversePerturb = true;
   12286          344 :                 if (SHR < 0.5) {
   12287            0 :                     bStillValidating = false; // have to stop somewhere, this is lower than the lower limit of SHR empirical model (see
   12288              :                 }
   12289              :                 // Autosizing/CoolingSHRSizing)
   12290              :             } else {
   12291         2625 :                 if (bReversePerturb) {
   12292           60 :                     bStillValidating = false; // stop iterating once SHR causes ADP to cross back under saturation curve, take what you get
   12293              :                 } else {
   12294         2565 :                     SHR += 0.001; // increase SHR slowly until ADP temps are resolved
   12295              :                 }
   12296              :             }
   12297         2969 :             if (SHR > 0.8) {
   12298           30 :                 bStillValidating = false; // have to stop somewhere, this is the upper limit of SHR empirical model (see Autosizing/CoolingSHRSizing)
   12299              :             }
   12300              :         } else {
   12301            0 :             bStillValidating = false; // ADP temps are close enough. Normal input files hit this on first pass
   12302              :         }
   12303              :     }
   12304              : 
   12305           90 :     return SHR;
   12306              : }
   12307              : 
   12308       116065 : Real64 CalcEffectiveSHR(EnergyPlusData &state,
   12309              :                         int const DXCoilNum,                         // Index number for cooling coil
   12310              :                         Real64 const SHRss,                          // Steady-state sensible heat ratio
   12311              :                         Real64 const RTF,                            // Compressor run-time fraction
   12312              :                         Real64 const QLatRated,                      // Rated latent capacity
   12313              :                         Real64 const QLatActual,                     // Actual latent capacity
   12314              :                         Real64 const EnteringDB,                     // Entering air dry-bulb temperature
   12315              :                         Real64 const EnteringWB,                     // Entering air wet-bulb temperature
   12316              :                         ObjexxFCL::Optional_int_const Mode,          // Performance mode for MultiMode DX coil; Always 1 for other coil types
   12317              :                         ObjexxFCL::Optional<Real64 const> HeatingRTF // Used to recalculate Toff for cycling fan systems
   12318              : )
   12319              : {
   12320              : 
   12321              :     // FUNCTION INFORMATION:
   12322              :     //    AUTHOR         Richard Raustad, FSEC
   12323              :     //    DATE WRITTEN   September 2003
   12324              :     //                   Feb 2005 M. J. Witte, GARD Analytics, Inc.
   12325              :     //                    Add new coil type COIL:DX:MultiMode:CoolingEmpirical:
   12326              :     //                   Nov 2008 R. Raustad, FSEC
   12327              :     //                    Modified to allow latent degradation with cycling fan
   12328              : 
   12329              :     // PURPOSE OF THIS FUNCTION:
   12330              :     //    Adjust sensible heat ratio to account for degradation of DX coil latent
   12331              :     //    capacity at part-load (cycling) conditions.
   12332              : 
   12333              :     // METHODOLOGY EMPLOYED:
   12334              :     //    With model parameters entered by the user, the part-load latent performance
   12335              :     //    of a DX cooling coil is determined for a constant air flow system with
   12336              :     //    a cooling coil that cycles on/off. The model calculates the time
   12337              :     //    required for condensate to begin falling from the cooling coil.
   12338              :     //    Runtimes greater than this are integrated to a "part-load" latent
   12339              :     //    capacity which is used to determine the "part-load" sensible heat ratio.
   12340              :     //    See reference below for additional details (linear decay model, Eq. 8b).
   12341              :     // REFERENCES:
   12342              :     //   "A Model to Predict the Latent Capacity of Air Conditioners and
   12343              :     //    Heat Pumps at Part-Load Conditions with Constant Fan Operation"
   12344              :     //    1996 ASHRAE Transactions, Volume 102, Part 1, Pp. 266 - 274,
   12345              :     //    Hugh I. Henderson, Jr., P.E., Kannan Rengarajan, P.E.
   12346              : 
   12347              :     // Return value
   12348              :     Real64 SHReff; // Effective sensible heat ratio, includes degradation due to cycling effects
   12349              : 
   12350              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   12351              :     Real64 Twet; // Nominal time for condensate to begin leaving the coil's condensate drain line
   12352              :     //   at the current operating conditions (sec)
   12353              :     Real64 Gamma; // Initial moisture evaporation rate divided by steady-state AC latent capacity
   12354              :     //   at the current operating conditions
   12355              :     Real64 Twet_Rated;  // Twet at rated conditions (coil air flow rate and air temperatures), sec
   12356              :     Real64 Gamma_Rated; // Gamma at rated conditions (coil air flow rate and air temperatures)
   12357              :     Real64 Twet_max;    // Maximum allowed value for Twet
   12358              :     Real64 Nmax;        // Maximum ON/OFF cycles per hour for the compressor (cycles/hr)
   12359              :     Real64 Tcl;         // Time constant for latent capacity to reach steady state after startup (sec)
   12360              :     Real64 Ton;         // Coil on time (sec)
   12361              :     Real64 Toff;        // Coil off time (sec)
   12362              :     Real64 Toffa;       // Actual coil off time (sec). Equations valid for Toff <= (2.0 * Twet/Gamma)
   12363              :     Real64 aa;          // Intermediate variable
   12364              :     Real64 To1;         // Intermediate variable (first guess at To). To = time to the start of moisture removal
   12365              :     Real64 To2;         // Intermediate variable (second guess at To). To = time to the start of moisture removal
   12366              :     Real64 Error;       // Error for iteration (DO) loop
   12367              :     Real64 LHRmult;     // Latent Heat Ratio (LHR) multiplier. The effective latent heat ratio LHR = (1-SHRss)*LHRmult
   12368              :     Real64 Ton_heating;
   12369              :     Real64 Toff_heating;
   12370              : 
   12371       116065 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   12372              : 
   12373       116065 :     if (thisDXCoil.DXCoilType_Num != HVAC::CoilDX_MultiSpeedCooling) {
   12374       116024 :         Twet_Rated = thisDXCoil.Twet_Rated(Mode);
   12375       116024 :         Gamma_Rated = thisDXCoil.Gamma_Rated(Mode);
   12376       116024 :         Nmax = thisDXCoil.MaxONOFFCyclesperHour(Mode);
   12377       116024 :         Tcl = thisDXCoil.LatentCapacityTimeConstant(Mode);
   12378              :     } else {
   12379           41 :         Twet_Rated = thisDXCoil.MSTwet_Rated(Mode);
   12380           41 :         Gamma_Rated = thisDXCoil.MSGamma_Rated(Mode);
   12381           41 :         Nmax = thisDXCoil.MSMaxONOFFCyclesperHour(Mode);
   12382           41 :         Tcl = thisDXCoil.MSLatentCapacityTimeConstant(Mode);
   12383              :     }
   12384              : 
   12385              :     //  No moisture evaporation (latent degradation) occurs for runtime fraction of 1.0
   12386              :     //  All latent degradation model parameters cause divide by 0.0 if not greater than 0.0
   12387              :     //  Latent degradation model parameters initialize to 0.0 meaning no evaporation model used.
   12388       116065 :     if (RTF >= 1.0 || Twet_Rated <= 0.0 || Gamma_Rated <= 0.0 || Nmax <= 0.0 || Tcl <= 0.0) {
   12389       107135 :         SHReff = SHRss;
   12390       107135 :         return SHReff;
   12391              :     }
   12392              : 
   12393         8930 :     Twet_max = 9999.0; // high limit for Twet
   12394              : 
   12395              :     //  Calculate the model parameters at the actual operating conditions
   12396         8930 :     Twet = min(Twet_Rated * QLatRated / (QLatActual + 1.e-10), Twet_max);
   12397         8930 :     Gamma = Gamma_Rated * QLatRated * (EnteringDB - EnteringWB) / ((26.7 - 19.4) * QLatActual + 1.e-10);
   12398              : 
   12399              :     //  Calculate the compressor on and off times using a conventional thermostat curve
   12400         8930 :     Ton = 3600.0 / (4.0 * Nmax * (1.0 - RTF)); // duration of cooling coil on-cycle (sec)
   12401         8930 :     Toff = 3600.0 / (4.0 * Nmax * RTF);        // duration of cooling coil off-cycle (sec)
   12402              : 
   12403              :     //  Cap Toff to meet the equation restriction
   12404         8930 :     if (Gamma > 0.0) {
   12405         8930 :         Toffa = min(Toff, 2.0 * Twet / Gamma);
   12406              :     } else {
   12407            0 :         Toffa = Toff;
   12408              :     }
   12409              : 
   12410              :     //  Need to include the reheat coil operation to account for actual fan run time. E+ uses a
   12411              :     //  separate heating coil for heating and reheat (to separate the heating and reheat loads)
   12412              :     //  and real world applications would use a single heating coil for both purposes, the actual
   12413              :     //  fan operation is based on HeatingPLR + ReheatPLR. For cycling fan RH control, latent
   12414              :     //  degradation only occurs when a heating load exists, in this case the reheat load is
   12415              :     //  equal to and opposite in magnitude to the cooling coil sensible output but the reheat
   12416              :     //  coil is not always active. This additional fan run time has not been accounted for at this time.
   12417              :     //  Recalculate Toff for cycling fan systems when heating is active
   12418         8930 :     if (present(HeatingRTF)) {
   12419            0 :         if (HeatingRTF < 1.0 && HeatingRTF > RTF) {
   12420            0 :             Ton_heating = 3600.0 / (4.0 * Nmax * (1.0 - HeatingRTF));
   12421            0 :             Toff_heating = 3600.0 / (4.0 * Nmax * HeatingRTF);
   12422              :             //    add additional heating coil operation during cooling coil off cycle (due to cycling rate difference of coils)
   12423            0 :             Ton_heating += max(0.0, min(Ton_heating, (Ton + Toffa) - (Ton_heating + Toff_heating)));
   12424            0 :             Toffa = min(Toffa, Ton_heating - Ton);
   12425              :         }
   12426              :     }
   12427              : 
   12428              :     //  Use successive substitution to solve for To
   12429         8930 :     aa = (Gamma * Toffa) - (0.25 / Twet) * pow_2(Gamma) * pow_2(Toffa);
   12430         8930 :     To1 = aa + Tcl;
   12431         8930 :     Error = 1.0;
   12432        19126 :     while (Error > 0.001) {
   12433        10196 :         To2 = aa - Tcl * (std::exp(-To1 / Tcl) - 1.0);
   12434        10196 :         Error = std::abs((To2 - To1) / To1);
   12435        10196 :         To1 = To2;
   12436              :     }
   12437              : 
   12438              :     //  Adjust Sensible Heat Ratio (SHR) using Latent Heat Ratio (LHR) multiplier
   12439              :     //  Floating underflow errors occur when -Ton/Tcl is a large negative number.
   12440              :     //  Cap lower limit at -700 to avoid the underflow errors.
   12441         8930 :     aa = std::exp(max(-700.0, -Ton / Tcl));
   12442              :     //  Calculate latent heat ratio multiplier
   12443         8930 :     LHRmult = max(((Ton - To2) / (Ton + Tcl * (aa - 1.0))), 0.0);
   12444              : 
   12445              :     //  Calculate part-load or "effective" sensible heat ratio
   12446         8930 :     SHReff = 1.0 - (1.0 - SHRss) * LHRmult;
   12447              : 
   12448         8930 :     if (SHReff < SHRss) {
   12449            3 :         SHReff = SHRss; // Effective SHR can be less than the steady-state SHR
   12450              :     }
   12451         8930 :     if (SHReff > 1.0) {
   12452            0 :         SHReff = 1.0; // Effective sensible heat ratio can't be greater than 1.0
   12453              :     }
   12454              : 
   12455         8930 :     return SHReff;
   12456              : }
   12457              : 
   12458        44594 : void CalcTotCapSHR(EnergyPlusData &state,
   12459              :                    Real64 const InletDryBulb,     // inlet air dry bulb temperature [C]
   12460              :                    Real64 const InletHumRat,      // inlet air humidity ratio [kg water / kg dry air]
   12461              :                    Real64 const InletEnthalpy,    // inlet air specific enthalpy [J/kg]
   12462              :                    Real64 const InletWetBulb,     // inlet air wet bulb temperature [C]
   12463              :                    Real64 const AirMassFlowRatio, // Ratio of actual air mass flow to nominal air mass flow
   12464              :                    Real64 const AirMassFlow,      // actual mass flow for capacity and SHR calculation
   12465              :                    Real64 const TotCapNom,        // nominal total capacity [W]
   12466              :                    Real64 const CBF,              // coil bypass factor
   12467              :                    int const CCapFTemp,           // capacity modifier curve index, function of entering wetbulb
   12468              :                    int const CCapFFlow,           // capacity modifier curve, function of actual flow vs rated flow
   12469              :                    Real64 &TotCap,                // total capacity at the given conditions [W]
   12470              :                    Real64 &SHR,                   // sensible heat ratio at the given conditions
   12471              :                    Real64 const CondInletTemp,    // Condenser inlet temperature [C]
   12472              :                    Real64 const Pressure,         // air pressure [Pa]
   12473              :                    Real64 &TotCapModFac           // capacity modification factor, func of temp and func of flow
   12474              : )
   12475              : {
   12476              : 
   12477              :     // SUBROUTINE INFORMATION:
   12478              :     //       AUTHOR         Fred Buhl using Don Shirey's code
   12479              :     //       DATE WRITTEN   September 2002
   12480              : 
   12481              :     // PURPOSE OF THIS SUBROUTINE:
   12482              :     // Calculates total capacity and sensible heat ratio of a DX coil at the specified conditions
   12483              : 
   12484              :     // METHODOLOGY EMPLOYED:
   12485              :     // With the rated performance data entered by the user, the model employs some of the
   12486              :     // DOE-2.1E curve fits to adjust the capacity and SHR of the unit as a function
   12487              :     // of entering air temperatures and supply air flow rate (actual vs rated flow). The model
   12488              :     // does NOT employ the exact same methodology to calculate performance as DOE-2, although
   12489              :     // some of the DOE-2 curve fits are employed by this model.
   12490              : 
   12491              :     // The model checks for coil dryout conditions, and adjusts the calculated performance
   12492              :     // appropriately.
   12493              : 
   12494              :     // REFERENCES:
   12495              :     // ASHRAE HVAC 2 Toolkit page 4-81.
   12496              :     // Henderson, H.I. Jr., K. Rengarajan and D.B. Shirey, III. 1992.The impact of comfort
   12497              :     // control on air conditioner energy use in humid climates. ASHRAE Transactions 98(2):
   12498              :     // 104-113.
   12499              :     // Henderson, H.I. Jr., Danny Parker and Y.J. Huang. 2000.Improving DOE-2's RESYS routine:
   12500              :     // User Defined Functions to Provide More Accurate Part Load Energy Use and Humidity
   12501              :     // Predictions. Proceedings of ACEEE Conference.
   12502              : 
   12503              :     // Using/Aliasing
   12504              :     using Curve::CurveValue;
   12505              : 
   12506              :     // Locals
   12507              :     // SUBROUTINE ARGUMENT DEFINITIONS:
   12508              :     // and outside drybulb
   12509              : 
   12510              :     // SUBROUTINE PARAMETER DEFINITIONS:
   12511        44594 :     constexpr int MaxIter(30);               // Maximum number of iterations for dry evaporator calculations
   12512        44594 :     constexpr Real64 RF(0.4);                // Relaxation factor for dry evaporator iterations
   12513        44594 :     constexpr Real64 Tolerance(0.01);        // Error tolerance for dry evaporator iterations
   12514        44594 :     constexpr Real64 MinHumRatCalc(0.00001); // Error tolerance for dry evaporator iterations
   12515              : 
   12516              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   12517              :     Real64 InletWetBulbCalc; // calculated inlet wetbulb temperature used for finding dry coil point [C]
   12518              :     Real64 InletHumRatCalc;  // calculated inlet humidity ratio used for finding dry coil point [kg water / kg dry air]
   12519              :     Real64 TotCapTempModFac; // Total capacity modifier (function of entering wetbulb, outside drybulb)
   12520              :     Real64 TotCapFlowModFac; // Total capacity modifier (function of actual supply air flow vs nominal flow)
   12521              :     Real64 hDelta;           // Change in air enthalpy across the cooling coil [J/kg]
   12522              :     Real64 hADP;             // Apparatus dew point enthalpy [J/kg]
   12523              :     Real64 tADP;             // Apparatus dew point temperature [C]
   12524              :     Real64 wADP;             // Apparatus dew point humidity ratio [kg/kg]
   12525              :     Real64 hTinwADP;         // Enthalpy at inlet dry-bulb and wADP [J/kg]
   12526              :     Real64 SHRCalc;          // temporary calculated value of SHR
   12527              :     Real64 TotCapCalc;       // temporary calculated value of total capacity [W]
   12528              :     int Counter;             // Counter for dry evaporator iterations
   12529              :     Real64 werror;           // Deviation of humidity ratio in dry evaporator iteration loop
   12530              : 
   12531              :     //  MaxIter = 30
   12532              :     //  RF = 0.4d0
   12533        44594 :     Counter = 0;
   12534              :     //  Tolerance = 0.01d0
   12535        44594 :     werror = 0.0;
   12536              : 
   12537        44594 :     InletWetBulbCalc = InletWetBulb;
   12538        44594 :     InletHumRatCalc = InletHumRat;
   12539              : 
   12540        44594 :     if (AirMassFlow <= 0.00001) {
   12541            3 :         TotCap = 0.0;
   12542            3 :         SHR = 0.0;
   12543            3 :         return;
   12544              :     }
   12545              : 
   12546              :     //  DO WHILE (ABS(werror) .gt. Tolerance .OR. Counter == 0)
   12547              :     //   Get capacity modifying factor (function of inlet wetbulb & outside drybulb) for off-rated conditions
   12548              :     while (true) {
   12549       158090 :         TotCapTempModFac = CurveValue(state, CCapFTemp, InletWetBulbCalc, CondInletTemp);
   12550              :         //   Get capacity modifying factor (function of mass flow) for off-rated conditions
   12551       158090 :         TotCapFlowModFac = CurveValue(state, CCapFFlow, AirMassFlowRatio);
   12552              :         //   Get total capacity
   12553       158090 :         TotCapCalc = TotCapNom * TotCapFlowModFac * TotCapTempModFac;
   12554              : 
   12555              :         //   Calculate apparatus dew point conditions using TotCap and CBF
   12556       158090 :         hDelta = TotCapCalc / AirMassFlow;
   12557       158090 :         hADP = InletEnthalpy - hDelta / (1.0 - CBF);
   12558       158090 :         tADP = PsyTsatFnHPb(state, hADP, Pressure);
   12559       158090 :         wADP = PsyWFnTdbH(state, tADP, hADP);
   12560       158090 :         hTinwADP = PsyHFnTdbW(InletDryBulb, wADP);
   12561       158090 :         if ((InletEnthalpy - hADP) > 1.e-10) {
   12562       158090 :             SHRCalc = min((hTinwADP - hADP) / (InletEnthalpy - hADP), 1.0);
   12563              :         } else {
   12564            0 :             SHRCalc = 1.0;
   12565              :         }
   12566              :         //   Check for dry evaporator conditions (win < wadp)
   12567       158090 :         if (wADP > InletHumRatCalc || (Counter >= 1 && Counter < MaxIter)) {
   12568       128338 :             if (InletHumRatCalc == 0.0) {
   12569           14 :                 InletHumRatCalc = MinHumRatCalc;
   12570              :             }
   12571              :             //      InletHumRatCalc=MAX(InletHumRatCalc,MinHumRatCalc)  ! proposed.
   12572              : 
   12573       128338 :             werror = (InletHumRatCalc - wADP) / InletHumRatCalc;
   12574              :             //     Increase InletHumRatCalc at constant inlet air temp to find coil dry-out point. Then use the
   12575              :             //     capacity at the dry-out point to determine exiting conditions from coil. This is required
   12576              :             //     since the TotCapTempModFac doesn't work properly with dry-coil conditions.
   12577       128338 :             InletHumRatCalc = RF * wADP + (1.0 - RF) * InletHumRatCalc;
   12578       128338 :             InletWetBulbCalc = PsyTwbFnTdbWPb(state, InletDryBulb, InletHumRatCalc, Pressure);
   12579       128338 :             ++Counter;
   12580       128338 :             if (std::abs(werror) > Tolerance) {
   12581       113499 :                 continue; // Recalculate with modified inlet conditions
   12582              :             }
   12583        14839 :             break; // conditions are satisfied
   12584              :         } else {
   12585              :             break; // conditions are satisfied
   12586              :         }
   12587              :     }
   12588              : 
   12589              :     // END DO
   12590              : 
   12591              :     //  Calculate full load output conditions
   12592        44591 :     if (SHRCalc > 1.0 || Counter > 0) {
   12593        14839 :         SHRCalc = 1.0;
   12594              :     }
   12595              : 
   12596        44591 :     SHR = SHRCalc;
   12597        44591 :     TotCap = TotCapCalc;
   12598        44591 :     TotCapModFac = TotCapTempModFac * TotCapFlowModFac;
   12599              : }
   12600              : 
   12601          265 : void CalcMultiSpeedDXCoilCooling(EnergyPlusData &state,
   12602              :                                  int const DXCoilNum,     // the number of the DX heating coil to be simulated
   12603              :                                  Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
   12604              :                                  Real64 const CycRatio,   // cycling part load ratio
   12605              :                                  int const SpeedNum,      // Speed number
   12606              :                                  HVAC::FanOp const fanOp, // Sets fan control to FanOp::Cycling or FanOp::Continuous
   12607              :                                  HVAC::CompressorOp const compressorOp, // Compressor on/off; 1=on, 0=off
   12608              :                                  int const SingleMode                   // Single mode operation Yes/No; 1=Yes, 0=No
   12609              : )
   12610              : {
   12611              : 
   12612              :     // SUBROUTINE INFORMATION:
   12613              :     //       AUTHOR         Lixing Gu, FSEC
   12614              :     //       DATE WRITTEN   June 2007
   12615              :     //       MODIFIED       April 2010, Chandan sharma, FSEC, added basin heater
   12616              :     //       RE-ENGINEERED  Revised based on CalcMultiSpeedDXCoil
   12617              : 
   12618              :     // PURPOSE OF THIS SUBROUTINE:
   12619              :     // Calculates the air-side performance and electrical energy use of a direct-
   12620              :     // expansion, air-cooled cooling unit with a multispeed compressor.
   12621              : 
   12622              :     // METHODOLOGY EMPLOYED:
   12623              :     // Uses the same methodology as the single speed DX unit model (SUBROUTINE CalcDoe2DXCoil).
   12624              :     // In addition it assumes that the unit performance is obtained by interpolating between
   12625              :     // the performance at high speed and that at low speed. If the output needed is below
   12626              :     // that produced at low speed, the compressor cycles between off and low speed.
   12627              : 
   12628              :     // Using/Aliasing
   12629              :     using Curve::CurveValue;
   12630          265 :     Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
   12631          265 :     Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
   12632          265 :     auto &MSHPWasteHeat = state.dataHVACGlobal->MSHPWasteHeat;
   12633              : 
   12634              :     // Locals
   12635              :     // SUBROUTINE ARGUMENT DEFINITIONS:
   12636              :     // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
   12637              : 
   12638              :     // SUBROUTINE PARAMETER DEFINITIONS:
   12639              :     static constexpr std::string_view RoutineName("CalcMultiSpeedDXCoilCooling");
   12640              :     static constexpr std::string_view RoutineNameHighSpeedAlt("CalcMultiSpeedDXCoilCooling highspeed");
   12641              : 
   12642              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   12643              :     Real64 AirMassFlow;         // dry air mass flow rate through coil [kg/s]
   12644              :     Real64 InletAirWetBulbC;    // wetbulb temperature of inlet air [C]
   12645              :     Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
   12646              :     Real64 InletAirEnthalpy;    // inlet air enthalpy [J/kg]
   12647              :     Real64 InletAirHumRat;      // inlet air humidity ratio [kg/kg]
   12648              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12649              :     // REAL(r64)   :: InletAirPressure    ! inlet air pressure [Pa]
   12650              :     Real64 OutletAirDryBulbTemp;    // outlet air dry bulb temperature [C]
   12651              :     Real64 OutletAirEnthalpy;       // outlet air enthalpy [J/kg]
   12652              :     Real64 OutletAirHumRat;         // outlet air humidity ratio [kg/kg]
   12653              :     Real64 OutletAirDryBulbTempSat; // outlet air dry bulb temp at saturation at the outlet enthalpy [C]
   12654              :     Real64 LSOutletAirDryBulbTemp;  // low speed outlet air dry bulb temperature [C]
   12655              :     Real64 LSOutletAirEnthalpy;     // low speed outlet air enthalpy [J/kg]
   12656              :     Real64 LSOutletAirHumRat;       // low speed outlet air humidity ratio [kg/kg]
   12657              :     Real64 HSOutletAirDryBulbTemp;  // high speed outlet air dry bulb temperature [C]
   12658              :     Real64 HSOutletAirEnthalpy;     // high speed outlet air enthalpy [J/kg]
   12659              :     Real64 HSOutletAirHumRat;       // high speed outlet air humidity ratio [kg/kg]
   12660              :     Real64 hDelta;                  // Change in air enthalpy across the cooling coil [J/kg]
   12661              :     Real64 hTinwout;                // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
   12662              :     Real64 hADP;                    // Apparatus dew point enthalpy [J/kg]
   12663              :     Real64 tADP;                    // Apparatus dew point temperature [C]
   12664              :     Real64 wADP;                    // Apparatus dew point humidity ratio [kg/kg]
   12665              :     Real64 hTinwADP;                // Enthalpy at inlet dry-bulb and wADP [J/kg]
   12666              :     Real64 RatedCBFHS;              // coil bypass factor at rated conditions (high speed)
   12667              :     Real64 CBFHS;                   // coil bypass factor at max flow (high speed)
   12668              :     Real64 RatedCBFLS;              // coil bypass factor at rated conditions (low speed)
   12669              :     Real64 CBFLS;                   // coil bypass factor at max flow (low speed)
   12670              :     Real64 TotCapHS;                // total capacity at high speed [W]
   12671              :     Real64 SHRHS;                   // sensible heat ratio at high speed
   12672              :     Real64 TotCapLS;                // total capacity at low speed [W]
   12673              :     Real64 SHRLS;                   // sensible heat ratio at low speed
   12674              :     Real64 EIRTempModFacHS;         // EIR modifier (function of entering wetbulb, outside drybulb) (high speed)
   12675              :     Real64 EIRFlowModFacHS;         // EIR modifier (function of actual supply air flow vs rated flow) (high speed)
   12676              :     Real64 EIRHS;                   // EIR at off rated conditions (high speed)
   12677              :     Real64 EIRTempModFacLS;         // EIR modifier (function of entering wetbulb, outside drybulb) (low speed)
   12678              :     Real64 EIRFlowModFacLS;         // EIR modifier (function of actual supply air flow vs rated flow) (low speed)
   12679              :     Real64 EIRLS;                   // EIR at off rated conditions (low speed)
   12680              :     Real64 SHR;                     // sensible heat ratio at current speed
   12681              :     Real64 EIR;                     // EIR at current speed
   12682              :     Real64 CBF;                     // CBFNom adjusted for actual air mass flow rate
   12683              :     Real64 PLF;                     // Part load factor, accounts for thermal lag at compressor startup, used in
   12684              :     // power calculation
   12685              :     Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
   12686              :     // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
   12687              :     Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
   12688              :     // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
   12689              :     Real64 RhoAir;                // Density of air [kg/m3]
   12690              :     Real64 RhoWater;              // Density of water [kg/m3]
   12691              :     Real64 CondAirMassFlow;       // Condenser air mass flow rate [kg/s]
   12692              :     Real64 EvapCondPumpElecPower; // Evaporative condenser electric pump power [W]
   12693          265 :     constexpr int DXMode(1);      // Performance mode for MultiMode DX coil; Always 1 for other coil types
   12694              :     Real64 OutdoorDryBulb;        // Outdoor dry-bulb temperature at condenser (C)
   12695              :     Real64 OutdoorWetBulb;        // Outdoor wet-bulb temperature at condenser (C)
   12696              :     Real64 OutdoorHumRat;         // Outdoor humidity ratio at condenser (kg/kg)
   12697              :     Real64 OutdoorPressure;       // Outdoor barometric pressure at condenser (Pa)
   12698              :     int SpeedNumHS;               // High speed number
   12699              :     int SpeedNumLS;               // Low speed number
   12700              :     Real64 SHRUnadjusted;         // Temp SHR
   12701              :     Real64 QLatRated;             // Qlatent at rated conditions of indoor(TDB,TWB)=(26.7C,19.4C)
   12702              :     Real64 QLatActual;            // Qlatent at actual operating conditions
   12703              :     Real64 AirMassFlowRatioLS;    // airflow ratio at low speed
   12704              :     Real64 AirMassFlowRatioHS;    // airflow ratio at high speed
   12705              :     Real64 WasteHeatLS;           // Waste heat at low speed
   12706              :     Real64 WasteHeatHS;           // Waste heat at high speed
   12707              :     Real64 LSElecCoolingPower;    // low speed power [W]
   12708              :     Real64 HSElecCoolingPower;    // high speed power [W]
   12709              :     Real64 CrankcaseHeatingPower; // Power due to crank case heater
   12710              :     Real64 AirVolumeFlowRate;     // Air volume flow rate across the heating coil
   12711              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total heating capacity
   12712              : 
   12713          265 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   12714              : 
   12715          265 :     if (thisDXCoil.CondenserInletNodeNum(DXMode) != 0) {
   12716           74 :         OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Press;
   12717              :         // If node is not connected to anything, pressure = default, use weather data
   12718           74 :         if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   12719           74 :             OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   12720           74 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   12721           74 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   12722           74 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   12723              :         } else {
   12724            0 :             OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).Temp;
   12725            0 :             OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(DXMode)).HumRat;
   12726            0 :             OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, RoutineName);
   12727              :         }
   12728           74 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
   12729            0 :             auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   12730            0 :             OutdoorDryBulb = secZoneHB.ZT;
   12731            0 :             OutdoorHumRat = secZoneHB.airHumRat;
   12732            0 :             OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   12733            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   12734              :         }
   12735          191 :     } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
   12736            0 :         auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   12737            0 :         OutdoorDryBulb = secZoneHB.ZT;
   12738            0 :         OutdoorHumRat = secZoneHB.airHumRat;
   12739            0 :         OutdoorWetBulb = thisDXCoil.EvapInletWetBulb;
   12740            0 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   12741              :     } else {
   12742          191 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   12743          191 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   12744          191 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   12745          191 :         OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   12746              :     }
   12747              : 
   12748          265 :     if (SpeedNum > 1) {
   12749           59 :         SpeedNumLS = SpeedNum - 1;
   12750           59 :         SpeedNumHS = SpeedNum;
   12751           59 :         if (SpeedNum > thisDXCoil.NumOfSpeeds) {
   12752            0 :             SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
   12753            0 :             SpeedNumHS = thisDXCoil.NumOfSpeeds;
   12754              :         }
   12755              :     } else {
   12756          206 :         SpeedNumLS = 1;
   12757          206 :         SpeedNumHS = 1;
   12758              :     }
   12759              : 
   12760          265 :     MSHPWasteHeat = 0.0;
   12761          265 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   12762          265 :     AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
   12763          265 :     AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
   12764          265 :     if ((AirMassFlow > 0.0) && (CycRatio > 0.0) && (MSHPMassFlowRateHigh == 0.0)) {
   12765            0 :         ShowSevereError(
   12766              :             state,
   12767            0 :             format("CalcMultiSpeedDXCoilCooling: {} \"{} Developer error - inconsistent airflow rates.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   12768            0 :         if (MSHPMassFlowRateLow == 0.0 && SpeedNum > 1) {
   12769            0 :             ShowContinueError(state,
   12770              :                               "When AirMassFlow > 0.0 and CycRatio > 0.0 and SpeedNum > 1, then MSHPMassFlowRateLow and MSHPMassFlowRateHigh "
   12771              :                               "must also be > 0.0");
   12772            0 :             ShowContinueErrorTimeStamp(state, "");
   12773            0 :             ShowContinueError(state,
   12774            0 :                               format("AirMassFlow={:.3R},CycRatio={:.3R},SpeedNum={:.0R}, MSHPMassFlowRateLow={:.3R}, MSHPMassFlowRateHigh={:.3R}",
   12775              :                                      AirMassFlow,
   12776            0 :                                      double(SpeedNum),
   12777              :                                      CycRatio,
   12778              :                                      MSHPMassFlowRateLow,
   12779              :                                      MSHPMassFlowRateHigh));
   12780            0 :             ShowFatalError(state, "Preceding condition(s) causes termination.");
   12781              :         } else {
   12782            0 :             ShowContinueError(state, "When AirMassFlow > 0.0 and CycRatio > 0.0, then MSHPMassFlowRateHigh must also be > 0.0");
   12783            0 :             ShowContinueErrorTimeStamp(state, "");
   12784            0 :             ShowContinueError(state,
   12785            0 :                               format("AirMassFlow={:.3R},CycRatio={:.3R}, MSHPMassFlowRateHigh={:.3R}", AirMassFlow, CycRatio, MSHPMassFlowRateHigh));
   12786            0 :             ShowFatalError(state, "Preceding condition(s) causes termination.");
   12787              :         }
   12788          265 :     } else if (CycRatio > 1.0 || SpeedRatio > 1.0) {
   12789            0 :         ShowSevereError(
   12790              :             state,
   12791            0 :             format("CalcMultiSpeedDXCoilCooling: {} \"{} Developer error - inconsistent speed ratios.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   12792            0 :         ShowContinueError(state, "CycRatio and SpeedRatio must be between 0.0 and 1.0");
   12793            0 :         ShowContinueErrorTimeStamp(state, "");
   12794            0 :         ShowContinueError(state, format("CycRatio={:.1R}, SpeedRatio = {:.1R}", CycRatio, SpeedRatio));
   12795            0 :         ShowFatalError(state, "Preceding condition(s) causes termination.");
   12796              :     }
   12797              : 
   12798          265 :     thisDXCoil.PartLoadRatio = 0.0;
   12799          265 :     state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
   12800          265 :     thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
   12801          265 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   12802          265 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   12803          265 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   12804              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12805              :     // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
   12806              :     // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
   12807          265 :     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
   12808          265 :     if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Air) {
   12809          265 :         CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp
   12810            0 :     } else if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
   12811              :         // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   12812            0 :         CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.MSEvapCondEffect(SpeedNumHS));
   12813            0 :         CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure, RoutineName);
   12814              :     }
   12815          265 :     if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
   12816          168 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   12817          168 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   12818            2 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
   12819              :         }
   12820              :     } else {
   12821           97 :         CrankcaseHeatingPower = 0.0;
   12822              :     }
   12823              : 
   12824          230 :     if ((AirMassFlow > 0.0 && CondInletTemp >= thisDXCoil.MinOATCompressor) && (thisDXCoil.availSched->getCurrentVal() > 0.0) &&
   12825          495 :         ((SpeedRatio > 0.0 && SingleMode == 0) || CycRatio > 0.0) && (compressorOp == HVAC::CompressorOp::On)) {
   12826              : 
   12827           99 :         RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat, RoutineName);
   12828           99 :         if (SpeedNum > 1 && SingleMode == 0) {
   12829              : 
   12830              :             // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at low speed
   12831           21 :             AirVolumeFlowRate = MSHPMassFlowRateLow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   12832              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12833              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   12834           21 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
   12835           21 :             if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   12836           26 :                  (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
   12837            5 :                 state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
   12838            5 :                 if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
   12839            2 :                     ShowWarningMessage(
   12840              :                         state,
   12841            2 :                         format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
   12842            1 :                                thisDXCoil.DXCoilType,
   12843            1 :                                thisDXCoil.Name,
   12844              :                                SpeedNumLS));
   12845            2 :                     ShowContinueErrorTimeStamp(state, "");
   12846            2 :                     ShowContinueError(state,
   12847            2 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   12848            1 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   12849            1 :                                              HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   12850              :                                              VolFlowperRatedTotCap));
   12851            2 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   12852            3 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   12853              :                 }
   12854           40 :                 ShowRecurringWarningErrorAtEnd(state,
   12855           10 :                                                format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
   12856              :                                                       "at speed {} error continues...",
   12857            5 :                                                       thisDXCoil.DXCoilType,
   12858            5 :                                                       thisDXCoil.Name,
   12859              :                                                       SpeedNumLS),
   12860              :                                                thisDXCoil.MSErrIndex(SpeedNumLS),
   12861              :                                                VolFlowperRatedTotCap,
   12862              :                                                VolFlowperRatedTotCap);
   12863              :             }
   12864              : 
   12865              :             // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at high speed
   12866           21 :             AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   12867              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12868              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   12869           21 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
   12870           21 :             if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   12871           21 :                  (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
   12872            0 :                 state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
   12873            0 :                 if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
   12874            0 :                     ShowWarningMessage(
   12875              :                         state,
   12876            0 :                         format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
   12877            0 :                                thisDXCoil.DXCoilType,
   12878            0 :                                thisDXCoil.Name,
   12879              :                                SpeedNumHS));
   12880            0 :                     ShowContinueErrorTimeStamp(state, "");
   12881            0 :                     ShowContinueError(state,
   12882            0 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   12883            0 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   12884            0 :                                              HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   12885              :                                              VolFlowperRatedTotCap));
   12886            0 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   12887            0 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   12888              :                 }
   12889            0 :                 ShowRecurringWarningErrorAtEnd(state,
   12890            0 :                                                format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
   12891              :                                                       "at speed {} error continues...",
   12892            0 :                                                       thisDXCoil.DXCoilType,
   12893            0 :                                                       thisDXCoil.Name,
   12894              :                                                       SpeedNumHS),
   12895              :                                                thisDXCoil.MSErrIndex(SpeedNumHS),
   12896              :                                                VolFlowperRatedTotCap,
   12897              :                                                VolFlowperRatedTotCap);
   12898              :             }
   12899              : 
   12900              :             // Adjust high speed coil bypass factor for actual maximum air flow rate.
   12901           21 :             RatedCBFHS = thisDXCoil.MSRatedCBF(SpeedNumHS);
   12902           21 :             CBFHS = AdjustCBF(RatedCBFHS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS), MSHPMassFlowRateHigh);
   12903           21 :             RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNumLS);
   12904           21 :             CBFLS = AdjustCBF(RatedCBFLS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS), MSHPMassFlowRateLow);
   12905              :             // get low speed total capacity and SHR at current conditions
   12906           63 :             CalcTotCapSHR(state,
   12907              :                           InletAirDryBulbTemp,
   12908              :                           InletAirHumRat,
   12909              :                           InletAirEnthalpy,
   12910              :                           InletAirWetBulbC,
   12911              :                           AirMassFlowRatioLS,
   12912              :                           MSHPMassFlowRateLow,
   12913           21 :                           thisDXCoil.MSRatedTotCap(SpeedNumLS),
   12914              :                           CBFLS,
   12915           21 :                           thisDXCoil.MSCCapFTemp(SpeedNumLS),
   12916           21 :                           thisDXCoil.MSCCapFFlow(SpeedNumLS),
   12917              :                           TotCapLS,
   12918              :                           SHRLS,
   12919              :                           CondInletTemp,
   12920              :                           OutdoorPressure,
   12921           21 :                           thisDXCoil.capModFacTotal);
   12922              :             // get low speed outlet conditions
   12923           21 :             hDelta = TotCapLS / MSHPMassFlowRateLow;
   12924              :             // Calculate new apparatus dew point conditions
   12925           21 :             hADP = InletAirEnthalpy - hDelta / (1.0 - CBFLS);
   12926           21 :             tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineNameHighSpeedAlt);
   12927              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12928              :             //  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   12929           21 :             wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
   12930           21 :             hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   12931              :             // get corresponding SHR
   12932           21 :             if ((InletAirEnthalpy - hADP) > 1.e-10) {
   12933           21 :                 SHRLS = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   12934              :             } else {
   12935            0 :                 SHRLS = 1.0;
   12936              :             }
   12937              :             // cr8918    SHRLS = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
   12938              :             // get low speed outlet conditions
   12939           21 :             LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
   12940           21 :             hTinwout = InletAirEnthalpy - (1.0 - SHRLS) * hDelta;
   12941           21 :             LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
   12942           21 :             LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
   12943           21 :             OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
   12944           21 :             if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   12945            1 :                 LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   12946            1 :                 LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineName);
   12947              :             }
   12948              : 
   12949              :             // get high speed total capacity and SHR at current conditions
   12950              : 
   12951           63 :             CalcTotCapSHR(state,
   12952              :                           InletAirDryBulbTemp,
   12953              :                           InletAirHumRat,
   12954              :                           InletAirEnthalpy,
   12955              :                           InletAirWetBulbC,
   12956              :                           AirMassFlowRatioHS,
   12957              :                           MSHPMassFlowRateHigh,
   12958           21 :                           thisDXCoil.MSRatedTotCap(SpeedNumHS),
   12959              :                           CBFHS,
   12960           21 :                           thisDXCoil.MSCCapFTemp(SpeedNumHS),
   12961           21 :                           thisDXCoil.MSCCapFFlow(SpeedNumHS),
   12962              :                           TotCapHS,
   12963              :                           SHRHS,
   12964              :                           CondInletTemp,
   12965              :                           OutdoorPressure,
   12966           21 :                           thisDXCoil.capModFacTotal);
   12967           21 :             hDelta = TotCapHS / MSHPMassFlowRateHigh;
   12968              :             // Calculate new apparatus dew point conditions
   12969           21 :             hADP = InletAirEnthalpy - hDelta / (1.0 - CBFHS);
   12970           21 :             tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
   12971              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   12972              :             //  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   12973           21 :             wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
   12974           21 :             hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   12975              :             // get corresponding SHR
   12976           21 :             if ((InletAirEnthalpy - hADP) > 1.e-10) {
   12977           21 :                 SHRHS = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   12978              :             } else {
   12979            0 :                 SHRHS = 1.0;
   12980              :             }
   12981              :             // cr8918    SHRHS = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
   12982              :             // get the part load factor that will account for cycling losses
   12983           21 :             PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), SpeedRatio);
   12984           21 :             if (PLF < 0.7) {
   12985            0 :                 PLF = 0.7;
   12986              :             }
   12987              :             // calculate the run time fraction
   12988           21 :             thisDXCoil.CoolingCoilRuntimeFraction = SpeedRatio / PLF;
   12989           21 :             thisDXCoil.PartLoadRatio = SpeedRatio;
   12990              : 
   12991           21 :             if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
   12992            0 :                 thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   12993              :             }
   12994              : 
   12995              :             // get high speed outlet conditions
   12996           21 :             HSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
   12997           21 :             hTinwout = InletAirEnthalpy - (1.0 - SHRHS) * hDelta;
   12998           21 :             HSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
   12999           21 :             HSOutletAirDryBulbTemp = PsyTdbFnHW(HSOutletAirEnthalpy, HSOutletAirHumRat);
   13000           21 :             OutletAirDryBulbTempSat = PsyTsatFnHPb(state, HSOutletAirEnthalpy, OutdoorPressure, RoutineName);
   13001           21 :             if (HSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   13002            1 :                 HSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   13003            1 :                 HSOutletAirHumRat = PsyWFnTdbH(state, HSOutletAirDryBulbTemp, HSOutletAirEnthalpy, RoutineName);
   13004              :             }
   13005              : 
   13006              :             //  If constant fan with cycling compressor, call function to determine "effective SHR"
   13007              :             //  which includes the part-load degradation on latent capacity
   13008           21 :             if (thisDXCoil.LatentImpact && fanOp == HVAC::FanOp::Continuous && SpeedRatio > 0.0) {
   13009            0 :                 QLatRated = thisDXCoil.MSRatedTotCap(SpeedNumHS) * (1.0 - thisDXCoil.MSRatedSHR(SpeedNumHS));
   13010            0 :                 QLatActual = TotCapHS * (1.0 - SHRHS);
   13011            0 :                 SHRUnadjusted = SHRHS;
   13012            0 :                 SHR = CalcEffectiveSHR(state,
   13013              :                                        DXCoilNum,
   13014              :                                        SHRHS,
   13015              :                                        thisDXCoil.CoolingCoilRuntimeFraction,
   13016              :                                        QLatRated,
   13017              :                                        QLatActual,
   13018              :                                        InletAirDryBulbTemp,
   13019              :                                        InletAirWetBulbC,
   13020              :                                        SpeedNumHS);
   13021              :                 // Calculate full load output conditions
   13022            0 :                 if (SHR > 1.0) {
   13023            0 :                     SHR = 1.0;
   13024              :                 }
   13025            0 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   13026            0 :                 if (SHR < 1.0) {
   13027            0 :                     HSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
   13028              :                 } else {
   13029            0 :                     HSOutletAirHumRat = InletAirHumRat;
   13030              :                 }
   13031            0 :                 HSOutletAirDryBulbTemp = PsyTdbFnHW(HSOutletAirEnthalpy, HSOutletAirHumRat);
   13032              :             }
   13033              : 
   13034              :             // get high speed EIR at current conditions
   13035           21 :             EIRTempModFacHS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirWetBulbC, CondInletTemp);
   13036           21 :             EIRFlowModFacHS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
   13037           21 :             EIRHS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumHS) * EIRFlowModFacHS * EIRTempModFacHS;
   13038              :             // get low speed EIR at current conditions
   13039           21 :             EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirWetBulbC, CondInletTemp);
   13040           21 :             EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
   13041           21 :             EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFacLS * EIRFlowModFacLS;
   13042              : 
   13043              :             // get current total capacity, SHR, EIR
   13044           21 :             if (SpeedRatio >= 1.0) {
   13045           15 :                 SHR = SHRHS;
   13046           15 :                 EIR = EIRHS;
   13047           15 :                 CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS);
   13048           15 :                 EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS);
   13049              :             } else {
   13050            6 :                 EIR = SpeedRatio * EIRHS + (1.0 - SpeedRatio) * EIRLS;
   13051            6 :                 SHR = SpeedRatio * SHRHS + (1.0 - SpeedRatio) * SHRLS;
   13052            6 :                 CondAirMassFlow =
   13053            6 :                     RhoAir * (SpeedRatio * thisDXCoil.MSEvapCondAirFlow(SpeedNumHS) + (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondAirFlow(SpeedNumLS));
   13054            6 :                 EvapCondPumpElecPower = SpeedRatio * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumHS) +
   13055            6 :                                         (1.0 - SpeedRatio) * thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNumLS);
   13056              :             }
   13057              : 
   13058              :             // Outlet calculation
   13059           21 :             Real64 SensibleOutputLS(0.0); // low speed sensible output rate
   13060           21 :             Real64 LatentOutputLS(0.0);   // low speed latent output rate
   13061           21 :             Real64 TotalOutputLS(0.0);    // low speed total output rate
   13062           21 :             Real64 SensibleOutputHS(0.0); // high speed sensible output rate
   13063           21 :             Real64 LatentOutputHS(0.0);   // high speed latent output rate
   13064           21 :             Real64 TotalOutputHS(0.0);    // high speed total output rate
   13065           21 :             CalcComponentSensibleLatentOutput(MSHPMassFlowRateLow,
   13066              :                                               InletAirDryBulbTemp,
   13067              :                                               InletAirHumRat,
   13068              :                                               LSOutletAirDryBulbTemp,
   13069              :                                               LSOutletAirHumRat,
   13070              :                                               SensibleOutputLS,
   13071              :                                               LatentOutputLS,
   13072              :                                               TotalOutputLS);
   13073           21 :             CalcComponentSensibleLatentOutput(MSHPMassFlowRateHigh,
   13074              :                                               InletAirDryBulbTemp,
   13075              :                                               InletAirHumRat,
   13076              :                                               HSOutletAirDryBulbTemp,
   13077              :                                               HSOutletAirHumRat,
   13078              :                                               SensibleOutputHS,
   13079              :                                               LatentOutputHS,
   13080              :                                               TotalOutputHS);
   13081           21 :             thisDXCoil.TotalCoolingEnergyRate = TotalOutputHS * SpeedRatio + TotalOutputLS * (1.0 - SpeedRatio);
   13082           21 :             thisDXCoil.SensCoolingEnergyRate = SensibleOutputHS * SpeedRatio + SensibleOutputLS * (1.0 - SpeedRatio);
   13083           21 :             thisDXCoil.LatCoolingEnergyRate = LatentOutputHS * SpeedRatio + LatentOutputLS * (1.0 - SpeedRatio);
   13084              :             // Average outlet enthalpy
   13085           21 :             OutletAirEnthalpy = InletAirEnthalpy - thisDXCoil.TotalCoolingEnergyRate / thisDXCoil.InletAirMassFlowRate;
   13086              : 
   13087           21 :             if (fanOp == HVAC::FanOp::Cycling) {
   13088            9 :                 state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
   13089              :             }
   13090              :             // Update outlet conditions
   13091           21 :             if (SpeedRatio == 0.0 && fanOp == HVAC::FanOp::Cycling) {
   13092            3 :                 OutletAirEnthalpy = LSOutletAirEnthalpy;
   13093            3 :                 OutletAirHumRat = LSOutletAirHumRat;
   13094            3 :                 OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
   13095           18 :             } else if (SpeedRatio >= 1.0 && fanOp == HVAC::FanOp::Cycling) {
   13096            6 :                 OutletAirEnthalpy = HSOutletAirEnthalpy;
   13097            6 :                 OutletAirHumRat = HSOutletAirHumRat;
   13098            6 :                 OutletAirDryBulbTemp = HSOutletAirDryBulbTemp;
   13099              :             } else {
   13100           12 :                 OutletAirHumRat =
   13101           12 :                     ((HSOutletAirHumRat * SpeedRatio * MSHPMassFlowRateHigh) + (LSOutletAirHumRat * (1.0 - SpeedRatio) * MSHPMassFlowRateLow)) /
   13102           12 :                     thisDXCoil.InletAirMassFlowRate;
   13103           12 :                 OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   13104           12 :                 if (OutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   13105            0 :                     OutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   13106            0 :                     OutletAirHumRat = PsyWFnTdbH(state, OutletAirDryBulbTemp, OutletAirEnthalpy, RoutineName);
   13107            0 :                     CalcComponentSensibleLatentOutput(AirMassFlow,
   13108              :                                                       InletAirDryBulbTemp,
   13109              :                                                       InletAirHumRat,
   13110              :                                                       OutletAirDryBulbTemp,
   13111              :                                                       OutletAirHumRat,
   13112            0 :                                                       thisDXCoil.SensCoolingEnergyRate,
   13113            0 :                                                       thisDXCoil.LatCoolingEnergyRate,
   13114            0 :                                                       thisDXCoil.TotalCoolingEnergyRate);
   13115              :                 }
   13116              :             }
   13117              : 
   13118           21 :             LSElecCoolingPower = TotCapLS * EIRLS;
   13119           21 :             HSElecCoolingPower = TotCapHS * EIRHS;
   13120              : 
   13121              :             // Power calculation
   13122           21 :             if (!thisDXCoil.PLRImpact) {
   13123           21 :                 thisDXCoil.ElecCoolingPower = SpeedRatio * HSElecCoolingPower + (1.0 - SpeedRatio) * LSElecCoolingPower;
   13124              :             } else {
   13125            0 :                 thisDXCoil.ElecCoolingPower =
   13126            0 :                     thisDXCoil.CoolingCoilRuntimeFraction * HSElecCoolingPower + (1.0 - thisDXCoil.CoolingCoilRuntimeFraction) * LSElecCoolingPower;
   13127              :             }
   13128              :             // Now reset runtime fraction to 1.0 (because LS is running the full timestep)
   13129           21 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0;
   13130              : 
   13131              :             //   Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
   13132           21 :             state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
   13133              : 
   13134              :             // Waste heat calculation
   13135              :             // TODO: waste heat not considered even if defined in Cooling:DX:MultiSpeed, N16, \field Speed 1 Rated Waste Heat Fraction of
   13136              :             // Power Input
   13137           21 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   13138            8 :                 if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
   13139            7 :                     WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
   13140              :                 } else {
   13141            1 :                     WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
   13142            1 :                                   thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
   13143              :                 }
   13144            8 :                 if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
   13145            7 :                     WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
   13146              :                 } else {
   13147            1 :                     WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
   13148            1 :                                   thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
   13149              :                 }
   13150            8 :                 thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
   13151            8 :                 if (thisDXCoil.MSHPHeatRecActive) {
   13152            1 :                     MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
   13153              :                 }
   13154              :             }
   13155              : 
   13156              :             // Energy use for other fuel types
   13157           21 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   13158            8 :                 thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
   13159            8 :                 thisDXCoil.ElecCoolingPower = 0.0;
   13160              :             }
   13161              : 
   13162           21 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   13163           21 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   13164           21 :             thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
   13165           21 :             thisDXCoil.CrankcaseHeaterPower = 0.0;
   13166              : 
   13167           99 :         } else if (CycRatio > 0.0) {
   13168              : 
   13169           78 :             if (fanOp == HVAC::FanOp::Cycling) {
   13170           37 :                 AirMassFlow /= CycRatio;
   13171              :             }
   13172           78 :             if (fanOp == HVAC::FanOp::Continuous) {
   13173           41 :                 AirMassFlow = MSHPMassFlowRateHigh;
   13174              :             }
   13175              : 
   13176              :             // Check for valid air volume flow per rated total cooling capacity (200 - 500 cfm/ton) at low speed
   13177           78 :             AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   13178              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13179              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   13180           78 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
   13181           78 :             if (((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   13182           99 :                  (VolFlowperRatedTotCap > HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) &&
   13183           21 :                 state.dataHVACGlobal->MSUSEconoSpeedNum == 0) {
   13184           21 :                 if (thisDXCoil.MSErrIndex(SpeedNum) == 0) {
   13185            4 :                     ShowWarningMessage(
   13186              :                         state,
   13187            4 :                         format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range at speed {}.",
   13188            2 :                                thisDXCoil.DXCoilType,
   13189            2 :                                thisDXCoil.Name,
   13190              :                                SpeedNum));
   13191            4 :                     ShowContinueErrorTimeStamp(state, "");
   13192            4 :                     ShowContinueError(state,
   13193            4 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   13194            2 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13195            2 :                                              HVAC::MaxCoolVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13196              :                                              VolFlowperRatedTotCap));
   13197            4 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   13198            6 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   13199              :                 }
   13200          168 :                 ShowRecurringWarningErrorAtEnd(state,
   13201           42 :                                                format("{} \"{}\" - Air volume flow rate per watt of rated total cooling capacity is out of range "
   13202              :                                                       "at speed {} error continues...",
   13203           21 :                                                       thisDXCoil.DXCoilType,
   13204           21 :                                                       thisDXCoil.Name,
   13205              :                                                       SpeedNumHS),
   13206              :                                                thisDXCoil.MSErrIndex(SpeedNumHS),
   13207              :                                                VolFlowperRatedTotCap,
   13208              :                                                VolFlowperRatedTotCap);
   13209              :             }
   13210              : 
   13211           78 :             if (thisDXCoil.CondenserType(SpeedNum) == DataHeatBalance::RefrigCondenserType::Evap) {
   13212              :                 // Outdoor wet-bulb temp from DataEnvironment + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   13213            0 :                 CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.MSEvapCondEffect(SpeedNum));
   13214            0 :                 CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure, RoutineName);
   13215              :             }
   13216              : 
   13217           78 :             RatedCBFLS = thisDXCoil.MSRatedCBF(SpeedNum);
   13218           78 :             CBFLS = AdjustCBF(RatedCBFLS, thisDXCoil.MSRatedAirMassFlowRate(SpeedNum), MSHPMassFlowRateHigh);
   13219              : 
   13220              :             // Adjust low speed coil bypass factor for actual flow rate.
   13221              :             // CBF = AdjustCBF(DXCoil(DXCoilNum)%RatedCBF2,DXCoil(DXCoilNum)%RatedAirMassFlowRate2,AirMassFlow)
   13222              :             // get low speed total capacity and SHR at current conditions
   13223          234 :             CalcTotCapSHR(state,
   13224              :                           InletAirDryBulbTemp,
   13225              :                           InletAirHumRat,
   13226              :                           InletAirEnthalpy,
   13227              :                           InletAirWetBulbC,
   13228              :                           AirMassFlowRatioLS,
   13229              :                           MSHPMassFlowRateHigh,
   13230           78 :                           thisDXCoil.MSRatedTotCap(SpeedNum),
   13231              :                           CBFLS,
   13232           78 :                           thisDXCoil.MSCCapFTemp(SpeedNum),
   13233           78 :                           thisDXCoil.MSCCapFFlow(SpeedNum),
   13234              :                           TotCapLS,
   13235              :                           SHRLS,
   13236              :                           CondInletTemp,
   13237              :                           OutdoorPressure,
   13238           78 :                           thisDXCoil.capModFacTotal);
   13239              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13240              :             //  Node(DXCoil(DXCoilNum)%AirInNode)%Press)
   13241           78 :             hDelta = TotCapLS / AirMassFlow;
   13242              :             // Adjust CBF for off-nominal flow
   13243           78 :             CBF = AdjustCBF(thisDXCoil.MSRatedCBF(SpeedNum), thisDXCoil.MSRatedAirMassFlowRate(SpeedNum), AirMassFlow);
   13244              :             // Calculate new apparatus dew point conditions
   13245           78 :             hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
   13246           78 :             tADP = PsyTsatFnHPb(state, hADP, OutdoorPressure, RoutineName);
   13247              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13248              :             //  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   13249           78 :             wADP = PsyWFnTdbH(state, tADP, hADP, RoutineName);
   13250           78 :             hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   13251              :             // get corresponding SHR
   13252           78 :             if ((InletAirEnthalpy - hADP) > 1.e-10) {
   13253           78 :                 SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   13254              :             } else {
   13255            0 :                 SHR = 1.0;
   13256              :             }
   13257              :             // cr8918    SHR = MIN((hTinwADP-hADP)/(InletAirEnthalpy-hADP),1.0d0)
   13258              : 
   13259              :             // get the part load factor that will account for cycling losses
   13260           78 :             PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNum), CycRatio);
   13261           78 :             if (fanOp == HVAC::FanOp::Cycling && CycRatio == 1.0 && PLF != 1.0) {
   13262            0 :                 if (thisDXCoil.PLFErrIndex == 0) {
   13263            0 :                     ShowWarningMessage(state,
   13264            0 :                                        format("The PLF curve value for DX cooling coil {} ={:.2R} for part-load ratio = 1", thisDXCoil.Name, PLF));
   13265            0 :                     ShowContinueError(state, "PLF curve value must be = 1.0 and has been reset to 1.0. Simulation is continuing.");
   13266            0 :                     ShowContinueErrorTimeStamp(state, "");
   13267              :                 }
   13268            0 :                 ShowRecurringWarningErrorAtEnd(
   13269            0 :                     state, thisDXCoil.Name + "\": DX cooling coil PLF curve value <> 1.0 warning continues...", thisDXCoil.PLFErrIndex, PLF, PLF);
   13270            0 :                 PLF = 1.0;
   13271              :             }
   13272              : 
   13273           78 :             if (PLF < 0.7) {
   13274            0 :                 PLF = 0.7;
   13275              :             }
   13276              :             // calculate the run time fraction
   13277           78 :             thisDXCoil.CoolingCoilRuntimeFraction = CycRatio / PLF;
   13278           78 :             thisDXCoil.PartLoadRatio = CycRatio;
   13279              : 
   13280           78 :             if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
   13281            0 :                 thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   13282              :             }
   13283              : 
   13284              :             // get low speed outlet conditions
   13285           78 :             LSOutletAirEnthalpy = InletAirEnthalpy - hDelta;
   13286           78 :             hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   13287           78 :             LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
   13288           78 :             LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
   13289           78 :             OutletAirDryBulbTempSat = PsyTsatFnHPb(state, LSOutletAirEnthalpy, OutdoorPressure, RoutineName);
   13290           78 :             if (LSOutletAirDryBulbTemp < OutletAirDryBulbTempSat) { // Limit to saturated conditions at OutletAirEnthalpy
   13291            0 :                 LSOutletAirDryBulbTemp = OutletAirDryBulbTempSat;
   13292            0 :                 LSOutletAirHumRat = PsyWFnTdbH(state, LSOutletAirDryBulbTemp, LSOutletAirEnthalpy, RoutineName);
   13293              :             }
   13294              : 
   13295              :             //  If constant fan with cycling compressor, call function to determine "effective SHR"
   13296              :             //  which includes the part-load degradation on latent capacity
   13297           78 :             if (fanOp == HVAC::FanOp::Continuous) {
   13298           41 :                 QLatRated = thisDXCoil.MSRatedTotCap(SpeedNum) * (1.0 - thisDXCoil.MSRatedSHR(SpeedNum));
   13299           41 :                 QLatActual = TotCapLS * (1.0 - SHR);
   13300           41 :                 SHRUnadjusted = SHR;
   13301           41 :                 SHR = CalcEffectiveSHR(state,
   13302              :                                        DXCoilNum,
   13303              :                                        SHR,
   13304              :                                        thisDXCoil.CoolingCoilRuntimeFraction,
   13305              :                                        QLatRated,
   13306              :                                        QLatActual,
   13307              :                                        InletAirDryBulbTemp,
   13308              :                                        InletAirWetBulbC,
   13309              :                                        SpeedNum);
   13310              :                 // Calculate full load output conditions
   13311           41 :                 if (SHR > 1.0) {
   13312            0 :                     SHR = 1.0;
   13313              :                 }
   13314           41 :                 hTinwout = InletAirEnthalpy - (1.0 - SHR) * hDelta;
   13315           41 :                 if (SHR < 1.0) {
   13316           33 :                     LSOutletAirHumRat = PsyWFnTdbH(state, InletAirDryBulbTemp, hTinwout, RoutineName);
   13317              :                 } else {
   13318            8 :                     LSOutletAirHumRat = InletAirHumRat;
   13319              :                 }
   13320           41 :                 LSOutletAirDryBulbTemp = PsyTdbFnHW(LSOutletAirEnthalpy, LSOutletAirHumRat);
   13321              :             }
   13322              : 
   13323           78 :             if (fanOp == HVAC::FanOp::Cycling) {
   13324           37 :                 state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
   13325              :             }
   13326           78 :             if (fanOp == HVAC::FanOp::Continuous) {
   13327              :                 // outlet conditions are average of inlet and low speed weighted by CycRatio
   13328              :                 // Continuous fan, cycling compressor
   13329           41 :                 Real64 CycAirFlowRatio =
   13330           41 :                     CycRatio * AirMassFlow / thisDXCoil.InletAirMassFlowRate; // ratio of compressor on airflow to average timestep airflow
   13331           41 :                 OutletAirEnthalpy = CycAirFlowRatio * LSOutletAirEnthalpy + (1.0 - CycAirFlowRatio) * InletAirEnthalpy;
   13332           41 :                 OutletAirHumRat = CycAirFlowRatio * LSOutletAirHumRat + (1.0 - CycAirFlowRatio) * InletAirHumRat;
   13333           41 :                 OutletAirDryBulbTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   13334              :             } else {
   13335           37 :                 OutletAirHumRat = LSOutletAirHumRat;
   13336           37 :                 OutletAirDryBulbTemp = LSOutletAirDryBulbTemp;
   13337           37 :                 OutletAirEnthalpy = LSOutletAirEnthalpy;
   13338              :             }
   13339              : 
   13340              :             // get low speed EIR at current conditions
   13341           78 :             EIRTempModFacLS = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNum), InletAirWetBulbC, CondInletTemp);
   13342           78 :             EIRFlowModFacLS = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNum), AirMassFlowRatioLS);
   13343           78 :             EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNum) * EIRTempModFacLS * EIRFlowModFacLS;
   13344              : 
   13345              :             // get the electrical power consumption
   13346           78 :             thisDXCoil.ElecCoolingPower = TotCapLS * EIRLS * thisDXCoil.CoolingCoilRuntimeFraction;
   13347              :             // calculate cooling output power
   13348              :             //    AirMassFlow = DXCoil(DXCoilNum)%InletAirMassFlowRate
   13349           78 :             CalcComponentSensibleLatentOutput(AirMassFlow,
   13350              :                                               InletAirDryBulbTemp,
   13351              :                                               InletAirHumRat,
   13352              :                                               LSOutletAirDryBulbTemp,
   13353              :                                               LSOutletAirHumRat,
   13354           78 :                                               thisDXCoil.SensCoolingEnergyRate,
   13355           78 :                                               thisDXCoil.LatCoolingEnergyRate,
   13356           78 :                                               thisDXCoil.TotalCoolingEnergyRate);
   13357           78 :             thisDXCoil.TotalCoolingEnergyRate = thisDXCoil.TotalCoolingEnergyRate * CycRatio;
   13358           78 :             thisDXCoil.SensCoolingEnergyRate = thisDXCoil.SensCoolingEnergyRate * CycRatio;
   13359           78 :             thisDXCoil.LatCoolingEnergyRate = thisDXCoil.LatCoolingEnergyRate * CycRatio;
   13360              : 
   13361              :             //   Calculation for heat reclaim needs to be corrected to use compressor power (not including condenser fan power)
   13362           78 :             state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
   13363           78 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   13364           78 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   13365           78 :             thisDXCoil.OutletAirTemp = OutletAirDryBulbTemp;
   13366           78 :             CondAirMassFlow = RhoAir * thisDXCoil.MSEvapCondAirFlow(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
   13367           78 :             EvapCondPumpElecPower = thisDXCoil.MSEvapCondPumpElecNomPower(SpeedNum) * thisDXCoil.CoolingCoilRuntimeFraction;
   13368              : 
   13369              :             // Waste heat
   13370           78 :             if (thisDXCoil.MSHPHeatRecActive) {
   13371            0 :                 if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
   13372            0 :                     thisDXCoil.MSFuelWasteHeat = thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecCoolingPower;
   13373              :                 } else {
   13374            0 :                     thisDXCoil.MSFuelWasteHeat = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNum), OutdoorDryBulb, InletAirDryBulbTemp) *
   13375            0 :                                                  thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecCoolingPower;
   13376              :                 }
   13377            0 :                 if (thisDXCoil.MSHPHeatRecActive) {
   13378            0 :                     MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
   13379              :                 }
   13380              :             }
   13381              :             // Energy use for other fuel types
   13382           78 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   13383           22 :                 thisDXCoil.FuelUsed = thisDXCoil.ElecCoolingPower;
   13384           22 :                 thisDXCoil.ElecCoolingPower = 0.0;
   13385              :             }
   13386              : 
   13387           78 :             if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   13388           78 :                 thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   13389              :             } else {
   13390            0 :                 thisDXCoil.CrankcaseHeaterPower =
   13391            0 :                     CrankcaseHeatingPower * (1.0 - max(thisDXCoil.CoolingCoilRuntimeFraction,
   13392            0 :                                                        state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction));
   13393              :             }
   13394              :         }
   13395              : 
   13396           99 :         if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
   13397              :             //******************
   13398              :             //             WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
   13399              :             //             H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
   13400              :             //                                /RhoWater [kgWater/m3]
   13401              :             //******************
   13402            0 :             RhoWater = RhoH2O(OutdoorDryBulb);
   13403            0 :             thisDXCoil.EvapWaterConsumpRate = (CondInletHumRat - OutdoorHumRat) * CondAirMassFlow / RhoWater;
   13404            0 :             thisDXCoil.EvapCondPumpElecPower = EvapCondPumpElecPower;
   13405              :             // set water system demand request (if needed)
   13406            0 :             if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
   13407            0 :                 state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
   13408            0 :                     thisDXCoil.EvapWaterConsumpRate;
   13409              :             }
   13410              : 
   13411              :             // Calculate basin heater power
   13412            0 :             CalcBasinHeaterPower(state,
   13413              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
   13414              :                                  thisDXCoil.basinHeaterSched,
   13415              :                                  thisDXCoil.BasinHeaterSetPointTemp,
   13416            0 :                                  thisDXCoil.BasinHeaterPower);
   13417            0 :             thisDXCoil.BasinHeaterPower *= (1.0 - thisDXCoil.CoolingCoilRuntimeFraction);
   13418              :         }
   13419              : 
   13420              :     } else {
   13421              : 
   13422              :         // DX coil is off; just pass through conditions
   13423          166 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   13424          166 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   13425          166 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   13426              : 
   13427          166 :         thisDXCoil.FuelUsed = 0.0;
   13428          166 :         thisDXCoil.ElecCoolingPower = 0.0;
   13429          166 :         thisDXCoil.TotalCoolingEnergyRate = 0.0;
   13430          166 :         thisDXCoil.SensCoolingEnergyRate = 0.0;
   13431          166 :         thisDXCoil.LatCoolingEnergyRate = 0.0;
   13432          166 :         thisDXCoil.EvapCondPumpElecPower = 0.0;
   13433          166 :         thisDXCoil.EvapWaterConsumpRate = 0.0;
   13434              : 
   13435          166 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   13436          166 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
   13437              :         } else {
   13438            0 :             thisDXCoil.CrankcaseHeaterPower =
   13439            0 :                 CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).HeatingCoilRuntimeFraction);
   13440              :         }
   13441              : 
   13442              :         // Calculate basin heater power
   13443          166 :         if (thisDXCoil.CondenserType(DXMode) == DataHeatBalance::RefrigCondenserType::Evap) {
   13444            0 :             CalcBasinHeaterPower(state,
   13445              :                                  thisDXCoil.BasinHeaterPowerFTempDiff,
   13446              :                                  thisDXCoil.basinHeaterSched,
   13447              :                                  thisDXCoil.BasinHeaterSetPointTemp,
   13448            0 :                                  thisDXCoil.BasinHeaterPower);
   13449              :         }
   13450              :     }
   13451              : 
   13452          265 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   13453          265 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   13454          265 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
   13455          265 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   13456          265 :     thisDXCoil.CondInletTemp = CondInletTemp; // Save condenser inlet temp in the data structure
   13457              : 
   13458              :     // set outlet node conditions
   13459          265 :     int airOutletNode = thisDXCoil.AirOutNode;
   13460          265 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   13461          265 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   13462              : 
   13463              :     // calc secondary coil if specified
   13464          265 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   13465            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   13466              :     }
   13467          265 : }
   13468              : 
   13469          211 : void CalcMultiSpeedDXCoilHeating(EnergyPlusData &state,
   13470              :                                  int const DXCoilNum,     // the number of the DX heating coil to be simulated
   13471              :                                  Real64 const SpeedRatio, // = (CompressorSpeed - CompressorSpeedMin) / (CompressorSpeedMax - CompressorSpeedMin)
   13472              :                                  Real64 const CycRatio,   // cycling part load ratio
   13473              :                                  int const SpeedNum,      // Speed number
   13474              :                                  HVAC::FanOp const fanOp, // Fan operation mode
   13475              :                                  int const SingleMode     // Single mode operation Yes/No; 1=Yes, 0=No
   13476              : )
   13477              : {
   13478              : 
   13479              :     // SUBROUTINE INFORMATION:
   13480              :     //       AUTHOR         Lixing Gu, FSEC
   13481              :     //       DATE WRITTEN   June 2007
   13482              :     //       RE-ENGINEERED  Revised based on CalcDXHeatingCoil
   13483              : 
   13484              :     // PURPOSE OF THIS SUBROUTINE:
   13485              :     // Calculates the air-side performance and electrical energy use of a direct-
   13486              :     // expansion, air-cooled cooling unit with a multispeed compressor.
   13487              : 
   13488              :     // METHODOLOGY EMPLOYED:
   13489              :     // Uses the same methodology as the single speed DX heating unit model (SUBROUTINE CalcDXHeatingCoil).
   13490              :     // In addition it assumes that the unit performance is obtained by interpolating between
   13491              :     // the performance at high speed and that at low speed. If the output needed is below
   13492              :     // that produced at low speed, the compressor cycles between off and low speed.
   13493              : 
   13494              :     // Using/Aliasing
   13495              :     using Curve::CurveValue;
   13496          211 :     Real64 MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
   13497          211 :     Real64 MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
   13498          211 :     auto &MSHPWasteHeat = state.dataHVACGlobal->MSHPWasteHeat;
   13499              : 
   13500              :     // SUBROUTINE ARGUMENT DEFINITIONS:
   13501              :     // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
   13502              : 
   13503              :     // SUBROUTINE PARAMETER DEFINITIONS:
   13504              :     static constexpr std::string_view RoutineName("CalcMultiSpeedDXCoilHeating");
   13505              :     static constexpr std::string_view RoutineNameAverageLoad("CalcMultiSpeedDXCoilHeating:Averageload");
   13506              :     static constexpr std::string_view RoutineNameFullLoad("CalcMultiSpeedDXCoilHeating:fullload");
   13507              : 
   13508              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   13509              :     Real64 AirMassFlow;         // dry air mass flow rate through coil [kg/s]
   13510              :     Real64 InletAirWetBulbC;    // wetbulb temperature of inlet air [C]
   13511              :     Real64 InletAirDryBulbTemp; // inlet air dry bulb temperature [C]
   13512              :     Real64 InletAirEnthalpy;    // inlet air enthalpy [J/kg]
   13513              :     Real64 InletAirHumRat;      // inlet air humidity ratio [kg/kg]
   13514              :     Real64 OutletAirEnthalpy;   // outlet air enthalpy [J/kg]
   13515              :     Real64 OutletAirHumRat;     // outlet air humidity ratio [kg/kg]
   13516              :     Real64 TotCapHS;            // total capacity at high speed [W]
   13517              :     Real64 TotCapLS;            // total capacity at low speed [W]
   13518              :     Real64 TotCapHSAdj;         // total adjusted capacity at high speed [W]
   13519              :     Real64 TotCapLSAdj;         // total adjusted capacity at low speed [W]
   13520              :     Real64 EIRHS;               // EIR at off rated conditions (high speed)
   13521              :     Real64 EIRLS;               // EIR at off rated conditions (low speed)
   13522              :     Real64 TotCap;              // total capacity at current speed [W]
   13523              :     Real64 TotCapAdj;           // total adjusted capacity at current speed [W]
   13524              :     Real64 EIR;                 // EIR at current speed
   13525              :     Real64 PLF;                 // Part load factor, accounts for thermal lag at compressor startup, used in
   13526              :     // power calculation
   13527              :     Real64 OutdoorDryBulb;            // Outdoor dry-bulb temperature at condenser (C)
   13528              :     Real64 OutdoorHumRat;             // Outdoor humidity ratio at condenser (kg/kg)
   13529              :     Real64 OutdoorPressure;           // Outdoor barometric pressure at condenser (Pa)
   13530              :     int SpeedNumHS;                   // High speed number
   13531              :     int SpeedNumLS;                   // Low speed number
   13532              :     Real64 AirMassFlowRatioLS;        // airflow ratio at low speed
   13533              :     Real64 AirMassFlowRatioHS;        // airflow ratio at high speed
   13534              :     Real64 AirFlowRatio;              // Airflow ratio
   13535              :     Real64 PLRHeating;                // Part load ratio in heating
   13536              :     Real64 CrankcaseHeatingPower;     // Power due to crank case heater
   13537              :     Real64 AirVolumeFlowRate;         // Air volume flow rate across the heating coil
   13538              :     Real64 VolFlowperRatedTotCap;     // Air volume flow rate divided by rated total heating capacity
   13539          211 :     Real64 TotCapTempModFac(0.0);     // Total capacity modifier as a function of temperature
   13540              :     Real64 TotCapFlowModFac;          // Total capacity modifier as a function of flow ratio
   13541              :     Real64 OutdoorCoilT;              // Outdoor coil temperature
   13542              :     Real64 OutdoorCoildw;             // Outdoor coil delta w assuming coil temperature of OutdoorCoilT
   13543              :     Real64 LoadDueToDefrost;          // Additional load due to defrost
   13544              :     Real64 LoadDueToDefrostLS;        // Additional load due to defrost at low speed
   13545              :     Real64 LoadDueToDefrostHS;        // Additional load due to defrost at high speed
   13546              :     Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
   13547              :     Real64 FractionalDefrostTime;     // Fraction of time step when system is in defrost
   13548              :     Real64 InputPowerMultiplier;      // Multiplier for power when system is in defrost
   13549              :     Real64 DefrostEIRTempModFac;      // EIR modifier for defrost
   13550              :     Real64 FullLoadOutAirEnth;        // Outlet full load enthalpy
   13551              :     Real64 FullLoadOutAirHumRat;      // Outlet humidity ratio at full load
   13552              :     Real64 FullLoadOutAirTemp;        // Outlet temperature at full load
   13553              :     Real64 FullLoadOutAirRH;          // Outlet relative humidity at full load
   13554              :     Real64 OutletAirTemp;             // Supply air temperature
   13555          211 :     Real64 EIRTempModFac(0.0);        // EIR modifier as a function of temperature
   13556              :     Real64 EIRFlowModFac;             // EIR modifier as a function of airflow ratio
   13557              :     Real64 WasteHeatLS;               // Waste heat at low speed
   13558              :     Real64 WasteHeatHS;               // Waste heat at high speed
   13559              :     Real64 LSFullLoadOutAirEnth;      // Outlet full load enthalpy at low speed
   13560              :     Real64 HSFullLoadOutAirEnth;      // Outlet full load enthalpy at high speed
   13561              :     Real64 LSElecHeatingPower;        // Full load power at low speed
   13562              :     Real64 HSElecHeatingPower;        // Full load power at high speed
   13563              :     Real64 DefrostPowerLS;            // Defrost power at low speed [W]
   13564              :     Real64 DefrostPowerHS;            // Defrost power at high speed [W]
   13565              : 
   13566              :     // Autodesk:Uninit Initialize variables used uninitialized
   13567          211 :     FullLoadOutAirEnth = 0.0; // Autodesk:Uninit Force default initialization
   13568              : 
   13569          211 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   13570              : 
   13571          211 :     if (SpeedNum > 1) {
   13572           54 :         SpeedNumLS = SpeedNum - 1;
   13573           54 :         SpeedNumHS = SpeedNum;
   13574           54 :         if (SpeedNum > thisDXCoil.NumOfSpeeds) {
   13575            0 :             SpeedNumLS = thisDXCoil.NumOfSpeeds - 1;
   13576            0 :             SpeedNumHS = thisDXCoil.NumOfSpeeds;
   13577              :         }
   13578              :     } else {
   13579          157 :         SpeedNumLS = 1;
   13580          157 :         SpeedNumHS = 1;
   13581              :     }
   13582              : 
   13583          211 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   13584          211 :     AirMassFlowRatioLS = MSHPMassFlowRateLow / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumLS);
   13585          211 :     AirMassFlowRatioHS = MSHPMassFlowRateHigh / thisDXCoil.MSRatedAirMassFlowRate(SpeedNumHS);
   13586          211 :     if ((AirMassFlow > 0.0) && (CycRatio > 0.0) && (MSHPMassFlowRateHigh == 0.0)) {
   13587            0 :         ShowSevereError(
   13588              :             state,
   13589            0 :             format("CalcMultiSpeedDXCoilHeating: {} \"{} Developer error - inconsistent airflow rates.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   13590            0 :         if (MSHPMassFlowRateLow == 0.0 && SpeedNum > 1) {
   13591            0 :             ShowContinueError(state,
   13592              :                               "When AirMassFlow > 0.0 and CycRatio > 0.0 and SpeedNum > 1, then MSHPMassFlowRateLow and MSHPMassFlowRateHigh "
   13593              :                               "must also be > 0.0");
   13594            0 :             ShowContinueErrorTimeStamp(state, "");
   13595            0 :             ShowContinueError(state,
   13596            0 :                               format("AirMassFlow={:.3R},CycRatio={:.3R},SpeedNum={:.0R}, MSHPMassFlowRateLow={:.3R}, MSHPMassFlowRateHigh={:.3R}",
   13597              :                                      AirMassFlow,
   13598            0 :                                      double(SpeedNum),
   13599              :                                      CycRatio,
   13600              :                                      MSHPMassFlowRateLow,
   13601              :                                      MSHPMassFlowRateHigh));
   13602            0 :             ShowFatalError(state, "Preceding condition(s) causes termination.");
   13603              :         } else {
   13604            0 :             ShowContinueError(state, "When AirMassFlow > 0.0 and CycRatio > 0.0, then MSHPMassFlowRateHigh must also be > 0.0");
   13605            0 :             ShowContinueErrorTimeStamp(state, "");
   13606            0 :             ShowContinueError(state,
   13607            0 :                               format("AirMassFlow={:.3R},CycRatio={:.3R}, MSHPMassFlowRateHigh={:.3R}", AirMassFlow, CycRatio, MSHPMassFlowRateHigh));
   13608            0 :             ShowFatalError(state, "Preceding condition(s) causes termination.");
   13609              :         }
   13610          211 :     } else if (CycRatio > 1.0 || SpeedRatio > 1.0) {
   13611            0 :         ShowSevereError(
   13612              :             state,
   13613            0 :             format("CalcMultiSpeedDXCoilHeating: {} \"{} Developer error - inconsistent speed ratios.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   13614            0 :         ShowContinueError(state, "CycRatio and SpeedRatio must be between 0.0 and 1.0");
   13615            0 :         ShowContinueErrorTimeStamp(state, "");
   13616            0 :         ShowContinueError(state, format("CycRatio={:.1R}, SpeedRatio = {:.1R}", CycRatio, SpeedRatio));
   13617            0 :         ShowFatalError(state, "Preceding condition(s) causes termination.");
   13618              :     }
   13619              : 
   13620          211 :     AirFlowRatio = 1.0;
   13621          211 :     if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   13622           22 :         MSHPWasteHeat = 0.0;
   13623              :     }
   13624              : 
   13625              :     // Get condenser outdoor node info from DX Heating Coil
   13626          211 :     if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
   13627           71 :         OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Press;
   13628              :         // If node is not connected to anything, pressure = default, use weather data
   13629           71 :         if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   13630           71 :             OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   13631           71 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   13632           71 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   13633              :         } else {
   13634            0 :             OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp;
   13635            0 :             OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).HumRat;
   13636              :         }
   13637           71 :         if (thisDXCoil.IsSecondaryDXCoilInZone) {
   13638            0 :             auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   13639            0 :             OutdoorDryBulb = secZoneHB.ZT;
   13640            0 :             OutdoorHumRat = secZoneHB.airHumRat;
   13641              :             // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb;
   13642            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   13643              :         }
   13644          140 :     } else if (thisDXCoil.IsSecondaryDXCoilInZone) {
   13645            0 :         auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   13646            0 :         OutdoorDryBulb = secZoneHB.ZT;
   13647            0 :         OutdoorHumRat = secZoneHB.airHumRat;
   13648              :         // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb;
   13649            0 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   13650              :     } else {
   13651          140 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   13652          140 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   13653          140 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   13654              :     }
   13655              : 
   13656          211 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   13657          211 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   13658          211 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   13659              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13660              :     // InletAirPressure = DXCoil(DXCoilNum)%InletAirPressure
   13661              :     // InletAirWetBulbC = PsyTwbFnTdbWPb(InletAirDryBulbTemp,InletAirHumRat,InletAirPressure)
   13662          211 :     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure, RoutineName);
   13663          211 :     PLRHeating = 0.0;
   13664          211 :     thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
   13665              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
   13666          211 :     if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
   13667          123 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   13668          123 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   13669            0 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
   13670              :         }
   13671              :     } else {
   13672           88 :         CrankcaseHeatingPower = 0.0;
   13673              :     }
   13674          211 :     thisDXCoil.PartLoadRatio = 0.0;
   13675          211 :     state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
   13676              : 
   13677          302 :     if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && ((CycRatio > 0.0) || (SpeedRatio > 0.0 && SingleMode == 0)) &&
   13678           91 :         OutdoorDryBulb > thisDXCoil.MinOATCompressor) {
   13679              : 
   13680           91 :         if (SpeedNum > 1 && SingleMode == 0) {
   13681              : 
   13682              :             // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton) at low speed
   13683           28 :             AirVolumeFlowRate = MSHPMassFlowRateLow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   13684              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13685              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   13686           28 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumLS);
   13687           56 :             if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   13688           28 :                 (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
   13689            0 :                 if (thisDXCoil.MSErrIndex(SpeedNumLS) == 0) {
   13690            0 :                     ShowWarningMessage(
   13691              :                         state,
   13692            0 :                         format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
   13693            0 :                                thisDXCoil.DXCoilType,
   13694            0 :                                thisDXCoil.Name,
   13695              :                                SpeedNumLS));
   13696            0 :                     ShowContinueErrorTimeStamp(state, "");
   13697            0 :                     ShowContinueError(state,
   13698            0 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   13699            0 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13700            0 :                                              HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13701              :                                              VolFlowperRatedTotCap));
   13702            0 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   13703            0 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   13704              :                 }
   13705            0 :                 ShowRecurringWarningErrorAtEnd(state,
   13706            0 :                                                format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
   13707              :                                                       "at speed {} error continues...",
   13708            0 :                                                       thisDXCoil.DXCoilType,
   13709            0 :                                                       thisDXCoil.Name,
   13710              :                                                       SpeedNumLS),
   13711              :                                                thisDXCoil.MSErrIndex(SpeedNumLS),
   13712              :                                                VolFlowperRatedTotCap,
   13713              :                                                VolFlowperRatedTotCap);
   13714              :             }
   13715              : 
   13716              :             // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton) at high speed
   13717           28 :             AirVolumeFlowRate = MSHPMassFlowRateHigh / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   13718              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13719              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   13720           28 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNumHS);
   13721           56 :             if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   13722           28 :                 (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
   13723            0 :                 if (thisDXCoil.MSErrIndex(SpeedNumHS) == 0) {
   13724            0 :                     ShowWarningMessage(
   13725              :                         state,
   13726            0 :                         format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed {}.",
   13727            0 :                                thisDXCoil.DXCoilType,
   13728            0 :                                thisDXCoil.Name,
   13729              :                                SpeedNumHS));
   13730            0 :                     ShowContinueErrorTimeStamp(state, "");
   13731            0 :                     ShowContinueError(state,
   13732            0 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   13733            0 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13734            0 :                                              HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   13735              :                                              VolFlowperRatedTotCap));
   13736            0 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   13737            0 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   13738              :                 }
   13739            0 :                 ShowRecurringWarningErrorAtEnd(state,
   13740            0 :                                                format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range "
   13741              :                                                       "at speed {} error continues...",
   13742            0 :                                                       thisDXCoil.DXCoilType,
   13743            0 :                                                       thisDXCoil.Name,
   13744              :                                                       SpeedNumHS),
   13745              :                                                thisDXCoil.MSErrIndex(SpeedNumHS),
   13746              :                                                VolFlowperRatedTotCap,
   13747              :                                                VolFlowperRatedTotCap);
   13748              :             }
   13749              : 
   13750              :             // Get total capacity modifying factor (function of temperature) for off-rated conditions
   13751              :             // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
   13752              :             // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   13753              :             // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   13754              :             // Low speed
   13755           28 :             if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNumLS))->numDims == 1) {
   13756            1 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), OutdoorDryBulb);
   13757              :             } else {
   13758           27 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
   13759              :             }
   13760              :             //  Get total capacity modifying factor (function of mass flow) for off-rated conditions
   13761           28 :             TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumLS), AirMassFlowRatioLS);
   13762              :             // Calculate total heating capacity for off-rated conditions
   13763           28 :             TotCapLS = thisDXCoil.MSRatedTotCap(SpeedNumLS) * TotCapFlowModFac * TotCapTempModFac;
   13764              :             // High speed
   13765           28 :             if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNumHS))->numDims == 1) {
   13766            1 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), OutdoorDryBulb);
   13767              :             } else {
   13768           27 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
   13769              :             }
   13770              :             //  Get total capacity modifying factor (function of mass flow) for off-rated conditions
   13771           28 :             TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNumHS), AirMassFlowRatioHS);
   13772              :             // Calculate total heating capacity for off-rated conditions
   13773           28 :             TotCapHS = thisDXCoil.MSRatedTotCap(SpeedNumHS) * TotCapFlowModFac * TotCapTempModFac;
   13774              :             // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
   13775              :             // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
   13776              :             // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   13777              :             // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   13778              :             // Low Speed
   13779           28 :             if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(SpeedNumLS))->numDims == 1) {
   13780            1 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), OutdoorDryBulb);
   13781              :             } else {
   13782           27 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumLS), InletAirDryBulbTemp, OutdoorDryBulb);
   13783              :             }
   13784           28 :             EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumLS), AirMassFlowRatioLS);
   13785           28 :             EIRLS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumLS) * EIRTempModFac * EIRFlowModFac;
   13786              :             // High Speed
   13787           28 :             if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(SpeedNumHS))->numDims == 1) {
   13788            1 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), OutdoorDryBulb);
   13789              :             } else {
   13790           27 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(SpeedNumHS), InletAirDryBulbTemp, OutdoorDryBulb);
   13791              :             }
   13792           28 :             EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(SpeedNumHS), AirMassFlowRatioHS);
   13793           28 :             EIRHS = 1.0 / thisDXCoil.MSRatedCOP(SpeedNumHS) * EIRTempModFac * EIRFlowModFac;
   13794              : 
   13795              :             // Calculating adjustment factors for defrost
   13796              :             // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
   13797           28 :             OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
   13798           28 :             OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
   13799              : 
   13800              :             // Initializing defrost adjustment factors
   13801           28 :             LoadDueToDefrostLS = 0.0;
   13802           28 :             LoadDueToDefrostHS = 0.0;
   13803           28 :             HeatingCapacityMultiplier = 1.0;
   13804           28 :             FractionalDefrostTime = 0.0;
   13805           28 :             InputPowerMultiplier = 1.0;
   13806           28 :             DefrostPowerLS = 0.0;
   13807           28 :             DefrostPowerHS = 0.0;
   13808              : 
   13809              :             // Check outdoor temperature to determine if defrost is active
   13810           28 :             if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
   13811              :                 // Calculate defrost adjustment factors depending on defrost control type
   13812            6 :                 if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
   13813            6 :                     FractionalDefrostTime = thisDXCoil.DefrostTime;
   13814            6 :                     if (FractionalDefrostTime > 0.0) {
   13815            5 :                         if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13816            2 :                             HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   13817            2 :                             InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   13818              :                         } else {
   13819            3 :                             HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
   13820            3 :                             InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
   13821            3 :                             if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13822            2 :                                 ShowWarningMessage(
   13823              :                                     state,
   13824            2 :                                     format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   13825              :                                            "actuator must be both provided for DX heating coil {}",
   13826            1 :                                            thisDXCoil.Name));
   13827            3 :                                 ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   13828              :                             }
   13829              :                         }
   13830              :                     }
   13831              :                 } else { // else defrost control is on-demand
   13832            0 :                     FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
   13833            0 :                     if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13834            0 :                         HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   13835            0 :                         InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   13836              :                     } else {
   13837            0 :                         HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
   13838            0 :                         InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
   13839            0 :                         if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   13840            0 :                             ShowWarningMessage(state,
   13841            0 :                                                format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   13842              :                                                       "actuator must be both provided for DX heating coil {}",
   13843            0 :                                                       thisDXCoil.Name));
   13844            0 :                             ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   13845              :                         }
   13846              :                     }
   13847              :                 }
   13848              : 
   13849            6 :                 if (FractionalDefrostTime > 0.0) {
   13850              :                     // Calculate defrost adjustment factors depending on defrost control strategy
   13851            5 :                     if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
   13852            1 :                         DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
   13853            1 :                         LoadDueToDefrostLS =
   13854            1 :                             (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667);
   13855            1 :                         DefrostPowerLS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumLS) / 1.01667) * FractionalDefrostTime;
   13856            1 :                         LoadDueToDefrostHS =
   13857            1 :                             (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667);
   13858            1 :                         DefrostPowerHS = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(SpeedNumHS) / 1.01667) * FractionalDefrostTime;
   13859              :                     } else { // Defrost strategy is resistive
   13860            4 :                         thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
   13861              :                     }
   13862              :                 } else { // Defrost is not active because (OutDryBulbTemp .GT. DXCoil(DXCoilNum)%MaxOATDefrost)
   13863            1 :                     thisDXCoil.DefrostPower = 0.0;
   13864              :                 }
   13865              :             }
   13866              : 
   13867           28 :             TotCapLSAdj = TotCapLS * HeatingCapacityMultiplier;
   13868           28 :             TotCapHSAdj = TotCapHS * HeatingCapacityMultiplier;
   13869              : 
   13870              :             // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
   13871           28 :             PLRHeating = min(1.0, (SpeedRatio + LoadDueToDefrostHS / TotCapHSAdj));
   13872           28 :             PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(SpeedNumHS), PLRHeating); // Calculate part-load factor
   13873              : 
   13874           28 :             if (PLF < 0.7) {
   13875            0 :                 if (thisDXCoil.PLRErrIndex == 0) {
   13876            0 :                     ShowWarningMessage(
   13877              :                         state,
   13878            0 :                         format("The PLF curve value at high speed for DX multispeed heating coil {} ={:.2R} for part-load ratio ={:.2R}",
   13879            0 :                                thisDXCoil.Name,
   13880              :                                PLF,
   13881              :                                PLRHeating));
   13882            0 :                     ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   13883            0 :                     ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:MultiSpeed].");
   13884            0 :                     ShowContinueErrorTimeStamp(state, "");
   13885              :                 }
   13886            0 :                 ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
   13887            0 :                 PLF = 0.7;
   13888              :             }
   13889              : 
   13890           28 :             thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
   13891           28 :             if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
   13892            0 :                 if (thisDXCoil.ErrIndex4 == 0) {
   13893            0 :                     ShowWarningMessage(state,
   13894            0 :                                        format("The runtime fraction at high speed for DX multispeed heating coil {} exceeded 1.0. [{:.4R}].",
   13895            0 :                                               thisDXCoil.Name,
   13896            0 :                                               thisDXCoil.HeatingCoilRuntimeFraction));
   13897            0 :                     ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
   13898            0 :                     ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   13899            0 :                     ShowContinueErrorTimeStamp(state, "");
   13900              :                 }
   13901            0 :                 ShowRecurringWarningErrorAtEnd(state,
   13902            0 :                                                thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
   13903            0 :                                                thisDXCoil.ErrIndex4,
   13904            0 :                                                thisDXCoil.HeatingCoilRuntimeFraction,
   13905            0 :                                                thisDXCoil.HeatingCoilRuntimeFraction);
   13906            0 :                 thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   13907           28 :             } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
   13908            0 :                 thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   13909              :             }
   13910              : 
   13911              :             // Get full load output and power
   13912           28 :             LSFullLoadOutAirEnth = InletAirEnthalpy + TotCapLSAdj / MSHPMassFlowRateLow;
   13913           28 :             HSFullLoadOutAirEnth = InletAirEnthalpy + TotCapHSAdj / MSHPMassFlowRateHigh;
   13914           28 :             LSElecHeatingPower = TotCapLS * EIRLS * InputPowerMultiplier;
   13915           28 :             HSElecHeatingPower = TotCapHS * EIRHS * InputPowerMultiplier;
   13916           28 :             OutletAirHumRat = InletAirHumRat;
   13917              : 
   13918              :             // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
   13919           28 :             if (fanOp == HVAC::FanOp::Cycling) {
   13920            1 :                 state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
   13921              :             }
   13922              : 
   13923              :             // Power calculation
   13924           28 :             if (!thisDXCoil.PLRImpact) {
   13925           28 :                 thisDXCoil.ElecHeatingPower = SpeedRatio * HSElecHeatingPower + (1.0 - SpeedRatio) * LSElecHeatingPower;
   13926              :             } else {
   13927            0 :                 thisDXCoil.ElecHeatingPower =
   13928            0 :                     thisDXCoil.HeatingCoilRuntimeFraction * HSElecHeatingPower + (1.0 - thisDXCoil.HeatingCoilRuntimeFraction) * LSElecHeatingPower;
   13929              :             }
   13930              : 
   13931           28 :             thisDXCoil.TotalHeatingEnergyRate = MSHPMassFlowRateHigh * (HSFullLoadOutAirEnth - InletAirEnthalpy) * SpeedRatio +
   13932           28 :                                                 MSHPMassFlowRateLow * (LSFullLoadOutAirEnth - InletAirEnthalpy) * (1.0 - SpeedRatio);
   13933           28 :             OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
   13934           28 :             OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   13935           28 :             FullLoadOutAirRH = PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, OutdoorPressure, RoutineNameAverageLoad);
   13936           28 :             if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
   13937            0 :                 OutletAirTemp = PsyTsatFnHPb(state,
   13938              :                                              FullLoadOutAirEnth,
   13939              :                                              OutdoorPressure,
   13940              :                                              RoutineName); // Autodesk:Uninit FullLoadOutAirEnth was possibly uninitialized
   13941            0 :                 OutletAirHumRat = PsyWFnTdbH(
   13942              :                     state, OutletAirTemp, FullLoadOutAirEnth, RoutineName); // Autodesk:Uninit FullLoadOutAirEnth was possibly uninitialized
   13943              :             }
   13944              : 
   13945              :             // Waste heat calculation
   13946           28 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   13947            1 :                 if (thisDXCoil.MSWasteHeat(SpeedNumLS) == 0) {
   13948            0 :                     WasteHeatLS = thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
   13949              :                 } else {
   13950            1 :                     WasteHeatLS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumLS), OutdoorDryBulb, InletAirDryBulbTemp) *
   13951            1 :                                   thisDXCoil.MSWasteHeatFrac(SpeedNumLS);
   13952              :                 }
   13953            1 :                 if (thisDXCoil.MSWasteHeat(SpeedNumHS) == 0) {
   13954            0 :                     WasteHeatHS = thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
   13955              :                 } else {
   13956            1 :                     WasteHeatHS = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNumHS), OutdoorDryBulb, InletAirDryBulbTemp) *
   13957            1 :                                   thisDXCoil.MSWasteHeatFrac(SpeedNumHS);
   13958              :                 }
   13959            1 :                 thisDXCoil.MSFuelWasteHeat = (SpeedRatio * WasteHeatHS + (1.0 - SpeedRatio) * WasteHeatLS) * thisDXCoil.ElecCoolingPower;
   13960            1 :                 if (thisDXCoil.MSHPHeatRecActive) {
   13961            0 :                     MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
   13962              :                 }
   13963              :             }
   13964           28 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   13965              : 
   13966            1 :                 thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
   13967            1 :                 thisDXCoil.ElecHeatingPower = 0.0;
   13968              :             }
   13969              : 
   13970              :             // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
   13971              :             // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
   13972           28 :             if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
   13973           21 :                 if (!thisDXCoil.PLRImpact) {
   13974           21 :                     thisDXCoil.DefrostPower = DefrostPowerHS * SpeedRatio + DefrostPowerLS * (1.0 - SpeedRatio);
   13975              :                 } else {
   13976            0 :                     thisDXCoil.DefrostPower =
   13977            0 :                         DefrostPowerHS * thisDXCoil.HeatingCoilRuntimeFraction + DefrostPowerLS * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
   13978              :                 }
   13979              :             }
   13980           28 :             thisDXCoil.OutletAirTemp = OutletAirTemp;
   13981           28 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   13982           28 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   13983           28 :             thisDXCoil.CrankcaseHeaterPower = 0.0;
   13984              : 
   13985              :             // Stage 1
   13986           63 :         } else if (CycRatio > 0.0 || (CycRatio > 0.0 && SingleMode == 1)) {
   13987              : 
   13988              :             // for cycling fan, reset mass flow to full on rate
   13989           63 :             if (fanOp == HVAC::FanOp::Cycling) {
   13990           32 :                 AirMassFlow /= CycRatio;
   13991              :             }
   13992           63 :             if (fanOp == HVAC::FanOp::Continuous) {
   13993           31 :                 AirMassFlow = MSHPMassFlowRateHigh;
   13994              :             }
   13995              :             // Check for valid air volume flow per rated total cooling capacity (200 - 600 cfm/ton)
   13996           63 :             AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat, RoutineName);
   13997              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   13998              :             //  AirVolumeFlowRate = AirMassFlow/PsyRhoAirFnPbTdbW(InletAirPressure,InletAirDryBulbTemp, InletAirHumRat)
   13999           63 :             VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.MSRatedTotCap(SpeedNum);
   14000              : 
   14001          126 :             if ((VolFlowperRatedTotCap < HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT]) ||
   14002           63 :                 (VolFlowperRatedTotCap > HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT])) {
   14003            5 :                 if (thisDXCoil.ErrIndex1 == 0) {
   14004            2 :                     ShowWarningMessage(state,
   14005            2 :                                        format("{} \"{}\" - Air volume flow rate per watt of rated total heating capacity is out of range at speed 1.",
   14006            1 :                                               thisDXCoil.DXCoilType,
   14007            1 :                                               thisDXCoil.Name));
   14008            2 :                     ShowContinueErrorTimeStamp(state, "");
   14009            2 :                     ShowContinueError(state,
   14010            2 :                                       format("Expected range for VolumeFlowPerRatedTotalCapacity=[{:.3R}--{:.3R}] Current value is {:.3R} m3/s/W",
   14011            1 :                                              HVAC::MinOperVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   14012            1 :                                              HVAC::MaxHeatVolFlowPerRatedTotCap[(int)state.dataHVACGlobal->DXCT],
   14013              :                                              VolFlowperRatedTotCap));
   14014            2 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components or");
   14015            3 :                     ShowContinueError(state, "inconsistent supply air fan operation modes in coil and unitary system objects.");
   14016              :                 }
   14017           40 :                 ShowRecurringWarningErrorAtEnd(
   14018              :                     state,
   14019           10 :                     thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   14020              :                         "\" - Air volume flow rate per watt of rated total heating capacity is out of range error continues at speed 1...",
   14021            5 :                     thisDXCoil.ErrIndex1,
   14022              :                     VolFlowperRatedTotCap,
   14023              :                     VolFlowperRatedTotCap);
   14024              :             }
   14025              : 
   14026              :             // Get total capacity modifying factor (function of temperature) for off-rated conditions
   14027              :             // Model was extended to accept bi-quadratic curves. This allows sensitivity of the heating capacity
   14028              :             // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   14029              :             // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   14030           63 :             if (state.dataCurveManager->curves(thisDXCoil.MSCCapFTemp(SpeedNum))->numDims == 1) {
   14031           32 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNum), OutdoorDryBulb);
   14032              :             } else {
   14033           31 :                 TotCapTempModFac = CurveValue(state, thisDXCoil.MSCCapFTemp(SpeedNum), InletAirDryBulbTemp, OutdoorDryBulb);
   14034              :             }
   14035              : 
   14036              :             //  Get total capacity modifying factor (function of mass flow) for off-rated conditions
   14037              :             //    AirMassFlowRatio = AirMassFlow/DXCoil(DXCoilNum)%MSRatedAirMassFlowRate(SpeedNumLS)
   14038              :             //    TotCapFlowModFac = CurveValue(state, DXCoil(DXCoilNum)%MSCCapFFlow(SpeedNumLS),AirMassFlowRatio)
   14039           63 :             TotCapFlowModFac = CurveValue(state, thisDXCoil.MSCCapFFlow(SpeedNum), AirMassFlowRatioLS);
   14040              :             // Calculate total heating capacity for off-rated conditions
   14041           63 :             TotCap = thisDXCoil.MSRatedTotCap(SpeedNum) * TotCapFlowModFac * TotCapTempModFac;
   14042              : 
   14043              :             // Calculating adjustment factors for defrost
   14044              :             // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
   14045           63 :             OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
   14046           63 :             OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure, RoutineName)));
   14047              : 
   14048              :             // Initializing defrost adjustment factors
   14049           63 :             LoadDueToDefrost = 0.0;
   14050           63 :             HeatingCapacityMultiplier = 1.0;
   14051           63 :             FractionalDefrostTime = 0.0;
   14052           63 :             InputPowerMultiplier = 1.0;
   14053              : 
   14054              :             // Check outdoor temperature to determine of defrost is active
   14055           63 :             if (OutdoorDryBulb <= thisDXCoil.MaxOATDefrost) {
   14056              :                 // Calculate defrost adjustment factors depending on defrost control type
   14057           36 :                 if (thisDXCoil.DefrostControl == StandardRatings::HPdefrostControl::Timed) {
   14058           36 :                     FractionalDefrostTime = thisDXCoil.DefrostTime;
   14059           36 :                     if (FractionalDefrostTime > 0.0) {
   14060           36 :                         if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   14061            2 :                             HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   14062            2 :                             InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   14063              :                         } else {
   14064           34 :                             HeatingCapacityMultiplier = 0.909 - 107.33 * OutdoorCoildw;
   14065           34 :                             InputPowerMultiplier = 0.90 - 36.45 * OutdoorCoildw;
   14066           34 :                             if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   14067            4 :                                 ShowWarningMessage(
   14068              :                                     state,
   14069            4 :                                     format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   14070              :                                            "actuator must be both provided for DX heating coil {}",
   14071            2 :                                            thisDXCoil.Name));
   14072            6 :                                 ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   14073              :                             }
   14074              :                         }
   14075              :                     }
   14076              :                 } else { // else defrost control is on-demand
   14077            0 :                     FractionalDefrostTime = 1.0 / (1.0 + 0.01446 / OutdoorCoildw);
   14078            0 :                     if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn && thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   14079            0 :                         HeatingCapacityMultiplier = thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideValue;
   14080            0 :                         InputPowerMultiplier = thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideValue;
   14081              :                     } else {
   14082            0 :                         HeatingCapacityMultiplier = 0.875 * (1.0 - FractionalDefrostTime);
   14083            0 :                         InputPowerMultiplier = 0.954 * (1.0 - FractionalDefrostTime);
   14084            0 :                         if (thisDXCoil.FrostHeatingCapacityMultiplierEMSOverrideOn || thisDXCoil.FrostHeatingInputPowerMultiplierEMSOverrideOn) {
   14085            0 :                             ShowWarningMessage(state,
   14086            0 :                                                format("The Frost Heating Capacity Multiplier actuator and the Frost Heating Input Power Multiplier "
   14087              :                                                       "actuator must be both provided for DX heating coil {}",
   14088            0 :                                                       thisDXCoil.Name));
   14089            0 :                             ShowContinueError(state, "EMS actuators are ignored. Simulation is continuing.");
   14090              :                         }
   14091              :                     }
   14092              :                 }
   14093              : 
   14094           36 :                 if (FractionalDefrostTime > 0.0) {
   14095              :                     // Calculate defrost adjustment factors depending on defrost control strategy
   14096           36 :                     if (thisDXCoil.DefrostStrategy == StandardRatings::DefrostStrat::ReverseCycle) {
   14097           32 :                         LoadDueToDefrost = (0.01 * FractionalDefrostTime) * (7.222 - OutdoorDryBulb) * (thisDXCoil.MSRatedTotCap(1) / 1.01667);
   14098           32 :                         DefrostEIRTempModFac = CurveValue(state, thisDXCoil.DefrostEIRFT, max(15.555, InletAirWetBulbC), max(15.555, OutdoorDryBulb));
   14099           32 :                         thisDXCoil.DefrostPower = DefrostEIRTempModFac * (thisDXCoil.MSRatedTotCap(1) / 1.01667) * FractionalDefrostTime;
   14100              :                     } else { // Defrost strategy is resistive
   14101            4 :                         thisDXCoil.DefrostPower = thisDXCoil.DefrostCapacity * FractionalDefrostTime;
   14102              :                     }
   14103              :                 } else { // Defrost is not active because (OutDryBulbTemp .GT. DXCoil(DXCoilNum)%MaxOATDefrost)
   14104            0 :                     thisDXCoil.DefrostPower = 0.0;
   14105              :                 }
   14106              :             }
   14107              : 
   14108              :             // Modify total heating capacity based on defrost heating capacity multiplier
   14109           63 :             TotCapAdj = TotCap * HeatingCapacityMultiplier;
   14110              : 
   14111              :             // Calculate full load outlet conditions
   14112           63 :             FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
   14113           63 :             FullLoadOutAirHumRat = InletAirHumRat;
   14114           63 :             FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   14115           63 :             FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
   14116              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   14117              :             //  FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
   14118           63 :             if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
   14119            0 :                 FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure, RoutineName);
   14120              :                 //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   14121              :                 //  FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
   14122            0 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
   14123              :             }
   14124              : 
   14125              :             // Set outlet conditions from the full load calculation
   14126           63 :             OutletAirEnthalpy = FullLoadOutAirEnth;
   14127           63 :             OutletAirHumRat = FullLoadOutAirHumRat;
   14128           63 :             OutletAirTemp = FullLoadOutAirTemp;
   14129              :             // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
   14130              :             // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
   14131              :             // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   14132              :             // advised to use the bi-quadratic curve if sufficient manufacturer data is available.
   14133           63 :             if (state.dataCurveManager->curves(thisDXCoil.MSEIRFTemp(1))->numDims == 1) {
   14134           32 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), OutdoorDryBulb);
   14135              :             } else {
   14136           31 :                 EIRTempModFac = CurveValue(state, thisDXCoil.MSEIRFTemp(1), InletAirDryBulbTemp, OutdoorDryBulb);
   14137              :             }
   14138           63 :             EIRFlowModFac = CurveValue(state, thisDXCoil.MSEIRFFlow(1), AirMassFlowRatioLS);
   14139           63 :             EIR = 1.0 / thisDXCoil.MSRatedCOP(1) * EIRTempModFac * EIRFlowModFac;
   14140              :             // Calculate modified PartLoadRatio due to defrost (reverse-cycle defrost only)
   14141           63 :             PLRHeating = min(1.0, (CycRatio + LoadDueToDefrost / TotCapAdj));
   14142           63 :             PLF = CurveValue(state, thisDXCoil.MSPLFFPLR(1), PLRHeating); // Calculate part-load factor
   14143           63 :             if (fanOp == HVAC::FanOp::Cycling && CycRatio == 1.0 && PLF != 1.0) {
   14144            0 :                 if (thisDXCoil.PLFErrIndex == 0) {
   14145            0 :                     ShowWarningMessage(state,
   14146            0 :                                        format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio = 1", thisDXCoil.Name, PLF));
   14147            0 :                     ShowContinueError(state, "PLF curve value must be = 1.0 and has been reset to 1.0. Simulation is continuing.");
   14148            0 :                     ShowContinueErrorTimeStamp(state, "");
   14149              :                 }
   14150            0 :                 ShowRecurringWarningErrorAtEnd(
   14151            0 :                     state, thisDXCoil.Name + "\": DX heating coil PLF curve value <> 1.0 warning continues...", thisDXCoil.PLFErrIndex, PLF, PLF);
   14152            0 :                 PLF = 1.0;
   14153              :             }
   14154              : 
   14155           63 :             if (PLF < 0.7) {
   14156            0 :                 if (thisDXCoil.PLRErrIndex == 0) {
   14157            0 :                     ShowWarningMessage(
   14158              :                         state,
   14159            0 :                         format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
   14160            0 :                     ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   14161            0 :                     ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   14162            0 :                     ShowContinueErrorTimeStamp(state, "");
   14163              :                 }
   14164            0 :                 ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
   14165            0 :                 PLF = 0.7;
   14166              :             }
   14167              : 
   14168           63 :             thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
   14169           63 :             if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
   14170            0 :                 if (thisDXCoil.ErrIndex4 == 0) {
   14171            0 :                     ShowWarningMessage(state,
   14172            0 :                                        format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
   14173            0 :                                               thisDXCoil.Name,
   14174            0 :                                               thisDXCoil.HeatingCoilRuntimeFraction));
   14175            0 :                     ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
   14176            0 :                     ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   14177            0 :                     ShowContinueErrorTimeStamp(state, "");
   14178              :                 }
   14179            0 :                 ShowRecurringWarningErrorAtEnd(state,
   14180            0 :                                                thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
   14181            0 :                                                thisDXCoil.ErrIndex4,
   14182            0 :                                                thisDXCoil.HeatingCoilRuntimeFraction,
   14183            0 :                                                thisDXCoil.HeatingCoilRuntimeFraction);
   14184            0 :                 thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   14185           63 :             } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
   14186            0 :                 thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   14187              :             }
   14188              :             // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
   14189           63 :             if (fanOp == HVAC::FanOp::Cycling) {
   14190           32 :                 state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
   14191              :             }
   14192           63 :             thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
   14193              : 
   14194              :             // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
   14195              :             // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
   14196              : 
   14197           63 :             if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   14198            5 :                 thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
   14199              :             } else {
   14200           58 :                 thisDXCoil.CrankcaseHeaterPower =
   14201           58 :                     CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
   14202           58 :                                                        state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
   14203              :             }
   14204              : 
   14205           63 :             thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (FullLoadOutAirEnth - InletAirEnthalpy) * CycRatio;
   14206           63 :             if (fanOp == HVAC::FanOp::Continuous) {
   14207           31 :                 OutletAirEnthalpy = InletAirEnthalpy + thisDXCoil.TotalHeatingEnergyRate / thisDXCoil.InletAirMassFlowRate;
   14208           31 :                 OutletAirTemp = PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
   14209              :             }
   14210           63 :             if (thisDXCoil.MSHPHeatRecActive || thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   14211           32 :                 if (thisDXCoil.MSWasteHeat(SpeedNum) == 0) {
   14212            0 :                     thisDXCoil.MSFuelWasteHeat = thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
   14213              :                 } else {
   14214           32 :                     thisDXCoil.MSFuelWasteHeat = CurveValue(state, thisDXCoil.MSWasteHeat(SpeedNum), OutdoorDryBulb, InletAirDryBulbTemp) *
   14215           32 :                                                  thisDXCoil.MSWasteHeatFrac(SpeedNum) * thisDXCoil.ElecHeatingPower;
   14216              :                 }
   14217           32 :                 if (thisDXCoil.MSHPHeatRecActive) {
   14218            0 :                     MSHPWasteHeat = thisDXCoil.MSFuelWasteHeat;
   14219              :                 }
   14220              :             }
   14221           63 :             if (thisDXCoil.FuelType != Constant::eFuel::Electricity) {
   14222              : 
   14223           32 :                 thisDXCoil.FuelUsed = thisDXCoil.ElecHeatingPower;
   14224           32 :                 thisDXCoil.ElecHeatingPower = 0.0;
   14225              :             }
   14226              :             // Adjust defrost power to correct for DOE-2 bug where defrost power is constant regardless of compressor runtime fraction
   14227              :             // Defrosts happen based on compressor run time (frost buildup on outdoor coil), not total elapsed time.
   14228           63 :             thisDXCoil.DefrostPower *= thisDXCoil.HeatingCoilRuntimeFraction;
   14229              : 
   14230           63 :             thisDXCoil.OutletAirTemp = OutletAirTemp;
   14231           63 :             thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   14232           63 :             thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   14233              :         }
   14234              : 
   14235              :     } else {
   14236              : 
   14237              :         // DX coil is off; just pass through conditions
   14238          120 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   14239          120 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   14240          120 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   14241              : 
   14242          120 :         thisDXCoil.ElecHeatingPower = 0.0;
   14243          120 :         thisDXCoil.FuelUsed = 0.0;
   14244          120 :         thisDXCoil.TotalHeatingEnergyRate = 0.0;
   14245          120 :         thisDXCoil.DefrostPower = 0.0;
   14246              : 
   14247              :         // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
   14248              :         // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
   14249          120 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   14250           10 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
   14251              :         } else {
   14252          110 :             thisDXCoil.CrankcaseHeaterPower =
   14253          110 :                 CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
   14254              :         }
   14255              : 
   14256              :     } // end of on/off if - else
   14257              : 
   14258          211 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   14259          211 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   14260          211 :     thisDXCoil.PartLoadRatio = PLRHeating;
   14261          211 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   14262          211 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
   14263          211 :     thisDXCoil.MSSpeedNumLS = SpeedNumLS;
   14264          211 :     thisDXCoil.MSSpeedNumHS = SpeedNumHS;
   14265          211 :     thisDXCoil.MSSpeedRatio = SpeedRatio;
   14266          211 :     thisDXCoil.MSCycRatio = CycRatio;
   14267              : 
   14268              :     // set outlet node conditions
   14269          211 :     int airOutletNode = thisDXCoil.AirOutNode;
   14270          211 :     state.dataLoopNodes->Node(airOutletNode).Temp = thisDXCoil.OutletAirTemp;
   14271          211 :     state.dataLoopNodes->Node(airOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   14272              : 
   14273              :     // calc secondary coil if specified
   14274          211 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   14275            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   14276              :     }
   14277          211 : }
   14278              : 
   14279       539062 : void UpdateDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current fan coil unit being simulated
   14280              : {
   14281              : 
   14282              :     // SUBROUTINE INFORMATION:
   14283              :     //       AUTHOR         Fred Buhl
   14284              :     //       DATE WRITTEN   May 2000
   14285              : 
   14286              :     // PURPOSE OF THIS SUBROUTINE:
   14287              :     // This subroutine is for passing results to the outlet air node.
   14288              : 
   14289              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   14290              :     int AirOutletNode; // air outlet node number
   14291              :     int AirInletNode;  // air inlet node number
   14292              : 
   14293       539062 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   14294              : 
   14295       539062 :     AirOutletNode = thisDXCoil.AirOutNode;
   14296       539062 :     AirInletNode = thisDXCoil.AirInNode;
   14297              :     // changed outputs
   14298       539062 :     state.dataLoopNodes->Node(AirOutletNode).Enthalpy = thisDXCoil.OutletAirEnthalpy;
   14299       539062 :     state.dataLoopNodes->Node(AirOutletNode).Temp = thisDXCoil.OutletAirTemp;
   14300       539062 :     state.dataLoopNodes->Node(AirOutletNode).HumRat = thisDXCoil.OutletAirHumRat;
   14301       539062 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = thisDXCoil.InletAirMassFlowRate;
   14302              :     // pass through outputs
   14303       539062 :     state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
   14304       539062 :     state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
   14305       539062 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
   14306       539062 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
   14307       539062 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
   14308       539062 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMaxAvail;
   14309              : 
   14310       539062 :     if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
   14311            0 :         state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
   14312              :     }
   14313       539062 :     if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
   14314            0 :         state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
   14315              :     }
   14316       539062 : }
   14317              : 
   14318       539064 : void ReportDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the current fan coil unit being simulated
   14319              : {
   14320              : 
   14321              :     // SUBROUTINE INFORMATION:
   14322              :     //       AUTHOR         Fred Buhl
   14323              :     //       DATE WRITTEN   May 2000
   14324              :     //       MODIFIED       Richard Raustad/Don Shirey Oct 2001, Feb 2004
   14325              :     //                      Feb 2005 M. J. Witte, GARD Analytics, Inc.
   14326              :     //                        Always update evap value to support new coil type COIL:DX:MultiMode:CoolingEmpirical:
   14327              :     //                      Lixing Gu. Jan. 5, 2007, pass information to the AirflowNetwork model
   14328              : 
   14329              :     // PURPOSE OF THIS SUBROUTINE:
   14330              :     // Fills some of the report variables for the DX coils
   14331              : 
   14332              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   14333              : 
   14334       539064 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   14335              : 
   14336       539064 :     if (thisDXCoil.reportCoilFinalSizes) {
   14337       192897 :         if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
   14338          104 :             Real64 ratedSensCap(0.0);
   14339          104 :             ratedSensCap = thisDXCoil.RatedTotCap(1) * thisDXCoil.RatedSHR(1);
   14340          104 :             state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
   14341          104 :                 state, thisDXCoil.Name, thisDXCoil.DXCoilType, thisDXCoil.RatedTotCap(1), ratedSensCap, thisDXCoil.RatedAirVolFlowRate(1), -999.0);
   14342          104 :             thisDXCoil.reportCoilFinalSizes = false;
   14343              :         }
   14344              :     }
   14345              : 
   14346       539064 :     Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
   14347              : 
   14348       539064 :     switch (thisDXCoil.DXCoilType_Num) {
   14349       201111 :     case HVAC::CoilDX_HeatingEmpirical:
   14350              :     case HVAC::CoilVRF_Heating:
   14351              :     case HVAC::CoilVRF_FluidTCtrl_Heating: {
   14352       201111 :         thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
   14353       201111 :         thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
   14354       201111 :         thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
   14355       201111 :         thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
   14356       201111 :         state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
   14357       201111 :         state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
   14358       201111 :     } break;
   14359          199 :     case HVAC::CoilDX_MultiSpeedHeating: {
   14360          199 :         thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
   14361          199 :         if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
   14362          116 :             thisDXCoil.ElecHeatingConsumption = thisDXCoil.ElecHeatingPower * ReportingConstant;
   14363              :         } else {
   14364           83 :             thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
   14365              :         }
   14366          199 :         thisDXCoil.DefrostConsumption = thisDXCoil.DefrostPower * ReportingConstant;
   14367          199 :         thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
   14368          199 :         state.dataHVACGlobal->DXElecHeatingPower = thisDXCoil.ElecHeatingPower + thisDXCoil.CrankcaseHeaterPower;
   14369          199 :         state.dataHVACGlobal->DefrostElecPower = thisDXCoil.DefrostPower;
   14370          199 :     } break;
   14371          251 :     case HVAC::CoilDX_MultiSpeedCooling: {
   14372          251 :         thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
   14373          251 :         thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
   14374          251 :         thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
   14375          251 :         thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
   14376          251 :         state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
   14377          251 :         thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
   14378          251 :         thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
   14379          251 :         if (thisDXCoil.FuelType == Constant::eFuel::Electricity) {
   14380          179 :             thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
   14381              :         } else {
   14382           72 :             thisDXCoil.FuelConsumed = thisDXCoil.FuelUsed * ReportingConstant;
   14383              :         }
   14384          251 :         if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
   14385            0 :             thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
   14386              :         }
   14387          251 :     } break;
   14388          161 :     case HVAC::CoilDX_HeatPumpWaterHeaterPumped:
   14389              :     case HVAC::CoilDX_HeatPumpWaterHeaterWrapped: {
   14390              :         // water heating energy for HP water heater DX Coil condenser
   14391          161 :         thisDXCoil.TotalHeatingEnergy = thisDXCoil.TotalHeatingEnergyRate * ReportingConstant;
   14392              :         // water heating power for HP water heater
   14393          161 :         thisDXCoil.ElecWaterHeatingConsumption = thisDXCoil.ElecWaterHeatingPower * ReportingConstant;
   14394              :         // other usual DX cooling coil outputs
   14395          161 :         thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
   14396          161 :         thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
   14397          161 :         thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
   14398          161 :         thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
   14399          161 :         thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
   14400              :         // DXElecCoolingPower global is only used for air-to-air cooling and heating coils
   14401          161 :         state.dataHVACGlobal->DXElecCoolingPower = 0.0;
   14402          161 :     } break;
   14403       337342 :     default: {
   14404       337342 :         thisDXCoil.TotalCoolingEnergy = thisDXCoil.TotalCoolingEnergyRate * ReportingConstant;
   14405       337342 :         thisDXCoil.SensCoolingEnergy = thisDXCoil.SensCoolingEnergyRate * ReportingConstant;
   14406       337342 :         thisDXCoil.LatCoolingEnergy = thisDXCoil.TotalCoolingEnergy - thisDXCoil.SensCoolingEnergy;
   14407       337342 :         thisDXCoil.ElecCoolingConsumption = thisDXCoil.ElecCoolingPower * ReportingConstant;
   14408       337342 :         thisDXCoil.CrankcaseHeaterConsumption = thisDXCoil.CrankcaseHeaterPower * ReportingConstant;
   14409       337342 :         state.dataHVACGlobal->DXElecCoolingPower = thisDXCoil.ElecCoolingPower;
   14410       337342 :         thisDXCoil.EvapCondPumpElecConsumption = thisDXCoil.EvapCondPumpElecPower * ReportingConstant;
   14411       337342 :         thisDXCoil.EvapWaterConsump = thisDXCoil.EvapWaterConsumpRate * ReportingConstant;
   14412       337342 :         if (any_eq(thisDXCoil.CondenserType, DataHeatBalance::RefrigCondenserType::Evap)) {
   14413        33575 :             thisDXCoil.BasinHeaterConsumption = thisDXCoil.BasinHeaterPower * ReportingConstant;
   14414              :         }
   14415       337342 :     } break;
   14416              :     }
   14417              : 
   14418       539064 :     if (thisDXCoil.CondensateCollectMode == CondensateCollectAction::ToTank) {
   14419              :         // calculate and report condensation rates  (how much water extracted from the air stream)
   14420              :         // water flow of water in m3/s for water system interactions
   14421              :         //  put here to catch all types of DX coils
   14422            2 :         Real64 Tavg = (thisDXCoil.InletAirTemp + thisDXCoil.OutletAirTemp) / 2.0;
   14423              :         // CR9155 Remove specific humidity calculations
   14424              :         //  mdot * del HumRat / rho water
   14425            2 :         thisDXCoil.CondensateVdot =
   14426            2 :             max(0.0, (thisDXCoil.InletAirMassFlowRate * (thisDXCoil.InletAirHumRat - thisDXCoil.OutletAirHumRat) / Psychrometrics::RhoH2O(Tavg)));
   14427            2 :         thisDXCoil.CondensateVol = thisDXCoil.CondensateVdot * ReportingConstant;
   14428              : 
   14429            2 :         state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).VdotAvailSupply(thisDXCoil.CondensateTankSupplyARRID) =
   14430            2 :             thisDXCoil.CondensateVdot;
   14431            2 :         state.dataWaterData->WaterStorage(thisDXCoil.CondensateTankID).TwaterSupply(thisDXCoil.CondensateTankSupplyARRID) = thisDXCoil.OutletAirTemp;
   14432              :     }
   14433              : 
   14434       539064 :     state.dataAirLoop->LoopDXCoilRTF = max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
   14435       539064 :     if (thisDXCoil.AirLoopNum > 0) {
   14436       223282 :         state.dataAirLoop->AirLoopAFNInfo(thisDXCoil.AirLoopNum).AFNLoopDXCoilRTF =
   14437       223282 :             max(thisDXCoil.CoolingCoilRuntimeFraction, thisDXCoil.HeatingCoilRuntimeFraction);
   14438              :     }
   14439       539064 : }
   14440              : 
   14441            6 : void CalcTwoSpeedDXCoilStandardRating(EnergyPlusData &state, int const DXCoilNum)
   14442              : {
   14443              :     // SUBROUTINE INFORMATION:
   14444              :     //       AUTHOR         B. Griffith, (Derived from CalcDXCoilStandardRating by Bereket Nigusse & Chandan Sharma)
   14445              :     //       DATE WRITTEN   July 2012
   14446              : 
   14447              :     // PURPOSE OF THIS SUBROUTINE:
   14448              :     // Calculate the following
   14449              :     //                 (1) Standard Rated (net) Cooling Capacity
   14450              :     //                 (2) Energy Efficiency Ratio (EER),
   14451              :     //                 (3) Integrated Energy Efficiency Ratio (IEER)
   14452              : 
   14453              :     // REFERENCES:
   14454              :     // ANSI/AHRI Standard 340/360-2007, Performance Rating of Commercial and Industrial Unitary Air-Conditioning and
   14455              :     //  Heat Pump Equipment, Air-Conditioning, Heating, and Refrigeration Institute, Arlington VA.
   14456              : 
   14457              :     // Using/Aliasing
   14458              :     using Curve::CurveValue;
   14459              :     using namespace OutputReportPredefined;
   14460              : 
   14461              :     // SUBROUTINE PARAMETER DEFINITIONS:
   14462              :     // AHRI Standard 340/360-2007 Performance Rating of Commercial and Industrial Unitary Air-Conditioning and Heat Pump Equipment
   14463            6 :     Real64 constexpr CoolingCoilInletAirWetBulbTempRated(19.4); // 19.44C (67F)
   14464            6 :     Real64 constexpr CoolingCoilInletAirDryBulbTempRated(26.7);
   14465            6 :     Real64 constexpr OutdoorUnitInletAirDryBulbTempRated(35.0); // 35.00C (95F)
   14466            6 :     static Array1D<Real64> const OutdoorUnitInletAirDryBulbTempPLTestPoint(3, {27.5, 20.0, 18.3});
   14467            6 :     static Array1D<Real64> const NetCapacityFactorPLTestPoint(3, {0.75, 0.50, 0.25});
   14468            6 :     Real64 constexpr ConvFromSIToIP(3.412141633); // Conversion from SI to IP [3.412 Btu/hr-W]
   14469              : 
   14470            6 :     Real64 constexpr AirMassFlowRatioRated(1.0); // AHRI test is at the design flow rate
   14471              :     // and hence AirMassFlowRatio is 1.0
   14472              : 
   14473            6 :     Real64 constexpr DefaultFanPowerPerEvapAirFlowRate(773.3);      // 365 W/1000 scfm or 773.3 W/(m3/s). The AHRI standard
   14474            6 :     Real64 constexpr DefaultFanPowerPerEvapAirFlowRateSEER2(934.4); // 441 W/1000 scfm or 934.4 W/(m3/s). The AHRI standard
   14475              :     // specifies a nominal/default fan electric power consumption per rated air
   14476              :     // volume flow rate to account for indoor fan electric power consumption
   14477              :     // when the standard tests are conducted on units that do not have an
   14478              :     // indoor air circulating fan. Used if user doesn't enter a specific value.
   14479              : 
   14480              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   14481              :     static constexpr std::string_view RoutineName("CalcTwoSpeedDXCoilStandardRating");
   14482              : 
   14483            6 :     auto &NetCoolingCapRated = state.dataDXCoils->NetCoolingCapRated;
   14484            6 :     auto &EER = state.dataDXCoils->EER;
   14485            6 :     auto &IEER = state.dataDXCoils->IEER;
   14486            6 :     auto &TotCapTempModFac = state.dataDXCoils->TotCapTempModFac;
   14487            6 :     auto &TotCapFlowModFac = state.dataDXCoils->TotCapFlowModFac;
   14488            6 :     auto &EIRTempModFac = state.dataDXCoils->EIRTempModFac;
   14489            6 :     auto &EIRFlowModFac = state.dataDXCoils->EIRFlowModFac;
   14490            6 :     auto &TempDryBulb_Leaving_Apoint = state.dataDXCoils->TempDryBulb_Leaving_Apoint;
   14491              : 
   14492            6 :     constexpr Real64 AccuracyTolerance(0.2); // tolerance in AHRI 340/360 Table 6 note 1
   14493            6 :     constexpr int MaximumIterations(1000);
   14494              :     Real64 EIR;
   14495              :     Real64 TotalElecPowerRated;
   14496            6 :     Array1D<Real64> EER_TestPoint_SI(4);      // 1 = A, 2 = B, 3= C, 4= D
   14497            6 :     Array1D<Real64> EER_TestPoint_IP(4);      // 1 = A, 2 = B, 3= C, 4= D
   14498            6 :     Array1D<Real64> NetCapacity_TestPoint(4); // 1 = A, 2 = B, 3= C, 4= D
   14499            6 :     Array1D<Real64> NetPower_TestPoint(4);    // 1 = A, 2 = B, 3= C, 4= D
   14500            6 :     Array1D<Real64> SupAirMdot_TestPoint(4);  // 1 = A, 2 = B, 3= C, 4= D
   14501              : 
   14502              :     Real64 HighSpeedNetCoolingCap;
   14503              :     Real64 LowSpeedNetCoolingCap;
   14504              : 
   14505              :     Real64 PartLoadAirMassFlowRate;
   14506              :     Real64 AirMassFlowRatio;
   14507              :     int SolverFlag;
   14508              :     Real64 EIR_HighSpeed;
   14509              :     Real64 EIR_LowSpeed;
   14510              :     int FanInletNode;
   14511              :     int FanOutletNode;
   14512              :     int Iter;
   14513              :     Real64 ExternalStatic;
   14514              :     Real64 FanStaticPressureRise;
   14515              :     Real64 FanHeatCorrection;
   14516              :     Real64 FanPowerCorrection;
   14517            6 :     Real64 FanPowerPerEvapAirFlowRate = 0.0;
   14518              :     Real64 FanPowerPerEvapAirFlowRateSEER2;
   14519              :     Real64 SpeedRatio;
   14520              :     Real64 CycRatio;
   14521              :     Real64 TargetNetCapacity;
   14522              :     Real64 SupplyAirHumRat;
   14523              :     Real64 SupplyAirRho;
   14524              :     Real64 SupplyAirVolFlowRate;
   14525              :     Real64 HighSpeedTotCoolingCap;
   14526              :     Real64 LowSpeedTotCoolingCap;
   14527              :     Real64 TotCoolingCap;
   14528              :     Real64 NetCoolingCap;
   14529              :     Real64 PLF;
   14530              :     Real64 RunTimeFraction;
   14531              :     Real64 LowerBoundMassFlowRate;
   14532              :     int PartLoadTestPoint;
   14533              :     int countStaticInputs;
   14534              :     int index;
   14535              : 
   14536              :     // Formats
   14537              :     static constexpr std::string_view Header(
   14538              :         "! <VAV DX Cooling Coil Standard Rating Information>, DX Coil Type, DX Coil Name, Fan Type, Fan Name, Standard Net Cooling Capacity "
   14539              :         "{{W}}, Standard Net Cooling Capacity {{Btu/h}}, IEER {{Btu/W-h}}, COP 100% Capacity {{W/W}}, COP 75% Capacity {{W/W}}, COP 50% Capacity "
   14540              :         "{{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% "
   14541              :         "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% "
   14542              :         "{{kg/s}}\n");
   14543              : 
   14544              :     static constexpr std::string_view Format_891{
   14545              :         " VAV DX Cooling Coil Standard Rating Information, "
   14546              :         "{},{},{},{},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.4R},{:.4R},{:.4R},{:.4R},\n"};
   14547              : 
   14548            6 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   14549              : 
   14550              :     // Get fan index and name if not already available
   14551            6 :     if (thisDXCoil.SupplyFanIndex == 0) {
   14552            2 :         GetFanIndexForTwoSpeedCoil(state, DXCoilNum, thisDXCoil.SupplyFanIndex, thisDXCoil.SupplyFanName, thisDXCoil.supplyFanType);
   14553              :     }
   14554            6 :     if (thisDXCoil.SupplyFanIndex == 0) { // didn't find VAV fan, do not rate this coil
   14555            0 :         thisDXCoil.RateWithInternalStaticAndFanObject = false;
   14556            0 :         ShowWarningError(state,
   14557            0 :                          format("CalcTwoSpeedDXCoilStandardRating: Did not find an appropriate fan associated with DX coil named = \"{}\". Standard "
   14558              :                                 "Ratings will not be calculated.",
   14559            0 :                                 thisDXCoil.Name));
   14560            0 :         return;
   14561              :     }
   14562            6 :     bool saveTurnFansOn = state.dataHVACGlobal->TurnFansOn;
   14563            6 :     bool saveTurnFansOff = state.dataHVACGlobal->TurnFansOff;
   14564            6 :     state.dataHVACGlobal->TurnFansOn = true; // enable fans, will override fan availability schedule if needed
   14565            6 :     state.dataHVACGlobal->TurnFansOff = false;
   14566              : 
   14567              :     // Calculate the Indoor fan electric power consumption.  The electric power consumption is estimated
   14568              :     // using either user supplied or AHRI default value for fan power per air volume flow rate
   14569            6 :     if (thisDXCoil.RateWithInternalStaticAndFanObject) {
   14570              : 
   14571            3 :         TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
   14572            3 :         TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
   14573           15 :         for (Iter = 1; Iter <= 4; ++Iter) { // iterative solution in the event that net capacity is near a threshold for external static
   14574              :             // Obtain external static pressure from Table 5 in ANSI/AHRI Std. 340/360-2007
   14575           12 :             if (NetCoolingCapRated <= 21000.0) {
   14576           12 :                 ExternalStatic = 50.0;
   14577            0 :             } else if (21000.0 < NetCoolingCapRated && NetCoolingCapRated <= 30800.0) {
   14578            0 :                 ExternalStatic = 60.0;
   14579            0 :             } else if (30800.0 < NetCoolingCapRated && NetCoolingCapRated <= 39300.0) {
   14580            0 :                 ExternalStatic = 70.0;
   14581            0 :             } else if (39300.0 < NetCoolingCapRated && NetCoolingCapRated <= 61500.0) {
   14582            0 :                 ExternalStatic = 90.0;
   14583            0 :             } else if (61500.0 < NetCoolingCapRated && NetCoolingCapRated <= 82100.0) {
   14584            0 :                 ExternalStatic = 100.0;
   14585            0 :             } else if (82100.0 < NetCoolingCapRated && NetCoolingCapRated <= 103000.0) {
   14586            0 :                 ExternalStatic = 110.0;
   14587            0 :             } else if (103000.0 < NetCoolingCapRated && NetCoolingCapRated <= 117000.0) {
   14588            0 :                 ExternalStatic = 140.0;
   14589            0 :             } else if (117000.0 < NetCoolingCapRated && NetCoolingCapRated <= 147000.0) {
   14590            0 :                 ExternalStatic = 160.0;
   14591            0 :             } else if (147000.0 < NetCoolingCapRated) {
   14592            0 :                 ExternalStatic = 190.0;
   14593              :             }
   14594           12 :             FanStaticPressureRise = ExternalStatic + thisDXCoil.InternalStaticPressureDrop;
   14595           12 :             FanInletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->inletNodeNum;
   14596           12 :             FanOutletNode = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->outletNodeNum;
   14597              : 
   14598              :             // set node state variables in preparation for fan model.
   14599           12 :             state.dataLoopNodes->Node(FanInletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
   14600           12 :             state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
   14601           12 :             state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
   14602           12 :             state.dataLoopNodes->Node(FanInletNode).HumRat = PsyWFnTdbTwbPb(
   14603           12 :                 state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
   14604           12 :             state.dataLoopNodes->Node(FanInletNode).Enthalpy =
   14605           12 :                 PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, state.dataLoopNodes->Node(FanInletNode).HumRat);
   14606           12 :             state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
   14607           12 :             FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
   14608              : 
   14609           12 :             FanHeatCorrection = state.dataLoopNodes->Node(FanInletNode).MassFlowRate *
   14610           12 :                                 (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
   14611              : 
   14612           12 :             NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
   14613              :         }
   14614              : 
   14615              :     } else {
   14616            3 :         FanPowerPerEvapAirFlowRate = DefaultFanPowerPerEvapAirFlowRate;
   14617            3 :         FanPowerPerEvapAirFlowRateSEER2 = DefaultFanPowerPerEvapAirFlowRateSEER2;
   14618            3 :         FanPowerCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
   14619            3 :         FanHeatCorrection = DefaultFanPowerPerEvapAirFlowRate * thisDXCoil.RatedAirVolFlowRate(1);
   14620            3 :         TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatioRated);
   14621            3 :         TotCapTempModFac = CurveValue(state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
   14622            3 :         NetCoolingCapRated = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
   14623              :     }
   14624              : 
   14625            6 :     SupAirMdot_TestPoint(1) = thisDXCoil.RatedAirMassFlowRate(1);
   14626              : 
   14627              :     // Calculate Energy Efficiency Ratio (EER) at (19.44C WB and 35.0C DB ), ANSI/AHRI Std. 340/360
   14628            6 :     EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
   14629            6 :     EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatioRated);
   14630            6 :     if (thisDXCoil.RatedCOP(1) > 0.0) {
   14631              :         // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
   14632            6 :         EIR = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP(1);
   14633              :     } else {
   14634            0 :         EIR = 0.0;
   14635              :     }
   14636            6 :     TotalElecPowerRated = EIR * (thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac) + FanPowerCorrection;
   14637              : 
   14638            6 :     if (TotalElecPowerRated > 0.0) {
   14639            6 :         EER = NetCoolingCapRated / TotalElecPowerRated;
   14640              :     } else {
   14641            0 :         EER = 0.0;
   14642              :     }
   14643              : 
   14644              :     // IEER - A point 100 % net capacity
   14645            6 :     EER_TestPoint_SI(1) = EER;
   14646            6 :     EER_TestPoint_IP(1) = EER * ConvFromSIToIP;
   14647              : 
   14648              :     // find coil leaving drybulb at point A, with full rated air flow rate.
   14649              :     // init coil
   14650            6 :     thisDXCoil.InletAirMassFlowRate = thisDXCoil.RatedAirMassFlowRate(1);
   14651            6 :     thisDXCoil.InletAirMassFlowRateMax = thisDXCoil.RatedAirMassFlowRate(1);
   14652            6 :     thisDXCoil.InletAirTemp = 26.7;
   14653            6 :     thisDXCoil.InletAirHumRat = PsyWFnTdbTwbPb(state, 26.7, 19.4, state.dataEnvrn->OutBaroPress, RoutineName);
   14654            6 :     thisDXCoil.InletAirEnthalpy = PsyHFnTdbW(26.7, thisDXCoil.InletAirHumRat);
   14655              : 
   14656            6 :     Real64 const heldOutDryBulb = state.dataEnvrn->OutDryBulbTemp;
   14657            6 :     if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
   14658            0 :         state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempRated;
   14659              :     } else {
   14660            6 :         state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempRated;
   14661              :     }
   14662            6 :     SpeedRatio = 1.0;
   14663            6 :     CycRatio = 1.0;
   14664            6 :     CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
   14665            6 :     TempDryBulb_Leaving_Apoint = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum); // store result
   14666              : 
   14667              :     // IEER - part load test points ***************************************************
   14668           24 :     for (PartLoadTestPoint = 1; PartLoadTestPoint <= 3; ++PartLoadTestPoint) {
   14669              :         // determine minimum unloading capacity fraction at point B conditions.
   14670           18 :         if (thisDXCoil.CondenserInletNodeNum(1) != 0) {
   14671            0 :             state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(1)).Temp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
   14672              :         } else {
   14673           18 :             state.dataEnvrn->OutDryBulbTemp = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
   14674              :         }
   14675              : 
   14676           18 :         TargetNetCapacity = NetCapacityFactorPLTestPoint(PartLoadTestPoint) * NetCoolingCapRated;
   14677              : 
   14678              :         // set up parameters for the solver here
   14679           18 :         Real64 const par3 = OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint);
   14680           18 :         Real64 par7 = FanPowerPerEvapAirFlowRate;
   14681           18 :         int fanInNode = 0;
   14682           18 :         int fanOutNode = 0;
   14683           18 :         Real64 externalStatic = 0.0;
   14684           18 :         int fanIndex = 0;
   14685           18 :         if (thisDXCoil.RateWithInternalStaticAndFanObject) {
   14686            9 :             par7 = 0.0;
   14687            9 :             fanInNode = FanInletNode;
   14688            9 :             fanOutNode = FanOutletNode;
   14689            9 :             externalStatic = ExternalStatic;
   14690            9 :             fanIndex = thisDXCoil.SupplyFanIndex;
   14691              :         }
   14692              : 
   14693           18 :         LowerBoundMassFlowRate = 0.01 * thisDXCoil.RatedAirMassFlowRate(1);
   14694              : 
   14695              :         // OK, so there are two variables here which are const at compile time.  The question is whether compile time data needs to be
   14696              :         // explicitly captured in the lambda capture block.
   14697              :         // For GCC it currently doesn't mind whether they are captured or not, no warnings.
   14698              :         // On Clang, if you list them, there is a compiler warning.
   14699              :         // 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.
   14700              :         // 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
   14701              :         // really simple, I'm just going to use two local variables and capture them instead of the original data.
   14702              :         // 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.
   14703           18 :         Real64 dbRated = CoolingCoilInletAirDryBulbTempRated;
   14704           18 :         Real64 wbRated = CoolingCoilInletAirWetBulbTempRated;
   14705              :         auto f = // (AUTO_OK_LAMBDA)
   14706         3318 :             [&state, DXCoilNum, TempDryBulb_Leaving_Apoint, TargetNetCapacity, par3, par7, fanInNode, fanOutNode, externalStatic, dbRated, wbRated](
   14707              :                 Real64 SupplyAirMassFlowRate) {
   14708              :                 static constexpr std::string_view RoutineName("CalcTwoSpeedDXCoilIEERResidual");
   14709         3300 :                 auto &coil = state.dataDXCoils->DXCoil(DXCoilNum);
   14710         3300 :                 Real64 AirMassFlowRatio = 0.0;
   14711         3300 :                 if (coil.RatedAirMassFlowRate(1) > 0.0) {
   14712         3300 :                     AirMassFlowRatio = SupplyAirMassFlowRate / coil.RatedAirMassFlowRate(1);
   14713              :                 }
   14714         3300 :                 Real64 SupplyAirHumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
   14715         3300 :                 Real64 SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, dbRated, SupplyAirHumRat, RoutineName);
   14716         3300 :                 Real64 SupplyAirVolFlowRate = SupplyAirMassFlowRate / SupplyAirRho;
   14717              : 
   14718              :                 Real64 FanHeatCorrection;
   14719         3300 :                 if (coil.RateWithInternalStaticAndFanObject) {
   14720              :                     // modify external static per AHRI 340/360, Table 6, note 1.
   14721         1539 :                     Real64 FanStaticPressureRise = coil.InternalStaticPressureDrop + (externalStatic * pow_2(AirMassFlowRatio));
   14722         1539 :                     auto &inletNode = state.dataLoopNodes->Node(fanInNode);
   14723         1539 :                     auto &outletNode = state.dataLoopNodes->Node(fanOutNode);
   14724         1539 :                     inletNode.MassFlowRate = SupplyAirMassFlowRate;
   14725         1539 :                     outletNode.MassFlowRate = SupplyAirMassFlowRate;
   14726         1539 :                     inletNode.Temp = dbRated;
   14727         1539 :                     inletNode.HumRat = PsyWFnTdbTwbPb(state, dbRated, wbRated, state.dataEnvrn->OutBaroPress, RoutineName);
   14728         1539 :                     inletNode.Enthalpy = PsyHFnTdbW(dbRated, inletNode.HumRat);
   14729         1539 :                     state.dataFans->fans(coil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
   14730         1539 :                     FanHeatCorrection = SupplyAirMassFlowRate * (outletNode.Enthalpy - inletNode.Enthalpy);
   14731              :                 } else {
   14732         1761 :                     FanHeatCorrection = par7 * SupplyAirVolFlowRate;
   14733              :                 }
   14734              : 
   14735         3300 :                 Real64 TotCapFlowModFac = Curve::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
   14736         3300 :                 Real64 TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp(1), wbRated, par3);
   14737         3300 :                 Real64 HighSpeedNetCoolingCap = coil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
   14738              : 
   14739              :                 // TotCapFlowModFac = CurveManager::CurveValue(state, coil.CCapFFlow(1), AirMassFlowRatio);
   14740         3300 :                 TotCapTempModFac = Curve::CurveValue(state, coil.CCapFTemp2, wbRated, par3);
   14741         3300 :                 Real64 LowSpeedNetCoolingCap = coil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac - FanHeatCorrection;
   14742              : 
   14743              :                 Real64 SpeedRatio;
   14744              :                 Real64 CycRatio;
   14745         3300 :                 if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
   14746         1899 :                     CycRatio = 1.0;
   14747         1899 :                     SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
   14748              :                 } else { // minimum unloading limit exceeded for no cycling
   14749         1401 :                     SpeedRatio = 0.0;
   14750         1401 :                     CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
   14751              :                 }
   14752              : 
   14753         3300 :                 coil.InletAirMassFlowRate = SupplyAirMassFlowRate;
   14754         3300 :                 CalcMultiSpeedDXCoil(state, DXCoilNum, SpeedRatio, CycRatio, true);
   14755         3300 :                 Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(DXCoilNum);
   14756         3300 :                 return TempDryBulb_Leaving_Apoint - OutletAirTemp;
   14757           18 :             };
   14758           18 :         General::SolveRoot(state,
   14759              :                            AccuracyTolerance,
   14760              :                            MaximumIterations,
   14761              :                            SolverFlag,
   14762              :                            PartLoadAirMassFlowRate,
   14763              :                            f,
   14764              :                            LowerBoundMassFlowRate,
   14765           18 :                            thisDXCoil.RatedAirMassFlowRate(1));
   14766              : 
   14767           18 :         if (SolverFlag == -1) {
   14768              : 
   14769            0 :             ShowWarningError(state, "CalcTwoSpeedDXCoilStandardRating: air flow rate solver failed. Iteration limit exceeded ");
   14770              : 
   14771            0 :             SupAirMdot_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14772            0 :             EER_TestPoint_SI(1 + PartLoadTestPoint) = -999.0;
   14773            0 :             EER_TestPoint_IP(1 + PartLoadTestPoint) = -999.0;
   14774            0 :             NetCapacity_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14775            0 :             NetPower_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14776              : 
   14777           18 :         } else if (SolverFlag == -2) {
   14778            0 :             ShowWarningError(state, "CalcTwoSpeedDXCoilStandardRating: air flow rate solver failed. root not bounded ");
   14779              : 
   14780            0 :             SupAirMdot_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14781            0 :             EER_TestPoint_SI(1 + PartLoadTestPoint) = -999.0;
   14782            0 :             EER_TestPoint_IP(1 + PartLoadTestPoint) = -999.0;
   14783            0 :             NetCapacity_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14784            0 :             NetPower_TestPoint(1 + PartLoadTestPoint) = -999.0;
   14785              :         } else {
   14786              :             // now we have the supply air flow rate
   14787           18 :             SupAirMdot_TestPoint(1 + PartLoadTestPoint) = PartLoadAirMassFlowRate;
   14788           18 :             AirMassFlowRatio = PartLoadAirMassFlowRate / thisDXCoil.RatedAirMassFlowRate(1);
   14789           18 :             SupplyAirHumRat = PsyWFnTdbTwbPb(
   14790           18 :                 state, CoolingCoilInletAirDryBulbTempRated, CoolingCoilInletAirWetBulbTempRated, state.dataEnvrn->OutBaroPress, RoutineName);
   14791           18 :             SupplyAirRho = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat, RoutineName);
   14792           18 :             SupplyAirVolFlowRate = PartLoadAirMassFlowRate / SupplyAirRho;
   14793              : 
   14794           18 :             if (thisDXCoil.RateWithInternalStaticAndFanObject) {
   14795            9 :                 FanStaticPressureRise = thisDXCoil.InternalStaticPressureDrop + (ExternalStatic * pow_2(AirMassFlowRatio));
   14796            9 :                 state.dataLoopNodes->Node(FanInletNode).MassFlowRate = PartLoadAirMassFlowRate;
   14797            9 :                 state.dataLoopNodes->Node(FanInletNode).Temp = CoolingCoilInletAirDryBulbTempRated;
   14798            9 :                 state.dataLoopNodes->Node(FanInletNode).HumRat = SupplyAirHumRat;
   14799            9 :                 state.dataLoopNodes->Node(FanInletNode).Enthalpy = PsyHFnTdbW(CoolingCoilInletAirDryBulbTempRated, SupplyAirHumRat);
   14800              : 
   14801            9 :                 state.dataFans->fans(thisDXCoil.SupplyFanIndex)->simulate(state, true, _, FanStaticPressureRise);
   14802            9 :                 FanPowerCorrection = state.dataFans->fans(thisDXCoil.SupplyFanIndex)->totalPower;
   14803              : 
   14804            9 :                 FanHeatCorrection =
   14805            9 :                     PartLoadAirMassFlowRate * (state.dataLoopNodes->Node(FanOutletNode).Enthalpy - state.dataLoopNodes->Node(FanInletNode).Enthalpy);
   14806              : 
   14807              :             } else {
   14808            9 :                 FanPowerCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
   14809            9 :                 FanHeatCorrection = FanPowerPerEvapAirFlowRate * PartLoadAirMassFlowRate;
   14810              :             }
   14811              : 
   14812           18 :             TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatio);
   14813              :             //    Warn user if curve output goes negative
   14814           18 :             if (TotCapFlowModFac < 0.0) {
   14815            0 :                 if (thisDXCoil.CCapFFlowErrorIndex == 0) {
   14816            0 :                     ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
   14817            0 :                     ShowContinueError(
   14818              :                         state,
   14819            0 :                         format(" Total Cooling Capacity Modifier curve (function of flow fraction) output is negative ({:.3T}).", TotCapFlowModFac));
   14820            0 :                     ShowContinueError(state, format(" Negative value occurs using an air flow fraction of {:.3T}.", AirMassFlowRatio));
   14821            0 :                     ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
   14822              :                 }
   14823            0 :                 ShowRecurringWarningErrorAtEnd(
   14824              :                     state,
   14825            0 :                     format("{}{}\"{}\": Total Cooling Capacity Modifier curve (function of flow fraction) output is negative warning continues...",
   14826              :                            RoutineName,
   14827            0 :                            thisDXCoil.DXCoilType,
   14828            0 :                            thisDXCoil.Name),
   14829            0 :                     thisDXCoil.CCapFFlowErrorIndex,
   14830              :                     TotCapFlowModFac,
   14831              :                     TotCapFlowModFac);
   14832            0 :                 TotCapFlowModFac = 0.0;
   14833              :             }
   14834              : 
   14835           54 :             TotCapTempModFac = CurveValue(
   14836           18 :                 state, thisDXCoil.CCapFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
   14837              :             //    Warn user if curve output goes negative
   14838           18 :             if (TotCapTempModFac < 0.0) {
   14839            0 :                 if (thisDXCoil.CCapFTempErrorIndex == 0) {
   14840            0 :                     ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
   14841            0 :                     ShowContinueError(
   14842              :                         state,
   14843            0 :                         format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
   14844            0 :                     ShowContinueError(state,
   14845            0 :                                       format(" Negative value occurs using a coil inlet wet-bulb temperature of {:.1T} and an outdoor unit inlet air "
   14846              :                                              "dry-bulb temperature of {:.1T}.",
   14847              :                                              CoolingCoilInletAirWetBulbTempRated,
   14848              :                                              OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint)));
   14849            0 :                     ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
   14850              :                 }
   14851            0 :                 ShowRecurringWarningErrorAtEnd(
   14852              :                     state,
   14853            0 :                     format("{}{} \"{}\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
   14854              :                            RoutineName,
   14855            0 :                            thisDXCoil.DXCoilType,
   14856            0 :                            thisDXCoil.Name),
   14857            0 :                     thisDXCoil.CCapFTempErrorIndex,
   14858              :                     TotCapTempModFac,
   14859              :                     TotCapTempModFac);
   14860            0 :                 TotCapTempModFac = 0.0;
   14861              :             }
   14862              : 
   14863           18 :             HighSpeedTotCoolingCap = thisDXCoil.RatedTotCap(1) * TotCapTempModFac * TotCapFlowModFac;
   14864           18 :             HighSpeedNetCoolingCap = HighSpeedTotCoolingCap - FanHeatCorrection;
   14865              : 
   14866           54 :             EIRTempModFac = CurveValue(
   14867           18 :                 state, thisDXCoil.EIRFTemp(1), CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
   14868           18 :             EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
   14869           18 :             if (thisDXCoil.RatedCOP(1) > 0.0) {
   14870              :                 // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
   14871           18 :                 EIR_HighSpeed = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP(1);
   14872              :             } else {
   14873            0 :                 EIR = 0.0;
   14874              :             }
   14875              : 
   14876              :             // TotCapFlowModFac = CurveValue(state, thisDXCoil.CCapFFlow(1), AirMassFlowRatio);
   14877           36 :             TotCapTempModFac = CurveValue(
   14878           18 :                 state, thisDXCoil.CCapFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
   14879              :             //    Warn user if curve output goes negative
   14880           18 :             if (TotCapTempModFac < 0.0) {
   14881            0 :                 if (thisDXCoil.CCapFTempErrorIndex == 0) {
   14882            0 :                     ShowWarningMessage(state, format("{}{} \"{}\":", RoutineName, thisDXCoil.DXCoilType, thisDXCoil.Name));
   14883            0 :                     ShowContinueError(
   14884              :                         state,
   14885            0 :                         format(" Total Cooling Capacity Modifier curve (function of temperature) output is negative ({:.3T}).", TotCapTempModFac));
   14886            0 :                     ShowContinueError(state,
   14887            0 :                                       format(" Negative value occurs using a coil inlet wet-bulb temperature of {:.1T} and an outdoor unit inlet air "
   14888              :                                              "dry-bulb temperature of {:.1T}.",
   14889              :                                              CoolingCoilInletAirWetBulbTempRated,
   14890              :                                              OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint)));
   14891            0 :                     ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
   14892              :                 }
   14893            0 :                 ShowRecurringWarningErrorAtEnd(
   14894              :                     state,
   14895            0 :                     format("{}{} \"{}\": Total Cooling Capacity Modifier curve (function of temperature) output is negative warning continues...",
   14896              :                            RoutineName,
   14897            0 :                            thisDXCoil.DXCoilType,
   14898            0 :                            thisDXCoil.Name),
   14899            0 :                     thisDXCoil.CCapFTempErrorIndex,
   14900              :                     TotCapTempModFac,
   14901              :                     TotCapTempModFac);
   14902            0 :                 TotCapTempModFac = 0.0;
   14903              :             }
   14904              : 
   14905           18 :             LowSpeedTotCoolingCap = thisDXCoil.RatedTotCap2 * TotCapTempModFac * TotCapFlowModFac;
   14906           18 :             LowSpeedNetCoolingCap = LowSpeedTotCoolingCap - FanHeatCorrection;
   14907              : 
   14908           36 :             EIRTempModFac = CurveValue(
   14909           18 :                 state, thisDXCoil.EIRFTemp2, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempPLTestPoint(PartLoadTestPoint));
   14910           18 :             EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(1), AirMassFlowRatio);
   14911           18 :             if (thisDXCoil.RatedCOP2 > 0.0) {
   14912              :                 // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
   14913           18 :                 EIR_LowSpeed = EIRTempModFac * EIRFlowModFac / thisDXCoil.RatedCOP2;
   14914              :             } else {
   14915            0 :                 EIR_LowSpeed = 0.0;
   14916              :             }
   14917              : 
   14918           18 :             if (LowSpeedNetCoolingCap <= TargetNetCapacity) {
   14919           12 :                 CycRatio = 1.0;
   14920           12 :                 SpeedRatio = (TargetNetCapacity - LowSpeedNetCoolingCap) / (HighSpeedNetCoolingCap - LowSpeedNetCoolingCap);
   14921           12 :                 TotCoolingCap = HighSpeedTotCoolingCap * SpeedRatio + LowSpeedTotCoolingCap * (1.0 - SpeedRatio);
   14922           12 :                 NetCoolingCap = TotCoolingCap - FanHeatCorrection;
   14923           12 :                 EIR = EIR_HighSpeed * SpeedRatio + EIR_LowSpeed * (1.0 - SpeedRatio);
   14924           12 :                 TotalElecPowerRated = TotCoolingCap * EIR + FanPowerCorrection;
   14925           12 :                 EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
   14926           12 :                 EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
   14927           12 :                 NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
   14928           12 :                 NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
   14929              :             } else { // minimum unloading limit exceeded without cycling, so cycle
   14930            6 :                 SpeedRatio = 0.0;
   14931            6 :                 CycRatio = TargetNetCapacity / LowSpeedNetCoolingCap;
   14932            6 :                 PLF = CurveValue(state, thisDXCoil.PLFFPLR(1), CycRatio);
   14933            6 :                 if (PLF < 0.7) {
   14934            0 :                     PLF = 0.7;
   14935              :                 }
   14936            6 :                 RunTimeFraction = CycRatio / PLF;
   14937            6 :                 RunTimeFraction = min(RunTimeFraction, 1.0);
   14938            6 :                 TotCoolingCap = LowSpeedTotCoolingCap * RunTimeFraction;
   14939            6 :                 NetCoolingCap = TotCoolingCap - FanHeatCorrection;
   14940            6 :                 TotalElecPowerRated = LowSpeedTotCoolingCap * EIR_LowSpeed * RunTimeFraction + FanPowerCorrection;
   14941            6 :                 EER_TestPoint_SI(1 + PartLoadTestPoint) = NetCoolingCap / TotalElecPowerRated;
   14942            6 :                 EER_TestPoint_IP(1 + PartLoadTestPoint) = EER_TestPoint_SI(1 + PartLoadTestPoint) * ConvFromSIToIP;
   14943            6 :                 NetCapacity_TestPoint(1 + PartLoadTestPoint) = NetCoolingCap;
   14944            6 :                 NetPower_TestPoint(1 + PartLoadTestPoint) = TotalElecPowerRated;
   14945              :             }
   14946              :         }
   14947              :     } // loop over 3 part load test points
   14948            6 :     state.dataHVACGlobal->TurnFansOn = saveTurnFansOn;
   14949            6 :     state.dataHVACGlobal->TurnFansOff = saveTurnFansOff;
   14950              : 
   14951            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));
   14952              :     // CalcMultiSpeedDXCoilCooling() //??
   14953              :     // begin output
   14954            6 :     if (state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite) {
   14955            4 :         print(state.files.eio, Header);
   14956            4 :         state.dataDXCoils->CalcTwoSpeedDXCoilStandardRatingOneTimeEIOHeaderWrite = false;
   14957            8 :         state.dataOutRptPredefined->pdstVAVDXCoolCoil =
   14958            4 :             newPreDefSubTable(state, state.dataOutRptPredefined->pdrEquip, "VAV DX Cooling Standard Rating Details");
   14959            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilType =
   14960            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "DX Cooling Coil Type");
   14961            4 :         state.dataOutRptPredefined->pdchVAVDXFanName = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Associated Fan");
   14962            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI =
   14963            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Net Cooling Capacity [W]");
   14964            4 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP [W/W]");
   14965            4 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER [Btu/W-h]");
   14966            4 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP = newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "IEER [Btu/W-h]");
   14967            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA =
   14968            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 100% [kg/s]");
   14969            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B =
   14970            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 75% Capacity [W/W]");
   14971            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP =
   14972            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 75% Capacity [Btu/W-h]");
   14973            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB =
   14974            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 75% [kg/s]");
   14975            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C =
   14976            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 50% Capacity [W/W]");
   14977            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP =
   14978            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 50% Capacity [Btu/W-h]");
   14979            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC =
   14980            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 50% [kg/s]");
   14981            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D =
   14982            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "COP 25% Capacity [W/W]");
   14983            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP =
   14984            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "EER 25% Capacity [Btu/W-h]");
   14985            8 :         state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD =
   14986            4 :             newPreDefColumn(state, state.dataOutRptPredefined->pdstVAVDXCoolCoil, "Supply Air Flow 25% [kg/s]");
   14987              : 
   14988              :         // determine footnote content
   14989            4 :         countStaticInputs = 0;
   14990            8 :         for (index = 1; index <= state.dataDXCoils->NumDXCoils; ++index) {
   14991              : 
   14992            7 :             if (state.dataDXCoils->DXCoil(index).RateWithInternalStaticAndFanObject &&
   14993            3 :                 state.dataDXCoils->DXCoil(index).DXCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
   14994            3 :                 ++countStaticInputs;
   14995              :             }
   14996              :         }
   14997              : 
   14998            4 :         if (countStaticInputs == state.dataDXCoils->NumDXMulSpeedCoils) {
   14999            6 :             addFootNoteSubTable(state,
   15000            3 :                                 state.dataOutRptPredefined->pdstVAVDXCoolCoil,
   15001              :                                 "Packaged VAV unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2");
   15002            1 :         } else if (countStaticInputs == 0) {
   15003            2 :             addFootNoteSubTable(state,
   15004            1 :                                 state.dataOutRptPredefined->pdstVAVDXCoolCoil,
   15005              :                                 "Indoor-coil-only unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2, with "
   15006              :                                 "supply fan specific power at 365 {{W/1000cfm}} (773.3 {{W/(m3/s)}})");
   15007              :         } else { // both
   15008            0 :             addFootNoteSubTable(state,
   15009            0 :                                 state.dataOutRptPredefined->pdstVAVDXCoolCoil,
   15010              :                                 "Packaged VAV unit ratings per ANSI/AHRI Standard 340/360-2007 with Addenda 1 and 2, "
   15011              :                                 "indoor-coil-only units with supply fan specific power at 365 {{W/1000cfm}} (773.3 {{W/(m3/s)}})");
   15012              :         }
   15013              :     }
   15014              : 
   15015            0 :     const auto &fan_type_name = [&]() -> std::pair<const char *, std::string> {
   15016            6 :         if (thisDXCoil.RateWithInternalStaticAndFanObject) {
   15017            3 :             return {"Fan:VariableVolume", thisDXCoil.SupplyFanName};
   15018              :         } else {
   15019            3 :             return {"N/A", "N/A"};
   15020              :         }
   15021            6 :     }();
   15022              : 
   15023            6 :     print(state.files.eio,
   15024              :           Format_891,
   15025              :           "Coil:Cooling:DX:TwoSpeed",
   15026            6 :           thisDXCoil.Name,
   15027            6 :           fan_type_name.first,
   15028            6 :           fan_type_name.second,
   15029              :           NetCoolingCapRated,
   15030            6 :           (NetCoolingCapRated * ConvFromSIToIP),
   15031              :           IEER,
   15032              :           EER_TestPoint_SI(1),
   15033              :           EER_TestPoint_SI(2),
   15034              :           EER_TestPoint_SI(3),
   15035              :           EER_TestPoint_SI(4),
   15036              :           EER_TestPoint_IP(1),
   15037              :           EER_TestPoint_IP(2),
   15038              :           EER_TestPoint_IP(3),
   15039              :           EER_TestPoint_IP(4),
   15040              :           SupAirMdot_TestPoint(1),
   15041              :           SupAirMdot_TestPoint(2),
   15042              :           SupAirMdot_TestPoint(3),
   15043              :           SupAirMdot_TestPoint(4));
   15044              : 
   15045            6 :     if (state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag) {
   15046              :         static constexpr std::string_view Format_994(
   15047              :             "! <DX Cooling Coil Standard Rating Information>, Component Type, Component Name, Standard Rating (Net) "
   15048              :             "Cooling Capacity {W}, Standard Rating Net COP {W/W}, EER {Btu/W-h}, SEER User {Btu/W-h}, SEER Standard {Btu/W-h}, "
   15049              :             "IEER "
   15050              :             "{Btu/W-h}");
   15051            4 :         print(state.files.eio, "{}\n", Format_994);
   15052            4 :         state.dataHVACGlobal->StandardRatingsMyCoolOneTimeFlag = false;
   15053              :     }
   15054              :     static constexpr std::string_view Format_995(" DX Cooling Coil Standard Rating Information, {}, {}, {:.1R}, {}, {}, {}, {}, {}\n");
   15055            6 :     print(state.files.eio,
   15056              :           Format_995,
   15057              :           "Coil:Cooling:DX:TwoSpeed",
   15058            6 :           thisDXCoil.Name,
   15059              :           NetCoolingCapRated,
   15060              :           EER_TestPoint_SI(1),
   15061              :           EER_TestPoint_IP(1),
   15062              :           "N/A",
   15063              :           "N/A",
   15064              :           IEER);
   15065              : 
   15066            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
   15067              :     // W to tons
   15068            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilNetCapSI, thisDXCoil.Name, NetCoolingCapRated, 1);
   15069              : 
   15070              :     // TODO: Commercial and industrial unitary air-conditioning condensing units with a capacity greater than 135,000 Btu/h (39564.59445 Watts)
   15071              :     // as defined in ANSI/AHRI Standard 365(I-P). | Scope 2.2.6 (ANSI/AHRI 340-360 2022)
   15072              :     //
   15073              :     // These will convert with a factor of 1 which is ok
   15074              :     // SEER | Capacity less than 65K Btu/h (19050 W) - calculated as per AHRI Standard 210/240-2023.
   15075            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
   15076            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilEERIP, thisDXCoil.Name, EER_TestPoint_IP(1), 2);
   15077              :     // These will convert with a factor of 1 which is ok
   15078              :     // IEER | Capacity of 65K Btu/h (19050 W) to less than 135K Btu/h (39565 W) - calculated as per AHRI Standard 340/360-2022.
   15079            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 1);
   15080            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERUserIP, thisDXCoil.Name, "N/A");
   15081            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchDXCoolCoilSEERStandardIP, thisDXCoil.Name, "N/A");
   15082              : 
   15083            6 :     addFootNoteSubTable(state, state.dataOutRptPredefined->pdstDXCoolCoil, StandardRatings::AHRI2017FOOTNOTE);
   15084              : 
   15085            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilType, thisDXCoil.Name, "Coil:Cooling:DX:TwoSpeed");
   15086            6 :     if (thisDXCoil.RateWithInternalStaticAndFanObject) {
   15087            3 :         PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, thisDXCoil.SupplyFanName);
   15088              :     } else {
   15089            3 :         PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXFanName, thisDXCoil.Name, "None");
   15090              :     }
   15091            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilNetCapSI, thisDXCoil.Name, NetCoolingCapRated, 2);
   15092            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP, thisDXCoil.Name, EER_TestPoint_SI(1), 2);
   15093            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilIEERIP, thisDXCoil.Name, IEER, 2);
   15094            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEERIP, thisDXCoil.Name, EER_TestPoint_IP(1), 2);
   15095            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotA, thisDXCoil.Name, SupAirMdot_TestPoint(1), 4);
   15096            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_B, thisDXCoil.Name, EER_TestPoint_SI(2), 2);
   15097            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_B_IP, thisDXCoil.Name, EER_TestPoint_IP(2), 2);
   15098            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotB, thisDXCoil.Name, SupAirMdot_TestPoint(2), 4);
   15099            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_C, thisDXCoil.Name, EER_TestPoint_SI(3), 2);
   15100            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_C_IP, thisDXCoil.Name, EER_TestPoint_IP(3), 2);
   15101            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotC, thisDXCoil.Name, SupAirMdot_TestPoint(3), 4);
   15102            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilCOP_D, thisDXCoil.Name, EER_TestPoint_SI(4), 2);
   15103            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilEER_D_IP, thisDXCoil.Name, EER_TestPoint_IP(4), 2);
   15104            6 :     PreDefTableEntry(state, state.dataOutRptPredefined->pdchVAVDXCoolCoilMdotD, thisDXCoil.Name, SupAirMdot_TestPoint(4), 4);
   15105              : 
   15106            6 :     state.dataEnvrn->OutDryBulbTemp = heldOutDryBulb; // reset the outdoor dry bulb when done with it
   15107            6 : }
   15108              : 
   15109            2 : void GetFanIndexForTwoSpeedCoil(
   15110              :     EnergyPlusData &state, int const CoolingCoilIndex, int &SupplyFanIndex, std::string &SupplyFanName, HVAC::FanType &supplyFanType)
   15111              : {
   15112              : 
   15113              :     // SUBROUTINE INFORMATION:
   15114              :     //       AUTHOR         <author>
   15115              :     //       DATE WRITTEN   <date_written>
   15116              : 
   15117              :     // PURPOSE OF THIS SUBROUTINE:
   15118              :     // This routine looks up the given TwoSpeed DX coil and returns the companion supply fan index
   15119              : 
   15120              :     // Using/Aliasing
   15121            2 :     int NumPrimaryAirSys = state.dataHVACGlobal->NumPrimaryAirSys;
   15122              : 
   15123              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   15124              :     int FoundBranch;
   15125              :     int FoundAirSysNum;
   15126              :     int AirSysNum;
   15127              :     int BranchNum;
   15128              :     int CompNum;
   15129              : 
   15130            2 :     FoundBranch = 0;
   15131            2 :     FoundAirSysNum = 0;
   15132            2 :     SupplyFanIndex = 0;
   15133            2 :     SupplyFanName = "n/a";
   15134            4 :     for (AirSysNum = 1; AirSysNum <= NumPrimaryAirSys; ++AirSysNum) {
   15135              : 
   15136            4 :         for (BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).NumBranches; ++BranchNum) {
   15137              : 
   15138            4 :             for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).TotalComponents; ++CompNum) {
   15139              : 
   15140            4 :                 if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
   15141              :                     SimAirServingZones::CompType::DXSystem) {
   15142              : 
   15143            2 :                     if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
   15144            2 :                                          state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
   15145            2 :                         FoundBranch = BranchNum;
   15146            2 :                         FoundAirSysNum = AirSysNum;
   15147            2 :                         break;
   15148              :                     }
   15149              :                     // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
   15150            2 :                 } else if (state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).CompType_Num ==
   15151              :                            SimAirServingZones::CompType::UnitarySystemModel) {
   15152              : 
   15153            0 :                     if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirSysNum).Branch(BranchNum).Comp(CompNum).Name,
   15154            0 :                                          state.dataDXCoils->DXCoil(CoolingCoilIndex).CoilSystemName)) {
   15155            0 :                         FoundBranch = BranchNum;
   15156            0 :                         FoundAirSysNum = AirSysNum;
   15157            0 :                         break;
   15158              :                     }
   15159              :                 }
   15160              :             }
   15161              : 
   15162            2 :             if (FoundBranch > 0 && FoundAirSysNum > 0) {
   15163            9 :                 for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).TotalComponents;
   15164              :                      ++CompNum) {
   15165            8 :                     if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
   15166              :                         SimAirServingZones::CompType::Fan_Simple_VAV) {
   15167            1 :                         SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
   15168            1 :                         SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
   15169            1 :                         supplyFanType = HVAC::FanType::VAV;
   15170            1 :                         break;
   15171              :                         // these are specified in SimAirServingZones and need to be moved to a Data* file. UnitarySystem=19
   15172            7 :                     } else if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
   15173              :                                SimAirServingZones::CompType::Fan_System_Object) {
   15174            1 :                         SupplyFanName = state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).Name;
   15175            1 :                         SupplyFanIndex = Fans::GetFanIndex(state, SupplyFanName);
   15176            1 :                         supplyFanType = HVAC::FanType::SystemModel;
   15177              : 
   15178            6 :                     } else if (state.dataAirSystemsData->PrimaryAirSystems(FoundAirSysNum).Branch(FoundBranch).Comp(CompNum).CompType_Num ==
   15179              :                                SimAirServingZones::CompType::UnitarySystemModel) {
   15180              :                         // fan may not be specified in a unitary system object, keep looking
   15181              :                         // Unitary System will "set" the fan index to the DX coil if contained within the HVAC system
   15182            0 :                         if (state.dataDXCoils->DXCoil(CoolingCoilIndex).SupplyFanIndex > 0) {
   15183            0 :                             break;
   15184              :                         }
   15185              :                     }
   15186              :                 }
   15187              :             }
   15188              :         }
   15189              :     }
   15190            2 : }
   15191              : 
   15192          165 : void GetDXCoilIndex(EnergyPlusData &state,
   15193              :                     std::string const &DXCoilName,
   15194              :                     int &DXCoilIndex,
   15195              :                     bool &ErrorsFound,
   15196              :                     std::string_view const ThisObjectType,
   15197              :                     bool const SuppressWarning)
   15198              : {
   15199              : 
   15200              :     // SUBROUTINE INFORMATION:
   15201              :     //       AUTHOR         Richard Raustad
   15202              :     //       DATE WRITTEN   March 2005
   15203              : 
   15204              :     // PURPOSE OF THIS SUBROUTINE:
   15205              :     // This subroutine sets an index for a given DX Coil -- issues error message if that
   15206              :     // DX Coil is not a legal DX Coil.
   15207              : 
   15208          165 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15209           58 :         GetDXCoils(state);
   15210           58 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15211              :     }
   15212              : 
   15213          165 :     DXCoilIndex = Util::FindItemInList(DXCoilName, state.dataDXCoils->DXCoil);
   15214          165 :     if (DXCoilIndex == 0) {
   15215            0 :         if (!SuppressWarning) {
   15216              :             //     No warning printed if only searching for the existence of a DX Coil
   15217            0 :             if (!ThisObjectType.empty()) {
   15218            0 :                 ShowSevereError(state, fmt::format("{}, GetDXCoilIndex: DX Coil not found={}", ThisObjectType, DXCoilName));
   15219              :             } else {
   15220            0 :                 ShowSevereError(state, format("GetDXCoilIndex: DX Coil not found={}", DXCoilName));
   15221              :             }
   15222              :         }
   15223            0 :         ErrorsFound = true;
   15224              :     }
   15225          165 : }
   15226              : 
   15227              : std::string
   15228            0 : GetDXCoilName(EnergyPlusData &state, int &DXCoilIndex, bool &ErrorsFound, std::string_view const ThisObjectType, bool const SuppressWarning)
   15229              : {
   15230              : 
   15231              :     // SUBROUTINE INFORMATION:
   15232              :     //       AUTHOR         Richard Raustad
   15233              :     //       DATE WRITTEN   May 2017
   15234              : 
   15235              :     // PURPOSE OF THIS SUBROUTINE:
   15236              :     // This subroutine gets a name for a given DX Coil -- issues error message if that
   15237              :     // DX Coil is not a legal DX Coil.
   15238              : 
   15239            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15240            0 :         GetDXCoils(state);
   15241            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15242              :     }
   15243              : 
   15244            0 :     if (DXCoilIndex == 0) {
   15245            0 :         if (!SuppressWarning) {
   15246              :             //     No warning printed if only searching for the existence of a DX Coil
   15247            0 :             if (!ThisObjectType.empty()) {
   15248            0 :                 ShowSevereError(state, fmt::format("{}, GetDXCoilIndex: DX Coil not found ", ThisObjectType));
   15249              :             } else {
   15250            0 :                 ShowSevereError(state, "GetDXCoilIndex: DX Coil not found ");
   15251              :             }
   15252              :         }
   15253            0 :         ErrorsFound = true;
   15254            0 :         return " "; // This does not seem great
   15255              : 
   15256              :     } else {
   15257            0 :         return state.dataDXCoils->DXCoil(DXCoilIndex).Name;
   15258              :     }
   15259              : }
   15260              : 
   15261            6 : Real64 GetCoilCapacity(EnergyPlusData &state,
   15262              :                        std::string const &CoilType, // must match coil types in this module
   15263              :                        std::string const &CoilName, // must match coil names for the coil type
   15264              :                        bool &ErrorsFound            // set to true if problem
   15265              : )
   15266              : {
   15267              : 
   15268              :     // FUNCTION INFORMATION:
   15269              :     //       AUTHOR         Linda Lawrie
   15270              :     //       DATE WRITTEN   February 2006
   15271              : 
   15272              :     // PURPOSE OF THIS FUNCTION:
   15273              :     // This function looks up the coil capacity for the given coil and returns it.  If
   15274              :     // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
   15275              :     // as negative.
   15276              : 
   15277              :     // Return value
   15278              :     Real64 CoilCapacity; // returned capacity of matched coil
   15279              : 
   15280              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15281              :     int WhichCoil;
   15282              : 
   15283              :     // Obtains and Allocates DXCoils
   15284            6 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15285            0 :         GetDXCoils(state);
   15286            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15287              :     }
   15288              : 
   15289            6 :     if (Util::SameString(CoilType, "Coil:Heating:DX:SingleSpeed") || Util::SameString(CoilType, "Coil:Cooling:DX:SingleSpeed")) {
   15290            6 :         WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
   15291            6 :         if (WhichCoil != 0) {
   15292            6 :             CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(1);
   15293              :         }
   15294            0 :     } else if (Util::SameString(CoilType, "Coil:Cooling:DX:TwoStageWithHumidityControlMode")) {
   15295            0 :         WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
   15296            0 :         if (WhichCoil != 0) {
   15297            0 :             CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(state.dataDXCoils->DXCoil(WhichCoil).NumCapacityStages);
   15298              :         }
   15299            0 :     } else if (Util::SameString(CoilType, "Coil:Cooling:DX:TwoSpeed")) {
   15300            0 :         WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
   15301            0 :         if (WhichCoil != 0) {
   15302            0 :             CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).RatedTotCap(1);
   15303              :         }
   15304            0 :     } else if (Util::SameString(CoilType, "Coil:Cooling:DX:MultiSpeed") || Util::SameString(CoilType, "Coil:Heating:DX:MultiSpeed")) {
   15305            0 :         WhichCoil = Util::FindItem(CoilName, state.dataDXCoils->DXCoil);
   15306            0 :         if (WhichCoil != 0) {
   15307            0 :             CoilCapacity = state.dataDXCoils->DXCoil(WhichCoil).MSRatedTotCap(state.dataDXCoils->DXCoil(WhichCoil).NumOfSpeeds);
   15308              :         }
   15309              :     } else {
   15310            0 :         WhichCoil = 0;
   15311              :     }
   15312              : 
   15313            6 :     if (WhichCoil == 0) {
   15314            0 :         ShowSevereError(state, format("GetCoilCapacity: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
   15315            0 :         ShowContinueError(state, "... returning capacity as -1000.");
   15316            0 :         ErrorsFound = true;
   15317            0 :         CoilCapacity = -1000.0;
   15318              :     }
   15319              : 
   15320            6 :     return CoilCapacity;
   15321              : }
   15322              : 
   15323           39 : Real64 GetCoilCapacityByIndexType(EnergyPlusData &state,
   15324              :                                   int const CoilIndex,    // must match coil index for the coil type
   15325              :                                   int const CoilType_Num, // must match coil types in this module
   15326              :                                   bool &ErrorsFound       // set to true if problem
   15327              : )
   15328              : {
   15329              : 
   15330              :     // FUNCTION INFORMATION:
   15331              :     //       AUTHOR         Richard Raustad
   15332              :     //       DATE WRITTEN   October 2010
   15333              : 
   15334              :     // PURPOSE OF THIS FUNCTION:
   15335              :     // This function looks up the coil capacity for the given coil and returns it.  If
   15336              :     // incorrect coil index or type is given, ErrorsFound is returned as true and capacity is returned
   15337              :     // as negative.
   15338              : 
   15339              :     // Return value
   15340              :     Real64 CoilCapacity; // returned capacity of matched coil
   15341              : 
   15342              :     // Obtains and Allocates DXCoils
   15343           39 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15344            0 :         GetDXCoils(state);
   15345            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15346              :     }
   15347              : 
   15348           39 :     if (CoilIndex == 0) {
   15349            0 :         ShowSevereError(state, "GetCoilCapacityByIndexType: Invalid index passed = 0");
   15350            0 :         ShowContinueError(state, "... returning capacity as -1000.");
   15351            0 :         ErrorsFound = true;
   15352            0 :         CoilCapacity = -1000.0;
   15353            0 :         return CoilCapacity;
   15354              :     }
   15355              : 
   15356           39 :     if (CoilType_Num != state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
   15357            0 :         ShowSevereError(state, "GetCoilCapacityByIndexType: Index passed does not match DX Coil type passed.");
   15358            0 :         ShowContinueError(state, "... returning capacity as -1000.");
   15359            0 :         ErrorsFound = true;
   15360            0 :         CoilCapacity = -1000.0;
   15361              :     } else {
   15362           39 :         switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
   15363            4 :         case HVAC::CoilDX_MultiSpeedCooling:
   15364              :         case HVAC::CoilDX_MultiSpeedHeating: {
   15365            4 :             CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).MSRatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
   15366            4 :         } break;
   15367           35 :         default: {
   15368           35 :             CoilCapacity = state.dataDXCoils->DXCoil(CoilIndex).RatedTotCap(state.dataDXCoils->DXCoil(CoilIndex).NumCapacityStages);
   15369           35 :         } break;
   15370              :         }
   15371              :     }
   15372              : 
   15373           39 :     return CoilCapacity;
   15374              : }
   15375              : 
   15376           76 : int GetCoilTypeNum(EnergyPlusData &state,
   15377              :                    std::string const &CoilType,                // must match coil types in this module
   15378              :                    std::string const &CoilName,                // must match coil names for the coil type
   15379              :                    bool &ErrorsFound,                          // set to true if problem
   15380              :                    ObjexxFCL::Optional_bool_const PrintWarning // prints warning when true
   15381              : )
   15382              : {
   15383              : 
   15384              :     // FUNCTION INFORMATION:
   15385              :     //       AUTHOR         R. Raustad - FSEC
   15386              :     //       DATE WRITTEN   August 2008
   15387              : 
   15388              :     // PURPOSE OF THIS FUNCTION:
   15389              :     // This function looks up the integerized coil type for the given coil and returns it.  If
   15390              :     // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
   15391              :     // as negative.
   15392              : 
   15393              :     // Return value
   15394              :     int TypeNum; // returned integerized type of matched coil
   15395              : 
   15396              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15397              :     int WhichCoil;
   15398              :     bool PrintMessage;
   15399              : 
   15400              :     // Obtains and Allocates DXCoils
   15401           76 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15402           29 :         GetDXCoils(state);
   15403           29 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15404              :     }
   15405              : 
   15406           76 :     if (present(PrintWarning)) {
   15407           74 :         PrintMessage = PrintWarning;
   15408              :     } else {
   15409            2 :         PrintMessage = true;
   15410              :     }
   15411              : 
   15412           76 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15413           76 :     if (WhichCoil != 0) {
   15414           76 :         TypeNum = state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num;
   15415              :     } else {
   15416            0 :         if (PrintMessage) {
   15417            0 :             ShowSevereError(state, format("GetCoilTypeNum: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
   15418              :         }
   15419            0 :         ErrorsFound = true;
   15420            0 :         TypeNum = 0;
   15421              :     }
   15422              : 
   15423           76 :     return TypeNum;
   15424              : }
   15425              : 
   15426           76 : Real64 GetMinOATCompressor(EnergyPlusData &state,
   15427              :                            int const CoilIndex, // index to cooling coil
   15428              :                            bool &ErrorsFound    // set to true if problem
   15429              : )
   15430              : {
   15431              : 
   15432              :     // Obtains and Allocates DXCoils
   15433           76 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15434            0 :         GetDXCoils(state);
   15435            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15436              :     }
   15437              : 
   15438           76 :     if (CoilIndex == 0) {
   15439            0 :         ShowSevereError(state, "GetMinOATCompressor: Index passed = 0");
   15440            0 :         ShowContinueError(state, "... returning Min OAT for compressor operation as -1000.");
   15441            0 :         ErrorsFound = true;
   15442            0 :         return -1000.0;
   15443              :     } else {
   15444           76 :         return state.dataDXCoils->DXCoil(CoilIndex).MinOATCompressor;
   15445              :     }
   15446              : }
   15447              : 
   15448           78 : int GetCoilInletNode(EnergyPlusData &state,
   15449              :                      std::string const &CoilType, // must match coil types in this module
   15450              :                      std::string const &CoilName, // must match coil names for the coil type
   15451              :                      bool &ErrorsFound            // set to true if problem
   15452              : )
   15453              : {
   15454              : 
   15455              :     // FUNCTION INFORMATION:
   15456              :     //       AUTHOR         Linda Lawrie
   15457              :     //       DATE WRITTEN   February 2006
   15458              : 
   15459              :     // PURPOSE OF THIS FUNCTION:
   15460              :     // This function looks up the given coil and returns the inlet node number.  If
   15461              :     // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
   15462              :     // as zero.
   15463              : 
   15464              :     // Return value
   15465              :     int NodeNumber; // returned node number of matched coil
   15466              : 
   15467              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15468              :     int WhichCoil;
   15469              : 
   15470              :     // Obtains and Allocates DXCoils
   15471           78 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15472            1 :         GetDXCoils(state);
   15473            1 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15474              :     }
   15475              : 
   15476           78 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15477           78 :     if (WhichCoil != 0) {
   15478           78 :         NodeNumber = state.dataDXCoils->DXCoil(WhichCoil).AirInNode;
   15479              :     } else {
   15480            0 :         ShowSevereError(state, format("GetCoilInletNode: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
   15481            0 :         ErrorsFound = true;
   15482            0 :         NodeNumber = 0;
   15483              :     }
   15484              : 
   15485           78 :     return NodeNumber;
   15486              : }
   15487              : 
   15488            0 : int getCoilInNodeIndex(EnergyPlusData &state,
   15489              :                        int const CoilIndex, // coil index
   15490              :                        bool &ErrorsFound    // set to true if problem
   15491              : )
   15492              : {
   15493              : 
   15494              :     int NodeNumber; // returned node number of matched coil
   15495              : 
   15496              :     // Obtains and Allocates DXCoils
   15497            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15498            0 :         GetDXCoils(state);
   15499            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15500              :     }
   15501              : 
   15502            0 :     if (CoilIndex != 0) {
   15503            0 :         NodeNumber = state.dataDXCoils->DXCoil(CoilIndex).AirInNode;
   15504              :     } else {
   15505            0 :         ShowSevereError(state, "GetCoilInletNode: Could not find Coil Type");
   15506            0 :         ErrorsFound = true;
   15507            0 :         NodeNumber = 0;
   15508              :     }
   15509              : 
   15510            0 :     return NodeNumber;
   15511              : }
   15512              : 
   15513           83 : int GetCoilOutletNode(EnergyPlusData &state,
   15514              :                       std::string const &CoilType, // must match coil types in this module
   15515              :                       std::string const &CoilName, // must match coil names for the coil type
   15516              :                       bool &ErrorsFound            // set to true if problem
   15517              : )
   15518              : {
   15519              : 
   15520              :     // FUNCTION INFORMATION:
   15521              :     //       AUTHOR         Linda Lawrie
   15522              :     //       DATE WRITTEN   February 2006
   15523              : 
   15524              :     // PURPOSE OF THIS FUNCTION:
   15525              :     // This function looks up the given coil and returns the inlet node number.  If
   15526              :     // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
   15527              :     // as zero.
   15528              : 
   15529              :     // Return value
   15530              :     int NodeNumber; // returned node number of matched coil
   15531              : 
   15532              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15533              :     int WhichCoil;
   15534              : 
   15535              :     // Obtains and Allocates DXCoils
   15536           83 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15537            3 :         GetDXCoils(state);
   15538            3 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15539              :     }
   15540              : 
   15541           83 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15542           83 :     if (WhichCoil != 0) {
   15543           83 :         NodeNumber = state.dataDXCoils->DXCoil(WhichCoil).AirOutNode;
   15544              :     } else {
   15545            0 :         ShowSevereError(
   15546              :             state,
   15547            0 :             format("GetCoilOutletNode: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil outlet node number.", CoilType, CoilName));
   15548            0 :         ErrorsFound = true;
   15549            0 :         NodeNumber = 0;
   15550              :     }
   15551              : 
   15552           83 :     return NodeNumber;
   15553              : }
   15554              : 
   15555            0 : int getCoilOutNodeIndex(EnergyPlusData &state,
   15556              :                         int const CoilIndex, // must match coil types in this module
   15557              :                         bool &ErrorsFound    // set to true if problem
   15558              : )
   15559              : {
   15560              : 
   15561              :     int NodeNumber; // returned node number of matched coil
   15562              : 
   15563              :     // Obtains and Allocates DXCoils
   15564            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15565            0 :         GetDXCoils(state);
   15566            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15567              :     }
   15568              : 
   15569            0 :     if (CoilIndex != 0) {
   15570            0 :         NodeNumber = state.dataDXCoils->DXCoil(CoilIndex).AirOutNode;
   15571              :     } else {
   15572            0 :         ShowSevereError(state, "GetCoilOutletNode: Could not find Coil Type");
   15573            0 :         ErrorsFound = true;
   15574            0 :         NodeNumber = 0;
   15575              :     }
   15576              : 
   15577            0 :     return NodeNumber;
   15578              : }
   15579              : 
   15580           45 : int GetCoilCondenserInletNode(EnergyPlusData &state,
   15581              :                               std::string const &CoilType, // must match coil types in this module
   15582              :                               std::string const &CoilName, // must match coil names for the coil type
   15583              :                               bool &ErrorsFound            // set to true if problem
   15584              : )
   15585              : {
   15586              : 
   15587              :     // FUNCTION INFORMATION:
   15588              :     //       AUTHOR         R. Raustad
   15589              :     //       DATE WRITTEN   January 2007
   15590              : 
   15591              :     // PURPOSE OF THIS FUNCTION:
   15592              :     // This function looks up the given coil and returns the condenser inlet node.  If
   15593              :     // incorrect coil type or name is given, ErrorsFound is returned as true.
   15594              : 
   15595              :     // Return value
   15596              :     int CondNode; // returned condenser node number of matched coil
   15597              : 
   15598              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15599              :     int WhichCoil;
   15600              : 
   15601              :     // Obtains and Allocates DXCoils
   15602           45 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15603            0 :         GetDXCoils(state);
   15604            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15605              :     }
   15606              : 
   15607           45 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15608           45 :     if (WhichCoil != 0) {
   15609           45 :         CondNode = state.dataDXCoils->DXCoil(WhichCoil).CondenserInletNodeNum(1);
   15610              :     } else {
   15611            0 :         ShowSevereError(state, format("GetCoilCondenserInletNode: Invalid DX Coil, Type= \"{}\" Name=\"{}\"", CoilType, CoilName));
   15612            0 :         ErrorsFound = true;
   15613            0 :         CondNode = 0;
   15614              :     }
   15615              : 
   15616           45 :     return CondNode;
   15617              : }
   15618              : 
   15619            2 : Real64 GetDXCoilBypassedFlowFrac(EnergyPlusData &state,
   15620              :                                  std::string const &CoilType, // must match coil types in this module
   15621              :                                  std::string const &CoilName, // must match coil names for the coil type
   15622              :                                  bool &ErrorsFound            // set to true if problem
   15623              : )
   15624              : {
   15625              : 
   15626              :     // FUNCTION INFORMATION:
   15627              :     //       AUTHOR         R. Raustad
   15628              :     //       DATE WRITTEN   June 2007
   15629              : 
   15630              :     // PURPOSE OF THIS FUNCTION:
   15631              :     // This function looks up the given coil and returns the bypassed air flow fraction.
   15632              :     // Bypassed air flow fraction can only be greater than 0 for multimode DX cooling coils and is typical for 1st stage
   15633              :     // If incorrect coil type or name is given, ErrorsFound is returned as true.
   15634              : 
   15635              :     // Return value
   15636              :     Real64 BypassFraction; // returned bypass air fraction of matched coil
   15637              : 
   15638              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15639              :     int WhichCoil;
   15640              : 
   15641              :     // Obtains and Allocates DXCoils
   15642            2 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15643            0 :         GetDXCoils(state);
   15644            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15645              :     }
   15646              : 
   15647            2 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15648            2 :     if (WhichCoil != 0) {
   15649            2 :         BypassFraction = state.dataDXCoils->DXCoil(WhichCoil).BypassedFlowFrac(1);
   15650              :     } else {
   15651            0 :         ShowSevereError(state, format("GetDXCoilBypassedFlowFrac: Invalid DX Coil Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
   15652            0 :         ErrorsFound = true;
   15653            0 :         BypassFraction = 0.0;
   15654              :     }
   15655              : 
   15656            2 :     return BypassFraction;
   15657              : }
   15658              : 
   15659           40 : int GetHPCoolingCoilIndex(EnergyPlusData &state,
   15660              :                           std::string const &HeatingCoilType, // Type of DX heating coil used in HP
   15661              :                           std::string const &HeatingCoilName, // Name of DX heating coil used in HP
   15662              :                           int const HeatingCoilIndex          // Index of DX heating coil used in HP
   15663              : )
   15664              : {
   15665              : 
   15666              :     // FUNCTION INFORMATION:
   15667              :     //       AUTHOR         R. Raustad
   15668              :     //       DATE WRITTEN   February 2007
   15669              : 
   15670              :     // PURPOSE OF THIS FUNCTION:
   15671              :     // This function looks up the given DX heating coil and returns the companion DX cooling coil.
   15672              : 
   15673              :     // Return value
   15674              :     int DXCoolingCoilIndex; // Index of HP DX cooling coil returned from this function
   15675              : 
   15676              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15677              :     int WhichComp;           // DO loop counter to find correct comp set
   15678              :     int WhichCompanionComp;  // DO loop counter to find companion coil comp set
   15679              :     int WhichHXAssistedComp; // DO loop counter when DX coil is used in a HX assisted cooling coil
   15680              : 
   15681           40 :     DXCoolingCoilIndex = 0;
   15682              : 
   15683              :     DataLoopNode::ConnectionObjectType HeatingCoilTypeNum = static_cast<DataLoopNode::ConnectionObjectType>(
   15684           40 :         getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC, Util::makeUPPER(HeatingCoilType)));
   15685              : 
   15686              :     DataLoopNode::ConnectionObjectType CompSetsParentType; // Parent object type which uses DX heating coil pass into this function
   15687           40 :     std::string CompSetsParentName;
   15688          110 :     for (WhichComp = 1; WhichComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichComp) {
   15689              : 
   15690          151 :         if (HeatingCoilTypeNum != state.dataBranchNodeConnections->CompSets(WhichComp).ComponentObjectType ||
   15691           41 :             !Util::SameString(HeatingCoilName, state.dataBranchNodeConnections->CompSets(WhichComp).CName)) {
   15692           70 :             continue;
   15693              :         }
   15694           40 :         CompSetsParentType = state.dataBranchNodeConnections->CompSets(WhichComp).ParentObjectType;
   15695           40 :         CompSetsParentName = state.dataBranchNodeConnections->CompSets(WhichComp).ParentCName;
   15696           40 :         if ((CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAir) ||
   15697           14 :             (CompSetsParentType == DataLoopNode::ConnectionObjectType::ZoneHVACPackagedTerminalHeatPump) ||
   15698           12 :             (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed) ||
   15699           12 :             (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass) ||
   15700              :             (CompSetsParentType == DataLoopNode::ConnectionObjectType::AirLoopHVACUnitarySystem)) {
   15701              :             //       Search for DX cooling coils
   15702          104 :             for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
   15703          154 :                 if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
   15704           64 :                     (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
   15705              :                      DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed)) {
   15706           64 :                     continue;
   15707              :                 }
   15708              :                 DXCoolingCoilIndex =
   15709           26 :                     Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
   15710           26 :                 break;
   15711              :             }
   15712          152 :             for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
   15713          207 :                 if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, CompSetsParentName) ||
   15714           91 :                     (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
   15715              :                      DataLoopNode::ConnectionObjectType::CoilCoolingDXMultiSpeed)) {
   15716          112 :                     continue;
   15717              :                 }
   15718              :                 DXCoolingCoilIndex =
   15719            4 :                     Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
   15720            4 :                 break;
   15721              :             }
   15722              :             //       Search for Heat Exchanger Assisted DX cooling coils
   15723           40 :             if (DXCoolingCoilIndex == 0) {
   15724           93 :                 for (WhichHXAssistedComp = 1; WhichHXAssistedComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichHXAssistedComp) {
   15725          124 :                     if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ParentCName, CompSetsParentName) ||
   15726           62 :                         (state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ComponentObjectType !=
   15727              :                          DataLoopNode::ConnectionObjectType::CoilSystemCoolingDXHeatExchangerAssisted)) {
   15728           62 :                         continue;
   15729              :                     }
   15730              :                     DataLoopNode::ConnectionObjectType HXCompSetsParentType; // Used when DX cooling coil is a child of a HX assisted cooling coil
   15731            0 :                     HXCompSetsParentType = state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).ComponentObjectType;
   15732            0 :                     std::string const &HXCompSetsParentName = state.dataBranchNodeConnections->CompSets(WhichHXAssistedComp).CName;
   15733            0 :                     for (WhichCompanionComp = 1; WhichCompanionComp <= state.dataBranchNodeConnections->NumCompSets; ++WhichCompanionComp) {
   15734            0 :                         if (!Util::SameString(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ParentCName, HXCompSetsParentName) ||
   15735            0 :                             (state.dataBranchNodeConnections->CompSets(WhichCompanionComp).ComponentObjectType !=
   15736              :                              DataLoopNode::ConnectionObjectType::CoilCoolingDXSingleSpeed)) {
   15737            0 :                             continue;
   15738              :                         }
   15739              :                         DXCoolingCoilIndex =
   15740            0 :                             Util::FindItemInList(state.dataBranchNodeConnections->CompSets(WhichCompanionComp).CName, state.dataDXCoils->DXCoil);
   15741            0 :                         break;
   15742              :                     }
   15743            0 :                     break;
   15744              :                 }
   15745              :             }
   15746           40 :         } else {
   15747              :             //     ErrorFound, Coil:Heating:DX:SingleSpeed is used in wrong type of parent object (should never get here)
   15748            0 :             ShowSevereError(state,
   15749            0 :                             format("Configuration error in {}\"{}\"",
   15750            0 :                                    BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(CompSetsParentType)],
   15751              :                                    CompSetsParentName));
   15752            0 :             ShowContinueError(state, "DX heating coil not allowed in this configuration.");
   15753            0 :             ShowFatalError(state, "Preceding condition(s) causes termination.");
   15754              :         }
   15755           40 :         break;
   15756              :     }
   15757              : 
   15758              :     // Check and warn user is crankcase heater power or max OAT for crankcase heater differs in DX cooling and heating coils
   15759           40 :     if (DXCoolingCoilIndex > 0) {
   15760            9 :         if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity != 0.0) {
   15761            1 :             if (state.dataDXCoils->DXCoil(DXCoolingCoilIndex).CrankcaseHeaterCapacity !=
   15762            2 :                     state.dataDXCoils->DXCoil(HeatingCoilIndex).CrankcaseHeaterCapacity ||
   15763            1 :                 state.dataDXCoils->DXCoil(DXCoolingCoilIndex).MaxOATCrankcaseHeater !=
   15764            1 :                     state.dataDXCoils->DXCoil(HeatingCoilIndex).MaxOATCrankcaseHeater) {
   15765            0 :                 ShowWarningError(state, "Crankcase heater capacity or max outdoor temp for crankcase heater operation specified in");
   15766            0 :                 ShowContinueError(state, format("Coil:Cooling:DX:SingleSpeed = {}", state.dataDXCoils->DXCoil(DXCoolingCoilIndex).Name));
   15767            0 :                 ShowContinueError(state, format("is different than that specified in Coil:Heating:DX:SingleSpeed = {}.", HeatingCoilName));
   15768            0 :                 ShowContinueError(state,
   15769            0 :                                   format("Both of these DX coils are part of {}={}.",
   15770            0 :                                          BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(CompSetsParentType)],
   15771              :                                          CompSetsParentName));
   15772            0 :                 ShowContinueError(state, "The value specified in the DX heating coil will be used and the simulation continues...");
   15773              :             }
   15774              :         }
   15775              :     }
   15776              : 
   15777           40 :     return DXCoolingCoilIndex;
   15778           40 : }
   15779              : 
   15780            6 : int GetDXCoilNumberOfSpeeds(EnergyPlusData &state,
   15781              :                             std::string const &CoilType, // must match coil types in this module
   15782              :                             std::string const &CoilName, // must match coil names for the coil type
   15783              :                             bool &ErrorsFound            // set to true if problem
   15784              : )
   15785              : {
   15786              : 
   15787              :     // FUNCTION INFORMATION:
   15788              :     //       AUTHOR         L. Gu
   15789              :     //       DATE WRITTEN   July 2007
   15790              : 
   15791              :     // PURPOSE OF THIS FUNCTION:
   15792              :     // This function looks up the given coil and returns the number of speeds for multispeed coils.
   15793              :     // If incorrect coil type or name is given, ErrorsFound is returned as true.
   15794              : 
   15795              :     // Return value
   15796              :     int NumberOfSpeeds; // returned the number of speed of matched coil
   15797              : 
   15798              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15799              :     int WhichCoil;
   15800              : 
   15801              :     // Obtains and Allocates DXCoils
   15802            6 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15803            0 :         GetDXCoils(state);
   15804            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15805              :     }
   15806              : 
   15807            6 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15808            6 :     if (WhichCoil != 0) {
   15809            6 :         NumberOfSpeeds = state.dataDXCoils->DXCoil(WhichCoil).NumOfSpeeds;
   15810              :     } else {
   15811            0 :         ShowSevereError(state, format("GetDXCoilNumberOfSpeeds: Invalid DX Coil Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
   15812            0 :         ErrorsFound = true;
   15813            0 :         NumberOfSpeeds = 0;
   15814              :     }
   15815              : 
   15816            6 :     return NumberOfSpeeds;
   15817              : }
   15818              : 
   15819           68 : Sched::Schedule *GetDXCoilAvailSched(EnergyPlusData &state,
   15820              :                                      std::string const &CoilType,            // must match coil types in this module
   15821              :                                      std::string const &CoilName,            // must match coil names for the coil type
   15822              :                                      bool &ErrorsFound,                      // set to true if problem
   15823              :                                      ObjexxFCL::Optional_int_const CoilIndex // Coil index number
   15824              : )
   15825              : {
   15826              : 
   15827              :     // FUNCTION INFORMATION:
   15828              :     //       AUTHOR         Richard Raustad
   15829              :     //       DATE WRITTEN   January 2013
   15830              : 
   15831              :     // PURPOSE OF THIS FUNCTION:
   15832              :     // This function looks up the given coil and returns the availability schedule index.  If
   15833              :     // incorrect coil type or name is given, ErrorsFound is returned as true and schedule index is returned
   15834              :     // as -1.
   15835              : 
   15836              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15837              :     int WhichCoil;
   15838              : 
   15839              :     // Obtains and Allocates DXCoils
   15840           68 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15841            0 :         GetDXCoils(state);
   15842            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15843              :     }
   15844              : 
   15845           68 :     if (present(CoilIndex)) {
   15846            2 :         if (CoilIndex == 0) {
   15847            0 :             ShowSevereError(state, "GetDXCoilAvailSchPtr: Invalid index passed = 0");
   15848            0 :             ShowContinueError(state, "... returning DXCoilAvailSchPtr as -1.");
   15849            0 :             ErrorsFound = true;
   15850            0 :             return nullptr;
   15851              :         } else {
   15852            2 :             WhichCoil = CoilIndex;
   15853              :         }
   15854              :     } else {
   15855           66 :         WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15856              :     }
   15857           68 :     if (WhichCoil != 0) {
   15858           68 :         return state.dataDXCoils->DXCoil(WhichCoil).availSched;
   15859              :     } else {
   15860            0 :         if (!present(CoilIndex)) {
   15861            0 :             ShowSevereError(state,
   15862            0 :                             format("GetDXCoilAvailSch: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil availability schedule index.",
   15863              :                                    CoilType,
   15864              :                                    CoilName));
   15865              :         }
   15866            0 :         ErrorsFound = true;
   15867            0 :         return nullptr;
   15868              :     }
   15869              : }
   15870              : 
   15871            0 : Real64 GetDXCoilAirFlow(EnergyPlusData &state,
   15872              :                         std::string const &CoilType, // must match coil types in this module
   15873              :                         std::string const &CoilName, // must match coil names for the coil type
   15874              :                         bool &ErrorsFound            // set to true if problem
   15875              : )
   15876              : {
   15877              : 
   15878              :     // FUNCTION INFORMATION:
   15879              :     //       AUTHOR         Richard Raustad
   15880              :     //       DATE WRITTEN   January 2013
   15881              : 
   15882              :     // PURPOSE OF THIS FUNCTION:
   15883              :     // This function looks up the given coil and returns the availability schedule index.  If
   15884              :     // incorrect coil type or name is given, ErrorsFound is returned as true and schedule index is returned
   15885              :     // as -1.
   15886              : 
   15887              :     // Return value
   15888              :     Real64 AirFlow; // returned coil air flow rate
   15889              : 
   15890              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   15891              :     int WhichCoil;
   15892              : 
   15893              :     // Obtains and Allocates DXCoils
   15894            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15895            0 :         GetDXCoils(state);
   15896            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15897              :     }
   15898              : 
   15899            0 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   15900            0 :     if (WhichCoil != 0) {
   15901            0 :         switch (state.dataDXCoils->DXCoil(WhichCoil).DXCoilType_Num) {
   15902            0 :         case HVAC::CoilDX_CoolingSingleSpeed:
   15903              :         case HVAC::CoilDX_CoolingTwoSpeed:
   15904              :         case HVAC::CoilDX_HeatingEmpirical:
   15905              :         case HVAC::CoilDX_CoolingTwoStageWHumControl: {
   15906            0 :             AirFlow = state.dataDXCoils->DXCoil(WhichCoil).RatedAirVolFlowRate(1);
   15907            0 :         } break;
   15908            0 :         case HVAC::CoilDX_MultiSpeedCooling:
   15909              :         case HVAC::CoilDX_MultiSpeedHeating: {
   15910            0 :             AirFlow = state.dataDXCoils->DXCoil(WhichCoil).MSRatedAirVolFlowRate(1);
   15911            0 :         } break;
   15912            0 :         default: {
   15913            0 :             ShowSevereError(
   15914              :                 state,
   15915            0 :                 format("GetDXCoilAirFlow: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil air flow rate.", CoilType, CoilName));
   15916            0 :             ErrorsFound = true;
   15917            0 :             AirFlow = -1.0;
   15918            0 :         } break;
   15919              :         }
   15920              :     } else {
   15921            0 :         ShowSevereError(
   15922            0 :             state, format("GetDXCoilAirFlow: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil air flow rate.", CoilType, CoilName));
   15923            0 :         ErrorsFound = true;
   15924            0 :         AirFlow = -1.0;
   15925              :     }
   15926              : 
   15927            0 :     return AirFlow;
   15928              : }
   15929              : 
   15930           48 : int GetDXCoilCapFTCurveIndex(EnergyPlusData &state,
   15931              :                              int const CoilIndex, // coil index pointer
   15932              :                              bool &ErrorsFound    // set to true if problem
   15933              : )
   15934              : {
   15935              : 
   15936              :     // FUNCTION INFORMATION:
   15937              :     //       AUTHOR         Richard Raustad
   15938              :     //       DATE WRITTEN   August 2013
   15939              : 
   15940              :     // PURPOSE OF THIS FUNCTION:
   15941              :     // This function looks up the given coil and returns the CapFT schedule index.  If
   15942              :     // incorrect coil index is given, ErrorsFound is returned as true and schedule index is returned
   15943              :     // as -1.
   15944              : 
   15945              :     // Return value
   15946              :     int CapFTCurveIndex; // returned coil CapFT curve index
   15947              : 
   15948              :     // Obtains and Allocates DXCoils
   15949           48 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   15950            0 :         GetDXCoils(state);
   15951            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   15952              :     }
   15953              : 
   15954           48 :     if (CoilIndex != 0) {
   15955           48 :         switch (state.dataDXCoils->DXCoil(CoilIndex).DXCoilType_Num) {
   15956           18 :         case HVAC::CoilDX_CoolingSingleSpeed:
   15957              :         case HVAC::CoilDX_CoolingTwoSpeed:
   15958              :         case HVAC::CoilDX_HeatingEmpirical:
   15959              :         case HVAC::CoilDX_CoolingTwoStageWHumControl: {
   15960           18 :             CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
   15961           18 :         } break;
   15962            8 :         case HVAC::CoilDX_MultiSpeedCooling:
   15963              :         case HVAC::CoilDX_MultiSpeedHeating: {
   15964            8 :             CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).MSCCapFTemp(state.dataDXCoils->DXCoil(CoilIndex).NumOfSpeeds);
   15965            8 :         } break;
   15966           22 :         case HVAC::CoilVRF_Heating: {
   15967           22 :             CapFTCurveIndex = state.dataDXCoils->DXCoil(CoilIndex).CCapFTemp(1);
   15968           22 :         } break;
   15969            0 :         default: {
   15970              :             //        CALL ShowSevereError(state, 'GetDXCoilCapFTCurveIndex: Could not find Coil, Type="'// &
   15971              :             //             TRIM(cAllCoilTypes(DXCoil(CoilIndex)%DXCoilType_Num))//'" Name="'//TRIM(DXCoil(CoilIndex)%Name)//  &
   15972              :             //              '" when accessing coil capacity as a function of temperature curve.')
   15973            0 :             ErrorsFound = true;
   15974            0 :             CapFTCurveIndex = 0;
   15975            0 :         } break;
   15976              :         }
   15977              :     } else {
   15978              :         //    CALL ShowSevereError(state, 'GetDXCoilCapFTCurveIndex: Could not find Coil, Index = 0'// &
   15979              :         //          ' when accessing coil air flow rate.')
   15980            0 :         ErrorsFound = true;
   15981            0 :         CapFTCurveIndex = 0;
   15982              :     }
   15983              : 
   15984           48 :     return CapFTCurveIndex;
   15985              : }
   15986              : 
   15987          643 : void SetDXCoolingCoilData(
   15988              :     EnergyPlusData &state,
   15989              :     int const DXCoilNum,                                                     // Number of DX Cooling Coil
   15990              :     bool &ErrorsFound,                                                       // Set to true if certain errors found
   15991              :     ObjexxFCL::Optional_int HeatingCoilPLFCurvePTR,                          // Parameter equivalent of heating coil PLR curve index
   15992              :     ObjexxFCL::Optional<DataHeatBalance::RefrigCondenserType> CondenserType, // Parameter equivalent of condenser type parameter
   15993              :     ObjexxFCL::Optional_int CondenserInletNodeNum,                           // Parameter equivalent of condenser inlet node number
   15994              :     ObjexxFCL::Optional<Real64> MaxOATCrankcaseHeater,                       // Parameter equivalent of condenser Max OAT for Crank Case Heater temp
   15995              :     ObjexxFCL::Optional<Real64> MinOATCooling,                    // Parameter equivalent of condenser Min OAT for compressor cooling operation
   15996              :     ObjexxFCL::Optional<Real64> MaxOATCooling,                    // Parameter equivalent of condenser Max OAT for compressor cooling operation
   15997              :     ObjexxFCL::Optional<Real64> MinOATHeating,                    // Parameter equivalent of condenser Min OAT for compressor heating operation
   15998              :     ObjexxFCL::Optional<Real64> MaxOATHeating,                    // Parameter equivalent of condenser Max OAT for compressor heating operation
   15999              :     ObjexxFCL::Optional<HVAC::OATType> HeatingPerformanceOATType, // Parameter equivalent to condenser entering air temp type (1-db, 2=wb)
   16000              :     ObjexxFCL::Optional<StandardRatings::DefrostStrat> DefrostStrategy,
   16001              :     ObjexxFCL::Optional<StandardRatings::HPdefrostControl> DefrostControl,
   16002              :     ObjexxFCL::Optional_int DefrostEIRPtr,
   16003              :     ObjexxFCL::Optional<Real64> DefrostFraction,
   16004              :     ObjexxFCL::Optional<Real64> DefrostCapacity,
   16005              :     ObjexxFCL::Optional<Real64> MaxOATDefrost,
   16006              :     ObjexxFCL::Optional_bool CoolingCoilPresent,
   16007              :     ObjexxFCL::Optional_bool HeatingCoilPresent,
   16008              :     ObjexxFCL::Optional<Real64> HeatSizeRatio,
   16009              :     ObjexxFCL::Optional<Real64> TotCap,
   16010              :     ObjexxFCL::Optional_int SupplyFanIndex,
   16011              :     ObjexxFCL::Optional_string SupplyFanName,
   16012              :     ObjexxFCL::Optional<HVAC::FanType> supplyFanType)
   16013              : {
   16014              : 
   16015              :     // SUBROUTINE INFORMATION:
   16016              :     //       AUTHOR         Richard Raustad, FSEC
   16017              :     //       DATE WRITTEN   December 2008
   16018              : 
   16019              :     // PURPOSE OF THIS SUBROUTINE:
   16020              :     // This routine was designed to allow the DX coil to access information from a gas or
   16021              :     // electric heating coil when these coils are each used in a parent object.
   16022              :     // Also, this is an illustration of setting Data from an outside source.
   16023              : 
   16024              :     // Using/Aliasing
   16025              : 
   16026              :     // Obtains and Allocates DXCoils
   16027          643 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   16028            0 :         GetDXCoils(state);
   16029            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   16030              :     }
   16031              : 
   16032          643 :     if (DXCoilNum <= 0 || DXCoilNum > state.dataDXCoils->NumDXCoils) {
   16033            4 :         ShowSevereError(state,
   16034            4 :                         format("SetDXCoolingCoilData: called with DX Cooling Coil Number out of range={} should be >0 and <{}",
   16035              :                                DXCoilNum,
   16036            2 :                                state.dataDXCoils->NumDXCoils));
   16037            2 :         ErrorsFound = true;
   16038            2 :         return;
   16039              :     }
   16040              : 
   16041          641 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   16042          641 :     if (present(HeatingCoilPLFCurvePTR)) {
   16043            0 :         thisDXCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurvePTR;
   16044              :     }
   16045              : 
   16046          641 :     if (present(CondenserType)) {
   16047           66 :         thisDXCoil.CondenserType = CondenserType;
   16048              :     }
   16049              : 
   16050          641 :     if (present(CondenserInletNodeNum)) {
   16051           66 :         thisDXCoil.CondenserInletNodeNum(1) = CondenserInletNodeNum;
   16052              :     }
   16053              : 
   16054          641 :     if (present(MaxOATCrankcaseHeater)) {
   16055           66 :         thisDXCoil.MaxOATCrankcaseHeater = MaxOATCrankcaseHeater;
   16056              :     }
   16057              : 
   16058          641 :     if (present(MaxOATCooling)) {
   16059           33 :         thisDXCoil.MaxOATCompressor = MaxOATCooling;
   16060              :     }
   16061              : 
   16062          641 :     if (present(MaxOATHeating)) {
   16063           11 :         thisDXCoil.MaxOATCompressor = MaxOATHeating;
   16064              :     }
   16065              : 
   16066          641 :     if (present(MinOATCooling)) {
   16067           33 :         thisDXCoil.MinOATCompressor = MinOATCooling;
   16068              :     }
   16069              : 
   16070          641 :     if (present(MinOATHeating)) {
   16071           33 :         thisDXCoil.MinOATCompressor = MinOATHeating;
   16072              :     }
   16073              : 
   16074          641 :     if (present(HeatingPerformanceOATType)) {
   16075           33 :         thisDXCoil.HeatingPerformanceOATType = HeatingPerformanceOATType;
   16076              :     }
   16077              : 
   16078          641 :     if (present(DefrostStrategy)) {
   16079           33 :         thisDXCoil.DefrostStrategy = DefrostStrategy;
   16080              :     }
   16081              : 
   16082          641 :     if (present(DefrostControl)) {
   16083           33 :         thisDXCoil.DefrostControl = DefrostControl;
   16084              :     }
   16085              : 
   16086          641 :     if (present(DefrostEIRPtr)) {
   16087           33 :         thisDXCoil.DefrostEIRFT = DefrostEIRPtr;
   16088              :     }
   16089              : 
   16090          641 :     if (present(DefrostFraction)) {
   16091           33 :         thisDXCoil.DefrostTime = DefrostFraction;
   16092              :     }
   16093              : 
   16094          641 :     if (present(DefrostCapacity)) {
   16095           33 :         thisDXCoil.DefrostCapacity = DefrostCapacity;
   16096              :     }
   16097              : 
   16098          641 :     if (present(MaxOATDefrost)) {
   16099           33 :         thisDXCoil.MaxOATDefrost = MaxOATDefrost;
   16100              :     }
   16101              : 
   16102          641 :     if (present(CoolingCoilPresent)) {
   16103           33 :         thisDXCoil.CoolingCoilPresent = CoolingCoilPresent;
   16104              :     }
   16105              : 
   16106          641 :     if (present(HeatingCoilPresent)) {
   16107           33 :         thisDXCoil.HeatingCoilPresent = HeatingCoilPresent;
   16108              :     }
   16109              : 
   16110          641 :     if (present(HeatSizeRatio)) {
   16111            0 :         thisDXCoil.HeatSizeRatio = HeatSizeRatio;
   16112              :     }
   16113              : 
   16114          641 :     if (present(TotCap)) {
   16115            0 :         thisDXCoil.RatedTotCap(1) = TotCap;
   16116              :     }
   16117              : 
   16118          641 :     if (present(SupplyFanIndex)) {
   16119           12 :         thisDXCoil.SupplyFanIndex = SupplyFanIndex;
   16120              :     }
   16121              : 
   16122          641 :     if (present(SupplyFanName)) {
   16123           12 :         thisDXCoil.SupplyFanName = SupplyFanName;
   16124              :     }
   16125              : 
   16126          641 :     if (present(supplyFanType)) {
   16127           12 :         thisDXCoil.supplyFanType = supplyFanType;
   16128           12 :         if (thisDXCoil.SupplyFanIndex > 0) {
   16129           12 :             state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
   16130           12 :                                                                                      thisDXCoil.Name,
   16131           12 :                                                                                      thisDXCoil.DXCoilType,
   16132           12 :                                                                                      state.dataFans->fans(thisDXCoil.SupplyFanIndex)->Name,
   16133           12 :                                                                                      state.dataFans->fans(thisDXCoil.SupplyFanIndex)->type,
   16134              :                                                                                      thisDXCoil.SupplyFanIndex);
   16135              :         }
   16136              :     }
   16137              : }
   16138              : 
   16139            1 : void SetCoilSystemHeatingDXFlag(EnergyPlusData &state,
   16140              :                                 std::string const &CoilType, // must match coil types in this module
   16141              :                                 std::string const &CoilName  // must match coil names for the coil type
   16142              : )
   16143              : {
   16144              : 
   16145              :     // SUBROUTINE INFORMATION:
   16146              :     //       AUTHOR         B. Griffith
   16147              :     //       DATE WRITTEN   Jan. 2012
   16148              : 
   16149              :     // PURPOSE OF THIS SUBROUTINE:
   16150              :     // inform DX heating coil that is is part of a CoilSystem:Heating:DX
   16151              :     // and therefore it need not find its companion cooling coil
   16152              : 
   16153              :     // METHODOLOGY EMPLOYED:
   16154              :     // set value of logical flag FindCompanionUpStreamCoil to true
   16155              : 
   16156              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16157              :     int WhichCoil;
   16158              : 
   16159              :     // Obtains and Allocates DXCoils
   16160            1 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   16161            0 :         GetDXCoils(state);
   16162            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   16163              :     }
   16164              : 
   16165            1 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   16166            1 :     if (WhichCoil != 0) {
   16167            1 :         state.dataDXCoils->DXCoil(WhichCoil).FindCompanionUpStreamCoil = false;
   16168              :     } else {
   16169            0 :         ShowSevereError(state, format("SetCoilSystemHeatingDXFlag: Could not find Coil, Type=\"{}\"Name=\"{}\"", CoilType, CoilName));
   16170              :     }
   16171            1 : }
   16172              : 
   16173            2 : void SetCoilSystemCoolingData(EnergyPlusData &state,
   16174              :                               std::string const &CoilName, // must match coil names for the coil type
   16175              :                               std::string const &CoilSystemName)
   16176              : {
   16177              : 
   16178              :     // SUBROUTINE INFORMATION:
   16179              :     //       AUTHOR         B. Griffith
   16180              :     //       DATE WRITTEN   July 2012
   16181              : 
   16182              :     // PURPOSE OF THIS SUBROUTINE:
   16183              :     // inform the child DX coil what the name of its parent is.
   16184              : 
   16185              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16186              :     int WhichCoil;
   16187              : 
   16188            2 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   16189            0 :         GetDXCoils(state);
   16190            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   16191              :     }
   16192              : 
   16193            2 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   16194            2 :     if (WhichCoil != 0) {
   16195            2 :         state.dataDXCoils->DXCoil(WhichCoil).CoilSystemName = CoilSystemName;
   16196              :     } else {
   16197            0 :         ShowSevereError(state, format("SetCoilSystemCoolingData: Could not find Coil \"Name=\"{}\"", CoilName));
   16198              :     }
   16199            2 : }
   16200              : 
   16201            3 : Real64 CalcSHRUserDefinedCurves(EnergyPlusData &state,
   16202              :                                 Real64 const InletDryBulb,     // inlet air dry bulb temperature [C]
   16203              :                                 Real64 const InletWetBulb,     // inlet air wet bulb temperature [C]
   16204              :                                 Real64 const AirMassFlowRatio, // ratio of actual air mass flow to rated air mass flow
   16205              :                                 int const SHRFTempCurveIndex,  // SHR modifier curve index
   16206              :                                 int const SHRFFlowCurveIndex,  // SHR modifier curve index
   16207              :                                 Real64 const SHRRated          // rated sensible heat ratio, user input
   16208              : )
   16209              : {
   16210              : 
   16211              :     // SUBROUTINE INFORMATION:
   16212              :     //       AUTHOR         Bereket Nigusse, FSEC
   16213              :     //       DATE WRITTEN   December 2012
   16214              : 
   16215              :     // PURPOSE OF THIS FUNCTION:
   16216              :     //    Returns the operating sensible heat ratio for a given Rated SHR and coil entering
   16217              :     //    air DBT and WBT, and supply air mass flow fraction.
   16218              : 
   16219              :     // METHODOLOGY EMPLOYED:
   16220              :     //    Model uses user specified rated SHR, and SHR modifying curves for temperature and flow
   16221              :     //    fraction.  The curves adjust the rated SHR based on biquadratic curve for temperatures
   16222              :     //    and quadratic function for supply air mass flow ratio (actual vs rated).
   16223              :     //    The biquadratic and quadratic curves are normalized curves generated from manufacturer's
   16224              :     //    performance data
   16225              : 
   16226              :     // Using/Aliasing
   16227              :     using Curve::CurveValue;
   16228              : 
   16229              :     // Return value
   16230              :     Real64 SHRopr; // operating SHR, corrected for Temp and Flow Fraction
   16231              : 
   16232              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
   16233              :     Real64 SHRTempModFac; // Sensible Heat Ratio modifier (function of entering wetbulb, entering drybulb)
   16234              :     Real64 SHRFlowModFac; // Sensible Heat Ratio modifier (function of actual vs rated flow)
   16235              : 
   16236              :     //   Get SHR modifying factor (function of inlet wetbulb & drybulb) for off-rated conditions
   16237            3 :     if (SHRFTempCurveIndex == 0) {
   16238            3 :         SHRTempModFac = 1.0;
   16239              :     } else {
   16240            0 :         SHRTempModFac = CurveValue(state, SHRFTempCurveIndex, InletWetBulb, InletDryBulb);
   16241            0 :         if (SHRTempModFac < 0.0) {
   16242            0 :             SHRTempModFac = 0.0;
   16243              :         }
   16244              :     }
   16245              :     //   Get SHR modifying factor (function of mass flow ratio) for off-rated conditions
   16246            3 :     if (SHRFFlowCurveIndex == 0) {
   16247            3 :         SHRFlowModFac = 1.0;
   16248              :     } else {
   16249            0 :         SHRFlowModFac = CurveValue(state, SHRFFlowCurveIndex, AirMassFlowRatio);
   16250            0 :         if (SHRFlowModFac < 0.0) {
   16251            0 :             SHRFlowModFac = 0.0;
   16252              :         }
   16253              :     }
   16254              :     //  Calculate "operating" sensible heat ratio
   16255            3 :     SHRopr = SHRRated * SHRTempModFac * SHRFlowModFac;
   16256              : 
   16257            3 :     if (SHRopr < 0.0) {
   16258            0 :         SHRopr = 0.0; // SHR cannot be less than zero
   16259              :     }
   16260            3 :     if (SHRopr > 1.0) {
   16261            0 :         SHRopr = 1.0; // SHR cannot be greater than 1.0
   16262              :     }
   16263              : 
   16264            3 :     return SHRopr;
   16265              : }
   16266              : 
   16267            0 : void SetDXCoilTypeData(EnergyPlusData &state, std::string const &CoilName) // must match coil names for the coil type
   16268              : {
   16269              : 
   16270              :     // SUBROUTINE INFORMATION:
   16271              :     //       AUTHOR         B. Nigusse
   16272              :     //       DATE WRITTEN   January 2013
   16273              : 
   16274              :     // PURPOSE OF THIS SUBROUTINE:
   16275              :     // inform the child DX coil if the DX cooling coil is for 100% DOAS application.
   16276              : 
   16277              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16278              :     int WhichCoil;
   16279              : 
   16280            0 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   16281            0 :         GetDXCoils(state);
   16282            0 :         state.dataDXCoils->GetCoilsInputFlag = false;
   16283              :     }
   16284              : 
   16285            0 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   16286            0 :     if (WhichCoil != 0) {
   16287            0 :         state.dataDXCoils->DXCoil(WhichCoil).ISHundredPercentDOASDXCoil = true;
   16288              :     } else {
   16289              :         // DXCoil(WhichCoil)%ISHundredPercentDOASDXCoil = .FALSE. //Autodesk:BoundsViolation DXCoil(0): DXCoil is not allocated with a 0
   16290              :         // element: Commented out
   16291            0 :         ShowSevereError(state, format("SetDXCoilTypeData: Could not find Coil \"Name=\"{}\"", CoilName));
   16292              :     }
   16293            0 : }
   16294              : 
   16295            5 : void CalcSecondaryDXCoils(EnergyPlusData &state, int const DXCoilNum)
   16296              : {
   16297              : 
   16298              :     // SUBROUTINE INFORMATION:
   16299              :     //       AUTHOR         B. Nigusse
   16300              :     //       DATE WRITTEN   February 2015
   16301              : 
   16302              :     // PURPOSE OF THIS SUBROUTINE:
   16303              :     // Calculates secondary zone heat gain from secondary DX coils placed in a zone.
   16304              : 
   16305              :     // METHODOLOGY EMPLOYED:
   16306              :     // Energy balance:
   16307              :     //  (1) Condenser placed in a zone, the zone total (sensible) heat
   16308              :     //      gain rate is given Qcond = QEvap + WcompPluscondFanPower
   16309              :     //  (2) Evaporator placed in a zone, the zone total heat removal
   16310              :     //      rate is given Qevap = Qcond - WcompPluscondFanPower
   16311              :     //      Furthermore, the evaporator total heat removal is split into
   16312              :     //      latent and sensible components using user specified SHR
   16313              : 
   16314              :     // Using/Aliasing
   16315              :     using Curve::CurveValue;
   16316              : 
   16317              :     // SUBROUTINE PARAMETER DEFINITIONS:
   16318              :     static constexpr std::string_view RoutineName("CalcSecondaryDXCoils");
   16319              : 
   16320              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16321              :     Real64 CondInletDryBulb;       // condenser entering air dry-bulb temperature (C)
   16322              :     Real64 EvapAirMassFlow;        // Condenser air mass flow rate [kg/s]
   16323              :     Real64 EvapInletDryBulb;       // evaporator inlet air drybulb [C]
   16324              :     Real64 EvapInletHumRat;        // evaporator inlet air humidity ratio [kg/kg]
   16325              :     Real64 EvapInletWetBulb;       // evaporator inlet air wetbulb [C]
   16326              :     Real64 EvapInletEnthalpy;      // evaporator inlet air enthalpy [J/kg]
   16327              :     Real64 FullLoadOutAirEnth;     // evaporator outlet full load enthalpy [J/kg]
   16328              :     Real64 FullLoadOutAirHumRat;   // evaporator outlet humidity ratio at full load
   16329              :     Real64 FullLoadOutAirTemp;     // evaporator outlet air temperature at full load [C]
   16330              :     Real64 hTinwout;               // Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
   16331            5 :     Real64 SHR(0);                 // sensible heat ratio
   16332              :     Real64 RhoAir;                 // secondary coil entering air density [kg/m3]
   16333            5 :     Real64 PartLoadRatio(0);       // primary coil part-load ratio [-]
   16334              :     Real64 SecCoilRatedSHR;        // secondary DX coil nominal or rated sensible heat ratio
   16335              :     Real64 SecCoilFlowFraction;    // secondary coil flow fraction, is 1.0 for single speed machine
   16336              :     Real64 TotalHeatRemovalRate;   // secondary coil total heat removal rate
   16337              :     Real64 TotalHeatRejectionRate; // secondary coil total heat rejection rate
   16338              :     int SecCoilSHRFT;              // index of the SHR modifier curve for temperature of a secondary DX coil
   16339              :     int SecCoilSHRFF;              // index of the sHR modifier curve for flow fraction of a secondary DX coil
   16340              :     int MSSpeedNumLS;              // current low speed number of multispeed HP
   16341              :     int MSSpeedNumHS;              // current high speed number of multispeed HP
   16342              :     Real64 MSSpeedRatio;           // current speed ratio of multispeed HP
   16343              :     Real64 MSCycRatio;             // current cycling ratio of multispeed HP
   16344              :     Real64 SHRHighSpeed;           // sensible heat ratio at high speed
   16345              :     Real64 SHRLowSpeed;            // sensible heat ratio at low speed
   16346              : 
   16347            5 :     EvapAirMassFlow = 0.0;
   16348              : 
   16349            5 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   16350              : 
   16351            5 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   16352            5 :         auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisDXCoil.SecZonePtr);
   16353              :         // Select the correct unit type
   16354            5 :         switch (thisDXCoil.DXCoilType_Num) {
   16355            3 :         case HVAC::CoilDX_CoolingSingleSpeed:
   16356              :         case HVAC::CoilDX_CoolingTwoSpeed:
   16357              :         case HVAC::CoilDX_MultiSpeedCooling: {
   16358              :             // total sensible heat gain of the secondary zone from the secondary coil (condenser)
   16359            3 :             if (thisDXCoil.ElecCoolingPower > 0.0) {
   16360            3 :                 TotalHeatRejectionRate = thisDXCoil.TotalCoolingEnergyRate + thisDXCoil.ElecCoolingPower;
   16361              :             } else {
   16362            0 :                 TotalHeatRejectionRate = 0.0;
   16363            0 :                 return;
   16364              :             }
   16365            3 :             thisDXCoil.SecCoilSensibleHeatGainRate = TotalHeatRejectionRate;
   16366            3 :         } break;
   16367            1 :         case HVAC::CoilDX_HeatingEmpirical: {
   16368              :             // evaporator coil in the secondary zone
   16369            1 :             if (thisDXCoil.ElecHeatingPower > 0.0) {
   16370            1 :                 TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
   16371              :             } else {
   16372            0 :                 TotalHeatRemovalRate = 0.0;
   16373            0 :                 thisDXCoil.SecCoilSHR = 0.0;
   16374            0 :                 return;
   16375              :             }
   16376            1 :             thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
   16377            1 :             EvapInletDryBulb = secZoneHB.ZT;
   16378            1 :             EvapInletHumRat = secZoneHB.airHumRat;
   16379            1 :             RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
   16380            1 :             EvapAirMassFlow = RhoAir * thisDXCoil.SecCoilAirFlow;
   16381              :             ;
   16382            1 :             PartLoadRatio = thisDXCoil.CompressorPartLoadRatio;
   16383            1 :             SecCoilRatedSHR = thisDXCoil.SecCoilRatedSHR;
   16384            1 :             if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (PartLoadRatio > 0.0) &&
   16385            1 :                 (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
   16386            1 :                 SecCoilFlowFraction = 1.0;                          // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
   16387            1 :                 CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
   16388            1 :                 EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
   16389            1 :                 EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
   16390            1 :                 SecCoilSHRFT = thisDXCoil.SecCoilSHRFT;
   16391            1 :                 SecCoilSHRFF = thisDXCoil.SecCoilSHRFF;
   16392              :                 // determine the current SHR
   16393            1 :                 SHR = CalcSecondaryDXCoilsSHR(state,
   16394              :                                               DXCoilNum,
   16395              :                                               EvapAirMassFlow,
   16396              :                                               TotalHeatRemovalRate,
   16397              :                                               PartLoadRatio,
   16398              :                                               SecCoilRatedSHR,
   16399              :                                               EvapInletDryBulb,
   16400              :                                               EvapInletHumRat,
   16401              :                                               EvapInletWetBulb,
   16402              :                                               EvapInletEnthalpy,
   16403              :                                               CondInletDryBulb,
   16404              :                                               SecCoilFlowFraction,
   16405              :                                               SecCoilSHRFT,
   16406              :                                               SecCoilSHRFF);
   16407              :                 // Calculate full load output conditions
   16408            1 :                 FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
   16409            1 :                 hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
   16410            1 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
   16411            1 :                 FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   16412              :                 // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
   16413            1 :                 if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
   16414            0 :                     FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName);
   16415            0 :                     FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
   16416              :                     // Adjust SHR for the new outlet condition that balances energy
   16417            0 :                     hTinwout = PsyHFnTdbW(EvapInletDryBulb, FullLoadOutAirHumRat);
   16418            0 :                     SHR = 1.0 - (EvapInletEnthalpy - hTinwout) / ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
   16419            0 :                     SHR = min(SHR, 1.0);
   16420              :                 }
   16421              :                 // calculate the sensible and latent zone heat removal (extraction) rate by the secondary coil
   16422            1 :                 thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
   16423            1 :                 thisDXCoil.SecCoilLatentHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate - thisDXCoil.SecCoilSensibleHeatRemovalRate;
   16424              :             } else {
   16425              :                 // DX coil is off;
   16426            0 :                 thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
   16427            0 :                 thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
   16428            0 :                 thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
   16429            0 :                 SHR = 0.0; // SHR is set to zero if the coil is off
   16430              :             }
   16431            1 :             thisDXCoil.SecCoilSHR = SHR;
   16432            1 :         } break;
   16433            1 :         case HVAC::CoilDX_MultiSpeedHeating: {
   16434            1 :             EvapInletDryBulb = secZoneHB.ZT;
   16435            1 :             EvapInletHumRat = secZoneHB.airHumRat;
   16436            1 :             RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat);
   16437            1 :             MSSpeedRatio = thisDXCoil.MSSpeedRatio;
   16438            1 :             MSCycRatio = thisDXCoil.MSCycRatio;
   16439            1 :             MSSpeedNumHS = thisDXCoil.MSSpeedNumHS;
   16440            1 :             MSSpeedNumLS = thisDXCoil.MSSpeedNumLS;
   16441            1 :             if (MSSpeedRatio > 0.0) {
   16442            0 :                 EvapAirMassFlow = RhoAir * (thisDXCoil.MSSecCoilAirFlow(MSSpeedNumHS) * MSSpeedRatio +
   16443            0 :                                             thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS) * (1.0 - MSSpeedRatio));
   16444            1 :             } else if (MSCycRatio > 0.0) {
   16445            1 :                 EvapAirMassFlow = RhoAir * thisDXCoil.MSSecCoilAirFlow(MSSpeedNumLS);
   16446              :             }
   16447            1 :             if (thisDXCoil.ElecHeatingPower > 0.0) {
   16448            1 :                 TotalHeatRemovalRate = max(0.0, thisDXCoil.TotalHeatingEnergyRate - thisDXCoil.ElecHeatingPower);
   16449              :             } else {
   16450            0 :                 TotalHeatRemovalRate = 0.0;
   16451            0 :                 return;
   16452              :             }
   16453            1 :             thisDXCoil.SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower;
   16454            1 :             if ((EvapAirMassFlow > HVAC::SmallMassFlow) && (MSSpeedRatio > 0.0 || MSCycRatio > 0.0) &&
   16455            1 :                 (EvapInletDryBulb > thisDXCoil.MinOATCompressor)) { // coil is running
   16456            1 :                 SecCoilFlowFraction = 1.0;                          // for single speed DX coil the secondary coil (condenser) flow fraction is 1.0
   16457            1 :                 CondInletDryBulb = state.dataLoopNodes->Node(thisDXCoil.AirInNode).Temp;
   16458            1 :                 EvapInletWetBulb = PsyTwbFnTdbWPb(state, EvapInletDryBulb, EvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
   16459            1 :                 EvapInletEnthalpy = PsyHFnTdbW(EvapInletDryBulb, EvapInletHumRat);
   16460              :                 // determine the current SHR
   16461            1 :                 if (MSSpeedRatio > 0.0) {
   16462              :                     // calculate SHR for the higher speed
   16463            0 :                     PartLoadRatio = 1.0;
   16464            0 :                     SecCoilFlowFraction = 1.0;
   16465            0 :                     SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumHS);
   16466            0 :                     SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumHS);
   16467            0 :                     SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumHS);
   16468            0 :                     SHRHighSpeed = CalcSecondaryDXCoilsSHR(state,
   16469              :                                                            DXCoilNum,
   16470              :                                                            EvapAirMassFlow,
   16471              :                                                            TotalHeatRemovalRate,
   16472              :                                                            PartLoadRatio,
   16473              :                                                            SecCoilRatedSHR,
   16474              :                                                            EvapInletDryBulb,
   16475              :                                                            EvapInletHumRat,
   16476              :                                                            EvapInletWetBulb,
   16477              :                                                            EvapInletEnthalpy,
   16478              :                                                            CondInletDryBulb,
   16479              :                                                            SecCoilFlowFraction,
   16480              :                                                            SecCoilSHRFT,
   16481              :                                                            SecCoilSHRFF);
   16482              :                     // calculate SHR for the lower speed
   16483            0 :                     SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumLS);
   16484            0 :                     SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumLS);
   16485            0 :                     SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumLS);
   16486            0 :                     SHRLowSpeed = CalcSecondaryDXCoilsSHR(state,
   16487              :                                                           DXCoilNum,
   16488              :                                                           EvapAirMassFlow,
   16489              :                                                           TotalHeatRemovalRate,
   16490              :                                                           PartLoadRatio,
   16491              :                                                           SecCoilRatedSHR,
   16492              :                                                           EvapInletDryBulb,
   16493              :                                                           EvapInletHumRat,
   16494              :                                                           EvapInletWetBulb,
   16495              :                                                           EvapInletEnthalpy,
   16496              :                                                           CondInletDryBulb,
   16497              :                                                           SecCoilFlowFraction,
   16498              :                                                           SecCoilSHRFT,
   16499              :                                                           SecCoilSHRFF);
   16500            0 :                     SHR = SHRHighSpeed * MSSpeedRatio + SHRLowSpeed * (1.0 - MSSpeedRatio);
   16501              : 
   16502            1 :                 } else if (MSCycRatio > 0.0) {
   16503              :                     // calculate SHR for the lower speed
   16504            1 :                     PartLoadRatio = MSCycRatio;
   16505            1 :                     SecCoilSHRFT = thisDXCoil.MSSecCoilSHRFT(MSSpeedNumLS);
   16506            1 :                     SecCoilSHRFF = thisDXCoil.MSSecCoilSHRFF(MSSpeedNumLS);
   16507            1 :                     SecCoilRatedSHR = thisDXCoil.MSSecCoilRatedSHR(MSSpeedNumLS);
   16508            1 :                     SecCoilFlowFraction = 1.0;
   16509            1 :                     SHRLowSpeed = CalcSecondaryDXCoilsSHR(state,
   16510              :                                                           DXCoilNum,
   16511              :                                                           EvapAirMassFlow,
   16512              :                                                           TotalHeatRemovalRate,
   16513              :                                                           MSCycRatio,
   16514              :                                                           SecCoilRatedSHR,
   16515              :                                                           EvapInletDryBulb,
   16516              :                                                           EvapInletHumRat,
   16517              :                                                           EvapInletWetBulb,
   16518              :                                                           EvapInletEnthalpy,
   16519              :                                                           CondInletDryBulb,
   16520              :                                                           SecCoilFlowFraction,
   16521              :                                                           SecCoilSHRFT,
   16522              :                                                           SecCoilSHRFF);
   16523            1 :                     SHR = SHRLowSpeed;
   16524              :                 }
   16525              :                 // Calculate full load output conditions
   16526            1 :                 FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
   16527            1 :                 hTinwout = EvapInletEnthalpy - (1.0 - SHR) * ((TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow);
   16528            1 :                 FullLoadOutAirHumRat = PsyWFnTdbH(state, EvapInletDryBulb, hTinwout, RoutineName, true);
   16529            1 :                 FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   16530              :                 // when the air outlet temperature falls below the saturation temperature, it is reset to saturation temperature
   16531            1 :                 if (FullLoadOutAirTemp < PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
   16532            0 :                     FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName);
   16533            0 :                     FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
   16534              :                     // Adjust SHR for the new outlet condition that balances energy
   16535            0 :                     hTinwout = PsyHFnTdbW(EvapInletDryBulb, FullLoadOutAirHumRat);
   16536            0 :                     SHR = 1.0 - (EvapInletEnthalpy - hTinwout) / (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
   16537            0 :                     SHR = min(SHR, 1.0);
   16538              :                 }
   16539              :                 // calculate the sensible and latent zone heat removal (extraction) rate by the secondary coil
   16540            1 :                 thisDXCoil.SecCoilSensibleHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate * SHR;
   16541            1 :                 thisDXCoil.SecCoilLatentHeatRemovalRate = thisDXCoil.SecCoilTotalHeatRemovalRate - thisDXCoil.SecCoilSensibleHeatRemovalRate;
   16542              :             } else {
   16543              :                 // DX coil is off;
   16544            0 :                 thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
   16545            0 :                 thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
   16546            0 :                 thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
   16547            0 :                 SHR = 0.0; // SHR is set to rated value if the coil is off
   16548              :             }
   16549            1 :             thisDXCoil.SecCoilSHR = SHR;
   16550            1 :         } break;
   16551            0 :         default:
   16552            0 :             break;
   16553              :         }
   16554              : 
   16555              :     } else {
   16556            0 :         thisDXCoil.SecCoilSensibleHeatGainRate = 0.0;
   16557            0 :         thisDXCoil.SecCoilTotalHeatRemovalRate = 0.0;
   16558            0 :         thisDXCoil.SecCoilSensibleHeatRemovalRate = 0.0;
   16559            0 :         thisDXCoil.SecCoilLatentHeatRemovalRate = 0.0;
   16560              :     }
   16561              : }
   16562              : 
   16563            3 : Real64 CalcSecondaryDXCoilsSHR(EnergyPlusData &state,
   16564              :                                [[maybe_unused]] int const DXCoilNum,
   16565              :                                Real64 const EvapAirMassFlow,
   16566              :                                Real64 const TotalHeatRemovalRate,
   16567              :                                Real64 const PartLoadRatio,
   16568              :                                Real64 const SecCoilRatedSHR,
   16569              :                                Real64 const EvapInletDryBulb,
   16570              :                                Real64 const EvapInletHumRat,
   16571              :                                Real64 const EvapInletWetBulb,
   16572              :                                Real64 const EvapInletEnthalpy,
   16573              :                                Real64 const CondInletDryBulb,
   16574              :                                Real64 const SecCoilFlowFraction,
   16575              :                                int const SecCoilSHRFT,
   16576              :                                int const SecCoilSHRFF)
   16577              : {
   16578              : 
   16579              :     // SUBROUTINE INFORMATION:
   16580              :     //       AUTHOR         B. Nigusse
   16581              :     //       DATE WRITTEN   February 2015
   16582              : 
   16583              :     // PURPOSE OF THIS SUBROUTINE:
   16584              :     // Calculates secondary coil (evaporator) sensible heat ratio.
   16585              : 
   16586              :     // METHODOLOGY EMPLOYED:
   16587              :     // Energy balance:
   16588              :     //  (1) checks if the secondary coil operation is dry and calculates applicable SHR.
   16589              :     //  (2) determines SHR from user specified rated SHR values and SHR modifier curves for
   16590              :     //      temperature and flow fraction.
   16591              :     //  (3) if secondary coil operates dry then the larger of the user SHR value and dry
   16592              :     //      coil operation SHR is selected.
   16593              : 
   16594              :     // Using/Aliasing
   16595              :     using Curve::CurveValue;
   16596              : 
   16597              :     // SUBROUTINE PARAMETER DEFINITIONS:
   16598            3 :     int constexpr MaxIter(30);
   16599            3 :     Real64 constexpr RelaxationFactor(0.4);
   16600            3 :     Real64 constexpr Tolerance(0.1);
   16601            3 :     Real64 constexpr DryCoilTestEvapInletHumRatReset(0.00001);
   16602              :     static constexpr std::string_view RoutineName("CalcSecondaryDXCoilsSHR");
   16603              : 
   16604              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16605              :     Real64 DryCoilTestEvapInletHumRat;  // evaporator coil inlet humidity ratio test for dry coil
   16606              :     Real64 DryCoilTestEvapInletWetBulb; // evaporator coil inlet dry bulb temperature test for dry coil
   16607              :     Real64 FullLoadOutAirEnth;          // evaporator outlet full load enthalpy [J/kg]
   16608              :     Real64 FullLoadOutAirTemp;          // evaporator outlet air temperature at full load [C]
   16609              :     Real64 hTinwADP;                    // enthalpy of air at secondary coil entering temperature and Humidity ratio at ADP
   16610              :     Real64 SHRadp;                      // Sensible heat ratio
   16611              :     Real64 hADP;                        // enthalpy of air at secondary coil at ADP
   16612              :     Real64 tADP;                        // dry bulb temperature of air at secondary coil at ADP
   16613              :     Real64 wADP;                        // humidity ratio of air at secondary coil at ADP
   16614              :     Real64 HumRatError;                 // humidity ratio error
   16615              :     bool CoilMightBeDry;                // TRUE means the secondary DX coil runs dry
   16616              :     int Counter;                        // iteration counter
   16617              :     bool Converged;                     // convergence flag
   16618              :     Real64 SHR;                         // current time step sensible heat ratio of secondary coil
   16619              : 
   16620            3 :     CoilMightBeDry = false;
   16621            3 :     FullLoadOutAirEnth = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
   16622            3 :     FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, EvapInletHumRat);
   16623            3 :     if (FullLoadOutAirTemp > PsyTsatFnHPb(state, FullLoadOutAirEnth, state.dataEnvrn->OutBaroPress, RoutineName)) {
   16624            3 :         CoilMightBeDry = true;
   16625              :         // find wADP, humidity ratio at apparatus dewpoint and inlet hum rat that would have dry coil
   16626            3 :         DryCoilTestEvapInletHumRat = EvapInletHumRat;
   16627            3 :         DryCoilTestEvapInletWetBulb = EvapInletWetBulb;
   16628            3 :         Counter = 0;
   16629            3 :         Converged = false;
   16630            6 :         while (!Converged) {
   16631              :             // assumes coil bypass factor (CBF) = 0.0
   16632            3 :             hADP = EvapInletEnthalpy - (TotalHeatRemovalRate / PartLoadRatio) / EvapAirMassFlow;
   16633            3 :             tADP = PsyTsatFnHPb(state, hADP, state.dataEnvrn->OutBaroPress, RoutineName);
   16634            3 :             wADP = min(EvapInletHumRat, PsyWFnTdbH(state, tADP, hADP, RoutineName));
   16635            3 :             hTinwADP = PsyHFnTdbW(EvapInletDryBulb, wADP);
   16636            3 :             if ((EvapInletEnthalpy - hADP) > 1.e-10) {
   16637            3 :                 SHRadp = min((hTinwADP - hADP) / (EvapInletEnthalpy - hADP), 1.0);
   16638              :             } else {
   16639            0 :                 SHRadp = 1.0;
   16640              :             }
   16641            3 :             if ((wADP > DryCoilTestEvapInletHumRat) || (Counter >= 1 && Counter < MaxIter)) {
   16642            0 :                 if (DryCoilTestEvapInletHumRat <= 0.0) {
   16643            0 :                     DryCoilTestEvapInletHumRat = DryCoilTestEvapInletHumRatReset;
   16644              :                 }
   16645            0 :                 HumRatError = (DryCoilTestEvapInletHumRat - wADP) / DryCoilTestEvapInletHumRat;
   16646            0 :                 DryCoilTestEvapInletHumRat = RelaxationFactor * wADP + (1.0 - RelaxationFactor) * DryCoilTestEvapInletHumRat;
   16647              :                 DryCoilTestEvapInletWetBulb =
   16648            0 :                     PsyTwbFnTdbWPb(state, EvapInletDryBulb, DryCoilTestEvapInletHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
   16649            0 :                 ++Counter;
   16650            0 :                 if (std::abs(HumRatError) <= Tolerance) {
   16651            0 :                     Converged = true;
   16652              :                 } else {
   16653            0 :                     Converged = false;
   16654              :                 }
   16655              :             } else {
   16656            3 :                 Converged = true;
   16657              :             }
   16658              :         }
   16659              :     }
   16660              :     // determine SHR from user specified nominal value and SHR modifier curves
   16661            3 :     SHR = CalcSHRUserDefinedCurves(state, CondInletDryBulb, EvapInletWetBulb, SecCoilFlowFraction, SecCoilSHRFT, SecCoilSHRFF, SecCoilRatedSHR);
   16662            3 :     if (CoilMightBeDry) {
   16663            3 :         if ((EvapInletHumRat < DryCoilTestEvapInletHumRat) && (SHRadp > SHR)) { // coil is dry for sure
   16664            0 :             SHR = 1.0;
   16665            3 :         } else if (SHRadp > SHR) {
   16666            0 :             SHR = SHRadp;
   16667              :         }
   16668              :     }
   16669            3 :     return SHR;
   16670              : }
   16671              : 
   16672        23659 : void CalcVRFCoolingCoil_FluidTCtrl(EnergyPlusData &state,
   16673              :                                    int const DXCoilNum,                    // the number of the DX coil to be simulated
   16674              :                                    HVAC::CompressorOp const compressorOp,  // compressor operation; 1=on, 0=off
   16675              :                                    bool const FirstHVACIteration,          // true if this is the first iteration of HVAC
   16676              :                                    Real64 const PartLoadRatio,             // sensible cooling load / full load sensible cooling capacity
   16677              :                                    HVAC::FanOp const fanOp,                // Allows parent object to control fan operation
   16678              :                                    Real64 const CompCycRatio,              // cycling ratio of VRF condenser
   16679              :                                    ObjexxFCL::Optional_int_const PerfMode, // Performance mode for MultiMode DX coil; Always 1 for other coil types
   16680              :                                    ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
   16681              :                                    Real64 MaxCoolCap                                    // maximum allowed cooling capacity
   16682              : )
   16683              : {
   16684              :     // SUBROUTINE INFORMATION:
   16685              :     //       AUTHOR         Xiufeng Pang, LBNL
   16686              :     //       DATE WRITTEN   Jan 2013
   16687              :     //       MODIFIED       Nov 2015, RP Zhang, LBNL
   16688              : 
   16689              :     // PURPOSE OF THIS SUBROUTINE:
   16690              :     //         Calculates the air-side performance of a direct-expansion, air-cooled
   16691              :     //         VRF terminal unit cooling coil, for the VRF_FluidTCtrl model.
   16692              : 
   16693              :     // METHODOLOGY EMPLOYED:
   16694              :     //         This subroutine is derived from CalcVRFCoolingCoil, and implements the new VRF model for FluidTCtrl.
   16695              : 
   16696              :     // Using/Aliasing
   16697              :     using Curve::CurveValue;
   16698        23659 :     Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
   16699        23659 :     Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
   16700              :     using General::CreateSysTimeIntervalString;
   16701              : 
   16702              :     using namespace HVACVariableRefrigerantFlow;
   16703              : 
   16704              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   16705              : 
   16706              :     Real64 AirMassFlow;       // dry air mass flow rate through coil [kg/s] (adjusted for bypass if any)
   16707              :     Real64 AirVolumeFlowRate; // Air volume flow rate across the cooling coil [m3/s] (adjusted for bypass if any)
   16708              :     // (average flow if cycling fan, full flow if constant fan)
   16709              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W] (adjusted for bypass)
   16710              :     Real64 TotCap;                // gross total cooling capacity at off-rated conditions [W]
   16711              :     Real64 InletAirDryBulbTemp;   // inlet air dry bulb temperature [C]
   16712              :     Real64 InletAirEnthalpy;      // inlet air enthalpy [J/kg]
   16713              :     Real64 InletAirHumRat;        // inlet air humidity ratio [kg/kg]
   16714              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   16715              :     Real64 RatedCBF;      // coil bypass factor at rated conditions
   16716              :     Real64 CBF;           // coil bypass factor at off rated conditions
   16717              :     Real64 A0;            // NTU * air mass flow rate, used in CBF calculation
   16718              :     Real64 PLF;           // Part load factor, accounts for thermal lag at compressor startup, used in power calculation
   16719              :     Real64 CondInletTemp; // Condenser inlet temperature (C). Outdoor dry-bulb temp for air-cooled condenser.
   16720              :     // Outdoor Wetbulb +(1 - effectiveness)*(outdoor drybulb - outdoor wetbulb) for evap condenser.
   16721              :     Real64 CondInletHumRat; // Condenser inlet humidity ratio (kg/kg). Zero for air-cooled condenser.
   16722              :     // For evap condenser, its the humidity ratio of the air leaving the evap cooling pads.
   16723              :     Real64 CondAirMassFlow;       // Condenser air mass flow rate [kg/s]
   16724              :     Real64 RhoAir;                // Density of air [kg/m3]
   16725              :     Real64 CrankcaseHeatingPower; // power due to crankcase heater
   16726        23659 :     Real64 CompAmbTemp(0.0);      // Ambient temperature at compressor
   16727              :     Real64 AirFlowRatio;          // ratio of compressor on airflow to average timestep airflow
   16728              :     // used when constant fan mode yields different air flow rates when compressor is ON and OFF
   16729              :     // (e.g. Packaged Terminal Heat Pump)
   16730              :     Real64 OutdoorDryBulb;  // Outdoor dry-bulb temperature at condenser (C)
   16731              :     Real64 OutdoorWetBulb;  // Outdoor wet-bulb temperature at condenser (C)
   16732              :     Real64 OutdoorHumRat;   // Outdoor humidity ratio at condenser (kg/kg)
   16733              :     Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
   16734              : 
   16735              :     int Mode;                 // Performance mode for Multimode DX coil; Always 1 for other coil types
   16736              :     Real64 OutletAirTemp;     // Supply air temperature (average value if constant fan, full output if cycling fan)
   16737              :     Real64 OutletAirHumRat;   // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
   16738              :     Real64 OutletAirEnthalpy; // Supply air enthalpy (average value if constant fan, full output if cycling fan)
   16739              :     Real64 ADiff;             // Used for exponential
   16740              : 
   16741              :     // Followings for VRF FluidTCtrl Only
   16742              :     Real64 QCoilReq;       // Coil load (W)
   16743              :     Real64 FanSpdRatio;    // Fan speed ratio
   16744              :     Real64 AirMassFlowMin; // Min air mass flow rate due to OA requirement [kg/s]
   16745              :     Real64 ActualSH;       // Super heating degrees (C)
   16746              :     Real64 ActualSC;       // Sub cooling degrees (C)
   16747              : 
   16748              :     // If Performance mode not present, then set to 1.  Used only by Multimode/Multispeed DX coil (otherwise mode = 1)
   16749        23659 :     if (present(PerfMode)) {
   16750            0 :         Mode = PerfMode;
   16751              :     } else {
   16752        23659 :         Mode = 1;
   16753              :     }
   16754              : 
   16755              :     // If AirFlowRatio not present, then set to 1. Used only by DX coils with different air flow
   16756              :     // during cooling and when no cooling is required (constant fan, fan speed changes)
   16757        23659 :     if (present(OnOffAirFlowRatio)) {
   16758            0 :         AirFlowRatio = OnOffAirFlowRatio;
   16759              :     } else {
   16760        23659 :         AirFlowRatio = 1.0;
   16761              :     }
   16762              : 
   16763        23659 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   16764              : 
   16765              :     // Initialize coil air side parameters
   16766        23659 :     CondInletTemp = 0.0;
   16767        23659 :     CondInletHumRat = 0.0;
   16768        23659 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   16769        23659 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   16770        23659 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   16771        23659 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   16772        23659 :     state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).AvailCapacity = 0.0;
   16773        23659 :     thisDXCoil.CoolingCoilRuntimeFraction = 0.0;
   16774        23659 :     thisDXCoil.PartLoadRatio = 0.0;
   16775        23659 :     thisDXCoil.BasinHeaterPower = 0.0;
   16776        23659 :     thisDXCoil.EvaporatingTemp = state.dataHVACVarRefFlow->VRF(thisDXCoil.VRFOUPtr).IUEvaporatingTemp;
   16777              : 
   16778        23659 :     if (thisDXCoil.CondenserInletNodeNum(Mode) != 0) {
   16779            0 :         OutdoorDryBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Temp;
   16780            0 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
   16781            0 :             OutdoorHumRat = state.dataEnvrn->OutHumRat;
   16782            0 :             OutdoorPressure = state.dataEnvrn->OutBaroPress;
   16783            0 :             OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   16784              :         } else {
   16785            0 :             OutdoorPressure = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).Press;
   16786              :             // If node is not connected to anything, pressure = default, use weather data
   16787            0 :             if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
   16788            0 :                 OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   16789            0 :                 OutdoorHumRat = state.dataEnvrn->OutHumRat;
   16790            0 :                 OutdoorPressure = state.dataEnvrn->OutBaroPress;
   16791            0 :                 OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   16792              :             } else {
   16793            0 :                 OutdoorHumRat = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).HumRat;
   16794            0 :                 OutdoorWetBulb = state.dataLoopNodes->Node(thisDXCoil.CondenserInletNodeNum(Mode)).OutAirWetBulb;
   16795              :             }
   16796              :         }
   16797              :     } else {
   16798        23659 :         OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   16799        23659 :         OutdoorHumRat = state.dataEnvrn->OutHumRat;
   16800        23659 :         OutdoorPressure = state.dataEnvrn->OutBaroPress;
   16801        23659 :         OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   16802              :     }
   16803              : 
   16804        23659 :     if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Evap) {
   16805            0 :         RhoAir = PsyRhoAirFnPbTdbW(state, OutdoorPressure, OutdoorDryBulb, OutdoorHumRat);
   16806            0 :         CondAirMassFlow = RhoAir * thisDXCoil.EvapCondAirFlow(Mode);
   16807              :         // (Outdoor wet-bulb temp from DataEnvironment) + (1.0-EvapCondEffectiveness) * (drybulb - wetbulb)
   16808            0 :         CondInletTemp = OutdoorWetBulb + (OutdoorDryBulb - OutdoorWetBulb) * (1.0 - thisDXCoil.EvapCondEffect(Mode));
   16809            0 :         CondInletHumRat = PsyWFnTdbTwbPb(state, CondInletTemp, OutdoorWetBulb, OutdoorPressure);
   16810            0 :         CompAmbTemp = OutdoorDryBulb;
   16811              :     } else {                            // for air or water-cooled, inlet temp is stored in OutdoorDryBulb temp
   16812        23659 :         CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp or water inlet temp
   16813        23659 :         if (thisDXCoil.CondenserType(Mode) == DataHeatBalance::RefrigCondenserType::Water) {
   16814            0 :             CompAmbTemp = state.dataEnvrn->OutDryBulbTemp; // for crankcase heater use actual outdoor temp for water-cooled
   16815              :         } else {
   16816        23659 :             CompAmbTemp = OutdoorDryBulb;
   16817              :         }
   16818              :     }
   16819              : 
   16820              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX cooling coil
   16821              :     // If used in a heat pump, the value of MaxOAT in the heating coil overrides that in the cooling coil (in GetInput)
   16822        23659 :     if (CompAmbTemp < thisDXCoil.MaxOATCrankcaseHeater) {
   16823           32 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   16824           32 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   16825            0 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, CompAmbTemp);
   16826              :         }
   16827              :     } else {
   16828        23627 :         CrankcaseHeatingPower = 0.0;
   16829              :     }
   16830              : 
   16831              :     // calculate end time of current time step to determine if error messages should be printed
   16832        23659 :     state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime = state.dataGlobal->CurrentTime + SysTimeElapsed;
   16833              : 
   16834              :     // The following checks are not necessary for VRF-FluidTCtrl model. (1) OAT check is already performed in the VRF OU routines (2)
   16835              :     // VRF-FluidTCtrl model is physics based, not system curve based, and thus doesn't require special performance curves for operations at
   16836              :     // low inlet temperatures
   16837              :     //   Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
   16838              :     //   Wait for next time step to print warnings. If simulation iterates, print out
   16839              :     //   the warning for the last iteration only. Must wait for next time step to accomplish this.
   16840              :     //   If a warning occurs and the simulation down shifts, the warning is not valid.
   16841              :     // if ( DXCoil( DXCoilNum ).PrintLowAmbMessage ) { // .AND. &
   16842              :     //     if ( CurrentEndTime > DXCoil( DXCoilNum ).CurrentEndTimeLast && TimeStepSys >= DXCoil( DXCoilNum ).TimeStepSysLast ) {
   16843              :     //         if ( DXCoil( DXCoilNum ).LowAmbErrIndex == 0 ) {
   16844              :     //             ShowWarningMessage(state,  DXCoil( DXCoilNum ).LowAmbBuffer1 );
   16845              :     //             ShowContinueError(state,  DXCoil( DXCoilNum ).LowAmbBuffer2 );
   16846              :     //             ShowContinueError(state,  "... Operation at low inlet temperatures may require special performance curves." );
   16847              :     //         }
   16848              :     //         ShowRecurringWarningErrorAtEnd(state,  DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Low condenser inlet
   16849              :     // temperature error continues...", DXCoil( DXCoilNum ).LowAmbErrIndex, DXCoil( DXCoilNum ).LowTempLast, DXCoil( DXCoilNum ).LowTempLast,
   16850              :     // _,
   16851              :     // "[C]", "[C]" );
   16852              :     //     }
   16853              :     // }
   16854              :     //
   16855              :     // if ( DXCoil( DXCoilNum ).PrintHighAmbMessage ) { // .AND. &
   16856              :     //     if ( CurrentEndTime > DXCoil( DXCoilNum ).CurrentEndTimeLast && TimeStepSys >= DXCoil( DXCoilNum ).TimeStepSysLast ) {
   16857              :     //         if ( DXCoil( DXCoilNum ).HighAmbErrIndex == 0 ) {
   16858              :     //             ShowWarningMessage(state,  DXCoil( DXCoilNum ).HighAmbBuffer1 );
   16859              :     //             ShowContinueError(state,  DXCoil( DXCoilNum ).HighAmbBuffer2 );
   16860              :     //             ShowContinueError(state,  "... Operation at high inlet temperatures may require special performance curves." );
   16861              :     //         }
   16862              :     //         ShowRecurringWarningErrorAtEnd(state,  DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - High condenser inlet
   16863              :     // temperature error continues...", DXCoil( DXCoilNum ).HighAmbErrIndex, DXCoil( DXCoilNum ).HighTempLast, DXCoil( DXCoilNum
   16864              :     // ).HighTempLast,
   16865              :     // _, "[C]", "[C]" );
   16866              :     //     }
   16867              :     // }
   16868              : 
   16869        23659 :     if (thisDXCoil.PrintLowOutTempMessage) {
   16870            0 :         if ((state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime > thisDXCoil.CurrentEndTimeLast) &&
   16871            0 :             (TimeStepSys >= thisDXCoil.TimeStepSysLast)) {
   16872            0 :             if (thisDXCoil.LowOutletTempIndex == 0) {
   16873            0 :                 ShowWarningMessage(state, thisDXCoil.LowOutTempBuffer1);
   16874            0 :                 ShowContinueError(state, thisDXCoil.LowOutTempBuffer2);
   16875            0 :                 ShowContinueError(state, "... Possible reasons for low outlet air dry-bulb temperatures are: This DX coil");
   16876            0 :                 ShowContinueError(state,
   16877            0 :                                   format("   1) may have a low inlet air dry-bulb temperature. Inlet air temperature = {:.3T} C.",
   16878            0 :                                          thisDXCoil.FullLoadInletAirTempLast));
   16879            0 :                 ShowContinueError(state, "   2) may have a low air flow rate per watt of cooling capacity. Check inputs.");
   16880            0 :                 ShowContinueError(state,
   16881              :                                   "   3) is used as part of a HX assisted cooling coil which uses a high sensible effectiveness. Check inputs.");
   16882              :             }
   16883            0 :             ShowRecurringWarningErrorAtEnd(state,
   16884            0 :                                            thisDXCoil.DXCoilType + " \"" + thisDXCoil.Name +
   16885              :                                                "\" - Full load outlet temperature indicates a possibility of frost/freeze error continues. "
   16886              :                                                "Outlet air temperature statistics follow:",
   16887            0 :                                            thisDXCoil.LowOutletTempIndex,
   16888            0 :                                            thisDXCoil.FullLoadOutAirTempLast,
   16889            0 :                                            thisDXCoil.FullLoadOutAirTempLast);
   16890              :         }
   16891              :     }
   16892              : 
   16893              :     // save last system time step and last end time of current time step (used to determine if warning is valid)
   16894        23659 :     thisDXCoil.TimeStepSysLast = TimeStepSys;
   16895        23659 :     thisDXCoil.CurrentEndTimeLast = state.dataDXCoils->CalcVRFCoolingCoil_FluidTCtrlCurrentEndTime;
   16896        23659 :     thisDXCoil.PrintLowAmbMessage = false;
   16897        23659 :     thisDXCoil.PrintLowOutTempMessage = false;
   16898              : 
   16899        23659 :     if ((AirMassFlow > 0.0) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
   16900              :         (compressorOp == HVAC::CompressorOp::On)) { // for cycling fan, reset mass flow to full on rate
   16901              : 
   16902        10299 :         if (thisDXCoil.RatedTotCap(Mode) <= 0.0) {
   16903            0 :             ShowFatalError(state, format("{} \"{}\" - Rated total cooling capacity is zero or less.", thisDXCoil.DXCoilType, thisDXCoil.Name));
   16904              :         }
   16905              : 
   16906        10299 :         TotCap = min(MaxCoolCap, thisDXCoil.RatedTotCap(Mode));
   16907              : 
   16908        10299 :         QCoilReq = -PartLoadRatio * TotCap;
   16909        10299 :         if (PartLoadRatio == 0.0) {
   16910            0 :             AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
   16911              :         } else {
   16912        10299 :             AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
   16913              :         }
   16914              : 
   16915              :         // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
   16916        10299 :         ControlVRFIUCoil(state,
   16917              :                          DXCoilNum,
   16918              :                          QCoilReq,
   16919              :                          thisDXCoil.InletAirTemp,
   16920              :                          thisDXCoil.InletAirHumRat,
   16921              :                          thisDXCoil.EvaporatingTemp,
   16922              :                          AirMassFlowMin,
   16923              :                          FanSpdRatio,
   16924              :                          OutletAirHumRat,
   16925              :                          OutletAirTemp,
   16926              :                          OutletAirEnthalpy,
   16927              :                          ActualSH,
   16928              :                          ActualSC);
   16929        10299 :         AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
   16930              : 
   16931        10299 :         AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
   16932        10299 :         VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
   16933              :         // VolFlowperRatedTotCap was checked at the initialization step
   16934              :         // No need to check VolFlowperRatedTotCap at the simulation
   16935              :         // New VRF_FluidTCtrl model implements VAV fan which can vary air flow rate during simulation
   16936              : 
   16937        10299 :         RatedCBF = thisDXCoil.RatedCBF(Mode);
   16938        10299 :         if (RatedCBF > 0.0) {
   16939        10299 :             A0 = -std::log(RatedCBF) * thisDXCoil.RatedAirMassFlowRate(Mode);
   16940              :         } else {
   16941            0 :             A0 = 0.0;
   16942              :         }
   16943        10299 :         ADiff = -A0 / AirMassFlow;
   16944        10299 :         if (ADiff >= DataPrecisionGlobals::EXP_LowerLimit) {
   16945         7714 :             CBF = std::exp(ADiff);
   16946              :         } else {
   16947         2585 :             CBF = 0.0;
   16948              :         }
   16949              : 
   16950              :         // The following checks are not necessary for VRF-FluidTCtrl model. (1) OAT check is already performed in the VRF OU routines (2)
   16951              :         // VRF-FluidTCtrl model is physics based, not system curve based, and thus doesn't require special performance curves for operations
   16952              :         // at low inlet temperatures
   16953              :         // // check boundary for low ambient temperature and post warnings to individual DX coil buffers to print at end of time step
   16954              :         // if ( OutdoorDryBulb < DXCoil( DXCoilNum ).MinOATCompressor && ! WarmupFlag ) {
   16955              :         //     DXCoil( DXCoilNum ).PrintLowAmbMessage = true;
   16956              :         //     DXCoil( DXCoilNum ).LowTempLast = OutdoorDryBulb;
   16957              :         //     if ( DXCoil( DXCoilNum ).LowAmbErrIndex == 0 ) {
   16958              :         //         DXCoil( DXCoilNum ).LowAmbBuffer1 = DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Condenser
   16959              :         // inlet temperature below " + RoundSigDigits( DXCoil( DXCoilNum ).MinOATCompressor, 2 ) + " C. Condenser inlet temperature = " +
   16960              :         // RoundSigDigits( OutdoorDryBulb, 2 );
   16961              :         //         DXCoil( DXCoilNum ).LowAmbBuffer2 = " ... Occurrence info = " + EnvironmentName + ", " + CurMnDy + " " +
   16962              :         // CreateSysTimeIntervalString();
   16963              :         //     }
   16964              :         // }
   16965              :         //
   16966              :         // // check boundary for high ambient temperature and post warnings to individual DX coil buffers to print at end of time step
   16967              :         // if ( OutdoorDryBulb > DXCoil( DXCoilNum ).MaxOATCompressor && ! WarmupFlag ) {
   16968              :         //     DXCoil( DXCoilNum ).PrintHighAmbMessage = true;
   16969              :         //     DXCoil( DXCoilNum ).HighTempLast = OutdoorDryBulb;
   16970              :         //     if ( DXCoil( DXCoilNum ).HighAmbErrIndex == 0 ) {
   16971              :         //         DXCoil( DXCoilNum ).HighAmbBuffer1 = DXCoil( DXCoilNum ).DXCoilType + " \"" + DXCoil( DXCoilNum ).Name + "\" - Condenser
   16972              :         // inlet temperature above " + RoundSigDigits( DXCoil( DXCoilNum ).MaxOATCompressor, 2 ) + " C. Condenser temperature = " +
   16973              :         // RoundSigDigits( OutdoorDryBulb, 2 );         DXCoil( DXCoilNum ).HighAmbBuffer2 = " ... Occurrence info = " + EnvironmentName + ",
   16974              :         // "
   16975              :         // + CurMnDy + " " + CreateSysTimeIntervalString();
   16976              :         //     }
   16977              :         // }
   16978              : 
   16979              :         //  Get total capacity modifying factor (function of temperature) for off-rated conditions
   16980              :         //  InletAirHumRat may be modified in this ADP/BF loop, use temporary varible for calculations
   16981              : 
   16982              :         // commented, not used issue #6950
   16983              :         // InletAirHumRatTemp = InletAirHumRat;
   16984              : 
   16985              :         //// Calculate apparatus dew point conditions using TotCap and CBF
   16986              :         // hDelta = TotCap / AirMassFlow;
   16987              :         //// there is an issue here with using CBF to calculate the ADP enthalpy.
   16988              :         //// at low loads the bypass factor increases significantly.
   16989              :         // hADP = InletAirEnthalpy - hDelta / (1.0 - CBF);
   16990              :         // tADP = PsyTsatFnHPb(hADP, OutdoorPressure, RoutineName);
   16991              :         ////  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   16992              :         ////  tADP = PsyTsatFnHPb(hADP,InletAirPressure)
   16993              :         // wADP = min(InletAirHumRat, PsyWFnTdbH(tADP, hADP, RoutineName));
   16994              :         // hTinwADP = PsyHFnTdbW(InletAirDryBulbTemp, wADP);
   16995              :         // if ((InletAirEnthalpy - hADP) > 1.e-10) {
   16996              :         //    SHR = min((hTinwADP - hADP) / (InletAirEnthalpy - hADP), 1.0);
   16997              :         //} else {
   16998              :         //    SHR = 1.0;
   16999              :         //}
   17000              :         // commented, not used issue #6950 ends here
   17001              : 
   17002        10299 :         if (thisDXCoil.PLFFPLR(Mode) > 0 && CompCycRatio < 1.0) {
   17003            0 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), CompCycRatio); // Calculate part-load factor
   17004              :         } else {
   17005        10299 :             PLF = 1.0;
   17006              :         }
   17007              : 
   17008        10299 :         if (PLF < 0.7) {
   17009            0 :             if (thisDXCoil.ErrIndex2 == 0) {
   17010            0 :                 ShowWarningMessage(
   17011              :                     state,
   17012            0 :                     format(
   17013            0 :                         "The PLF curve value for the DX cooling coil {} ={:.3R} for part-load ratio ={:.3R}", thisDXCoil.Name, PLF, PartLoadRatio));
   17014            0 :                 ShowContinueErrorTimeStamp(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   17015            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
   17016              :             }
   17017            0 :             ShowRecurringWarningErrorAtEnd(
   17018            0 :                 state, thisDXCoil.Name + ", DX cooling coil PLF curve < 0.7 warning continues...", thisDXCoil.ErrIndex2, PLF, PLF);
   17019            0 :             PLF = 0.7;
   17020              :         }
   17021              : 
   17022        10299 :         thisDXCoil.PartLoadRatio = PartLoadRatio;
   17023        10299 :         thisDXCoil.CoolingCoilRuntimeFraction = CompCycRatio / PLF;
   17024        10299 :         if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.CoolingCoilRuntimeFraction - 1.0) > 0.001) {
   17025            0 :             if (thisDXCoil.ErrIndex3 == 0) {
   17026            0 :                 ShowWarningMessage(state,
   17027            0 :                                    format("The runtime fraction for DX cooling coil {} exceeded 1.0. [{:.4R}].",
   17028            0 :                                           thisDXCoil.Name,
   17029            0 :                                           thisDXCoil.CoolingCoilRuntimeFraction));
   17030            0 :                 ShowContinueError(state, "Runtime fraction reset to 1 and the simulation will continue.");
   17031            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Cooling:DX:SingleSpeed].");
   17032            0 :                 ShowContinueErrorTimeStamp(state, "");
   17033              :             }
   17034            0 :             ShowRecurringWarningErrorAtEnd(state,
   17035            0 :                                            thisDXCoil.Name + ", DX cooling coil runtime fraction > 1.0 warning continues...",
   17036            0 :                                            thisDXCoil.ErrIndex3,
   17037            0 :                                            thisDXCoil.CoolingCoilRuntimeFraction,
   17038            0 :                                            thisDXCoil.CoolingCoilRuntimeFraction);
   17039            0 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   17040        10299 :         } else if (thisDXCoil.CoolingCoilRuntimeFraction > 1.0) {
   17041            0 :             thisDXCoil.CoolingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   17042              :         }
   17043              : 
   17044              :         // If cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
   17045        10299 :         if (fanOp == HVAC::FanOp::Cycling) {
   17046        10299 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = thisDXCoil.CoolingCoilRuntimeFraction;
   17047              :         }
   17048              : 
   17049              :         // Check for saturation error and modify temperature at constant enthalpy
   17050        10299 :         if (OutletAirTemp < PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure)) {
   17051           18 :             OutletAirTemp = PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure);
   17052              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   17053              :             //   IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)) THEN
   17054              :             //    FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
   17055           18 :             OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy);
   17056              :         }
   17057              : 
   17058              :         // Store actual outlet conditions when DX coil is ON for use in heat recovery module
   17059        10299 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = OutletAirTemp;
   17060        10299 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = OutletAirHumRat;
   17061              : 
   17062              :         // Add warning message for cold cooling coil (OutletAirTemp < 2 C)
   17063        10299 :         if (OutletAirTemp < 2.0 && !FirstHVACIteration && !state.dataGlobal->WarmupFlag) {
   17064            0 :             thisDXCoil.PrintLowOutTempMessage = true;
   17065            0 :             thisDXCoil.FullLoadOutAirTempLast = OutletAirTemp;
   17066            0 :             if (thisDXCoil.LowOutletTempIndex == 0) {
   17067            0 :                 thisDXCoil.FullLoadInletAirTempLast = InletAirDryBulbTemp;
   17068            0 :                 thisDXCoil.LowOutTempBuffer1 = format("{} \"{}\" - Full load outlet air dry-bulb temperature < 2C. This indicates the "
   17069              :                                                       "possibility of coil frost/freeze. Outlet temperature = {:.2R} C.",
   17070            0 :                                                       thisDXCoil.DXCoilType,
   17071            0 :                                                       thisDXCoil.Name,
   17072            0 :                                                       OutletAirTemp);
   17073            0 :                 thisDXCoil.LowOutTempBuffer2 = " ...Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " + state.dataEnvrn->CurMnDy + " " +
   17074            0 :                                                CreateSysTimeIntervalString(state);
   17075              :             }
   17076              :         }
   17077              : 
   17078              :         // Coil total/sensible/latent cooling rates
   17079        10299 :         CalcComponentSensibleLatentOutput(AirMassFlow * PartLoadRatio,
   17080              :                                           InletAirDryBulbTemp,
   17081              :                                           InletAirHumRat,
   17082              :                                           OutletAirTemp,
   17083              :                                           OutletAirHumRat,
   17084        10299 :                                           thisDXCoil.SensCoolingEnergyRate,
   17085        10299 :                                           thisDXCoil.LatCoolingEnergyRate,
   17086        10299 :                                           thisDXCoil.TotalCoolingEnergyRate);
   17087              : 
   17088              :         // Coil outlet conditions
   17089        10299 :         thisDXCoil.OutletAirTemp = OutletAirTemp;
   17090        10299 :         thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   17091        10299 :         thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   17092              : 
   17093              :         // Coil SH/SC
   17094        10299 :         thisDXCoil.ActualSH = ActualSH;
   17095        10299 :         thisDXCoil.ActualSC = ActualSC;
   17096              : 
   17097              :     } else {
   17098              :         // DX coil is off; just pass through conditions
   17099              : 
   17100        13360 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   17101        13360 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   17102        13360 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   17103              : 
   17104        13360 :         thisDXCoil.ElecCoolingPower = 0.0;
   17105        13360 :         thisDXCoil.TotalCoolingEnergyRate = 0.0;
   17106        13360 :         thisDXCoil.SensCoolingEnergyRate = 0.0;
   17107        13360 :         thisDXCoil.LatCoolingEnergyRate = 0.0;
   17108        13360 :         thisDXCoil.EvapCondPumpElecPower = 0.0;
   17109        13360 :         thisDXCoil.EvapWaterConsumpRate = 0.0;
   17110              : 
   17111        13360 :         thisDXCoil.ActualSH = 999.0;
   17112        13360 :         thisDXCoil.ActualSC = 999.0;
   17113              : 
   17114              :         // Reset globals when DX coil is OFF for use in heat recovery module
   17115        13360 :         state.dataDXCoils->DXCoilFullLoadOutAirTemp(DXCoilNum) = 0.0;
   17116        13360 :         state.dataDXCoils->DXCoilFullLoadOutAirHumRat(DXCoilNum) = 0.0;
   17117              : 
   17118              :     } // end of on/off
   17119              : 
   17120              :     // set water system demand request (if needed)
   17121        23659 :     if (thisDXCoil.EvapWaterSupplyMode == EvapWaterSupply::FromTank) {
   17122            0 :         state.dataWaterData->WaterStorage(thisDXCoil.EvapWaterSupTankID).VdotRequestDemand(thisDXCoil.EvapWaterTankDemandARRID) =
   17123            0 :             thisDXCoil.EvapWaterConsumpRate;
   17124              :     }
   17125              : 
   17126        23659 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   17127        23659 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   17128        23659 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = thisDXCoil.PartLoadRatio;
   17129        23659 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   17130        23659 :     thisDXCoil.CondInletTemp = CondInletTemp;
   17131        23659 :     state.dataDXCoils->DXCoilTotalCooling(DXCoilNum) = thisDXCoil.TotalCoolingEnergyRate;
   17132        23659 :     state.dataDXCoils->DXCoilCoolInletAirWBTemp(DXCoilNum) = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   17133        23659 : }
   17134              : 
   17135        23659 : void CalcVRFHeatingCoil_FluidTCtrl(EnergyPlusData &state,
   17136              :                                    HVAC::CompressorOp const compressorOp,               // compressor operation; 1=on, 0=off
   17137              :                                    int const DXCoilNum,                                 // the number of the DX heating coil to be simulated
   17138              :                                    Real64 const PartLoadRatio,                          // sensible cooling load / full load sensible cooling capacity
   17139              :                                    HVAC::FanOp const fanOp,                             // Allows parent object to control fan mode
   17140              :                                    ObjexxFCL::Optional<Real64 const> OnOffAirFlowRatio, // ratio of compressor on airflow to compressor off airflow
   17141              :                                    ObjexxFCL::Optional<Real64 const> MaxHeatCap         // maximum allowed heating capacity
   17142              : )
   17143              : {
   17144              :     // SUBROUTINE INFORMATION:
   17145              :     //       AUTHOR         Xiufeng Pang (XP), LBNL
   17146              :     //       DATE WRITTEN   Mar 2013
   17147              :     //       MODIFIED       Nov 2015, RP Zhang, LBNL
   17148              : 
   17149              :     // PURPOSE OF THIS SUBROUTINE:
   17150              :     //         Calculates the air-side performance of a direct-expansion, air-cooled
   17151              :     //         VRF terminal unit heating coil, for the new VRF model.
   17152              : 
   17153              :     // METHODOLOGY EMPLOYED:
   17154              :     //         This subroutine is derived from CalcVRFCoolingCoil, and implements the new VRF model for FluidTCtrl.
   17155              : 
   17156              :     // Using/Aliasing
   17157              :     using Curve::CurveValue;
   17158              : 
   17159              :     using namespace HVACVariableRefrigerantFlow;
   17160              : 
   17161              :     // INTERFACE BLOCK SPECIFICATIONS
   17162              :     static constexpr std::string_view RoutineNameFullLoad("CalcVRFHeatingCoil_FluidTCtrl:fullload");
   17163              : 
   17164              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   17165              :     Real64 AirMassFlow;           // dry air mass flow rate through coil [kg/s]
   17166              :     Real64 AirMassFlowRatio;      // Ratio of actual air mass flow to rated air mass flow
   17167              :     Real64 AirVolumeFlowRate;     // Air volume flow rate across the cooling coil [m3/s]
   17168              :     Real64 VolFlowperRatedTotCap; // Air volume flow rate divided by rated total cooling capacity [m3/s-W]
   17169              :     Real64 TotCap;                // gross total cooling capacity at off-rated conditions [W]
   17170              :     Real64 TotCapAdj;             // adjusted total cooling capacity at off-rated conditions [W]
   17171              :     // on the type of curve
   17172              :     Real64 InletAirDryBulbTemp;  // inlet air dry bulb temperature [C]
   17173              :     Real64 InletAirWetBulbC;     // wetbulb temperature of inlet air [C]
   17174              :     Real64 InletAirEnthalpy;     // inlet air enthalpy [J/kg]
   17175              :     Real64 InletAirHumRat;       // inlet air humidity ratio [kg/kg]
   17176              :     Real64 FullLoadOutAirEnth;   // outlet full load enthalpy [J/kg]
   17177              :     Real64 FullLoadOutAirHumRat; // outlet humidity ratio at full load
   17178              :     Real64 FullLoadOutAirTemp;   // outlet air temperature at full load [C]
   17179              :     Real64 FullLoadOutAirRH;     // outlet air relative humidity at full load
   17180        23659 :     Real64 EIRTempModFac(0.0);   // EIR modifier (function of entering drybulb, outside drybulb) depending on the
   17181              :     //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   17182              :     // type of curve
   17183              :     // Real64 DefrostEIRTempModFac; // EIR modifier for defrost (function of entering wetbulb, outside drybulb)
   17184              :     Real64 EIRFlowModFac;             // EIR modifier (function of actual supply air flow vs rated flow)
   17185              :     Real64 EIR;                       // EIR at part load and off rated conditions
   17186              :     Real64 PLF;                       // Part load factor, accounts for thermal lag at compressor startup
   17187              :     Real64 PLRHeating;                // PartLoadRatio in heating
   17188              :     Real64 OutdoorCoilT;              // Outdoor coil temperature (C)
   17189              :     Real64 OutdoorCoildw;             // Outdoor coil delta w assuming coil temp of OutdoorCoilT (kg/kg)
   17190              :     Real64 FractionalDefrostTime;     // Fraction of time step system is in defrost
   17191              :     Real64 HeatingCapacityMultiplier; // Multiplier for heating capacity when system is in defrost
   17192              :     Real64 InputPowerMultiplier;      // Multiplier for power when system is in defrost
   17193              :     Real64 LoadDueToDefrost;          // Additional load due to defrost
   17194              :     Real64 CrankcaseHeatingPower;     // power due to crankcase heater
   17195              :     Real64 OutdoorDryBulb;            // Outdoor dry-bulb temperature at condenser (C)
   17196              :     Real64 OutdoorWetBulb;            // Outdoor wet-bulb temperature at condenser (C)
   17197              :     Real64 OutdoorHumRat;             // Outdoor humidity ratio at condenser (kg/kg)
   17198              :     Real64 OutdoorPressure;           // Outdoor barometric pressure at condenser (Pa)
   17199        23659 :     constexpr int Mode(1);            // Performance mode for MultiMode DX coil. Always 1 for other coil types
   17200              :     Real64 AirFlowRatio;              // Ratio of compressor on airflow to average timestep airflow
   17201              :     Real64 OutletAirTemp;             // Supply air temperature (average value if constant fan, full output if cycling fan)
   17202              :     Real64 OutletAirHumRat;           // Supply air humidity ratio (average value if constant fan, full output if cycling fan)
   17203              :     Real64 OutletAirEnthalpy;         // Supply air enthalpy (average value if constant fan, full output if cycling fan)
   17204              : 
   17205              :     // Followings for VRF FluidTCtrl Only
   17206              :     Real64 QCoilReq;       // Coil load (W)
   17207              :     Real64 FanSpdRatio;    // Fan Speed Ratio
   17208              :     Real64 AirMassFlowMin; // Min air mass flow rate due to OA requirement [kg/s]
   17209              :     Real64 ActualSH;       // Actual Super Heating
   17210              :     Real64 ActualSC;       // Actual Sub Cooling
   17211              : 
   17212        23659 :     if (present(OnOffAirFlowRatio)) {
   17213            0 :         AirFlowRatio = OnOffAirFlowRatio;
   17214              :     } else {
   17215        23659 :         AirFlowRatio = 1.0;
   17216              :     }
   17217              : 
   17218              :     // Air cooled condenser
   17219        23659 :     OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
   17220        23659 :     OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
   17221        23659 :     OutdoorHumRat = state.dataEnvrn->OutHumRat;
   17222        23659 :     OutdoorPressure = state.dataEnvrn->OutBaroPress;
   17223              : 
   17224        23659 :     auto &thisDXCoil = state.dataDXCoils->DXCoil(DXCoilNum);
   17225              : 
   17226        23659 :     AirMassFlow = thisDXCoil.InletAirMassFlowRate;
   17227        23659 :     InletAirDryBulbTemp = thisDXCoil.InletAirTemp;
   17228        23659 :     InletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   17229        23659 :     InletAirHumRat = thisDXCoil.InletAirHumRat;
   17230        23659 :     InletAirWetBulbC = PsyTwbFnTdbWPb(state, InletAirDryBulbTemp, InletAirHumRat, OutdoorPressure);
   17231        23659 :     PLRHeating = 0.0;
   17232        23659 :     thisDXCoil.HeatingCoilRuntimeFraction = 0.0;
   17233        23659 :     thisDXCoil.CondensingTemp = state.dataHVACVarRefFlow->VRF(thisDXCoil.VRFOUPtr).IUCondensingTemp;
   17234              : 
   17235              :     // Initialize crankcase heater, operates below OAT defined in input deck for HP DX heating coil
   17236        23659 :     if (OutdoorDryBulb < thisDXCoil.MaxOATCrankcaseHeater) {
   17237           32 :         CrankcaseHeatingPower = thisDXCoil.CrankcaseHeaterCapacity;
   17238           32 :         if (thisDXCoil.CrankcaseHeaterCapacityCurveIndex > 0) {
   17239            0 :             CrankcaseHeatingPower *= Curve::CurveValue(state, thisDXCoil.CrankcaseHeaterCapacityCurveIndex, OutdoorDryBulb);
   17240              :         }
   17241              :     } else {
   17242        23627 :         CrankcaseHeatingPower = 0.0;
   17243              :     }
   17244              : 
   17245        32212 :     if ((AirMassFlow > 0.0) && (compressorOp == HVAC::CompressorOp::On) && (thisDXCoil.availSched->getCurrentVal() > 0.0) && (PartLoadRatio > 0.0) &&
   17246         8553 :         (OutdoorDryBulb > thisDXCoil.MinOATCompressor)) {
   17247              : 
   17248         8553 :         TotCap = thisDXCoil.RatedTotCap(Mode);
   17249         8553 :         HeatingCapacityMultiplier = 1.0;
   17250              :         // Modify total heating capacity based on defrost heating capacity multiplier
   17251              :         // MaxHeatCap passed from parent object VRF Condenser and is used to limit capacity of TU's to that available from condenser
   17252         8553 :         if (present(MaxHeatCap)) {
   17253         8547 :             TotCapAdj = min(MaxHeatCap, TotCap * HeatingCapacityMultiplier);
   17254         8547 :             TotCap = min(MaxHeatCap, TotCap);
   17255              :         } else {
   17256            6 :             TotCapAdj = TotCap * HeatingCapacityMultiplier;
   17257              :         }
   17258              : 
   17259         8553 :         QCoilReq = PartLoadRatio * TotCap;
   17260         8553 :         if (PartLoadRatio == 0.0) {
   17261            0 :             AirMassFlowMin = state.dataHVACVarRefFlow->OACompOffMassFlow;
   17262              :         } else {
   17263         8553 :             AirMassFlowMin = state.dataHVACVarRefFlow->OACompOnMassFlow;
   17264              :         }
   17265              : 
   17266              :         // Call ControlVRFIUCoil to calculate: (1) FanSpdRatio, (2) coil inlet/outlet conditions, and (3) SH/SC
   17267         8553 :         ControlVRFIUCoil(state,
   17268              :                          DXCoilNum,
   17269              :                          QCoilReq,
   17270              :                          thisDXCoil.InletAirTemp,
   17271              :                          thisDXCoil.InletAirHumRat,
   17272              :                          thisDXCoil.CondensingTemp,
   17273              :                          AirMassFlowMin,
   17274              :                          FanSpdRatio,
   17275              :                          OutletAirHumRat,
   17276              :                          OutletAirTemp,
   17277              :                          OutletAirEnthalpy,
   17278              :                          ActualSH,
   17279              :                          ActualSC);
   17280         8553 :         AirMassFlow = FanSpdRatio * thisDXCoil.RatedAirMassFlowRate(Mode);
   17281              : 
   17282         8553 :         AirVolumeFlowRate = AirMassFlow / PsyRhoAirFnPbTdbW(state, OutdoorPressure, InletAirDryBulbTemp, InletAirHumRat);
   17283              :         // Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   17284         8553 :         VolFlowperRatedTotCap = AirVolumeFlowRate / thisDXCoil.RatedTotCap(Mode);
   17285              :         // VolFlowperRatedTotCap was checked at the initialization step
   17286              :         // No need to check VolFlowperRatedTotCap at the simulation
   17287              :         // New VRF_FluidTCtrl model implements VAV fan which can vary air flow rate during simulation
   17288              : 
   17289         8553 :         AirMassFlowRatio = AirMassFlow / thisDXCoil.RatedAirMassFlowRate(Mode);
   17290              : 
   17291              :         // Calculating adjustment factors for defrost
   17292              :         // Calculate delta w through outdoor coil by assuming a coil temp of 0.82*DBT-9.7(F) per DOE2.1E
   17293         8553 :         OutdoorCoilT = 0.82 * OutdoorDryBulb - 8.589;
   17294         8553 :         OutdoorCoildw = max(1.0e-6, (OutdoorHumRat - PsyWFnTdpPb(state, OutdoorCoilT, OutdoorPressure)));
   17295              : 
   17296              :         // Initializing defrost adjustment factors
   17297         8553 :         LoadDueToDefrost = 0.0;
   17298         8553 :         FractionalDefrostTime = 0.0;
   17299         8553 :         InputPowerMultiplier = 1.0;
   17300              : 
   17301              :         // Calculate full load outlet conditions
   17302         8553 :         FullLoadOutAirEnth = InletAirEnthalpy + TotCapAdj / AirMassFlow;
   17303         8553 :         FullLoadOutAirHumRat = InletAirHumRat;
   17304         8553 :         FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
   17305         8553 :         FullLoadOutAirRH = PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
   17306              :         //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   17307              :         //  FullLoadOutAirRH = PsyRhFnTdbWPb(FullLoadOutAirTemp,FullLoadOutAirHumRat,InletAirPressure)
   17308         8553 :         if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
   17309            0 :             FullLoadOutAirTemp = PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure);
   17310              :             //  Eventually inlet air conditions will be used in DX Coil, these lines are commented out and marked with this comment line
   17311              :             //    FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
   17312            0 :             FullLoadOutAirHumRat = PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth);
   17313              :         }
   17314              : 
   17315              :         // Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
   17316              :         // Model was extended to accept bi-quadratic curves. This allows sensitivity of the EIR
   17317              :         // to the entering dry-bulb temperature as well as the outside dry-bulb temperature. User is
   17318              :         // advised to use the bi-quaratic curve if sufficient manufacturer data is available.
   17319         8553 :         if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
   17320            0 :             if (state.dataCurveManager->curves(thisDXCoil.EIRFTemp(Mode))->numDims == 1) {
   17321            0 :                 EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), OutdoorDryBulb);
   17322              :             } else {
   17323            0 :                 EIRTempModFac = CurveValue(state, thisDXCoil.EIRFTemp(Mode), InletAirDryBulbTemp, OutdoorDryBulb);
   17324              :             }
   17325            0 :             EIRFlowModFac = CurveValue(state, thisDXCoil.EIRFFlow(Mode), AirMassFlowRatio);
   17326              :         } else {
   17327         8553 :             EIRTempModFac = 1.0;
   17328         8553 :             EIRFlowModFac = 1.0;
   17329              :         }
   17330         8553 :         EIR = thisDXCoil.RatedEIR(Mode) * EIRTempModFac * EIRFlowModFac;
   17331              : 
   17332              :         // Calculate PLRHeating: modified PartLoadRatio due to defrost ( reverse-cycle defrost only )
   17333         8553 :         if (TotCap > 0.0) {
   17334         8553 :             PLRHeating = min(1.0, (PartLoadRatio + LoadDueToDefrost / TotCap));
   17335              :         } else {
   17336            0 :             PLRHeating = min(1.0, PartLoadRatio);
   17337              :         }
   17338              : 
   17339         8553 :         if (thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_Heating && thisDXCoil.DXCoilType_Num != HVAC::CoilVRF_FluidTCtrl_Heating) {
   17340            0 :             PLF = CurveValue(state, thisDXCoil.PLFFPLR(Mode), PLRHeating); // Calculate part-load factor
   17341              :         } else {
   17342         8553 :             PLF = 1.0;
   17343              :         }
   17344              : 
   17345         8553 :         if (PLF < 0.7) {
   17346            0 :             if (thisDXCoil.PLRErrIndex == 0) {
   17347            0 :                 ShowWarningMessage(
   17348              :                     state,
   17349            0 :                     format("The PLF curve value for DX heating coil {} ={:.2R} for part-load ratio ={:.2R}", thisDXCoil.Name, PLF, PLRHeating));
   17350            0 :                 ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and simulation is continuing.");
   17351            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   17352            0 :                 ShowContinueErrorTimeStamp(state, "");
   17353              :             }
   17354            0 :             ShowRecurringWarningErrorAtEnd(state, "DX heating coil PLF curve < 0.7 warning continues... ", thisDXCoil.PLRErrIndex, PLF, PLF);
   17355            0 :             PLF = 0.7;
   17356              :         }
   17357              : 
   17358         8553 :         thisDXCoil.HeatingCoilRuntimeFraction = (PLRHeating / PLF);
   17359         8553 :         if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0 && std::abs(thisDXCoil.HeatingCoilRuntimeFraction - 1.0) > 0.001) {
   17360            0 :             if (thisDXCoil.ErrIndex4 == 0) {
   17361            0 :                 ShowWarningMessage(state,
   17362            0 :                                    format("The runtime fraction for DX heating coil {} exceeded 1.0. [{:.4R}].",
   17363            0 :                                           thisDXCoil.Name,
   17364            0 :                                           thisDXCoil.HeatingCoilRuntimeFraction));
   17365            0 :                 ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
   17366            0 :                 ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:DX:SingleSpeed].");
   17367            0 :                 ShowContinueErrorTimeStamp(state, "");
   17368              :             }
   17369            0 :             ShowRecurringWarningErrorAtEnd(state,
   17370            0 :                                            thisDXCoil.Name + ", DX heating coil runtime fraction > 1.0 warning continues...",
   17371            0 :                                            thisDXCoil.ErrIndex4,
   17372            0 :                                            thisDXCoil.HeatingCoilRuntimeFraction,
   17373            0 :                                            thisDXCoil.HeatingCoilRuntimeFraction);
   17374            0 :             thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   17375         8553 :         } else if (thisDXCoil.HeatingCoilRuntimeFraction > 1.0) {
   17376            0 :             thisDXCoil.HeatingCoilRuntimeFraction = 1.0; // Reset coil runtime fraction to 1.0
   17377              :         }
   17378              : 
   17379              :         // if cycling fan, send coil part-load fraction to on / off fan via HVACDataGlobals
   17380         8553 :         if (fanOp == HVAC::FanOp::Cycling) {
   17381         8553 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
   17382              :         }
   17383         8553 :         thisDXCoil.ElecHeatingPower = TotCap * EIR * thisDXCoil.HeatingCoilRuntimeFraction * InputPowerMultiplier;
   17384              : 
   17385              :         // Calculate crankcase heater power using the runtime fraction for this DX heating coil only if there is no companion DX coil.
   17386              :         // Else use the largest runtime fraction of this DX heating coil and the companion DX cooling coil.
   17387         8553 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   17388         8553 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower * (1.0 - thisDXCoil.HeatingCoilRuntimeFraction);
   17389              :         } else {
   17390            0 :             thisDXCoil.CrankcaseHeaterPower =
   17391            0 :                 CrankcaseHeatingPower * (1.0 - max(thisDXCoil.HeatingCoilRuntimeFraction,
   17392            0 :                                                    state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction));
   17393              :         }
   17394              : 
   17395         8553 :         thisDXCoil.OutletAirTemp = OutletAirTemp;
   17396         8553 :         thisDXCoil.OutletAirHumRat = OutletAirHumRat;
   17397         8553 :         thisDXCoil.OutletAirEnthalpy = OutletAirEnthalpy;
   17398         8553 :         thisDXCoil.CompressorPartLoadRatio = PartLoadRatio;
   17399         8553 :         thisDXCoil.ActualSH = ActualSH;
   17400         8553 :         thisDXCoil.ActualSC = ActualSC;
   17401         8553 :         thisDXCoil.TotalHeatingEnergyRate = AirMassFlow * (OutletAirEnthalpy - InletAirEnthalpy) * PartLoadRatio;
   17402         8553 :         thisDXCoil.DefrostPower = thisDXCoil.DefrostPower * thisDXCoil.HeatingCoilRuntimeFraction;
   17403              : 
   17404              :     } else {
   17405              :         // DX coil is off; just pass through conditions
   17406              : 
   17407        15106 :         thisDXCoil.OutletAirEnthalpy = thisDXCoil.InletAirEnthalpy;
   17408        15106 :         thisDXCoil.OutletAirHumRat = thisDXCoil.InletAirHumRat;
   17409        15106 :         thisDXCoil.OutletAirTemp = thisDXCoil.InletAirTemp;
   17410              : 
   17411        15106 :         thisDXCoil.ElecHeatingPower = 0.0;
   17412        15106 :         thisDXCoil.TotalHeatingEnergyRate = 0.0;
   17413        15106 :         thisDXCoil.DefrostPower = 0.0;
   17414              : 
   17415              :         // Calculate crankcase heater power using the runtime fraction for this DX heating coil (here DXHeatingCoilRTF=0) if
   17416              :         // there is no companion DX coil, or the runtime fraction of the companion DX cooling coil (here DXCoolingCoilRTF>=0).
   17417        15106 :         if (thisDXCoil.CompanionUpstreamDXCoil == 0) {
   17418        15106 :             thisDXCoil.CrankcaseHeaterPower = CrankcaseHeatingPower;
   17419              :         } else {
   17420            0 :             thisDXCoil.CrankcaseHeaterPower =
   17421            0 :                 CrankcaseHeatingPower * (1.0 - state.dataDXCoils->DXCoil(thisDXCoil.CompanionUpstreamDXCoil).CoolingCoilRuntimeFraction);
   17422              :         }
   17423        15106 :         thisDXCoil.CompressorPartLoadRatio = 0.0;
   17424              : 
   17425        15106 :         thisDXCoil.ActualSH = 999.0;
   17426        15106 :         thisDXCoil.ActualSC = 999.0;
   17427              :     } // end of on/off if - else
   17428              : 
   17429        23659 :     state.dataDXCoils->DXCoilOutletTemp(DXCoilNum) = thisDXCoil.OutletAirTemp;
   17430        23659 :     state.dataDXCoils->DXCoilOutletHumRat(DXCoilNum) = thisDXCoil.OutletAirHumRat;
   17431        23659 :     state.dataDXCoils->DXCoilFanOp(DXCoilNum) = fanOp;
   17432        23659 :     state.dataDXCoils->DXCoilPartLoadRatio(DXCoilNum) = PLRHeating;
   17433        23659 :     state.dataDXCoils->DXCoilTotalHeating(DXCoilNum) = thisDXCoil.TotalHeatingEnergyRate;
   17434        23659 :     state.dataDXCoils->DXCoilHeatInletAirDBTemp(DXCoilNum) = InletAirDryBulbTemp;
   17435        23659 :     state.dataDXCoils->DXCoilHeatInletAirWBTemp(DXCoilNum) = InletAirWetBulbC;
   17436              : 
   17437              :     // calc secondary coil if specified
   17438        23659 :     if (thisDXCoil.IsSecondaryDXCoilInZone) {
   17439            0 :         CalcSecondaryDXCoils(state, DXCoilNum);
   17440              :     }
   17441        23659 : }
   17442              : 
   17443        90388 : void ControlVRFIUCoil(EnergyPlusData &state,
   17444              :                       int const CoilIndex,     // index to VRFTU coil
   17445              :                       Real64 const QCoil,      // coil load
   17446              :                       Real64 const Tin,        // inlet air temperature
   17447              :                       Real64 const Win,        // inlet air humidity ratio
   17448              :                       Real64 const TeTc,       // evaporating or condensing temperature
   17449              :                       Real64 const OAMassFlow, // mass flow rate of outdoor air
   17450              :                       Real64 &FanSpdRatio,     // fan speed ratio: actual flow rate / rated flow rate
   17451              :                       Real64 &Wout,            // outlet air humidity ratio
   17452              :                       Real64 &Tout,            // outlet air temperature
   17453              :                       Real64 &Hout,            // outlet air enthalpy
   17454              :                       Real64 &SHact,           // actual SH
   17455              :                       Real64 &SCact            // actual SC
   17456              : )
   17457              : {
   17458              :     // SUBROUTINE INFORMATION:
   17459              :     //       AUTHOR         Xiufeng Pang, LBNL
   17460              :     //       DATE WRITTEN   Feb 2013
   17461              :     //       MODIFIED       Nov 2015, RP Zhang, LBNL
   17462              :     //
   17463              :     // PURPOSE OF THIS SUBROUTINE:
   17464              :     //       Analyze the VRF Indoor Unit operations given coil loads.
   17465              :     //       Calculated parameters include: (1) Fan Speed Ratio (2) SH/SC, (3) Coil Outlet conditions
   17466              :     //
   17467              :     // METHODOLOGY EMPLOYED:
   17468              :     //       A new physics based VRF model applicable for Fluid Temperature Control.
   17469              :     //
   17470              :     // USE STATEMENTS:
   17471              :     using Psychrometrics::PsyHFnTdbW;
   17472              : 
   17473              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   17474        90388 :     int MaxIter(500);              // Max iteration numbers (-)
   17475              :     int SolFla;                    // Solving flag for SolveRoot (-)
   17476        90388 :     int constexpr FlagCoolMode(0); // Flag for cooling mode
   17477        90388 :     int constexpr FlagHeatMode(1); // Flag for heating mode
   17478              :     Real64 BF;                     // Bypass factor (-)
   17479              :     Real64 C1Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17480              :     Real64 C2Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17481              :     Real64 C3Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17482              :     Real64 C1Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17483              :     Real64 C2Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17484              :     Real64 C3Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17485              :     Real64 CoilOnOffRatio;         // coil on/off ratio: time coil is on divided by total time
   17486              :     Real64 deltaT;                 // Difference between evaporating/condensing temperature and coil surface temperature (C)
   17487              :     Real64 FanSpdRatioMin;         // Min fan speed ratio, below which the cycling will be activated (-)
   17488              :     Real64 FanSpdRatioMax;         // Max fan speed ratio (-)
   17489              :     Real64 Garate;                 // Nominal air mass flow rate (m3/s)
   17490              :     Real64 MaxSH;                  // Max super heating degrees (C)
   17491              :     Real64 MaxSC;                  // Max subcooling degrees (C)
   17492              :     Real64 QinSenMin1;             // Coil capacity at minimum fan speed, corresponding to real SH (W)
   17493              :     Real64 QinSenMin2;             // Coil capacity at minimum fan speed, corresponding to corresponds maximum SH (W)
   17494              :     Real64 QinSenPerFlowRate;      // Coil capacity per air mass flow rate(W-s/kg)
   17495              :     Real64 QCoilSenCoolingLoad;    // Coil sensible cooling load (W)
   17496              :     Real64 QCoilSenHeatingLoad;    // Coil sensible heating load (W)
   17497              :     Real64 Ratio1;                 // Fan speed ratio (-)
   17498              :     Real64 RHsat;                  // Relative humidity of the air at saturated condition(-)
   17499              :     Real64 SH;                     // Super heating degrees (C)
   17500              :     Real64 SC;                     // Subcooling degrees (C)
   17501              :     Real64 Ts_1;                   // Air temperature at the coil surface, corresponding to SH (C)
   17502              :     Real64 Ts_2;                   // Air temperature at the coil surface, corresponding to MaxSH (C)
   17503              :     Real64 To_1;                   // Air temperature at the coil outlet, corresponding to SH (C)
   17504              :     Real64 To_2;                   // Air temperature at the coil outlet, corresponding to MaxSH (C)
   17505              :     Real64 Ts;                     // Air temperature at the coil surface (C)
   17506              :     Real64 Ws;                     // Air humidity ratio at the coil surface (kg/kg)
   17507              : 
   17508        90388 :     RHsat = 0.98; // Saturated RH
   17509        90388 :     MaxSH = 15;
   17510        90388 :     MaxSC = 20;
   17511        90388 :     Garate = state.dataDXCoils->DXCoil(CoilIndex).RatedAirMassFlowRate(1);
   17512        90388 :     FanSpdRatioMin = min(OAMassFlow / Garate, 1.0); // ensure that coil flow rate is higher than OA flow rate
   17513              : 
   17514        90388 :     if (QCoil == 0) {
   17515              :         // No Heating or Cooling
   17516            0 :         FanSpdRatio = OAMassFlow / Garate;
   17517            0 :         CoilOnOffRatio = 0.0;
   17518              : 
   17519            0 :         SHact = 999.0;
   17520            0 :         SCact = 999.0;
   17521            0 :         Tout = Tin;
   17522            0 :         Hout = PsyHFnTdbW(Tin, Win);
   17523            0 :         Wout = Win;
   17524              : 
   17525        90388 :     } else if (QCoil < 0) {
   17526              :         // Cooling Mode
   17527              : 
   17528              :         // Obtain coil cooling loads
   17529        47821 :         QCoilSenCoolingLoad = -QCoil;
   17530              : 
   17531              :         // Coefficients describing coil performance
   17532        47821 :         SH = state.dataDXCoils->DXCoil(CoilIndex).SH;
   17533        47821 :         C1Tevap = state.dataDXCoils->DXCoil(CoilIndex).C1Te;
   17534        47821 :         C2Tevap = state.dataDXCoils->DXCoil(CoilIndex).C2Te;
   17535        47821 :         C3Tevap = state.dataDXCoils->DXCoil(CoilIndex).C3Te;
   17536        47821 :         BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUEvap;
   17537              : 
   17538              :         // Coil sensible heat transfer_minimum value
   17539        47821 :         CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, SH, BF, QinSenPerFlowRate, Ts_1);
   17540        47821 :         To_1 = Tin - QinSenPerFlowRate / 1005;
   17541        47821 :         QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
   17542              : 
   17543        47821 :         CalcVRFCoilSenCap(state, FlagCoolMode, CoilIndex, Tin, TeTc, MaxSH, BF, QinSenPerFlowRate, Ts_2);
   17544        47821 :         To_2 = Tin - QinSenPerFlowRate / 1005;
   17545        47821 :         QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
   17546              : 
   17547        47821 :         if (QCoilSenCoolingLoad > QinSenMin1) {
   17548              :             // Increase fan speed to meet room sensible load; SH is not updated
   17549        45830 :             FanSpdRatioMax = 1.0;
   17550       130189 :             auto f = [QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
   17551       130189 :                 return FanSpdResidualCool(FanSpdRto, QCoilSenCoolingLoad, Ts_1, Tin, Garate, BF);
   17552        45830 :             };
   17553        45830 :             General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
   17554        45830 :             if (SolFla < 0) {
   17555         7301 :                 Ratio1 = FanSpdRatioMax; // over capacity
   17556              :             }
   17557        45830 :             FanSpdRatio = Ratio1;
   17558        45830 :             CoilOnOffRatio = 1.0;
   17559              : 
   17560        45830 :             Tout = To_1; // Since SH is not updated
   17561        45830 :             Ws = PsyWFnTdbRhPb(state, Ts_1, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
   17562        45830 :             if (Ws < Win) {
   17563        45829 :                 Wout = Win - (Win - Ws) * (1 - BF);
   17564              :             } else {
   17565            1 :                 Wout = Win;
   17566              :             }
   17567        45830 :             Hout = PsyHFnTdbW(Tout, Wout);
   17568        45830 :             SCact = 999.0;
   17569        45830 :             SHact = SH;
   17570              : 
   17571              :         } else {
   17572              :             // Low load modification algorithm
   17573              :             // Need to increase SH to further reduce coil capacity
   17574              :             // May further implement coil cycling control if SC modification is not enough
   17575              : 
   17576         1991 :             FanSpdRatio = FanSpdRatioMin;
   17577              : 
   17578         1991 :             CoilOnOffRatio = 1.0;
   17579              : 
   17580         1991 :             Tout = Tin - QCoilSenCoolingLoad / 1005.0 / FanSpdRatioMin / Garate;
   17581         1991 :             Ts = Tin - (Tin - Tout) / (1 - BF);
   17582         1991 :             deltaT = Ts - TeTc;
   17583              : 
   17584              :             // Update SH
   17585         1991 :             if (C3Tevap <= 0.0) {
   17586         1991 :                 if (C2Tevap > 0.0) {
   17587         1991 :                     SHact = (deltaT - C1Tevap) / C2Tevap;
   17588              :                 } else {
   17589            0 :                     SHact = 998.0;
   17590              :                 }
   17591              :             } else {
   17592            0 :                 SHact = (-C2Tevap + sqrt(pow_2(C2Tevap) - 4 * C3Tevap * (C1Tevap - deltaT))) / 2 / C3Tevap;
   17593              :             }
   17594              : 
   17595         1991 :             Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
   17596         1991 :             if (Ws < Win) {
   17597         1776 :                 Wout = Win - (Win - Ws) * (1 - BF);
   17598              :             } else {
   17599          215 :                 Wout = Win;
   17600              :             }
   17601              : 
   17602         1991 :             if (SHact > MaxSH) {
   17603              :                 // Further implement On/Off Control
   17604          791 :                 SHact = MaxSH;
   17605          791 :                 CoilOnOffRatio = QCoilSenCoolingLoad / QinSenMin2;
   17606              : 
   17607          791 :                 Ts = Ts_2;
   17608          791 :                 Ws = PsyWFnTdbRhPb(state, Ts, RHsat, state.dataEnvrn->OutBaroPress, "ControlVRFIUCoil");
   17609          791 :                 if (Ws < Win) {
   17610          791 :                     Wout = Win - (Win - Ws) * (1 - BF);
   17611              :                 } else {
   17612            0 :                     Wout = Win;
   17613              :                 }
   17614              : 
   17615              :                 // outlet air temperature and humidity ratio is time-weighted
   17616          791 :                 Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
   17617          791 :                 Wout = CoilOnOffRatio * Wout + (1 - CoilOnOffRatio) * Win;
   17618              :             }
   17619              : 
   17620         1991 :             Hout = PsyHFnTdbW(Tout, Wout);
   17621         1991 :             SCact = 999.0;
   17622              :         }
   17623              : 
   17624        42567 :     } else if (QCoil > 0) {
   17625              :         // Heating Mode
   17626              : 
   17627              :         // Obtain zonal heating loads
   17628        42567 :         QCoilSenHeatingLoad = QCoil;
   17629              : 
   17630              :         // Coefficients describing coil performance
   17631        42567 :         SC = state.dataDXCoils->DXCoil(CoilIndex).SC;
   17632        42567 :         C1Tcond = state.dataDXCoils->DXCoil(CoilIndex).C1Tc;
   17633        42567 :         C2Tcond = state.dataDXCoils->DXCoil(CoilIndex).C2Tc;
   17634        42567 :         C3Tcond = state.dataDXCoils->DXCoil(CoilIndex).C3Tc;
   17635        42567 :         BF = state.dataDXCoils->DXCoil(CoilIndex).RateBFVRFIUCond;
   17636              : 
   17637              :         // Coil sensible heat transfer_minimum value
   17638        42567 :         CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, SC, BF, QinSenPerFlowRate, Ts_1);
   17639        42567 :         To_1 = QinSenPerFlowRate / 1005 + Tin;
   17640        42567 :         QinSenMin1 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds real SH
   17641              : 
   17642        42567 :         CalcVRFCoilSenCap(state, FlagHeatMode, CoilIndex, Tin, TeTc, MaxSC, BF, QinSenPerFlowRate, Ts_2);
   17643        42567 :         To_2 = QinSenPerFlowRate / 1005 + Tin;
   17644        42567 :         QinSenMin2 = FanSpdRatioMin * Garate * QinSenPerFlowRate; // Corresponds maximum SH
   17645              : 
   17646        42567 :         if (QCoilSenHeatingLoad > QinSenMin1) {
   17647              :             // Modulate fan speed to meet room sensible load; SC is not updated
   17648        42271 :             FanSpdRatioMax = 1.0;
   17649       126812 :             auto f = [QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF](Real64 FanSpdRto) {
   17650       126812 :                 return FanSpdResidualHeat(FanSpdRto, QCoilSenHeatingLoad, Ts_1, Tin, Garate, BF);
   17651        42271 :             };
   17652        42271 :             General::SolveRoot(state, 1.0e-3, MaxIter, SolFla, Ratio1, f, FanSpdRatioMin, FanSpdRatioMax);
   17653              :             // this will likely cause problems eventually, -1 and -2 mean different things
   17654        42271 :             if (SolFla < 0) {
   17655            1 :                 Ratio1 = FanSpdRatioMax; // over capacity
   17656              :             }
   17657        42271 :             FanSpdRatio = Ratio1;
   17658        42271 :             CoilOnOffRatio = 1.0;
   17659              : 
   17660        42271 :             Tout = Tin + (Ts_1 - Tin) * (1 - BF);
   17661        42271 :             Wout = Win;
   17662        42271 :             Hout = PsyHFnTdbW(Tout, Wout);
   17663        42271 :             SHact = 999.0;
   17664        42271 :             SCact = SC;
   17665              : 
   17666              :         } else {
   17667              :             // Low load modification algorithm
   17668              :             // Need to increase SC to further reduce coil heating capacity
   17669              :             // May further implement coil cycling control if SC modification is not enough
   17670              : 
   17671          296 :             FanSpdRatio = FanSpdRatioMin;
   17672          296 :             CoilOnOffRatio = 1.0;
   17673              : 
   17674          296 :             Tout = Tin + QCoilSenHeatingLoad / 1005.0 / FanSpdRatio / Garate;
   17675          296 :             Ts = Tin + (Tout - Tin) / (1 - BF);
   17676          296 :             deltaT = TeTc - Ts;
   17677              : 
   17678              :             // Update SC
   17679          296 :             if (C3Tcond <= 0.0) {
   17680            0 :                 if (C2Tcond > 0.0) {
   17681            0 :                     SCact = (deltaT - C1Tcond) / C2Tcond;
   17682              :                 } else {
   17683            0 :                     SCact = 998.0;
   17684              :                 }
   17685              :             } else {
   17686          296 :                 SCact = (-C2Tcond + sqrt(pow_2(C2Tcond) - 4 * C3Tcond * (C1Tcond - deltaT))) / 2 / C3Tcond;
   17687              :             }
   17688              : 
   17689          296 :             if (SCact > MaxSC) {
   17690              :                 // Implement On/Off Control
   17691           77 :                 SCact = MaxSC;
   17692           77 :                 CoilOnOffRatio = QCoilSenHeatingLoad / QinSenMin2;
   17693              :                 // outlet air temperature is time-weighted
   17694           77 :                 Tout = CoilOnOffRatio * To_2 + (1 - CoilOnOffRatio) * Tin;
   17695              :             }
   17696          296 :             Wout = Win;
   17697          296 :             Hout = PsyHFnTdbW(Tout, Wout);
   17698          296 :             SHact = 999.0;
   17699              :         }
   17700              :     }
   17701        90388 : }
   17702              : 
   17703       180788 : void CalcVRFCoilSenCap(EnergyPlusData &state,
   17704              :                        int const OperationMode, // mode 0 for cooling, 1 for heating
   17705              :                        int const CoilNum,       // index to VRFTU cooling or heating coil
   17706              :                        Real64 const Tinlet,     // dry bulb temperature of air entering the coil
   17707              :                        Real64 const TeTc,       // evaporating or condensing temperature
   17708              :                        Real64 const SHSC,       // SH at cooling /SC at heating
   17709              :                        Real64 const BF,         // Bypass factor
   17710              :                        Real64 &Q_sen,           // VRF coil sensible capacity per air mass flow rate
   17711              :                        Real64 &T_coil_surf      // Air temperature at coil surface
   17712              : )
   17713              : {
   17714              :     // SUBROUTINE INFORMATION:
   17715              :     //       AUTHOR         Rongpeng Zhang, LBNL
   17716              :     //       DATE WRITTEN   Jul 2015
   17717              :     //
   17718              :     // PURPOSE OF THIS SUBROUTINE:
   17719              :     //        Calculate the VRF coil sensible capacity per air mass flow rate, given:
   17720              :     //        (1) refrigerant temperature (Te or Tc), (2) SH or SC, and (3) inlet air temperature.
   17721              :     //
   17722              :     // METHODOLOGY EMPLOYED:
   17723              :     //        A new physics based VRF model appliable for Fluid Temperature Control.
   17724              :     //
   17725              : 
   17726       180788 :     int constexpr FlagCoolMode(0); // Flag for cooling mode
   17727       180788 :     int constexpr FlagHeatMode(1); // Flag for heating mode
   17728              :     Real64 C1Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17729              :     Real64 C2Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17730              :     Real64 C3Tevap;                // Coefficient for indoor unit coil evaporating temperature curve (-)
   17731              :     Real64 C1Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17732              :     Real64 C2Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17733              :     Real64 C3Tcond;                // Coefficient for indoor unit coil condensing temperature curve (-)
   17734              :     Real64 deltaT;                 // Difference between Te/Tc and coil surface temperature (C)
   17735              :     Real64 SH;                     // Super heating at cooling mode(C)
   17736              :     Real64 SC;                     // Subcooling at heating mode (C)
   17737              :     Real64 T_coil_in;              // Air temperature at coil inlet (C)
   17738              :     Real64 T_coil_out;             // Air temperature at coil outlet (C)
   17739              : 
   17740       180788 :     if (OperationMode == FlagCoolMode) {
   17741              :         // Cooling: OperationMode 0
   17742              : 
   17743        95654 :         C1Tevap = state.dataDXCoils->DXCoil(CoilNum).C1Te;
   17744        95654 :         C2Tevap = state.dataDXCoils->DXCoil(CoilNum).C2Te;
   17745        95654 :         C3Tevap = state.dataDXCoils->DXCoil(CoilNum).C3Te;
   17746        95654 :         SH = SHSC;
   17747        95654 :         T_coil_in = Tinlet;
   17748              : 
   17749              :         // Coil surface temperature
   17750        95654 :         deltaT = C3Tevap * SH * SH + C2Tevap * SH + C1Tevap;
   17751        95654 :         T_coil_surf = TeTc + deltaT;
   17752              : 
   17753              :         // Outlet air temperature
   17754        95654 :         T_coil_out = T_coil_in - (T_coil_in - T_coil_surf) * (1 - BF);
   17755              : 
   17756              :         // Coil sensilbe heat transfer per mass flow rate
   17757        95654 :         Q_sen = max(1005 * (T_coil_in - T_coil_out), 0.0);
   17758              : 
   17759        85134 :     } else if (OperationMode == FlagHeatMode) {
   17760              :         // Heating: OperationMode 1
   17761              : 
   17762        85134 :         C1Tcond = state.dataDXCoils->DXCoil(CoilNum).C1Tc;
   17763        85134 :         C2Tcond = state.dataDXCoils->DXCoil(CoilNum).C2Tc;
   17764        85134 :         C3Tcond = state.dataDXCoils->DXCoil(CoilNum).C3Tc;
   17765        85134 :         SC = SHSC;
   17766        85134 :         T_coil_in = Tinlet;
   17767              : 
   17768              :         // Coil surface temperature
   17769        85134 :         deltaT = C3Tcond * SC * SC + C2Tcond * SC + C1Tcond;
   17770        85134 :         T_coil_surf = TeTc - deltaT;
   17771              : 
   17772              :         // Coil outlet air temperature
   17773        85134 :         T_coil_out = T_coil_in + (T_coil_surf - T_coil_in) * (1 - BF);
   17774              : 
   17775              :         // Coil sensilbe heat transfer_minimum value
   17776        85134 :         Q_sen = max(1005 * (T_coil_out - T_coil_in), 0.0);
   17777              :     }
   17778       180788 : }
   17779              : 
   17780            6 : void CalcVRFCoilCapModFac(EnergyPlusData &state,
   17781              :                           int const OperationMode,                   // mode 0 for cooling, 1 for heating
   17782              :                           ObjexxFCL::Optional<int const> CoilIndex,  // index to VRFTU cooling or heating coil
   17783              :                           ObjexxFCL::Optional<std::string> CoilName, // name of VRFTU cooling or heating coil
   17784              :                           Real64 const Tinlet,                       // dry bulb temperature of air entering the coil
   17785              :                           ObjexxFCL::Optional<Real64 const> TeTc,    // evaporating or condensing temperature
   17786              :                           ObjexxFCL::Optional<Real64 const> SHSC,    // SH at cooling /SC at heating
   17787              :                           ObjexxFCL::Optional<Real64 const> BF,      // Bypass factor
   17788              :                           Real64 &CapModFac                          // Coil capacity modification factor
   17789              : )
   17790              : {
   17791              :     // SUBROUTINE INFORMATION:
   17792              :     //       AUTHOR         Rongpeng Zhang, LBNL
   17793              :     //       DATE WRITTEN   Jul 2015
   17794              :     //
   17795              :     // PURPOSE OF THIS SUBROUTINE:
   17796              :     //        Calculate the VRF coil capacity modification factor, which is the ratio of
   17797              :     //        the capacity at real conditions and that at rated conditions.
   17798              :     //        This is used for the coil sizing subroutine.
   17799              :     //
   17800              :     // METHODOLOGY EMPLOYED:
   17801              :     //        A new physics based VRF model applicable for Fluid Temperature Control.
   17802              :     //
   17803              : 
   17804            6 :     bool ErrorsFound(false);       // Flag for errors
   17805            6 :     int constexpr FlagCoolMode(0); // Flag for cooling mode
   17806            6 :     int constexpr FlagHeatMode(1); // Flag for heating mode
   17807            6 :     Real64 constexpr SH_rate(3);   // Super heating at cooling mode, default 3(C)
   17808            6 :     Real64 constexpr SC_rate(5);   // Subcooling at heating mode, default 5 (C)
   17809            6 :     Real64 constexpr Te_rate(6);   // Evaporating temperature at cooling mode, default 6 (C)
   17810            6 :     Real64 constexpr Tc_rate(44);  // Condensing temperature at heating mode, default 44 (C)
   17811              :     int CoilNum;                   // index to VRFTU cooling or heating coil
   17812              :     Real64 BF_real;                // Bypass factor (-)
   17813              :     Real64 BFC_rate;               // Bypass factor at cooling mode (-)
   17814              :     Real64 BFH_rate;               // Bypass factor at heating mode (-)
   17815              :     Real64 SHSC_real;              // Super heating or Subcooling (C)
   17816              :     Real64 TeTc_real;              // Evaporating temperature or condensing temperature (C)
   17817              :     Real64 Ts;                     // Air temperature at coil surface (C)
   17818              :     Real64 Q_real;                 // Coil capacity at given condition (W)
   17819              :     Real64 Q_rate;                 // Coil capacity at rated condition (W)
   17820              : 
   17821            6 :     if (present(CoilIndex)) {
   17822            0 :         CoilNum = CoilIndex;
   17823              :     } else {
   17824            6 :         GetDXCoilIndex(state, CoilName, CoilNum, ErrorsFound, "", true);
   17825              :     }
   17826              : 
   17827            6 :     BFC_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUEvap;
   17828            6 :     BFH_rate = state.dataDXCoils->DXCoil(CoilNum).RateBFVRFIUCond;
   17829              : 
   17830            6 :     if (OperationMode == FlagCoolMode) {
   17831              :         // Cooling: OperationMode 0
   17832              : 
   17833            6 :         if (present(BF)) {
   17834            0 :             BF_real = BF;
   17835              :         } else {
   17836            6 :             BF_real = BFC_rate;
   17837              :         }
   17838            6 :         if (present(TeTc)) {
   17839            0 :             TeTc_real = TeTc;
   17840              :         } else {
   17841            6 :             TeTc_real = Te_rate;
   17842              :         }
   17843            6 :         if (present(SHSC)) {
   17844            0 :             SHSC_real = SHSC;
   17845              :         } else {
   17846            6 :             SHSC_real = SH_rate;
   17847              :         }
   17848              : 
   17849              :         // Coil capacity at rated conditions
   17850            6 :         CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, 26, Te_rate, SH_rate, BFC_rate, Q_rate, Ts);
   17851              : 
   17852              :         // Coil capacity at given conditions
   17853            6 :         CalcVRFCoilSenCap(state, FlagCoolMode, CoilNum, Tinlet, TeTc_real, SHSC_real, BF_real, Q_real, Ts);
   17854              : 
   17855            6 :         if (Q_rate > 0) {
   17856            6 :             CapModFac = Q_real / Q_rate;
   17857              :         } else {
   17858            0 :             CapModFac = 1.0;
   17859              :         }
   17860              : 
   17861            0 :     } else if (OperationMode == FlagHeatMode) {
   17862              :         // Heating: OperationMode 1
   17863              : 
   17864            0 :         if (present(BF)) {
   17865            0 :             BF_real = BF;
   17866              :         } else {
   17867            0 :             BF_real = BFH_rate;
   17868              :         }
   17869            0 :         if (present(TeTc)) {
   17870            0 :             TeTc_real = TeTc;
   17871              :         } else {
   17872            0 :             TeTc_real = Tc_rate;
   17873              :         }
   17874            0 :         if (present(SHSC)) {
   17875            0 :             SHSC_real = SHSC;
   17876              :         } else {
   17877            0 :             SHSC_real = SC_rate;
   17878              :         }
   17879              : 
   17880              :         // Coil capacity at rated conditions
   17881            0 :         CalcVRFCoilSenCap(state, FlagHeatMode, CoilNum, 20, Tc_rate, SC_rate, BFH_rate, Q_rate, Ts);
   17882              : 
   17883              :         // Coil capacity at given conditions
   17884            0 :         CalcVRFCoilSenCap(state, FlagHeatMode, CoilNum, Tinlet, TeTc_real, SHSC_real, BF_real, Q_real, Ts);
   17885              : 
   17886            0 :         if (Q_rate > 0) {
   17887            0 :             CapModFac = Q_real / Q_rate;
   17888              :         } else {
   17889            0 :             CapModFac = 1.0;
   17890              :         }
   17891              :     }
   17892            6 : }
   17893              : 
   17894       130190 : Real64 FanSpdResidualCool(
   17895              :     Real64 const FanSpdRto, Real64 const QCoilSenCoolingLoad, Real64 const Ts_1, Real64 const Tin, Real64 const Garate, Real64 const BF)
   17896              : {
   17897              :     // FUNCTION INFORMATION:
   17898              :     //       AUTHOR         Xiufeng Pang (XP)
   17899              :     //       DATE WRITTEN   Mar 2013
   17900              :     //       MODIFIED       Nov 2015, RP Zhang, LBNL
   17901              :     //
   17902              :     // PURPOSE OF THIS FUNCTION:
   17903              :     //       Calculates residual function (desired zone cooling load - actual coil cooling capacity)
   17904              :     //       This is used to modify the fan speed to adjust the coil cooling capacity to match
   17905              :     //       the zone cooling load.
   17906              :     //
   17907       130190 :     Real64 ZnSenLoad = QCoilSenCoolingLoad;
   17908              :     // +-100 W minimum zone load?
   17909       130190 :     if (std::abs(ZnSenLoad) < 100.0) {
   17910            0 :         ZnSenLoad = sign(100.0, ZnSenLoad);
   17911              :     }
   17912       130190 :     Real64 Tout = Tin - (Tin - Ts_1) * (1 - BF);
   17913       130190 :     Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tin - Tout);
   17914       130190 :     return (TotCap - ZnSenLoad) / ZnSenLoad;
   17915              : }
   17916              : 
   17917       126813 : Real64 FanSpdResidualHeat(Real64 FanSpdRto, Real64 QCoilSenHeatingLoad, Real64 Ts_1, Real64 Tin, Real64 Garate, Real64 BF)
   17918              : {
   17919              : 
   17920              :     // FUNCTION INFORMATION:
   17921              :     //       AUTHOR         Xiufeng Pang (XP)
   17922              :     //       DATE WRITTEN   Mar 2013
   17923              :     //       MODIFIED       Nov 2015, RP Zhang, LBNL
   17924              :     //
   17925              :     // PURPOSE OF THIS FUNCTION:
   17926              :     //       Calculates residual function (desired zone heating load - actual heating coil capacity)
   17927              :     //       This is used to modify the fan speed to adjust the coil heating capacity to match
   17928              :     //       the zone heating load.
   17929              :     //
   17930              : 
   17931       126813 :     Real64 ZnSenLoad = QCoilSenHeatingLoad;
   17932              :     // +-100 W minimum zone load?
   17933       126813 :     if (std::abs(ZnSenLoad) < 100.0) {
   17934            0 :         ZnSenLoad = sign(100.0, ZnSenLoad);
   17935              :     }
   17936       126813 :     Real64 Tout = Tin + (Ts_1 - Tin) * (1 - BF);
   17937       126813 :     Real64 TotCap = FanSpdRto * Garate * 1005.0 * (Tout - Tin);
   17938       126813 :     return (TotCap - ZnSenLoad) / ZnSenLoad;
   17939              : }
   17940              : 
   17941            4 : void SetMSHPDXCoilHeatRecoveryFlag(EnergyPlusData &state, int const DXCoilNum)
   17942              : {
   17943              : 
   17944              :     // SUBROUTINE INFORMATION:
   17945              :     //       AUTHOR         L. Gu
   17946              :     //       DATE WRITTEN   Sep. 2015
   17947              : 
   17948              :     // PURPOSE OF THIS SUBROUTINE:
   17949              :     // Set the heat recovery flag true when the parent object requests heat recovery.
   17950              : 
   17951            4 :     if (state.dataDXCoils->DXCoil(DXCoilNum).FuelType != Constant::eFuel::Electricity) {
   17952            2 :         state.dataDXCoils->DXCoil(DXCoilNum).MSHPHeatRecActive = true;
   17953              :     }
   17954            4 : }
   17955              : 
   17956            4 : void SetDXCoilAirLoopNumber(EnergyPlusData &state, std::string const &CoilName, int const AirLoopNum)
   17957              : {
   17958              :     // SUBROUTINE INFORMATION:
   17959              :     //       AUTHOR         L. Gu
   17960              :     //       DATE WRITTEN   March, 2018
   17961              : 
   17962              :     // PURPOSE OF THIS SUBROUTINE:
   17963              :     // Set AirLoopNum for AFN model with multiple AirLoops
   17964              : 
   17965              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   17966              :     int WhichCoil;
   17967              : 
   17968            4 :     if (state.dataDXCoils->GetCoilsInputFlag) {
   17969            1 :         GetDXCoils(state);
   17970            1 :         state.dataDXCoils->GetCoilsInputFlag = false;
   17971              :     }
   17972              : 
   17973            4 :     WhichCoil = Util::FindItemInList(CoilName, state.dataDXCoils->DXCoil);
   17974            4 :     if (WhichCoil != 0) {
   17975            2 :         state.dataDXCoils->DXCoil(WhichCoil).AirLoopNum = AirLoopNum;
   17976              :     } else {
   17977            2 :         ShowSevereError(state, format("SetDXCoilAirLoopNumber: Could not find Coil \"Name=\"{}\"", CoilName));
   17978              :     }
   17979            4 : } // must match coil names for the coil type
   17980              : 
   17981            1 : void DisableLatentDegradation(EnergyPlusData &state, int const DXCoilNum)
   17982              : {
   17983              :     // SUBROUTINE INFORMATION:
   17984              :     //       AUTHOR         L. Gu
   17985              :     //       DATE WRITTEN   JUne, 2019
   17986              : 
   17987              :     // PURPOSE OF THIS SUBROUTINE:
   17988              :     // Disable latent degradation when direct solution is used.
   17989              : 
   17990            1 :     state.dataDXCoils->DXCoil(DXCoilNum).Twet_Rated(1) = 0.0;
   17991            1 : }
   17992              : 
   17993              : } // namespace EnergyPlus::DXCoils
        

Generated by: LCOV version 2.0-1